-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ValueTracking] Support scalable vector splats of ConstantInt/ConstantFP in isGuaranteedNotToBeUndefOrPoison. #142894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…aranteedNotToBeUndefOrPoison. Scalable vectors use insertelt+shufflevector ConstantExpr to represent a splat.
|
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: Craig Topper (topperc) ChangesScalable vectors use insertelt+shufflevector ConstantExpr to Full diff: https://github.com/llvm/llvm-project/pull/142894.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 0a460786d00ea..b32d206f927ed 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7579,16 +7579,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))
+ 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/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(
|
llvm/lib/Analysis/ValueTracking.cpp
Outdated
| if (isa<ConstantInt>(SplatC)) | ||
| return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to support fp/ptr splats?
| if (isa<ConstantInt>(SplatC)) | |
| return true; | |
| return isGuaranteedNotToBeUndefOrPoison(SplatC, ...); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to support fp/ptr splats?
Just lack of tests. Should we increase the depth on the recursive call to isGuaranteedNotToBeUndefOrPoison or keep the current depth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latter one is ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added ConstantFP and an Attributor test was changed so that has some coverage.
Will a splat of ConstantPointerNull be folded to ConstantAggregateZero at creation?
dtcxzyw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
Scalable vectors use insertelt+shufflevector ConstantExpr to
represent a splat.