Skip to content

Commit d5855b6

Browse files
committed
[ValueTracking] Respect samesign flag in isKnownInversion
1 parent 749a4d2 commit d5855b6

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8522,14 +8522,26 @@ bool llvm::isKnownInversion(const Value *X, const Value *Y) {
85228522
!match(Y, m_c_ICmp(Pred2, m_Specific(A), m_Value(C))))
85238523
return false;
85248524

8525+
// If they are only differ in predicate. They must both have samesign flag or
8526+
// not.
85258527
if (B == C)
8526-
return Pred1 == ICmpInst::getInversePredicate(Pred2);
8528+
return Pred1 == ICmpInst::getInversePredicate(Pred2) &&
8529+
(!cast<ICmpInst>(X)->hasSameSign() ||
8530+
cast<ICmpInst>(Y)->hasSameSign());
8531+
;
85278532

85288533
// Try to infer the relationship from constant ranges.
85298534
const APInt *RHSC1, *RHSC2;
85308535
if (!match(B, m_APInt(RHSC1)) || !match(C, m_APInt(RHSC2)))
85318536
return false;
85328537

8538+
// They must both have samesign flag or not. And sign bits of two RHSCs should
8539+
// match.
8540+
if (cast<ICmpInst>(X)->hasSameSign() &&
8541+
(!cast<ICmpInst>(Y)->hasSameSign() ||
8542+
RHSC1->isNonNegative() != RHSC2->isNonNegative()))
8543+
return false;
8544+
85338545
const auto CR1 = ConstantRange::makeExactICmpRegion(Pred1, *RHSC1);
85348546
const auto CR2 = ConstantRange::makeExactICmpRegion(Pred2, *RHSC2);
85358547

llvm/test/Transforms/InstCombine/select-cmp.ll

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,9 @@ define i1 @test_select_inverse_samesign_true_arm(i64 %x, i64 %y, i1 %cond) {
494494

495495
define i1 @test_select_inverse_samesign_false_arm(i64 %x, i64 %y, i1 %cond) {
496496
; CHECK-LABEL: @test_select_inverse_samesign_false_arm(
497-
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign uge i64 [[X:%.*]], [[Y:%.*]]
498-
; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
497+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]]
498+
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign uge i64 [[X]], [[Y]]
499+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
499500
; CHECK-NEXT: ret i1 [[SEL]]
500501
;
501502
%cmp1 = icmp ult i64 %x, %y
@@ -518,8 +519,9 @@ define i1 @test_select_inverse_samesign_both(i64 %x, i64 %y, i1 %cond) {
518519

519520
define i1 @test_select_inverse_samesign_false_arm_rhsc_same_sign(i64 %x, i64 %y, i1 %cond) {
520521
; CHECK-LABEL: @test_select_inverse_samesign_false_arm_rhsc_same_sign(
521-
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ugt i64 [[X:%.*]], 10
522-
; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
522+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[X:%.*]], 11
523+
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ugt i64 [[X]], 10
524+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
523525
; CHECK-NEXT: ret i1 [[SEL]]
524526
;
525527
%cmp1 = icmp ult i64 %x, 11
@@ -554,8 +556,9 @@ define i1 @test_select_inverse_samesign_both_rhsc_same_sign(i64 %x, i64 %y, i1 %
554556

555557
define i1 @test_select_inverse_samesign_both_rhsc_diff_sign(i64 %x, i64 %y, i1 %cond) {
556558
; CHECK-LABEL: @test_select_inverse_samesign_both_rhsc_diff_sign(
557-
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign sgt i64 [[X:%.*]], -1
558-
; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[COND:%.*]], [[CMP2]]
559+
; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign slt i64 [[X:%.*]], 0
560+
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign sgt i64 [[X]], -1
561+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], i1 [[CMP1]], i1 [[CMP2]]
559562
; CHECK-NEXT: ret i1 [[SEL]]
560563
;
561564
%cmp1 = icmp samesign slt i64 %x, 0

0 commit comments

Comments
 (0)