[PATCH] D18842: [InstCombine] remove constant by inverting compare + logic (PR27105)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 6 13:17:47 PDT 2016
spatel created this revision.
spatel added reviewers: hfinkel, majnemer, nlopes, amehsan.
spatel added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.
This is a fix for PR27105:
https://llvm.org/bugs/show_bug.cgi?id=27105
We can check if all bits outside of a constant mask are set with a single constant.
As noted in the bug report, although this form should be considered the canonical IR, backends may want to transform this into an 'andn' / 'andc' comparison against zero because that could be a single machine instruction.
http://reviews.llvm.org/D18842
Files:
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/icmp.ll
Index: test/Transforms/InstCombine/icmp.ll
===================================================================
--- test/Transforms/InstCombine/icmp.ll
+++ test/Transforms/InstCombine/icmp.ll
@@ -1956,3 +1956,26 @@
%cmp = icmp uge i32 %addx, %addy
ret i1 %cmp
}
+
+define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
+; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, -43
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or i32 %x, 42
+ %cmp = icmp eq i32 %or, -1
+ ret i1 %cmp
+}
+
+define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
+; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, -43
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or i32 %x, 42
+ %cmp = icmp ne i32 %or, -1
+ ret i1 %cmp
+}
+
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2248,6 +2248,15 @@
Constant *NotCI = ConstantExpr::getNot(RHS);
if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
+
+ // Comparing if all bits outside of a constant mask are set?
+ // Replace (X | C) == -1 with (X & ~C) == ~C.
+ // This removes the -1 constant.
+ if (BO->hasOneUse() && RHS->isAllOnesValue()) {
+ Constant *NotBOC = ConstantExpr::getNot(BOC);
+ Value *And = Builder->CreateAnd(BO->getOperand(0), NotBOC);
+ return new ICmpInst(ICI.getPredicate(), And, NotBOC);
+ }
}
break;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18842.52844.patch
Type: text/x-patch
Size: 1828 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160406/16a81fd5/attachment.bin>
More information about the llvm-commits
mailing list