diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-07 19:08:40 +0200 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-09 21:55:29 +0200 |
| commit | 5c95f5fa6b6024ea0b8ed162e5d2c46c41aea1b0 (patch) | |
| tree | b4adf84eda41c22a58c084917b9a893dc8df9659 | |
| parent | 8789c9e59596c5f89c6be6b82a880e016d6c2f31 (diff) | |
| download | rust-5c95f5fa6b6024ea0b8ed162e5d2c46c41aea1b0.tar.gz rust-5c95f5fa6b6024ea0b8ed162e5d2c46c41aea1b0.zip | |
Fix float add/mul reduction codegen
The accumulator is now respected for unordered reductions.
| -rw-r--r-- | src/librustc_codegen_llvm/common.rs | 4 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 5 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/llvm/ffi.rs | 1 | ||||
| -rw-r--r-- | src/librustc_codegen_ssa/traits/consts.rs | 1 |
4 files changed, 9 insertions, 2 deletions
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 3b2701b893b..e9f25e6344b 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -249,6 +249,10 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.const_uint(self.type_i8(), i as u64) } + fn const_real(&self, t: &'ll Type, val: f64) -> &'ll Value { + unsafe { llvm::LLVMConstReal(t, val) } + } + fn const_struct( &self, elts: &[&'ll Value], diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 69f8356f669..dd6cfd7e29e 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1663,9 +1663,10 @@ fn generic_simd_intrinsic( acc } else { // unordered arithmetic reductions do not: + let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 }; match f.bit_width() { - 32 => bx.const_undef(bx.type_f32()), - 64 => bx.const_undef(bx.type_f64()), + 32 => bx.const_real(bx.type_f32(), identity_acc), + 64 => bx.const_real(bx.type_f64(), identity_acc), v => { return_error!(r#" unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 75f639ec3ec..4bf0faa1ec3 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -715,6 +715,7 @@ extern "C" { // Operations on scalar constants pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; + pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: &mut u64, low: &mut u64) -> bool; diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 46286b5329e..248fadfaf0f 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -17,6 +17,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_u64(&self, i: u64) -> Self::Value; fn const_usize(&self, i: u64) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value; + fn const_real(&self, t: Self::Type, val: f64) -> Self::Value; fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; |
