[llvm] [VectorCombine] foldShuffleChainsToReduce - add FADD/FMUL handling (PR #201302)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 3 19:58:28 PDT 2026


================
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=vector-combine -mtriple=x86_64-unknown-linux-gnu -S | FileCheck %s
+
+; Verify that FP reduction folding works correctly with the X86 cost model.
+
+define float @test_reduce_v8f32_fadd_x86(<8 x float> %a0) {
+; CHECK-LABEL: define float @test_reduce_v8f32_fadd_x86(
+; CHECK-SAME: <8 x float> [[A0:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc float @llvm.vector.reduce.fadd.v8f32(float -0.000000e+00, <8 x float> [[A0]])
+; CHECK-NEXT:    ret float [[TMP1]]
+;
+  %1 = shufflevector <8 x float> %a0, <8 x float> poison, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison>
+  %2 = fadd reassoc <8 x float> %a0, %1
+  %3 = shufflevector <8 x float> %2, <8 x float> poison, <8 x i32> <i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+  %4 = fadd reassoc <8 x float> %2, %3
+  %5 = shufflevector <8 x float> %4, <8 x float> poison, <8 x i32> <i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+  %6 = fadd reassoc <8 x float> %4, %5
----------------
Michael-Chen-NJU wrote:

Regarding the FMF handling — I considered using only the last binop's FMF, but I believe the intersection is the correct approach per the LangRef. Specifically, under [Fast-Math Flags](https://llvm.org/docs/LangRef.html#fast-math-flags):

> It is necessary that all of the instructions have the necessary rewrite-based flag present on them, and the rewritten instructions will generally have the intersection of the flags present on the input instruction.

Since the reduction intrinsic replaces *all* binops in the chain (not just the bottom one), flags like `nnan` on the output would assert that no intermediate computation produces NaN. If a top-level binop in the chain lacks `nnan`, we can't soundly propagate it to the output.

That said, I only require `reassoc` on every binop (as the legality gate), and the output FMF is the intersection of all binops' flags. This matches what the SLP vectorizer does for similar multi-instruction folds.

Would you prefer I change this to only use the last binop's FMF, or is the intersection approach acceptable?

https://github.com/llvm/llvm-project/pull/201302


More information about the llvm-commits mailing list