forked from OSchip/llvm-project
[InstCombine] add fold for icmp with or mask of low bits (PR32542)
We already have these 'and' folds: // X & -C == -C -> X > u ~C // X & -C != -C -> X <= u ~C // iff C is a power of 2 ...but we were missing the 'or' siblings. http://rise4fun.com/Alive/n6 This should improve: https://bugs.llvm.org/show_bug.cgi?id=32524 ...but there are 2 or more other pieces to fix still. Differential Revision: https://reviews.llvm.org/D31712 llvm-svn: 299570
This commit is contained in:
parent
4ecee77c9a
commit
50c82c4395
|
@ -1794,6 +1794,15 @@ Instruction *InstCombiner::foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or,
|
|||
ConstantInt::get(V->getType(), 1));
|
||||
}
|
||||
|
||||
// X | C == C --> X <=u C
|
||||
// X | C != C --> X >u C
|
||||
// iff C+1 is a power of 2 (C is a bitmask of the low bits)
|
||||
if (Cmp.isEquality() && Cmp.getOperand(1) == Or->getOperand(1) &&
|
||||
(*C + 1).isPowerOf2()) {
|
||||
Pred = (Pred == CmpInst::ICMP_EQ) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
|
||||
return new ICmpInst(Pred, Or->getOperand(0), Or->getOperand(1));
|
||||
}
|
||||
|
||||
if (!Cmp.isEquality() || *C != 0 || !Or->hasOneUse())
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -1876,12 +1876,12 @@ define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
|
|||
ret <2 x i1> %cmp
|
||||
}
|
||||
|
||||
; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
|
||||
; X | C == C --> X <=u C (when C+1 is PowerOf2).
|
||||
|
||||
define i1 @or1_eq1(i32 %x) {
|
||||
; CHECK-LABEL: @or1_eq1(
|
||||
; CHECK-NEXT: [[T0:%.*]] = or i32 %x, 1
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[T0]], 1
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 %x, 2
|
||||
; CHECK-NEXT: ret i1 [[T1]]
|
||||
;
|
||||
%t0 = or i32 %x, 1
|
||||
|
@ -1893,8 +1893,7 @@ define i1 @or1_eq1(i32 %x) {
|
|||
|
||||
define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @or3_eq3_vec(
|
||||
; CHECK-NEXT: [[T0:%.*]] = or <2 x i8> %x, <i8 3, i8 3>
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[T0]], <i8 3, i8 3>
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> %x, <i8 4, i8 4>
|
||||
; CHECK-NEXT: ret <2 x i1> [[T1]]
|
||||
;
|
||||
%t0 = or <2 x i8> %x, <i8 3, i8 3>
|
||||
|
@ -1906,8 +1905,7 @@ define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
|
|||
|
||||
define i1 @or7_ne7(i32 %x) {
|
||||
; CHECK-LABEL: @or7_ne7(
|
||||
; CHECK-NEXT: [[T0:%.*]] = or i32 %x, 7
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 7
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 %x, 7
|
||||
; CHECK-NEXT: ret i1 [[T1]]
|
||||
;
|
||||
%t0 = or i32 %x, 7
|
||||
|
@ -1919,8 +1917,7 @@ define i1 @or7_ne7(i32 %x) {
|
|||
|
||||
define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
|
||||
; CHECK-LABEL: @or63_ne63_vec(
|
||||
; CHECK-NEXT: [[T0:%.*]] = or <2 x i8> %x, <i8 63, i8 63>
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[T0]], <i8 63, i8 63>
|
||||
; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> %x, <i8 63, i8 63>
|
||||
; CHECK-NEXT: ret <2 x i1> [[T1]]
|
||||
;
|
||||
%t0 = or <2 x i8> %x, <i8 63, i8 63>
|
||||
|
|
Loading…
Reference in New Issue