[llvm-commits] [llvm] r121671 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll
Frits van Bommel
fvbommel at gmail.com
Mon Dec 13 04:29:42 PST 2010
On Mon, Dec 13, 2010 at 4:18 AM, Chris Lattner <sabre at nondot.org> wrote:
> Author: lattner
> Date: Sun Dec 12 21:18:54 2010
> New Revision: 121671
>
> URL: http://llvm.org/viewvc/llvm-project?rev=121671&view=rev
> Log:
> fix a fairly serious oversight with switch formation from
> or'd conditions. Previously we'd compile something like this:
>
> int crud (unsigned char c) {
> return c == 62 || c == 34 || c == 92;
> }
>
> into:
>
> switch i8 %c, label %lor.rhs [
> i8 62, label %lor.end
> i8 34, label %lor.end
> ]
>
> lor.rhs: ; preds = %entry
> %cmp8 = icmp eq i8 %c, 92
> br label %lor.end
>
> lor.end: ; preds = %entry, %entry, %lor.rhs
> %0 = phi i1 [ true, %entry ], [ %cmp8, %lor.rhs ], [ true, %entry ]
> %lor.ext = zext i1 %0 to i32
> ret i32 %lor.ext
>
> which failed to merge the compare-with-92 into the switch. With this patch
> we simplify this all the way to:
>
> switch i8 %c, label %lor.rhs [
> i8 62, label %lor.end
> i8 34, label %lor.end
> i8 92, label %lor.end
> ]
>
> lor.rhs: ; preds = %entry
> br label %lor.end
>
> lor.end: ; preds = %entry, %entry, %entry, %lor.rhs
> %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ]
> %lor.ext = zext i1 %0 to i32
> ret i32 %lor.ext
>
> which is much better for codegen's switch lowering stuff. This kicks in 33 times
> on 176.gcc (for example) cutting 103 instructions off the generated code.
I have some code where this doesn't work, probably due to the
requirement for the only use of the icmp to be a phi. A reduced test
case:
=====
bool foo(int x) { return x == 1; }
bool bar(int x) { return x == 2; }
bool baz(int x) { return x == 3; }
bool quux(int x) {
return foo(x) || bar(x) || baz(x);
}
=====
The problem seems to be that the return gets duplicated into the two
branches before inlining, causing quux() to come out of clang -O3 like
this:
=====
define zeroext i1 @quux(int)(i32 %x) nounwind readnone {
entry:
switch i32 %x, label %lor.rhs [
i32 1, label %lor.end
i32 2, label %lor.end
]
lor.rhs: ; preds = %entry
%cmp.i5 = icmp eq i32 %x, 3 ; [#uses=1]
ret i1 %cmp.i5
lor.end: ; preds = %entry, %entry
ret i1 true
}
=====
More information about the llvm-commits
mailing list