forked from OSchip/llvm-project
[InstCombine] improve fold for icmp_eq_and to icmp_ult
In D95959, the improve analysis for "C >> X" broken the fold ((%x & C) == 0) --> %x u< (-C) iff (-C) is power of two. It simplifies C, but fails to satisfy the fold condition. This patch try to restore C before the fold. Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D128790
This commit is contained in:
parent
220366d5b5
commit
b43dd2f6c4
|
@ -1777,11 +1777,16 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
|
|||
return new ICmpInst(NewPred, X, Zero);
|
||||
}
|
||||
|
||||
APInt NewC2 = *C2;
|
||||
KnownBits Know = computeKnownBits(And->getOperand(0), 0, And);
|
||||
// Set high zeros of C2 to allow matching negated power-of-2.
|
||||
NewC2 = *C2 + APInt::getHighBitsSet(C2->getBitWidth(),
|
||||
Know.countMinLeadingZeros());
|
||||
|
||||
// Restrict this fold only for single-use 'and' (PR10267).
|
||||
// ((%x & C) == 0) --> %x u< (-C) iff (-C) is power of two.
|
||||
if (C2->isNegatedPowerOf2()) {
|
||||
Constant *NegBOC =
|
||||
ConstantExpr::getNeg(cast<Constant>(And->getOperand(1)));
|
||||
if (NewC2.isNegatedPowerOf2()) {
|
||||
Constant *NegBOC = ConstantInt::get(And->getType(), -NewC2);
|
||||
auto NewPred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
|
||||
return new ICmpInst(NewPred, X, NegBOC);
|
||||
}
|
||||
|
|
|
@ -177,15 +177,10 @@ define i1 @scalar_lshr_and_negC_eq_extra_use_lshr_and(i32 %x, i32 %y, i32 %z, i3
|
|||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative tests
|
||||
|
||||
; TODO: This could be reduced to lshr+icmp ult.
|
||||
|
||||
define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant1(i32 %y) {
|
||||
; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant1(
|
||||
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 12345, [[Y:%.*]]
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 16376
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[LSHR]], 8
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%lshr = lshr i32 12345, %y
|
||||
|
@ -194,13 +189,9 @@ define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant1(i32 %y) {
|
|||
ret i1 %r
|
||||
}
|
||||
|
||||
; TODO: This could be reduced to lshr+icmp ult.
|
||||
|
||||
define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) {
|
||||
; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant2(
|
||||
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 268435456, [[Y:%.*]]
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 536870904
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ugt i32 [[Y:%.*]], 25
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%lshr = lshr i32 268435456, %y
|
||||
|
@ -208,7 +199,31 @@ define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) {
|
|||
%r = icmp eq i32 %and, 0
|
||||
ret i1 %r
|
||||
}
|
||||
define i1 @scalar_i32_udiv_and_negC_eq_X_is_constant3(i32 %y) {
|
||||
; CHECK-LABEL: @scalar_i32_udiv_and_negC_eq_X_is_constant3(
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[Y:%.*]], 1544
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%lshr = udiv i32 12345, %y
|
||||
%and = and i32 %lshr, 16376 ; 0x3ff8
|
||||
%r = icmp ne i32 %and, 0
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Negative test
|
||||
|
||||
define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant_negtive(i32 %y) {
|
||||
; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant_negtive(
|
||||
; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 16384, [[Y:%.*]]
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 16376
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[AND]], 0
|
||||
; CHECK-NEXT: ret i1 [[R]]
|
||||
;
|
||||
%lshr = lshr i32 16384, %y ; 0x4000
|
||||
%and = and i32 %lshr, 16376 ; 0x3ff8
|
||||
%r = icmp eq i32 %and, 0
|
||||
ret i1 %r
|
||||
}
|
||||
; Check 'slt' predicate
|
||||
|
||||
define i1 @scalar_i32_lshr_and_negC_slt(i32 %x, i32 %y) {
|
||||
|
|
Loading…
Reference in New Issue