[PATCH] D21397: Teach SimplifyCFG to Create Switches from InstCombine Or Mask'd Comparisons
Thomas Jablin via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 16 19:00:39 PDT 2016
tjablin updated the summary for this revision.
tjablin updated this revision to Diff 61059.
tjablin added a comment.
I have split out and applied the bug fix and m_ConstantInt => m_APInt portions of the past separately. What remains is just the new functionality.
http://reviews.llvm.org/D21397
Files:
lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/SimplifyCFG/switch_create.ll
Index: test/Transforms/SimplifyCFG/switch_create.ll
===================================================================
--- test/Transforms/SimplifyCFG/switch_create.ll
+++ test/Transforms/SimplifyCFG/switch_create.ll
@@ -618,4 +618,43 @@
else:
ret void
+}
+
+; Form a switch when or'ing a power of two
+; CHECK-LABEL: define void @test21
+; CHECK: i32 32, label %else
+; CHECK: i32 13, label %else
+; CHECK: i32 12, label %else
+define void @test21(i32 %arg) {
+ %and = or i32 %arg, 1
+ %cmp1 = icmp ne i32 %and, 13
+ %cmp2 = icmp ne i32 %arg, 32
+ %pred = and i1 %cmp1, %cmp2
+ br i1 %pred, label %if, label %else
+
+if:
+ call void @foo1()
+ ret void
+
+else:
+ ret void
+}
+
+; Since %cmp1 is always false, a switch is never formed
+; CHECK-LABEL: define void @test22
+; CHECK-NOT: switch
+; CHECK: ret void
+define void @test22(i32 %arg) {
+ %and = or i32 %arg, 1
+ %cmp1 = icmp ne i32 %and, 12
+ %cmp2 = icmp ne i32 %arg, 32
+ %pred = and i1 %cmp1, %cmp2
+ br i1 %pred, label %if, label %else
+
+if:
+ call void @foo1()
+ ret void
+
+else:
+ ret void
}
\ No newline at end of file
Index: lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyCFG.cpp
+++ lib/Transforms/Utils/SimplifyCFG.cpp
@@ -461,6 +461,9 @@
QUERY( (y & ~mask = y) =>
((x & ~mask = y) <=> (x = y OR x = (y | mask)))
);
+ QUERY( (y | mask = y) =>
+ ((x | mask = y) <=> (x = y OR x = (y & ~mask)))
+ );
*/
// Please note that each pattern must be a dual implication (<--> or
@@ -503,6 +506,28 @@
}
}
+ // Pattern match a special case:
+ /*
+ QUERY( (y | mask = y) =>
+ ((x | mask = y) <=> (x = y OR x = (y & ~mask)))
+ );
+ */
+ if (match(ICI->getOperand(0),
+ m_Or(m_Value(RHSVal), m_APInt(RHSC)))) {
+ APInt Mask = *RHSC;
+ if (Mask.isPowerOf2() && (C->getValue() | Mask) == C->getValue()) {
+ // If we already have a value for the switch, it has to match!
+ if (!setValueOnce(RHSVal))
+ return false;
+
+ Vals.push_back(C);
+ Vals.push_back(ConstantInt::get(C->getContext(),
+ C->getValue() & ~Mask));
+ UsedICmps++;
+ return true;
+ }
+ }
+
// If we already have a value for the switch, it has to match!
if (!setValueOnce(ICI->getOperand(0)))
return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21397.61059.patch
Type: text/x-patch
Size: 2584 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160617/41a65d36/attachment-0001.bin>
More information about the llvm-commits
mailing list