[llvm] [ValueTracking] Int vector reductions propagate noundef (PR #184173)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 08:51:09 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Gergo Stomfai (stomfaig)
<details>
<summary>Changes</summary>
In investigating #<!-- -->156233, it came up that fold like here: https://alive2.llvm.org/ce/z/Y6jzj6 cannot be carried out, or easily fixed for now, because integer reductions do not propagate noundef, even if their arguments are noundef. This patch adds this propagation.
---
Full diff: https://github.com/llvm/llvm-project/pull/184173.diff
6 Files Affected:
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+12)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/extracts-non-extendable.ll (+1-2)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll (+1-1)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/reduction-logical.ll (+1-1)
- (modified) llvm/test/Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll (+7-15)
- (modified) llvm/unittests/Analysis/ValueTrackingTest.cpp (+14-1)
``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 2684b41cd1e5d..9a4a498e386e7 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7532,6 +7532,18 @@ static bool canCreateUndefOrPoison(const Operator *Op, UndefPoisonKind Kind,
shiftAmountKnownInRange(II->getArgOperand(1)))
return false;
break;
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin:
+ // Integer reductions cannot introduce
+ // poison or undef.
+ return false;
}
}
[[fallthrough]];
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/extracts-non-extendable.ll b/llvm/test/Transforms/SLPVectorizer/X86/extracts-non-extendable.ll
index 3a7184f8e0519..0875b8dd2f9ee 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/extracts-non-extendable.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/extracts-non-extendable.ll
@@ -13,8 +13,7 @@ define void @test(i64 %v) {
; CHECK-NEXT: [[TMP19:%.*]] = icmp ult i64 0, 0
; CHECK-NEXT: [[TMP6:%.*]] = freeze <8 x i1> [[TMP4]]
; CHECK-NEXT: [[TMP18:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP6]])
-; CHECK-NEXT: [[TMP20:%.*]] = select i1 [[TMP19]], i1 [[TMP18]], i1 false
-; CHECK-NEXT: [[TMP8:%.*]] = freeze i1 [[TMP20]]
+; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[TMP18]], i1 [[TMP19]], i1 false
; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[TMP8]], i1 false, i1 false
; CHECK-NEXT: br i1 [[OP_RDX1]], label %[[BB_I107_PREHEADER:.*]], label %[[BB_I27_I_PREHEADER:.*]]
; CHECK: [[BB_I107_PREHEADER]]:
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll b/llvm/test/Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll
index 7df97492b874b..b965d27fe3ead 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll
@@ -14,7 +14,7 @@ define i1 @foo() {
; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> <i1 false, i1 false, i1 false, i1 false, i1 undef, i1 undef, i1 undef, i1 undef>, <8 x i1> [[TMP7]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
; CHECK-NEXT: [[TMP4:%.*]] = freeze <8 x i1> [[TMP3]]
; CHECK-NEXT: [[TMP5:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP4]])
-; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 false, i1 [[TMP5]], i1 false
+; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP5]], i1 false, i1 false
; CHECK-NEXT: ret i1 [[OP_RDX]]
;
entry:
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reduction-logical.ll b/llvm/test/Transforms/SLPVectorizer/X86/reduction-logical.ll
index 1904540c23146..5e0dea82bddac 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/reduction-logical.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/reduction-logical.ll
@@ -361,7 +361,7 @@ define i1 @logical_and_icmp_clamp_partial(<4 x i32> %x) {
; CHECK-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP4]]
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP5]])
; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i1> [[TMP3]], i32 0
-; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP7]], i1 [[TMP6]], i1 false
+; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP6]], i1 [[TMP7]], i1 false
; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP3]], i32 1
; CHECK-NEXT: [[TMP9:%.*]] = freeze i1 [[TMP8]]
; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[TMP9]], i1 [[C2]], i1 false
diff --git a/llvm/test/Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll b/llvm/test/Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll
index ae5018a63e214..e6bbbaac46476 100644
--- a/llvm/test/Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll
+++ b/llvm/test/Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll
@@ -10,8 +10,7 @@ define void @tes() {
; X86: 1:
; X86-NEXT: [[TMP2:%.*]] = shufflevector <2 x i1> zeroinitializer, <2 x i1> [[TMP0]], <4 x i32> <i32 0, i32 0, i32 0, i32 2>
; X86-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]])
-; X86-NEXT: [[OP_RDX:%.*]] = select i1 false, i1 [[TMP3]], i1 false
-; X86-NEXT: [[OP_RDX1:%.*]] = select i1 false, i1 [[OP_RDX]], i1 false
+; X86-NEXT: [[OP_RDX1:%.*]] = select i1 false, i1 [[TMP3]], i1 false
; X86-NEXT: br i1 [[OP_RDX1]], label [[TMP4:%.*]], label [[TMP5:%.*]]
; X86: 4:
; X86-NEXT: ret void
@@ -20,23 +19,16 @@ define void @tes() {
;
; AARCH64-LABEL: define void @tes() {
; AARCH64-NEXT: entry:
-; AARCH64-NEXT: [[TMP0:%.*]] = extractelement <2 x i1> zeroinitializer, i64 0
-; AARCH64-NEXT: [[TMP1:%.*]] = extractelement <2 x i1> zeroinitializer, i64 0
; AARCH64-NEXT: [[TMP2:%.*]] = fcmp ole <2 x double> zeroinitializer, zeroinitializer
-; AARCH64-NEXT: [[TMP3:%.*]] = extractelement <2 x i1> [[TMP2]], i64 0
-; AARCH64-NEXT: [[TMP4:%.*]] = extractelement <2 x i1> zeroinitializer, i64 0
; AARCH64-NEXT: br label [[TMP5:%.*]]
-; AARCH64: 5:
-; AARCH64-NEXT: [[TMP6:%.*]] = select i1 false, i1 false, i1 false
-; AARCH64-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i1 [[TMP0]], i1 false
-; AARCH64-NEXT: [[TMP8:%.*]] = select i1 [[TMP7]], i1 [[TMP1]], i1 false
-; AARCH64-NEXT: [[TMP9:%.*]] = select i1 [[TMP8]], i1 false, i1 false
-; AARCH64-NEXT: [[TMP10:%.*]] = select i1 [[TMP9]], i1 [[TMP3]], i1 false
-; AARCH64-NEXT: [[TMP11:%.*]] = select i1 [[TMP10]], i1 [[TMP4]], i1 false
+; AARCH64: 1:
+; AARCH64-NEXT: [[TMP4:%.*]] = shufflevector <2 x i1> zeroinitializer, <2 x i1> [[TMP2]], <4 x i32> <i32 0, i32 0, i32 0, i32 2>
+; AARCH64-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP4]])
+; AARCH64-NEXT: [[TMP11:%.*]] = select i1 false, i1 [[TMP3]], i1 false
; AARCH64-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]]
-; AARCH64: 12:
+; AARCH64: 4:
; AARCH64-NEXT: ret void
-; AARCH64: 13:
+; AARCH64: 5:
; AARCH64-NEXT: ret void
;
entry:
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index fa06b0caa6a64..ce9535f1c558d 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1354,7 +1354,20 @@ TEST(ValueTracking, canCreatePoisonOrUndef) {
{{false, false},
"call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)"},
{{false, false},
- "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)"}};
+ "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)"},
+ {{false, false}, "call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %vx)"},
+ {{false, false}, "call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %vx)"},
+ {{false, false}, "call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %vx)"},
+ {{false, false}, "call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %vx)"},
+ {{false, false}, "call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %vx)"},
+ {{false, false},
+ "call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> %vx)"},
+ {{false, false},
+ "call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> %vx)"},
+ {{false, false},
+ "call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %vx)"},
+ {{false, false},
+ "call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> %vx)"}};
std::string AssemblyStr = AsmHead;
for (auto &Itm : Data)
``````````
</details>
https://github.com/llvm/llvm-project/pull/184173
More information about the llvm-commits
mailing list