Skip to content

Commit b8a4a3b

Browse files
authored
[ValueTracking] Support scalable vector splats of ConstantInt/ConstantFP in isGuaranteedNotToBeUndefOrPoison. (#142894)
Scalable vectors use insertelt+shufflevector ConstantExpr to represent a splat.
1 parent 7005a76 commit b8a4a3b

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7580,16 +7580,23 @@ static bool isGuaranteedNotToBeUndefOrPoison(
75807580
if (isa<UndefValue>(C))
75817581
return !includesUndef(Kind);
75827582

7583-
if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(V) ||
7583+
if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(C) ||
75847584
isa<ConstantPointerNull>(C) || isa<Function>(C))
75857585
return true;
75867586

7587-
if (C->getType()->isVectorTy() && !isa<ConstantExpr>(C)) {
7588-
if (includesUndef(Kind) && C->containsUndefElement())
7589-
return false;
7590-
if (includesPoison(Kind) && C->containsPoisonElement())
7591-
return false;
7592-
return !C->containsConstantExpression();
7587+
if (C->getType()->isVectorTy()) {
7588+
if (isa<ConstantExpr>(C)) {
7589+
// Scalable vectors can use a ConstantExpr to build a splat.
7590+
if (Constant *SplatC = C->getSplatValue())
7591+
if (isa<ConstantInt>(SplatC) || isa<ConstantFP>(SplatC))
7592+
return true;
7593+
} else {
7594+
if (includesUndef(Kind) && C->containsUndefElement())
7595+
return false;
7596+
if (includesPoison(Kind) && C->containsPoisonElement())
7597+
return false;
7598+
return !C->containsConstantExpression();
7599+
}
75937600
}
75947601
}
75957602

llvm/test/Transforms/Attributor/nofpclass.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2665,7 +2665,7 @@ define [4 x float] @constant_aggregate_zero() {
26652665

26662666
define <vscale x 4 x float> @scalable_splat_pnorm() {
26672667
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2668-
; CHECK-LABEL: define <vscale x 4 x float> @scalable_splat_pnorm
2668+
; CHECK-LABEL: define noundef <vscale x 4 x float> @scalable_splat_pnorm
26692669
; CHECK-SAME: () #[[ATTR3]] {
26702670
; CHECK-NEXT: ret <vscale x 4 x float> splat (float 1.000000e+00)
26712671
;

llvm/test/Transforms/InstCombine/select-and-or.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,20 @@ define i1 @logical_or_implies(i32 %x) {
104104
ret i1 %res
105105
}
106106

107+
; Safe to convert to or due to poison implication.
108+
define <vscale x 2 x i1> @logical_or_implies_scalablevec(<vscale x 2 x i32> %x) {
109+
; CHECK-LABEL: @logical_or_implies_scalablevec(
110+
; CHECK-NEXT: [[C1:%.*]] = icmp eq <vscale x 2 x i32> [[X:%.*]], zeroinitializer
111+
; CHECK-NEXT: [[C2:%.*]] = icmp eq <vscale x 2 x i32> [[X]], splat (i32 42)
112+
; CHECK-NEXT: [[RES:%.*]] = or <vscale x 2 x i1> [[C1]], [[C2]]
113+
; CHECK-NEXT: ret <vscale x 2 x i1> [[RES]]
114+
;
115+
%c1 = icmp eq <vscale x 2 x i32> %x, zeroinitializer
116+
%c2 = icmp eq <vscale x 2 x i32> %x, splat (i32 42)
117+
%res = select <vscale x 2 x i1> %c1, <vscale x 2 x i1> splat (i1 true), <vscale x 2 x i1> %c2
118+
ret <vscale x 2 x i1> %res
119+
}
120+
107121
; Will fold after conversion to or.
108122
define i1 @logical_or_implies_folds(i32 %x) {
109123
; CHECK-LABEL: @logical_or_implies_folds(
@@ -129,6 +143,20 @@ define i1 @logical_and_implies(i32 %x) {
129143
ret i1 %res
130144
}
131145

146+
; Safe to convert to and due to poison implication.
147+
define <vscale x 2 x i1> @logical_and_implies_scalablevec(<vscale x 2 x i32> %x) {
148+
; CHECK-LABEL: @logical_and_implies_scalablevec(
149+
; CHECK-NEXT: [[C1:%.*]] = icmp ne <vscale x 2 x i32> [[X:%.*]], zeroinitializer
150+
; CHECK-NEXT: [[C2:%.*]] = icmp ne <vscale x 2 x i32> [[X]], splat (i32 42)
151+
; CHECK-NEXT: [[RES:%.*]] = and <vscale x 2 x i1> [[C1]], [[C2]]
152+
; CHECK-NEXT: ret <vscale x 2 x i1> [[RES]]
153+
;
154+
%c1 = icmp ne <vscale x 2 x i32> %x, zeroinitializer
155+
%c2 = icmp ne <vscale x 2 x i32> %x, splat (i32 42)
156+
%res = select <vscale x 2 x i1> %c1, <vscale x 2 x i1> %c2, <vscale x 2 x i1> zeroinitializer
157+
ret <vscale x 2 x i1> %res
158+
}
159+
132160
; Will fold after conversion to and.
133161
define i1 @logical_and_implies_folds(i32 %x) {
134162
; CHECK-LABEL: @logical_and_implies_folds(

0 commit comments

Comments
 (0)