-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[InstCombine] Relax one-use requirement for add iN (sext i1 X), (sext i1 Y) --> sext (X | Y) to iN #90509
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-transforms Author: AtariDreams (AtariDreams) ChangesSince these remove instructions, we can forgo the one-use check. Full diff: https://github.com/llvm/llvm-project/pull/90509.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 6739b8745d74e4..953b0da564a48f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -510,9 +510,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
}
// add iN (sext i1 X), (sext i1 Y) --> sext (X | Y) to iN
- // TODO: Relax the one-use checks because we are removing an instruction?
- if (match(I, m_Add(m_OneUse(m_SExt(m_Value(X))),
- m_OneUse(m_SExt(m_Value(Y))))) &&
+ if (match(I, m_Add(m_SExt(m_Value(X)), m_SExt(m_Value(Y)))) &&
X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType()) {
// Truth table for inputs and output signbits:
// X:0 | X:1
diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 56ee54d351e762..5c7826f33074c1 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -1435,15 +1435,12 @@ define i32 @and31_add_sexts(i1 %x, i1 %y) {
ret i32 %r
}
-; Negative test - extra use
-
define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
; CHECK-LABEL: @lshr_add_use_sexts(
; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
; CHECK-NEXT: store i32 [[XS]], ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
-; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
-; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
+; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%xs = sext i1 %x to i32
@@ -1454,15 +1451,12 @@ define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
ret i32 %r
}
-; Negative test - extra use
-
define i32 @lshr_add_use2_sexts(i1 %x, i1 %y, ptr %p) {
; CHECK-LABEL: @lshr_add_use2_sexts(
-; CHECK-NEXT: [[XS:%.*]] = sext i1 [[X:%.*]] to i32
; CHECK-NEXT: [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
; CHECK-NEXT: store i32 [[YS]], ptr [[P:%.*]], align 4
-; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
-; CHECK-NEXT: [[R:%.*]] = lshr i32 [[SUB]], 31
+; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = zext i1 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[R]]
;
%xs = sext i1 %x to i32
@@ -4018,8 +4012,8 @@ define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {
define i32 @fold_sext_addition_or_disjoint(i8 %x) {
; CHECK-LABEL: @fold_sext_addition_or_disjoint(
-; CHECK-NEXT: [[SE:%.*]] = sext i8 [[XX:%.*]] to i32
-; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[SE]], 1246
+; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 1246
; CHECK-NEXT: ret i32 [[R]]
;
%xx = or disjoint i8 %x, 12
@@ -4043,8 +4037,8 @@ define i32 @fold_sext_addition_fail(i8 %x) {
define i32 @fold_zext_addition_or_disjoint(i8 %x) {
; CHECK-LABEL: @fold_zext_addition_or_disjoint(
-; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX:%.*]] to i32
-; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[SE]], 1246
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1246
; CHECK-NEXT: ret i32 [[R]]
;
%xx = or disjoint i8 %x, 12
@@ -4055,9 +4049,9 @@ define i32 @fold_zext_addition_or_disjoint(i8 %x) {
define i32 @fold_zext_addition_or_disjoint2(i8 %x) {
; CHECK-LABEL: @fold_zext_addition_or_disjoint2(
-; CHECK-NEXT: [[XX:%.*]] = add nuw i8 [[X:%.*]], 4
-; CHECK-NEXT: [[SE:%.*]] = zext i8 [[XX]] to i32
-; CHECK-NEXT: ret i32 [[SE]]
+; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 4
+; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT: ret i32 [[R]]
;
%xx = or disjoint i8 %x, 18
%se = zext i8 %xx to i32
|
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.
Increases instruction count if both sexts have extra uses.
I guess I'm gonna test that then |
Just checked and at worst the count stays the same. |
In the worst case doesn't it remove 1 Add and insert an Or and a SExt. That's an increase of 1. |
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 case with two extra uses is still untested?
831777e
to
de4321e
Compare
43a21ae
to
0c6cfb3
Compare
…t i1 Y) --> sext (X | Y) to iN Since these remove instructions, we can forgo the one-use check, as long as at least ONE of the two sexts are one-use.
The the title should the "Relax one-use..." instead of "Remove one-use..." |
Fixed! |
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 appears to have a pretty significant compile time impact: https://llvm-compile-time-tracker.com/compare.php?from=519e0bb094bd9444b64ac62f2e8192543fdb94b9&to=dd0245e3d74955ace14c95d288abf72346ad52e8&stat=instructions:u |
@goldsteinn That range also contains other commits. The regression is mostly #96851. |
… i1 Y) --> sext (X | Y) to iN (llvm#90509) Since these remove instructions as long as at least one of X or Y is one-use, we don't need to check one-use for both.
Since these remove instructions as long as at least one of X or Y is one-use, we don't need to check one-use for both.