-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstCombine] Set samesign
when converting signed predicates into unsigned
#112642
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) ChangesAlive2: https://alive2.llvm.org/ce/z/6cqdt- Full diff: https://github.com/llvm/llvm-project/pull/112642.diff 5 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 18a6fdcec1728e..a9c88444ba2571 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6774,8 +6774,11 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
// have the same sign.
if (I.isSigned() &&
((Op0Known.Zero.isNegative() && Op1Known.Zero.isNegative()) ||
- (Op0Known.One.isNegative() && Op1Known.One.isNegative())))
- return new ICmpInst(I.getUnsignedPredicate(), Op0, Op1);
+ (Op0Known.One.isNegative() && Op1Known.One.isNegative()))) {
+ ICmpInst *NewICmp = new ICmpInst(I.getUnsignedPredicate(), Op0, Op1);
+ NewICmp->setSameSign();
+ return NewICmp;
+ }
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/call-guard.ll b/llvm/test/Transforms/InstCombine/call-guard.ll
index 6b31c78118d0b8..bc5f319e64f7fe 100644
--- a/llvm/test/Transforms/InstCombine/call-guard.ll
+++ b/llvm/test/Transforms/InstCombine/call-guard.ll
@@ -43,7 +43,7 @@ define void @test_guard_adjacent_diff_cond2(i32 %V1, i32 %V2) {
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[V1:%.*]], [[V2:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
; CHECK-NEXT: [[AND:%.*]] = and i32 [[V1]], 255
-; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[AND]], 129
+; CHECK-NEXT: [[C:%.*]] = icmp samesign ult i32 [[AND]], 129
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[C]]
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 123) [ "deopt"() ]
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 7cafb4885ff0ee..e44f7002438cb9 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -1457,7 +1457,7 @@ define <2 x i1> @test67vecinverse(<2 x i32> %x) {
define i1 @test68(i32 %x) {
; CHECK-LABEL: @test68(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
+; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[AND]], 30
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and i32 %x, 127
diff --git a/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll b/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll
index 79511cf9e666ff..1110bbc5403e49 100644
--- a/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll
+++ b/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll
@@ -40,7 +40,7 @@ define ptr @test1_nuw(ptr %A, i32 %Offset) {
; CHECK: bb:
; CHECK-NEXT: [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[RHS_ADD]] = add nuw nsw i32 [[RHS_IDX]], 4
-; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[RHS_IDX]], 400
+; CHECK-NEXT: [[COND:%.*]] = icmp samesign ugt i32 [[RHS_IDX]], 400
; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
; CHECK: bb2:
; CHECK-NEXT: [[RHS_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[RHS_IDX]]
diff --git a/llvm/test/Transforms/InstCombine/phi-known-bits-operand-order.ll b/llvm/test/Transforms/InstCombine/phi-known-bits-operand-order.ll
index 6a054688753500..9ff093635ad793 100644
--- a/llvm/test/Transforms/InstCombine/phi-known-bits-operand-order.ll
+++ b/llvm/test/Transforms/InstCombine/phi-known-bits-operand-order.ll
@@ -20,7 +20,7 @@ define void @phi_recurrence_start_first() {
; CHECK-NEXT: br i1 [[COND_V2]], label [[FOR_COND11:%.*]], label [[FOR_COND26]]
; CHECK: for.cond11:
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[START]], [[IF_THEN]] ], [ [[STEP:%.*]], [[FOR_COND11]] ]
-; CHECK-NEXT: [[CMP13:%.*]] = icmp ult i32 [[I_1]], 100
+; CHECK-NEXT: [[CMP13:%.*]] = icmp samesign ult i32 [[I_1]], 100
; CHECK-NEXT: [[STEP]] = add nuw nsw i32 [[I_1]], 1
; CHECK-NEXT: br i1 [[CMP13]], label [[FOR_COND11]], label [[WHILE_END]]
; CHECK: for.cond26:
@@ -68,7 +68,7 @@ define void @phi_recurrence_step_first() {
; CHECK-NEXT: br i1 [[COND_V2]], label [[FOR_COND11:%.*]], label [[FOR_COND26]]
; CHECK: for.cond11:
; CHECK-NEXT: [[I_1:%.*]] = phi i32 [ [[STEP:%.*]], [[FOR_COND11]] ], [ [[START]], [[IF_THEN]] ]
-; CHECK-NEXT: [[CMP13:%.*]] = icmp ult i32 [[I_1]], 100
+; CHECK-NEXT: [[CMP13:%.*]] = icmp samesign ult i32 [[I_1]], 100
; CHECK-NEXT: [[STEP]] = add nuw nsw i32 [[I_1]], 1
; CHECK-NEXT: br i1 [[CMP13]], label [[FOR_COND11]], label [[WHILE_END]]
; CHECK: for.cond26:
|
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
@@ -6774,8 +6774,11 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) { | |||
// have the same sign. | |||
if (I.isSigned() && |
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.
Shouldn't we also set the flag if !isSigned()
?
✅ With the latest revision this PR passed the C/C++ code formatter. |
@@ -1,5 +1,5 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |||
; RUN: opt < %s -passes=instcombine -S | FileCheck %s | |||
; RUN: opt < %s -passes="instcombine<no-verify-fixpoint>" -S | FileCheck %s |
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.
What's the issue here?
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.
In function trunc_in_loop_exit_block
:
define i8 @trunc_in_loop_exit_block() {
; CHECK-LABEL: @trunc_in_loop_exit_block(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[IV]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
; CHECK: loop.latch:
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
%phi = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
%cmp = icmp ult i32 %iv, 100
br i1 %cmp, label %loop.latch, label %exit
loop.latch:
%iv.next = add i32 %iv, 1
br label %loop
exit:
%trunc = trunc i32 %phi to i8
ret i8 %trunc
}
%iv u< 100
-> infer nsw/nuw
for %iv.next = add i32 %iv, 1
-> %iv
is non-negative -> infer samesign
for %cmp = icmp ult i32 %iv, 100
.
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 see. This is a bit of recurring problem, may be worthwhile to add a special case at some point to revisit phi users if we add nuw to a recurrence add.
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'm also wondering if it would make sense to add an "instcombine-no-verify-fixpoint"
function attribute, so that we can mark a single function instead of a whole file. This makes it easier to see which function is problematic and also avoids disabling verification for many unrelated tests...
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
…#113822) This patch introduces a function attribute `instcombine-no-verify-fixpoint` to avoids disabling fix-point verification for unrelated tests in the same file. Address comment #112642 (comment).
…llvm#113822) This patch introduces a function attribute `instcombine-no-verify-fixpoint` to avoids disabling fix-point verification for unrelated tests in the same file. Address comment llvm#112642 (comment).
…erred (#113933) This patch re-queue users of phi when one of its incoming add instructions is updated. If an add instruction is updated, the analysis results of phis may be improved. Thus we may further fold some users of this phi node. See the following case: ``` define i8 @trunc_in_loop_exit_block() { ; CHECK-LABEL: @trunc_in_loop_exit_block( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ] ; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[IV]], 100 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]] ; CHECK: loop.latch: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: br label [[LOOP]] ; CHECK: exit: ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8 ; CHECK-NEXT: ret i8 [[TRUNC]] ; entry: br label %loop loop: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] %phi = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] %cmp = icmp ult i32 %iv, 100 br i1 %cmp, label %loop.latch, label %exit loop.latch: %iv.next = add i32 %iv, 1 br label %loop exit: %trunc = trunc i32 %phi to i8 ret i8 %trunc } ``` `%iv u< 100` -> infer `nsw/nuw` for `%iv.next = add i32 %iv, 1` -> `%iv` is non-negative -> infer `samesign` for `%cmp = icmp ult i32 %iv, 100`. Without re-queuing users of phi nodes, we cannot improve `%cmp` in one iteration. Address review comment #112642 (comment). This patch also fixes some non-fixpoint issues in tests.
Alive2: https://alive2.llvm.org/ce/z/6cqdt-