1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[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.

llvm-svn: 258904
This commit is contained in:
David Majnemer 2016-01-27 02:43:28 +00:00
parent 991bc63f1d
commit 4ee6f6446b
2 changed files with 28 additions and 2 deletions

View File

@ -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;

View File

@ -554,3 +554,28 @@ bb20: ; preds = %bb19, %bb8
; 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