about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2020-08-08 18:09:40 -0700
committerAlex Crichton <alex@alexcrichton.com>2020-08-08 18:09:40 -0700
commitb21a3de35f4841ce4f5f7cd997faf9531ea998f2 (patch)
tree8b6ad83515f93895ee421d4636239aad5901c786 /src
parent2bac92bba14f3b260b337d2a51c77c0780456e65 (diff)
downloadrust-b21a3de35f4841ce4f5f7cd997faf9531ea998f2.tar.gz
rust-b21a3de35f4841ce4f5f7cd997faf9531ea998f2.zip
Don't try to use wasm intrinsics on vectors
This commit fixes an issue with #74695 where the fptosi and fptoui
specializations on wasm were accidentally used on vector types by the
`simd_cast` intrinsic. This issue showed up as broken CI for the stdsimd
crate. Here this commit simply skips the specialization on vector kinds
flowing into `fpto{s,u}i`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_codegen_llvm/builder.rs55
1 files changed, 31 insertions, 24 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 1124e91bf71..a0f4311b33a 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -728,20 +728,25 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         // codegen. Note that this has a semantic difference in that the
         // intrinsic can trap whereas `fptoui` never traps. That difference,
         // however, is handled by `fptosui_may_trap` above.
+        //
+        // Note that we skip the wasm intrinsics for vector types where `fptoui`
+        // must be used instead.
         if self.wasm_and_missing_nontrapping_fptoint() {
             let src_ty = self.cx.val_ty(val);
-            let float_width = self.cx.float_width(src_ty);
-            let int_width = self.cx.int_width(dest_ty);
-            let name = match (int_width, float_width) {
-                (32, 32) => Some("llvm.wasm.trunc.unsigned.i32.f32"),
-                (32, 64) => Some("llvm.wasm.trunc.unsigned.i32.f64"),
-                (64, 32) => Some("llvm.wasm.trunc.unsigned.i64.f32"),
-                (64, 64) => Some("llvm.wasm.trunc.unsigned.i64.f64"),
-                _ => None,
-            };
-            if let Some(name) = name {
-                let intrinsic = self.get_intrinsic(name);
-                return self.call(intrinsic, &[val], None);
+            if self.cx.type_kind(src_ty) != TypeKind::Vector {
+                let float_width = self.cx.float_width(src_ty);
+                let int_width = self.cx.int_width(dest_ty);
+                let name = match (int_width, float_width) {
+                    (32, 32) => Some("llvm.wasm.trunc.unsigned.i32.f32"),
+                    (32, 64) => Some("llvm.wasm.trunc.unsigned.i32.f64"),
+                    (64, 32) => Some("llvm.wasm.trunc.unsigned.i64.f32"),
+                    (64, 64) => Some("llvm.wasm.trunc.unsigned.i64.f64"),
+                    _ => None,
+                };
+                if let Some(name) = name {
+                    let intrinsic = self.get_intrinsic(name);
+                    return self.call(intrinsic, &[val], None);
+                }
             }
         }
         unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) }
@@ -750,18 +755,20 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
         if self.wasm_and_missing_nontrapping_fptoint() {
             let src_ty = self.cx.val_ty(val);
-            let float_width = self.cx.float_width(src_ty);
-            let int_width = self.cx.int_width(dest_ty);
-            let name = match (int_width, float_width) {
-                (32, 32) => Some("llvm.wasm.trunc.signed.i32.f32"),
-                (32, 64) => Some("llvm.wasm.trunc.signed.i32.f64"),
-                (64, 32) => Some("llvm.wasm.trunc.signed.i64.f32"),
-                (64, 64) => Some("llvm.wasm.trunc.signed.i64.f64"),
-                _ => None,
-            };
-            if let Some(name) = name {
-                let intrinsic = self.get_intrinsic(name);
-                return self.call(intrinsic, &[val], None);
+            if self.cx.type_kind(src_ty) != TypeKind::Vector {
+                let float_width = self.cx.float_width(src_ty);
+                let int_width = self.cx.int_width(dest_ty);
+                let name = match (int_width, float_width) {
+                    (32, 32) => Some("llvm.wasm.trunc.signed.i32.f32"),
+                    (32, 64) => Some("llvm.wasm.trunc.signed.i32.f64"),
+                    (64, 32) => Some("llvm.wasm.trunc.signed.i64.f32"),
+                    (64, 64) => Some("llvm.wasm.trunc.signed.i64.f64"),
+                    _ => None,
+                };
+                if let Some(name) = name {
+                    let intrinsic = self.get_intrinsic(name);
+                    return self.call(intrinsic, &[val], None);
+                }
             }
         }
         unsafe { llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty, UNNAMED) }