//@ revisions: OPT2 OPT3WINX64 OPT3LINX64 //@ [OPT2] compile-flags: -O //@ [OPT3LINX64] compile-flags: -C opt-level=3 //@ [OPT3WINX64] compile-flags: -C opt-level=3 //@ [OPT3LINX64] only-linux //@ [OPT3WINX64] only-windows //@ [OPT3LINX64] only-x86_64 //@ [OPT3WINX64] only-x86_64 //@ min-llvm-version: 18.1.3 #![crate_type = "lib"] #![no_std] // The code is from https://github.com/rust-lang/rust/issues/122805. // Ensure we do not generate the shufflevector instruction // to avoid complicating the code. // CHECK-LABEL: define{{.*}}void @convert( // CHECK-NOT: shufflevector // OPT2: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 2 // OPT2-NEXT: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 4 // OPT2-NEXT: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 6 // OPT2-NEXT: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 8 // OPT2-NEXT: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 10 // OPT2-NEXT: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 12 // OPT2-NEXT: store i16 // OPT2-NEXT: getelementptr inbounds i8, {{.+}} 14 // OPT2-NEXT: store i16 // OPT3LINX64: load <8 x i16> // OPT3LINX64-NEXT: call <8 x i16> @llvm.bswap // OPT3LINX64-NEXT: store <8 x i16> // OPT3WINX64: load <8 x i16> // OPT3WINX64-NEXT: call <8 x i16> @llvm.bswap // OPT3WINX64-NEXT: store <8 x i16> // CHECK-NEXT: ret void #[no_mangle] pub fn convert(value: [u16; 8]) -> [u8; 16] { #[cfg(target_endian = "little")] let bswap = u16::to_be; #[cfg(target_endian = "big")] let bswap = u16::to_le; let addr16 = [ bswap(value[0]), bswap(value[1]), bswap(value[2]), bswap(value[3]), bswap(value[4]), bswap(value[5]), bswap(value[6]), bswap(value[7]), ]; unsafe { core::mem::transmute::<_, [u8; 16]>(addr16) } }