InstCombine: variations on 0xffffffff - x >= 4

The following transforms are valid if -C is a power of 2:
(icmp ugt (xor X, C), ~C) -> (icmp ult X, C)
(icmp ult (xor X, C), -C) -> (icmp uge X, C)

These are nice, they get rid of the xor.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185915 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2013-07-09 09:20:58 +00:00
parent 36b6f7409d
commit fecf0d7a01
2 changed files with 30 additions and 0 deletions

View File

@ -1126,6 +1126,18 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
Builder->getInt(RHSV ^ NotSignBit));
}
}
// (icmp ugt (xor X, C), ~C) -> (icmp ult X, C)
// iff -C is a power of 2
if (ICI.getPredicate() == ICmpInst::ICMP_UGT &&
XorCST->getValue() == ~RHSV && (RHSV + 1).isPowerOf2())
return new ICmpInst(ICmpInst::ICMP_ULT, LHSI->getOperand(0), XorCST);
// (icmp ult (xor X, C), -C) -> (icmp uge X, C)
// iff -C is a power of 2
if (ICI.getPredicate() == ICmpInst::ICMP_ULT &&
XorCST->getValue() == -RHSV && RHSV.isPowerOf2())
return new ICmpInst(ICmpInst::ICMP_UGE, LHSI->getOperand(0), XorCST);
}
break;
case Instruction::And: // (icmp pred (and X, AndCST), RHS)

View File

@ -1181,3 +1181,21 @@ define i1 @icmp_and_X_-16_ne-16(i32 %X) {
%cmp = icmp ne i32 %and, -16
ret i1 %cmp
}
; CHECK: @icmp_sub_-1_X_ult_4
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %X, -5
; CHECK-NEXT: ret i1 [[CMP]]
define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
%sub = sub i32 -1, %X
%cmp = icmp ult i32 %sub, 4
ret i1 %cmp
}
; CHECK: @icmp_sub_-1_X_uge_4
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, -4
; CHECK-NEXT: ret i1 [[CMP]]
define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
%sub = sub i32 -1, %X
%cmp = icmp uge i32 %sub, 4
ret i1 %cmp
}