-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ValueTracking] Remove SPF support from computeKnownBitsFromOperator
#76630
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
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesThis patch removes redundant SPF support (5350e1b) from Compile-time improvement:
Full diff: https://github.com/llvm/llvm-project/pull/76630.diff 4 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index cac2602d455f9d..16d78c1ded6d7a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -983,45 +983,11 @@ static void computeKnownBitsFromOperator(const Operator *I,
break;
}
case Instruction::Select: {
- const Value *LHS = nullptr, *RHS = nullptr;
- SelectPatternFlavor SPF = matchSelectPattern(I, LHS, RHS).Flavor;
- if (SelectPatternResult::isMinOrMax(SPF)) {
- computeKnownBits(RHS, Known, Depth + 1, Q);
- computeKnownBits(LHS, Known2, Depth + 1, Q);
- switch (SPF) {
- default:
- llvm_unreachable("Unhandled select pattern flavor!");
- case SPF_SMAX:
- Known = KnownBits::smax(Known, Known2);
- break;
- case SPF_SMIN:
- Known = KnownBits::smin(Known, Known2);
- break;
- case SPF_UMAX:
- Known = KnownBits::umax(Known, Known2);
- break;
- case SPF_UMIN:
- Known = KnownBits::umin(Known, Known2);
- break;
- }
- break;
- }
-
computeKnownBits(I->getOperand(2), Known, Depth + 1, Q);
computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
// Only known if known in both the LHS and RHS.
Known = Known.intersectWith(Known2);
-
- if (SPF == SPF_ABS) {
- // RHS from matchSelectPattern returns the negation part of abs pattern.
- // If the negate has an NSW flag we can assume the sign bit of the result
- // will be 0 because that makes abs(INT_MIN) undefined.
- if (match(RHS, m_Neg(m_Specific(LHS))) &&
- Q.IIQ.hasNoSignedWrap(cast<OverflowingBinaryOperator>(RHS)))
- Known.Zero.setSignBit();
- }
-
break;
}
case Instruction::FPTrunc:
diff --git a/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll b/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
index d401ff31035e8f..c2d90537506938 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
@@ -229,21 +229,21 @@ define void @umax(i32 %tmp3) {
; CHECK-NEXT: %tmp48 = select i1 %tmp47, i32 %tmp44, i32 %tmp46
; CHECK-NEXT: --> ((7 + (256 umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umax (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin (1 + (256 umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>))<nuw><nsw> umin {%tmp3,+,-256}<%bb4>)) U: [7,264) S: [7,264) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: %tmp49 = ashr i32 %tmp48, 3
-; CHECK-NEXT: --> %tmp49 U: [0,128) S: [0,128) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
+; CHECK-NEXT: --> %tmp49 U: [-268435456,268435456) S: [-268435456,268435456) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
; CHECK-NEXT: %tmp51 = select i1 %tmp50, i32 %tmp49, i32 0
-; CHECK-NEXT: --> %tmp49 U: [0,128) S: [0,128) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
+; CHECK-NEXT: --> %tmp49 U: [-268435456,268435456) S: [-268435456,268435456) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
; CHECK-NEXT: %tmp52 = zext i32 %tmp51 to i64
-; CHECK-NEXT: --> (zext i32 %tmp49 to i64) U: [0,128) S: [0,128) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
+; CHECK-NEXT: --> (zext i32 %tmp49 to i64) U: [0,4294967296) S: [0,4294967296) Exits: <<Unknown>> LoopDispositions: { %bb4: Variant, %bb53: Invariant }
; CHECK-NEXT: %tmp54 = phi i64 [ undef, %bb4 ], [ %tmp59, %bb53 ]
; CHECK-NEXT: --> {undef,+,1}<nsw><%bb53> U: full-set S: full-set Exits: (-1 + (zext i32 %tmp49 to i64))<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp55 = trunc i64 %tmp54 to i32
; CHECK-NEXT: --> {(trunc i64 undef to i32),+,1}<%bb53> U: full-set S: full-set Exits: (-1 + %tmp49)<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp56 = shl nsw i32 %tmp55, 3
-; CHECK-NEXT: --> {(8 * (trunc i64 undef to i32)),+,8}<%bb53> U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * %tmp49)<nuw><nsw>)<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT: --> {(8 * (trunc i64 undef to i32)),+,8}<%bb53> U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * %tmp49)<nsw>) LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp57 = sext i32 %tmp56 to i64
-; CHECK-NEXT: --> (sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * (zext i32 %tmp49 to i64))<nuw><nsw>)<nsw> LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT: --> (sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) U: [0,-7) S: [-2147483648,2147483641) Exits: (sext i32 (-8 + (8 * %tmp49)<nsw>) to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp58 = getelementptr inbounds i8, ptr null, i64 %tmp57
-; CHECK-NEXT: --> ((sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) + null) U: [0,-7) S: [-2147483648,2147483641) Exits: (-8 + (8 * (zext i32 %tmp49 to i64))<nuw><nsw> + null) LoopDispositions: { %bb53: Computable, %bb4: Variant }
+; CHECK-NEXT: --> ((sext i32 {(8 * (trunc i64 undef to i32)),+,8}<%bb53> to i64) + null) U: [0,-7) S: [-2147483648,2147483641) Exits: ((sext i32 (-8 + (8 * %tmp49)<nsw>) to i64) + null) LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp59 = add nsw i64 %tmp54, 1
; CHECK-NEXT: --> {(1 + undef),+,1}<nsw><%bb53> U: full-set S: full-set Exits: (zext i32 %tmp49 to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp62 = add nuw nsw i64 %tmp5, 1
diff --git a/llvm/test/Transforms/LoopIdiom/ARM/ctlz.ll b/llvm/test/Transforms/LoopIdiom/ARM/ctlz.ll
index ec9271a683f47d..c80c94c90534dd 100644
--- a/llvm/test/Transforms/LoopIdiom/ARM/ctlz.ll
+++ b/llvm/test/Transforms/LoopIdiom/ARM/ctlz.ll
@@ -31,9 +31,7 @@
; Function Attrs: norecurse nounwind uwtable
define i32 @ctlz_and_other(i32 %n, ptr nocapture %a) {
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
%shr8 = lshr i32 %abs_n, 1
%tobool9 = icmp eq i32 %shr8, 0
br i1 %tobool9, label %while.end, label %while.body.preheader
@@ -90,9 +88,7 @@ while.end: ; preds = %while.end.loopexit,
; Function Attrs: norecurse nounwind readnone uwtable
define i32 @ctlz_zero_check(i32 %n) {
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
%tobool4 = icmp eq i32 %abs_n, 0
br i1 %tobool4, label %while.end, label %while.body.preheader
@@ -140,9 +136,7 @@ while.end: ; preds = %while.end.loopexit,
; Function Attrs: norecurse nounwind readnone uwtable
define i32 @ctlz(i32 %n) {
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
br label %while.cond
while.cond: ; preds = %while.cond, %entry
@@ -183,9 +177,7 @@ while.end: ; preds = %while.cond
; Function Attrs: norecurse nounwind readnone uwtable
define i32 @ctlz_add(i32 %n, i32 %i0) {
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
br label %while.cond
while.cond: ; preds = %while.cond, %entry
@@ -227,10 +219,8 @@ while.end: ; preds = %while.cond
; Function Attrs: norecurse nounwind readnone uwtable
define i32 @ctlz_sext(i16 %in) {
entry:
- %n = sext i16 %in to i32
- %c = icmp sgt i16 %in, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs = call i16 @llvm.abs.i16(i16 %in, i1 false)
+ %abs_n = zext i16 %abs to i32
br label %while.cond
while.cond: ; preds = %while.cond, %entry
@@ -244,3 +234,6 @@ while.cond: ; preds = %while.cond, %entry
while.end: ; preds = %while.cond
ret i32 %i.0
}
+
+declare i32 @llvm.abs.i32(i32, i1)
+declare i16 @llvm.abs.i16(i16, i1)
diff --git a/llvm/test/Transforms/LoopIdiom/X86/ctlz.ll b/llvm/test/Transforms/LoopIdiom/X86/ctlz.ll
index 8ea8ba8f346399..1b57fcc3966763 100644
--- a/llvm/test/Transforms/LoopIdiom/X86/ctlz.ll
+++ b/llvm/test/Transforms/LoopIdiom/X86/ctlz.ll
@@ -20,9 +20,7 @@
define i32 @ctlz_and_other(i32 %n, ptr nocapture %a) {
; ALL-LABEL: @ctlz_and_other(
; ALL-NEXT: entry:
-; ALL-NEXT: [[C:%.*]] = icmp sgt i32 [[N:%.*]], 0
-; ALL-NEXT: [[NEGN:%.*]] = sub nsw i32 0, [[N]]
-; ALL-NEXT: [[ABS_N:%.*]] = select i1 [[C]], i32 [[N]], i32 [[NEGN]]
+; ALL-NEXT: [[ABS_N:%.*]] = call i32 @llvm.abs.i32(i32 [[N:%.*]], i1 true)
; ALL-NEXT: [[SHR8:%.*]] = lshr i32 [[ABS_N]], 1
; ALL-NEXT: [[TOBOOL9:%.*]] = icmp eq i32 [[SHR8]], 0
; ALL-NEXT: br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
@@ -56,9 +54,7 @@ define i32 @ctlz_and_other(i32 %n, ptr nocapture %a) {
; ALL-NEXT: ret i32 [[I_0_LCSSA]]
;
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
%shr8 = lshr i32 %abs_n, 1
%tobool9 = icmp eq i32 %shr8, 0
br i1 %tobool9, label %while.end, label %while.body.preheader
@@ -108,9 +104,7 @@ while.end: ; preds = %while.end.loopexit,
define i32 @ctlz_zero_check(i32 %n) {
; ALL-LABEL: @ctlz_zero_check(
; ALL-NEXT: entry:
-; ALL-NEXT: [[C:%.*]] = icmp sgt i32 [[N:%.*]], 0
-; ALL-NEXT: [[NEGN:%.*]] = sub nsw i32 0, [[N]]
-; ALL-NEXT: [[ABS_N:%.*]] = select i1 [[C]], i32 [[N]], i32 [[NEGN]]
+; ALL-NEXT: [[ABS_N:%.*]] = call i32 @llvm.abs.i32(i32 [[N:%.*]], i1 true)
; ALL-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[ABS_N]], 0
; ALL-NEXT: br i1 [[TOBOOL4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
; ALL: while.body.preheader:
@@ -134,9 +128,7 @@ define i32 @ctlz_zero_check(i32 %n) {
; ALL-NEXT: ret i32 [[I_0_LCSSA]]
;
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
%tobool4 = icmp eq i32 %abs_n, 0
br i1 %tobool4, label %while.end, label %while.body.preheader
@@ -238,9 +230,7 @@ while.end: ; preds = %while.end.loopexit,
define i32 @ctlz(i32 %n) {
; ALL-LABEL: @ctlz(
; ALL-NEXT: entry:
-; ALL-NEXT: [[C:%.*]] = icmp sgt i32 [[N:%.*]], 0
-; ALL-NEXT: [[NEGN:%.*]] = sub nsw i32 0, [[N]]
-; ALL-NEXT: [[ABS_N:%.*]] = select i1 [[C]], i32 [[N]], i32 [[NEGN]]
+; ALL-NEXT: [[ABS_N:%.*]] = call i32 @llvm.abs.i32(i32 [[N:%.*]], i1 true)
; ALL-NEXT: [[TMP0:%.*]] = ashr i32 [[ABS_N]], 1
; ALL-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP0]], i1 false)
; ALL-NEXT: [[TMP2:%.*]] = sub i32 32, [[TMP1]]
@@ -260,9 +250,7 @@ define i32 @ctlz(i32 %n) {
; ALL-NEXT: ret i32 [[I_0_LCSSA]]
;
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
br label %while.cond
while.cond: ; preds = %while.cond, %entry
@@ -343,9 +331,7 @@ while.end: ; preds = %while.cond
define i32 @ctlz_add(i32 %n, i32 %i0) {
; ALL-LABEL: @ctlz_add(
; ALL-NEXT: entry:
-; ALL-NEXT: [[C:%.*]] = icmp sgt i32 [[N:%.*]], 0
-; ALL-NEXT: [[NEGN:%.*]] = sub nsw i32 0, [[N]]
-; ALL-NEXT: [[ABS_N:%.*]] = select i1 [[C]], i32 [[N]], i32 [[NEGN]]
+; ALL-NEXT: [[ABS_N:%.*]] = call i32 @llvm.abs.i32(i32 [[N:%.*]], i1 true)
; ALL-NEXT: [[TMP0:%.*]] = ashr i32 [[ABS_N]], 1
; ALL-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP0]], i1 false)
; ALL-NEXT: [[TMP2:%.*]] = sub i32 32, [[TMP1]]
@@ -366,9 +352,7 @@ define i32 @ctlz_add(i32 %n, i32 %i0) {
; ALL-NEXT: ret i32 [[I_0_LCSSA]]
;
entry:
- %c = icmp sgt i32 %n, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs_n = call i32 @llvm.abs.i32(i32 %n, i1 true)
br label %while.cond
while.cond: ; preds = %while.cond, %entry
@@ -452,10 +436,8 @@ while.end: ; preds = %while.cond
define i32 @ctlz_sext(i16 %in) {
; ALL-LABEL: @ctlz_sext(
; ALL-NEXT: entry:
-; ALL-NEXT: [[N:%.*]] = sext i16 [[IN:%.*]] to i32
-; ALL-NEXT: [[C:%.*]] = icmp sgt i16 [[IN]], 0
-; ALL-NEXT: [[NEGN:%.*]] = sub nsw i32 0, [[N]]
-; ALL-NEXT: [[ABS_N:%.*]] = select i1 [[C]], i32 [[N]], i32 [[NEGN]]
+; ALL-NEXT: [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[IN:%.*]], i1 false)
+; ALL-NEXT: [[ABS_N:%.*]] = zext i16 [[ABS]] to i32
; ALL-NEXT: [[TMP0:%.*]] = ashr i32 [[ABS_N]], 1
; ALL-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP0]], i1 false)
; ALL-NEXT: [[TMP2:%.*]] = sub i32 32, [[TMP1]]
@@ -475,10 +457,8 @@ define i32 @ctlz_sext(i16 %in) {
; ALL-NEXT: ret i32 [[I_0_LCSSA]]
;
entry:
- %n = sext i16 %in to i32
- %c = icmp sgt i16 %in, 0
- %negn = sub nsw i32 0, %n
- %abs_n = select i1 %c, i32 %n, i32 %negn
+ %abs = call i16 @llvm.abs.i16(i16 %in, i1 false)
+ %abs_n = zext i16 %abs to i32
br label %while.cond
while.cond: ; preds = %while.cond, %entry
@@ -753,3 +733,6 @@ while.cond: ; preds = %while.cond, %entry
while.end: ; preds = %while.cond
ret i32 %i.0
}
+
+declare i32 @llvm.abs.i32(i32, i1)
+declare i16 @llvm.abs.i16(i16, i1)
|
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.
LGTM
This also fixes a discrepancy with SimplifyDemandedBits.
This patch removes redundant SPF support (5350e1b) from
computeKnownBitsFromOperator
as we always canonicalize a SPF into an intrinsic call.Compile-time improvement: http://llvm-compile-time-tracker.com/compare.php?from=3dc0638cfc19e140daff7bf1281648daca8212fa&to=8771ef0749fb2ba4304dc68d418c88ec5769346f&stat=instructions:u