[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