Closed

Description
one of my current project would return an array at the end.
The code I wrote involves simd so it need to be included inside an unsafe parenthesis.
It just behaves very OK when running as waterfall from beginning to the end.
But, now I have made those simd code as a feature to be optional, and added #[cfg(feature="simd")]
sort of tags before each unsafe {...}
, the cargo run/test/...
would always leave error to me:
# cargo test hash_abc --features simd -- --nocapture
Compiling cryptaq v0.1.0 (/home/user/cryptaq)
warning: unused import: `super::hmac`
--> src/sm3/sm3.rs:966:9
|
966 | use super::hmac;
| ^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: `cryptaq` (lib test) generated 1 warning
warning: function is never used: `hmac`
--> src/sm3/sm3.rs:932:8
|
932 | pub fn hmac(m: String, key: String) -> [u8; HALF_BLOCK_SIZE] {
| ^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: `cryptaq` (bin "bench" test) generated 2 warnings (1 duplicate)
warning: `cryptaq` (bin "cryptaq" test) generated 1 warning (1 duplicate)
Finished test [unoptimized + debuginfo] target(s) in 1.47s
Running unittests (target/debug/deps/libaq-5ebfab2dfe6fe8da)
running 1 test
error: test failed, to rerun pass '--lib'
Caused by:
process didn't exit successfully: `/home/user/cryptaq/target/debug/deps/libaq-5ebfab2dfe6fe8da hash_abc --nocapture` (signal: 11, SIGSEGV: invalid memory reference)
# cargo run --release --example cwo --features simd
Compiling cryptaq v0.1.0 (/home/user/cryptaq)
Finished release [optimized] target(s) in 5.61s
Running `target/release/examples/cwo`
testing a length of 6061-Byte message...
fish: Job 1, 'cargo run --release --example c…' terminated by signal SIGSEGV (Address boundary error)
So I noticed #6489, I added codegen-units = 1
and it does'nt work. And I have the following hints.
# cargo fix --allow-dirty
Checking cryptaq v0.1.0 (/home/user/cryptaq)
error[E0308]: mismatched types
--> src/sm3/sm3.rs:71:26
|
71 | pub fn hash(m: &[u8]) -> [u8; HALF_BLOCK_SIZE] {
| ---- ^^^^^^^^^^^^^^^^^^^^^ expected array `[u8; 32]`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
For more information about this error, try `rustc --explain E0308`.
error: could not compile `cryptaq` due to previous error
warning: build failed, waiting for other jobs to finish...
warning: unused import: `super::hmac`
--> src/sm3/sm3.rs:966:9
|
966 | use super::hmac;
| ^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: `cryptaq` (lib test) generated 1 warning
error: build failed
This is rediculous because here are the very end of this function:
pub fn hash(m: &[u8]) -> [u8; HALF_BLOCK_SIZE] {
...
#[cfg(feature = "simd_gen_hash")]
unsafe {
simd_gen_hash(digest.get_unchecked(0))
}
#[cfg(feature = "gen_hash")]
{
...
}
}
//...and
#[inline]
#[target_feature(enable = "avx")]
#[target_feature(enable = "avx2")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[allow(unsafe_code)]
unsafe fn simd_gen_hash(final_digest: *const u32) -> [u8; 32] {
// Safe here because such a [u8; 32] array has a fixed size of 256-bit
let pmt = _mm256_load_si256(PMT_ARR.get_unchecked(0) as *const _ as *const __m256i);
// Safe here because we want to shuffle the u8x32 array
let reg = _mm256_shuffle_epi8(_mm256_load_si256(final_digest as *const __m256i), pmt);
// Safe here because a __m256i has same length as a [u8; 32] array
std::mem::transmute::<__m256i, [u8; HALF_BLOCK_SIZE]>(reg)
}
Just what can we do to make this right?