forked from OSchip/llvm-project
[InstCombine] handle icmp i1 X, C early to avoid creating an unknown pattern
The missing optimization for xor-of-icmps still needs to be added, but by being more efficient (not generating unnecessary logic ops with constants) we avoid the bug. See discussion in post-commit comments: https://reviews.llvm.org/D32143 llvm-svn: 303312
This commit is contained in:
parent
cde4b3f4e6
commit
ba212c241a
|
@ -4266,6 +4266,29 @@ static Instruction *canonicalizeICmpBool(ICmpInst &I,
|
|||
Value *A = I.getOperand(0), *B = I.getOperand(1);
|
||||
assert(A->getType()->getScalarType()->isIntegerTy(1) && "Bools only");
|
||||
|
||||
// A boolean compared to true/false can be simplified to Op0/true/false in
|
||||
// 14 out of the 20 (10 predicates * 2 constants) possible combinations.
|
||||
// Cases not handled by InstSimplify are always 'not' of Op0.
|
||||
if (match(B, m_Zero())) {
|
||||
switch (I.getPredicate()) {
|
||||
case CmpInst::ICMP_EQ: // A == 0 -> !A
|
||||
case CmpInst::ICMP_ULE: // A <=u 0 -> !A
|
||||
case CmpInst::ICMP_SGE: // A >=s 0 -> !A
|
||||
return BinaryOperator::CreateNot(A);
|
||||
default:
|
||||
llvm_unreachable("ICmp i1 X, C not simplified as expected.");
|
||||
}
|
||||
} else if (match(B, m_One())) {
|
||||
switch (I.getPredicate()) {
|
||||
case CmpInst::ICMP_NE: // A != 1 -> !A
|
||||
case CmpInst::ICMP_ULT: // A <u 1 -> !A
|
||||
case CmpInst::ICMP_SGT: // A >s -1 -> !A
|
||||
return BinaryOperator::CreateNot(A);
|
||||
default:
|
||||
llvm_unreachable("ICmp i1 X, C not simplified as expected.");
|
||||
}
|
||||
}
|
||||
|
||||
switch (I.getPredicate()) {
|
||||
default:
|
||||
llvm_unreachable("Invalid icmp instruction!");
|
||||
|
|
|
@ -152,10 +152,8 @@ define <3 x i1> @test14vec(<3 x i1> %A, <3 x i1> %B) {
|
|||
|
||||
define i1 @bool_eq0(i64 %a) {
|
||||
; CHECK-LABEL: @bool_eq0(
|
||||
; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 %a, 0
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp eq i64 %a, 1
|
||||
; CHECK-NEXT: [[AND:%.*]] = xor i1 [[C]], [[B]]
|
||||
; CHECK-NEXT: ret i1 [[AND]]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 %a, 1
|
||||
; CHECK-NEXT: ret i1 [[TMP1]]
|
||||
;
|
||||
%b = icmp sgt i64 %a, 0
|
||||
%c = icmp eq i64 %a, 1
|
||||
|
|
Loading…
Reference in New Issue