about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-31 04:43:48 +0000
committerbors <bors@rust-lang.org>2023-07-31 04:43:48 +0000
commit3be07c116128527fd9b9392f819b0dc502ff9fe5 (patch)
tree6d372db8af24aa718b711d1825a04b636b97d2a2
parentdfc9d3fee67c1323c396b001197126dbcfa9890e (diff)
parent77ed437de8336940c735d3468fee388f63d92bb6 (diff)
downloadrust-3be07c116128527fd9b9392f819b0dc502ff9fe5.tar.gz
rust-3be07c116128527fd9b9392f819b0dc502ff9fe5.zip
Auto merge of #114266 - calebzulawski:simd-bswap, r=compiler-errors
Fix simd_bswap for i8/u8

#114156 missed this test case ☹️
cc `@workingjubilee`
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs21
-rw-r--r--tests/ui/simd/intrinsic/generic-bswap-byte.rs22
2 files changed, 32 insertions, 11 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 43254bb4de8..ee71fb6e822 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -2096,29 +2096,28 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             sym::simd_cttz => "cttz",
             _ => unreachable!(),
         };
-        let llvm_intrinsic = &format!(
-            "llvm.{}.v{}i{}",
-            intrinsic_name,
-            in_len,
-            in_elem.int_size_and_signed(bx.tcx()).0.bits(),
-        );
+        let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits();
+        let llvm_intrinsic = &format!("llvm.{}.v{}i{}", intrinsic_name, in_len, int_size,);
 
-        return Ok(if matches!(name, sym::simd_ctlz | sym::simd_cttz) {
+        return if name == sym::simd_bswap && int_size == 8 {
+            // byte swap is no-op for i8/u8
+            Ok(args[0].immediate())
+        } else if matches!(name, sym::simd_ctlz | sym::simd_cttz) {
             let fn_ty = bx.type_func(&[vec_ty, bx.type_i1()], vec_ty);
             let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-            bx.call(
+            Ok(bx.call(
                 fn_ty,
                 None,
                 None,
                 f,
                 &[args[0].immediate(), bx.const_int(bx.type_i1(), 0)],
                 None,
-            )
+            ))
         } else {
             let fn_ty = bx.type_func(&[vec_ty], vec_ty);
             let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-            bx.call(fn_ty, None, None, f, &[args[0].immediate()], None)
-        });
+            Ok(bx.call(fn_ty, None, None, f, &[args[0].immediate()], None))
+        };
     }
 
     if name == sym::simd_arith_offset {
diff --git a/tests/ui/simd/intrinsic/generic-bswap-byte.rs b/tests/ui/simd/intrinsic/generic-bswap-byte.rs
new file mode 100644
index 00000000000..13fc942c25a
--- /dev/null
+++ b/tests/ui/simd/intrinsic/generic-bswap-byte.rs
@@ -0,0 +1,22 @@
+// run-pass
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i8x4([i8; 4]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x4([u8; 4]);
+
+extern "platform-intrinsic" {
+    fn simd_bswap<T>(x: T) -> T;
+}
+
+fn main() {
+    unsafe {
+        assert_eq!(simd_bswap(i8x4([0, 1, 2, 3])).0, [0, 1, 2, 3]);
+        assert_eq!(simd_bswap(u8x4([0, 1, 2, 3])).0, [0, 1, 2, 3]);
+    }
+}