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:
parent
991bc63f1d
commit
4ee6f6446b
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user