Skip to content

Commit ae3d759

Browse files
committed
[ConstraintElim] Eliminate exact right shifts in getConstraint
1 parent 045af21 commit ae3d759

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,40 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
718718
Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
719719
return {};
720720

721+
// Check if we can eliminate right shifts.
722+
auto ShiftOperands = [Pred](Value *&Op0, Value *&Op1) {
723+
uint64_t ShAmtC;
724+
Value *X;
725+
if (!match(Op0, m_Exact(m_Shr(m_Value(X), m_ConstantInt(ShAmtC)))))
726+
return false;
727+
bool IsLShr = cast<BinaryOperator>(Op0)->getOpcode() == Instruction::LShr;
728+
if (IsLShr && ICmpInst::isSigned(Pred))
729+
return false;
730+
// icmp pred (shr exact X, ShAmtC), (shr exact Y, ShAmtC) --> icmp pred X, Y
731+
Value *Y;
732+
if (match(Op1, m_Exact(m_Shr(m_Value(Y), m_SpecificInt(ShAmtC)))) &&
733+
cast<BinaryOperator>(Op0)->getOpcode() ==
734+
cast<BinaryOperator>(Op1)->getOpcode()) {
735+
Op0 = X;
736+
Op1 = Y;
737+
return true;
738+
}
739+
// icmp pred (shr exact X, ShAmtC), C --> icmp pred X, (C << ShAmtC)
740+
const APInt *RHSC;
741+
if (!match(Op1, m_APInt(RHSC)))
742+
return false;
743+
bool Overflow = false;
744+
APInt NewC = IsLShr ? RHSC->ushl_ov(ShAmtC, Overflow)
745+
: RHSC->sshl_ov(ShAmtC, Overflow);
746+
if (Overflow)
747+
return false;
748+
Op0 = X;
749+
Op1 = ConstantInt::get(Op1->getType(), NewC);
750+
return true;
751+
};
752+
if (!ShiftOperands(Op0, Op1))
753+
ShiftOperands(Op1, Op0);
754+
721755
SmallVector<ConditionTy, 4> Preconditions;
722756
bool IsSigned = ForceSignedSystem || CmpInst::isSigned(Pred);
723757
auto &Value2Index = getValue2Index(IsSigned);

llvm/test/Transforms/ConstraintElimination/shr-exact.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ define i1 @precond_icmp_ashr_and_rhsc(i64 %x) {
88
; CHECK-NEXT: [[SHR:%.*]] = ashr exact i64 [[X]], 3
99
; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[SHR]], 200
1010
; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
11-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X]], 9223372036854775800
12-
; CHECK-NEXT: ret i1 [[CMP]]
11+
; CHECK-NEXT: ret i1 false
1312
;
1413
entry:
1514
%shr = ashr exact i64 %x, 3
@@ -27,8 +26,7 @@ define i1 @precond_icmp_ashr_and_ashr(i64 %x, i64 %y) {
2726
; CHECK-NEXT: [[SHRY:%.*]] = ashr exact i64 [[Y]], 3
2827
; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[SHRX]], [[SHRY]]
2928
; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
30-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X]], [[Y]]
31-
; CHECK-NEXT: ret i1 [[CMP]]
29+
; CHECK-NEXT: ret i1 false
3230
;
3331
entry:
3432
%shrx = ashr exact i64 %x, 3
@@ -47,8 +45,7 @@ define i1 @precond_icmp_lshr_and_lshr(i64 %x, i64 %y) {
4745
; CHECK-NEXT: [[SHRY:%.*]] = lshr exact i64 [[Y]], 3
4846
; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[SHRX]], [[SHRY]]
4947
; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
50-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X]], [[Y]]
51-
; CHECK-NEXT: ret i1 [[CMP]]
48+
; CHECK-NEXT: ret i1 false
5249
;
5350
entry:
5451
%shrx = lshr exact i64 %x, 3

0 commit comments

Comments
 (0)