Skip to content

Commit 60dda1f

Browse files
committed
[InstCombine] fold (icmp eq/ne (and (shl -1, X), Y), 0) -> (icmp eq/ne (lshr Y, X), 0)
Proofs: https://alive2.llvm.org/ce/z/oSRGBt Closes #84691
1 parent cef862e commit 60dda1f

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,17 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
19621962
return BinaryOperator::CreateAnd(TruncY, X);
19631963
}
19641964

1965+
// (icmp eq/ne (and (shl -1, X), Y), 0)
1966+
// -> (icmp eq/ne (lshr Y, X), 0)
1967+
// We could technically handle any C == 0 or (C < 0 && isOdd(C)) but it seems
1968+
// highly unlikely the non-zero case will ever show up in code.
1969+
if (C.isZero() &&
1970+
match(And, m_OneUse(m_c_And(m_OneUse(m_Shl(m_AllOnes(), m_Value(X))),
1971+
m_Value(Y))))) {
1972+
Value *LShr = Builder.CreateLShr(Y, X);
1973+
return new ICmpInst(Pred, LShr, Constant::getNullValue(LShr->getType()));
1974+
}
1975+
19651976
return nullptr;
19661977
}
19671978

llvm/test/Transforms/InstCombine/icmp-and-shift.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,7 @@ define i1 @slt_and_shl_one(i8 %x, i8 %y) {
523523

524524
define i1 @fold_eq_lhs(i8 %x, i8 %y) {
525525
; CHECK-LABEL: @fold_eq_lhs(
526-
; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]
527-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHL]], [[Y:%.*]]
526+
; CHECK-NEXT: [[AND:%.*]] = lshr i8 [[Y:%.*]], [[X:%.*]]
528527
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
529528
; CHECK-NEXT: ret i1 [[R]]
530529
;
@@ -565,8 +564,7 @@ define i1 @fold_eq_lhs_fail_multiuse_shl(i8 %x, i8 %y) {
565564
define i1 @fold_ne_rhs(i8 %x, i8 %yy) {
566565
; CHECK-LABEL: @fold_ne_rhs(
567566
; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 123
568-
; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]
569-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[SHL]]
567+
; CHECK-NEXT: [[AND:%.*]] = lshr i8 [[Y]], [[X:%.*]]
570568
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], 0
571569
; CHECK-NEXT: ret i1 [[R]]
572570
;

0 commit comments

Comments
 (0)