about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-07-20 13:05:37 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-07-20 18:49:50 +0200
commit6fae7db65d5f772cfbf116fbb9e5944447725289 (patch)
treee11bb3110e1c0f33e835d5fe5c9ae71512569c9a
parentf69b07144a151f46aaee1b6230ba4160e9394562 (diff)
downloadrust-6fae7db65d5f772cfbf116fbb9e5944447725289.tar.gz
rust-6fae7db65d5f772cfbf116fbb9e5944447725289.zip
Remove vector fadd/fmul reduction workarounds
The bugs that this was working around have been fixed in LLVM 9.
-rw-r--r--src/librustc_codegen_llvm/builder.rs12
-rw-r--r--src/librustc_codegen_llvm/common.rs19
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs28
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs2
-rw-r--r--src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs10
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs22
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr46
7 files changed, 37 insertions, 102 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 5ac1cf8c36f..894e5c2fd3d 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -1153,11 +1153,14 @@ impl Builder<'a, 'll, 'tcx> {
         }
     }
 
+    pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+        unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
+    }
+    pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+        unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
+    }
     pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
         unsafe {
-            // FIXME: add a non-fast math version once
-            // https://bugs.llvm.org/show_bug.cgi?id=36732
-            // is fixed.
             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
             instr
@@ -1165,9 +1168,6 @@ impl Builder<'a, 'll, 'tcx> {
     }
     pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
         unsafe {
-            // FIXME: add a non-fast math version once
-            // https://bugs.llvm.org/show_bug.cgi?id=36732
-            // is fixed.
             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
             instr
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index e9f25e6344b..f00624f3811 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -166,25 +166,6 @@ impl CodegenCx<'ll, 'tcx> {
             r
         }
     }
-
-    pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
-        unsafe {
-            if self.is_const_real(v) {
-                let mut loses_info: llvm::Bool = 0;
-                let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
-                let loses_info = if loses_info == 1 { true } else { false };
-                Some((r, loses_info))
-            } else {
-                None
-            }
-        }
-    }
-
-    fn is_const_real(&self, v: &'ll Value) -> bool {
-        unsafe {
-            llvm::LLVMIsAConstantFP(v).is_some()
-        }
-    }
 }
 
 impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index dd6cfd7e29e..44b3eff2ac5 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -1640,29 +1640,11 @@ fn generic_simd_intrinsic(
                         }
                     },
                     ty::Float(f) => {
-                        // ordered arithmetic reductions take an accumulator
                         let acc = if $ordered {
-                            let acc = args[1].immediate();
-                            // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36734
-                            // * if the accumulator of the fadd isn't 0, incorrect
-                            //   code is generated
-                            // * if the accumulator of the fmul isn't 1, incorrect
-                            //   code is generated
-                            match bx.const_get_real(acc) {
-                                None => return_error!("accumulator of {} is not a constant", $name),
-                                Some((v, loses_info)) => {
-                                    if $name.contains("mul") && v != 1.0_f64 {
-                                        return_error!("accumulator of {} is not 1.0", $name);
-                                    } else if $name.contains("add") && v != 0.0_f64 {
-                                        return_error!("accumulator of {} is not 0.0", $name);
-                                    } else if loses_info {
-                                        return_error!("accumulator of {} loses information", $name);
-                                    }
-                                }
-                            }
-                            acc
+                            // ordered arithmetic reductions take an accumulator
+                            args[1].immediate()
                         } else {
-                            // unordered arithmetic reductions do not:
+                            // unordered arithmetic reductions use the identity accumulator
                             let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 };
                             match f.bit_width() {
                                 32 => bx.const_real(bx.type_f32(), identity_acc),
@@ -1688,8 +1670,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         }
     }
 
-    arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd_fast, true);
-    arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul_fast, true);
+    arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd, true);
+    arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul, true);
     arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false);
     arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false);
 
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 5d82698d8ef..8c6ea00eb8c 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -719,7 +719,6 @@ extern "C" {
     pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong;
     pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool,
                                   high: &mut u64, low: &mut u64) -> bool;
-    pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: &mut Bool) -> f64;
 
 
     // Operations on composite constants
@@ -1663,7 +1662,6 @@ extern "C" {
     pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
 
     pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>;
-    pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>;
 
     pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
     pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs
index e3faa7c625c..4195444a73f 100644
--- a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs
+++ b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs
@@ -2,7 +2,7 @@
 #![allow(non_camel_case_types)]
 
 // ignore-emscripten
-// ignore-aarch64 FIXME: https://github.com/rust-lang/rust/issues/54510
+// min-system-llvm-version: 9.0
 
 // Test that the simd_reduce_{op} intrinsics produce the correct results.
 
@@ -124,14 +124,14 @@ fn main() {
         assert_eq!(r, 6_f32);
         let r: f32 = simd_reduce_mul_unordered(x);
         assert_eq!(r, -24_f32);
-        // FIXME: only works correctly for accumulator, 0:
-        // https://bugs.llvm.org/show_bug.cgi?id=36734
         let r: f32 = simd_reduce_add_ordered(x, 0.);
         assert_eq!(r, 6_f32);
-        // FIXME: only works correctly for accumulator, 1:
-        // https://bugs.llvm.org/show_bug.cgi?id=36734
         let r: f32 = simd_reduce_mul_ordered(x, 1.);
         assert_eq!(r, -24_f32);
+        let r: f32 = simd_reduce_add_ordered(x, 1.);
+        assert_eq!(r, 7_f32);
+        let r: f32 = simd_reduce_mul_ordered(x, 2.);
+        assert_eq!(r, -48_f32);
 
         let r: f32 = simd_reduce_min(x);
         assert_eq!(r, -2_f32);
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
index 8e67c27ef22..9a6dbe9d9ab 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
@@ -30,13 +30,10 @@ fn main() {
     let z = f32x4(0.0, 0.0, 0.0, 0.0);
 
     unsafe {
-        simd_reduce_add_ordered(z, 0_f32);
-        simd_reduce_mul_ordered(z, 1_f32);
-
-        simd_reduce_add_ordered(z, 2_f32);
-        //~^ ERROR accumulator of simd_reduce_add_ordered is not 0.0
-        simd_reduce_mul_ordered(z, 3_f32);
-        //~^ ERROR accumulator of simd_reduce_mul_ordered is not 1.0
+        simd_reduce_add_ordered(z, 0);
+        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
+        simd_reduce_mul_ordered(z, 1);
+        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
 
         let _: f32 = simd_reduce_and(x);
         //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
@@ -56,16 +53,5 @@ fn main() {
         //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
         let _: bool = simd_reduce_any(z);
         //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-
-        foo(0_f32);
     }
 }
-
-#[inline(never)]
-unsafe fn foo(x: f32) {
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-    simd_reduce_add_ordered(z, x);
-    //~^ ERROR accumulator of simd_reduce_add_ordered is not a constant
-    simd_reduce_mul_ordered(z, x);
-    //~^ ERROR accumulator of simd_reduce_mul_ordered is not a constant
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
index 144571cb263..3863eeac3f3 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
@@ -1,74 +1,62 @@
-error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not 0.0
-  --> $DIR/simd-intrinsic-generic-reduction.rs:36:9
+error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
+  --> $DIR/simd-intrinsic-generic-reduction.rs:33:9
    |
-LL |         simd_reduce_add_ordered(z, 2_f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         simd_reduce_add_ordered(z, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not 1.0
-  --> $DIR/simd-intrinsic-generic-reduction.rs:38:9
+error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
+  --> $DIR/simd-intrinsic-generic-reduction.rs:35:9
    |
-LL |         simd_reduce_mul_ordered(z, 3_f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         simd_reduce_mul_ordered(z, 1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:41:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:38:22
    |
 LL |         let _: f32 = simd_reduce_and(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:43:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:40:22
    |
 LL |         let _: f32 = simd_reduce_or(x);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:45:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:42:22
    |
 LL |         let _: f32 = simd_reduce_xor(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:48:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:45:22
    |
 LL |         let _: f32 = simd_reduce_and(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:50:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:47:22
    |
 LL |         let _: f32 = simd_reduce_or(z);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:52:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:49:22
    |
 LL |         let _: f32 = simd_reduce_xor(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:55:23
+  --> $DIR/simd-intrinsic-generic-reduction.rs:52:23
    |
 LL |         let _: bool = simd_reduce_all(z);
    |                       ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:57:23
+  --> $DIR/simd-intrinsic-generic-reduction.rs:54:23
    |
 LL |         let _: bool = simd_reduce_any(z);
    |                       ^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not a constant
-  --> $DIR/simd-intrinsic-generic-reduction.rs:67:5
-   |
-LL |     simd_reduce_add_ordered(z, x);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not a constant
-  --> $DIR/simd-intrinsic-generic-reduction.rs:69:5
-   |
-LL |     simd_reduce_mul_ordered(z, x);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
+error: aborting due to 10 previous errors