[llvm] r303312 - [InstCombine] handle icmp i1 X, C early to avoid creating an unknown pattern
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed May 17 15:29:40 PDT 2017
Author: spatel
Date: Wed May 17 17:29:40 2017
New Revision: 303312
URL: http://llvm.org/viewvc/llvm-project?rev=303312&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/trunk/test/Transforms/InstCombine/set.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=303312&r1=303311&r2=303312&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Wed May 17 17:29:40 2017
@@ -4266,6 +4266,29 @@ static Instruction *canonicalizeICmpBool
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!");
Modified: llvm/trunk/test/Transforms/InstCombine/set.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/set.ll?rev=303312&r1=303311&r2=303312&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/set.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/set.ll Wed May 17 17:29:40 2017
@@ -152,10 +152,8 @@ define <3 x i1> @test14vec(<3 x i1> %A,
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
More information about the llvm-commits
mailing list