[llvm] b8a4a3b - [ValueTracking] Support scalable vector splats of ConstantInt/ConstantFP in isGuaranteedNotToBeUndefOrPoison. (#142894)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 5 22:08:06 PDT 2025
Author: Craig Topper
Date: 2025-06-05T22:08:03-07:00
New Revision: b8a4a3b99cb51b6ec8e3106cc81c434946f7b3d6
URL: https://github.com/llvm/llvm-project/commit/b8a4a3b99cb51b6ec8e3106cc81c434946f7b3d6
DIFF: https://github.com/llvm/llvm-project/commit/b8a4a3b99cb51b6ec8e3106cc81c434946f7b3d6.diff
LOG: [ValueTracking] Support scalable vector splats of ConstantInt/ConstantFP in isGuaranteedNotToBeUndefOrPoison. (#142894)
Scalable vectors use insertelt+shufflevector ConstantExpr to
represent a splat.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/Attributor/nofpclass.ll
llvm/test/Transforms/InstCombine/select-and-or.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index bde30060736c1..d6bb852e208f9 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7580,16 +7580,23 @@ static bool isGuaranteedNotToBeUndefOrPoison(
if (isa<UndefValue>(C))
return !includesUndef(Kind);
- if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(V) ||
+ if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(C) ||
isa<ConstantPointerNull>(C) || isa<Function>(C))
return true;
- if (C->getType()->isVectorTy() && !isa<ConstantExpr>(C)) {
- if (includesUndef(Kind) && C->containsUndefElement())
- return false;
- if (includesPoison(Kind) && C->containsPoisonElement())
- return false;
- return !C->containsConstantExpression();
+ if (C->getType()->isVectorTy()) {
+ if (isa<ConstantExpr>(C)) {
+ // Scalable vectors can use a ConstantExpr to build a splat.
+ if (Constant *SplatC = C->getSplatValue())
+ if (isa<ConstantInt>(SplatC) || isa<ConstantFP>(SplatC))
+ return true;
+ } else {
+ if (includesUndef(Kind) && C->containsUndefElement())
+ return false;
+ if (includesPoison(Kind) && C->containsPoisonElement())
+ return false;
+ return !C->containsConstantExpression();
+ }
}
}
diff --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index 8dd2aa34f94cd..6491f01a6d2a3 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -2665,7 +2665,7 @@ define [4 x float] @constant_aggregate_zero() {
define <vscale x 4 x float> @scalable_splat_pnorm() {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define <vscale x 4 x float> @scalable_splat_pnorm
+; CHECK-LABEL: define noundef <vscale x 4 x float> @scalable_splat_pnorm
; CHECK-SAME: () #[[ATTR3]] {
; CHECK-NEXT: ret <vscale x 4 x float> splat (float 1.000000e+00)
;
diff --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll
index b14186d737e98..453ca666a7477 100644
--- a/llvm/test/Transforms/InstCombine/select-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/select-and-or.ll
@@ -104,6 +104,20 @@ define i1 @logical_or_implies(i32 %x) {
ret i1 %res
}
+; Safe to convert to or due to poison implication.
+define <vscale x 2 x i1> @logical_or_implies_scalablevec(<vscale x 2 x i32> %x) {
+; CHECK-LABEL: @logical_or_implies_scalablevec(
+; CHECK-NEXT: [[C1:%.*]] = icmp eq <vscale x 2 x i32> [[X:%.*]], zeroinitializer
+; CHECK-NEXT: [[C2:%.*]] = icmp eq <vscale x 2 x i32> [[X]], splat (i32 42)
+; CHECK-NEXT: [[RES:%.*]] = or <vscale x 2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT: ret <vscale x 2 x i1> [[RES]]
+;
+ %c1 = icmp eq <vscale x 2 x i32> %x, zeroinitializer
+ %c2 = icmp eq <vscale x 2 x i32> %x, splat (i32 42)
+ %res = select <vscale x 2 x i1> %c1, <vscale x 2 x i1> splat (i1 true), <vscale x 2 x i1> %c2
+ ret <vscale x 2 x i1> %res
+}
+
; Will fold after conversion to or.
define i1 @logical_or_implies_folds(i32 %x) {
; CHECK-LABEL: @logical_or_implies_folds(
@@ -129,6 +143,20 @@ define i1 @logical_and_implies(i32 %x) {
ret i1 %res
}
+; Safe to convert to and due to poison implication.
+define <vscale x 2 x i1> @logical_and_implies_scalablevec(<vscale x 2 x i32> %x) {
+; CHECK-LABEL: @logical_and_implies_scalablevec(
+; CHECK-NEXT: [[C1:%.*]] = icmp ne <vscale x 2 x i32> [[X:%.*]], zeroinitializer
+; CHECK-NEXT: [[C2:%.*]] = icmp ne <vscale x 2 x i32> [[X]], splat (i32 42)
+; CHECK-NEXT: [[RES:%.*]] = and <vscale x 2 x i1> [[C1]], [[C2]]
+; CHECK-NEXT: ret <vscale x 2 x i1> [[RES]]
+;
+ %c1 = icmp ne <vscale x 2 x i32> %x, zeroinitializer
+ %c2 = icmp ne <vscale x 2 x i32> %x, splat (i32 42)
+ %res = select <vscale x 2 x i1> %c1, <vscale x 2 x i1> %c2, <vscale x 2 x i1> zeroinitializer
+ ret <vscale x 2 x i1> %res
+}
+
; Will fold after conversion to and.
define i1 @logical_and_implies_folds(i32 %x) {
; CHECK-LABEL: @logical_and_implies_folds(
More information about the llvm-commits
mailing list