[PATCH] D21512: [InstSimplify] look through zexts of icmps to eliminate obviously false logic (PR27869)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 19 15:06:32 PDT 2016
spatel created this revision.
spatel added reviewers: eli.friedman, majnemer, sanjoy.
spatel added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.
This is a specialized form of a transform that already exists in InstCombine. By doing this transform in InstSimplify, we sidestep the problem/question raised by PR27869:
https://llvm.org/bugs/show_bug.cgi?id=27869
...where InstCombine turns an icmp+zext into a shift causing us to miss the fold.
Ideally, we can generalize this a bit to catch other cases (and remove the corresponding code from InstCombine?), but I thought it was better to start with the specific case in the bug report.
http://reviews.llvm.org/D21512
Files:
lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstSimplify/AndOrXor.ll
Index: test/Transforms/InstSimplify/AndOrXor.ll
===================================================================
--- test/Transforms/InstSimplify/AndOrXor.ll
+++ test/Transforms/InstSimplify/AndOrXor.ll
@@ -233,12 +233,7 @@
define i32 @and_of_zexted_icmps(i32 %i) {
; CHECK-LABEL: @and_of_zexted_icmps(
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %i, 0
-; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %i, 4
-; CHECK-NEXT: [[CONV2:%.*]] = zext i1 [[CMP1]] to i32
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV]], [[CONV2]]
-; CHECK-NEXT: ret i32 [[AND]]
+; CHECK-NEXT: ret i32 0
;
%cmp = icmp eq i32 %i, 0
%conv = zext i1 %cmp to i32
@@ -250,12 +245,7 @@
define <4 x i32> @and_of_zexted_icmps_vec(<4 x i32> %i) {
; CHECK-LABEL: @and_of_zexted_icmps_vec(
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> %i, zeroinitializer
-; CHECK-NEXT: [[CONV:%.*]] = zext <4 x i1> [[CMP]] to <4 x i32>
-; CHECK-NEXT: [[CMP1:%.*]] = icmp slt <4 x i32> %i, zeroinitializer
-; CHECK-NEXT: [[CONV2:%.*]] = zext <4 x i1> [[CMP1]] to <4 x i32>
-; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[CONV]], [[CONV2]]
-; CHECK-NEXT: ret <4 x i32> [[AND]]
+; CHECK-NEXT: ret <4 x i32> zeroinitializer
;
%cmp = icmp eq <4 x i32> %i, zeroinitializer
%conv = zext <4 x i1> %cmp to <4 x i32>
Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp
+++ lib/Analysis/InstructionSimplify.cpp
@@ -1608,6 +1608,21 @@
}
}
+ // The compares may be hidden behind zexts.
+ // Look for this pattern: zext(icmp X, C0) & zext(icmp X, C1)).
+ ICmpInst::Predicate Pred0, Pred1;
+ const APInt *C0, *C1;
+ Value *X;
+ if (match(Op0, m_ZExt(m_ICmp(Pred0, m_Value(X), m_APInt(C0)))) &&
+ match(Op1, m_ZExt(m_ICmp(Pred1, m_Specific(X), m_APInt(C1))))) {
+ // Make a constant range that's the intersection of the two icmp ranges.
+ // If the intersection is empty, we know that the result is false.
+ auto Range0 = ConstantRange::makeAllowedICmpRegion(Pred0, *C0);
+ auto Range1 = ConstantRange::makeAllowedICmpRegion(Pred1, *C1);
+ if (Range0.intersectWith(Range1).isEmptySet())
+ return Constant::getNullValue(Op0->getType());
+ }
+
// Try some generic simplifications for associative operations.
if (Value *V = SimplifyAssociativeBinOp(Instruction::And, Op0, Op1, Q,
MaxRecurse))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21512.61230.patch
Type: text/x-patch
Size: 2521 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160619/5f0c6b1b/attachment.bin>
More information about the llvm-commits
mailing list