about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2021-07-24 15:24:06 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2021-07-24 15:24:06 +0200
commit344cbac150d08d0931d03ab0651becc977baa64b (patch)
treed05357702d646e37575cef02e943b2829efb0b56
parenta7b06e81fc008750de32b9a57e292bb341d0b842 (diff)
downloadrust-344cbac150d08d0931d03ab0651becc977baa64b.tar.gz
rust-344cbac150d08d0931d03ab0651becc977baa64b.zip
Fix simd_reduce_* intrinsics
-rw-r--r--src/intrinsics/mod.rs6
-rw-r--r--src/intrinsics/simd.rs8
2 files changed, 8 insertions, 6 deletions
diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs
index 42d1a53a2bb..6a818e2df1e 100644
--- a/src/intrinsics/mod.rs
+++ b/src/intrinsics/mod.rs
@@ -218,6 +218,7 @@ fn simd_pair_for_each_lane<'tcx>(
 fn simd_reduce<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     val: CValue<'tcx>,
+    acc: Option<Value>,
     ret: CPlace<'tcx>,
     f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, Value, Value) -> Value,
 ) {
@@ -225,8 +226,9 @@ fn simd_reduce<'tcx>(
     let lane_layout = fx.layout_of(lane_ty);
     assert_eq!(lane_layout, ret.layout());
 
-    let mut res_val = val.value_lane(fx, 0).load_scalar(fx);
-    for lane_idx in 1..lane_count {
+    let (mut res_val, start_lane) =
+        if let Some(acc) = acc { (acc, 0) } else { (val.value_lane(fx, 0).load_scalar(fx), 1) };
+    for lane_idx in start_lane..lane_count {
         let lane = val.value_lane(fx, lane_idx).load_scalar(fx);
         res_val = f(fx, lane_layout, res_val, lane);
     }
diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs
index e952942de87..db36437ab41 100644
--- a/src/intrinsics/simd.rs
+++ b/src/intrinsics/simd.rs
@@ -236,9 +236,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             simd_flt_binop!(fx, fmax(x, y) -> ret);
         };
 
-        simd_reduce_add_ordered | simd_reduce_add_unordered, (c v) {
+        simd_reduce_add_ordered | simd_reduce_add_unordered, (c v, v acc) {
             validate_simd_type!(fx, intrinsic, span, v.layout().ty);
-            simd_reduce(fx, v, ret, |fx, lane_layout, a, b| {
+            simd_reduce(fx, v, Some(acc), ret, |fx, lane_layout, a, b| {
                 if lane_layout.ty.is_floating_point() {
                     fx.bcx.ins().fadd(a, b)
                 } else {
@@ -247,9 +247,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             });
         };
 
-        simd_reduce_mul_ordered | simd_reduce_mul_unordered, (c v) {
+        simd_reduce_mul_ordered | simd_reduce_mul_unordered, (c v, v acc) {
             validate_simd_type!(fx, intrinsic, span, v.layout().ty);
-            simd_reduce(fx, v, ret, |fx, lane_layout, a, b| {
+            simd_reduce(fx, v, Some(acc), ret, |fx, lane_layout, a, b| {
                 if lane_layout.ty.is_floating_point() {
                     fx.bcx.ins().fmul(a, b)
                 } else {