[llvm] r258904 - [SimplifyCFG] Don't mistake icmp of and for a tree of comparisons
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 26 18:43:28 PST 2016
Author: majnemer
Date: Tue Jan 26 20:43:28 2016
New Revision: 258904
URL: http://llvm.org/viewvc/llvm-project?rev=258904&view=rev
Log:
[SimplifyCFG] Don't mistake icmp of and for a tree of comparisons
SimplifyCFG tries to turn complex branch conditions into a switch.
Some of it's logic attempts to reason about bitwise arithmetic produced
by InstCombine. InstCombine can turn things like (X == 2) || (X == 3)
into (X & 1) == 2 and so SimplifyCFG tries to detect when this occurs so
that it can produce a switch instruction.
However, the legality checking was not sufficient to determine whether
or not this had occured. Correctly check this case by requiring that
the right-hand side of the comparison be a power of two.
This fixes PR26323.
Modified:
llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=258904&r1=258903&r2=258904&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Tue Jan 26 20:43:28 2016
@@ -405,13 +405,14 @@ private:
ConstantInt *RHSC;
// Pattern match a special case
- // (x & ~2^x) == y --> x == y || x == y|2^x
+ // (x & ~2^z) == y --> x == y || x == y|2^z
// This undoes a transformation done by instcombine to fuse 2 compares.
if (ICI->getPredicate() == (isEQ ? ICmpInst::ICMP_EQ:ICmpInst::ICMP_NE)) {
if (match(ICI->getOperand(0),
m_And(m_Value(RHSVal), m_ConstantInt(RHSC)))) {
APInt Not = ~RHSC->getValue();
- if (Not.isPowerOf2()) {
+ if (Not.isPowerOf2() && C->getValue().isPowerOf2() &&
+ Not != C->getValue()) {
// If we already have a value for the switch, it has to match!
if(!setValueOnce(RHSVal))
return false;
Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=258904&r1=258903&r2=258904&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Tue Jan 26 20:43:28 2016
@@ -554,3 +554,28 @@ bb20:
; CHECK: %arg.off = add i32 %arg, -8
; CHECK: icmp ult i32 %arg.off, 11
}
+
+define void @PR26323(i1 %tobool23, i32 %tmp3) {
+entry:
+ %tobool5 = icmp ne i32 %tmp3, 0
+ %neg14 = and i32 %tmp3, -2
+ %cmp17 = icmp ne i32 %neg14, -1
+ %or.cond = and i1 %tobool5, %tobool23
+ %or.cond1 = and i1 %cmp17, %or.cond
+ br i1 %or.cond1, label %if.end29, label %if.then27
+
+if.then27: ; preds = %entry
+ call void @foo1()
+ unreachable
+
+if.end29: ; preds = %entry
+ ret void
+}
+
+; CHECK-LABEL: define void @PR26323(
+; CHECK: %tobool5 = icmp ne i32 %tmp3, 0
+; CHECK: %neg14 = and i32 %tmp3, -2
+; CHECK: %cmp17 = icmp ne i32 %neg14, -1
+; CHECK: %or.cond = and i1 %tobool5, %tobool23
+; CHECK: %or.cond1 = and i1 %cmp17, %or.cond
+; CHECK: br i1 %or.cond1, label %if.end29, label %if.then27
More information about the llvm-commits
mailing list