[PATCH] [GVN] Eliminate redundant loads whose addresses are dependent on the result of a select instruction.
Daniel Berlin
dberlin at dberlin.org
Tue Mar 24 17:36:57 PDT 2015
On Tue, Mar 24, 2015 at 5:31 PM, Daniel Berlin <dberlin at dberlin.org> wrote:
> So, this is an awfully specific redundancy to detect in GVN.
>
> The more general case doesn't use select's but phi's, and is tested in gcc
> with GVNPRE with testcases like:
>
>
> int
> foo (int i)
> {
> int a, b;
> if (i)
> a = 3, b = 2;
> else
> a = 2, b = 3;
> return a + b;
> }
>
> and more complex testcase that involve expressions.
> But the basic idea is the same - if both values are computed already, the
> end is redundant.
> (here, the result is constant along both edges)
>
> GVN doesn't touch this (and wouldn't with your patch):
>
> ; Function Attrs: nounwind readnone ssp uwtable
> define i32 @foo(i32 %i) #0 {
> %1 = icmp eq i32 %i, 0
> %. = select i1 %1, i32 2, i32 3
> %.1 = select i1 %1, i32 3, i32 2
> %2 = add nsw i32 %., %.1
> ret i32 %2
> }
>
>
> GCC treats this as a GVNPRE problem rather than a GVN one, because it
> involves computing available values along edges.
>
> Putting these as selects, sadly, makes it harder for things like PRE to
> see this (though you could treat the selects are false blocks with incoming
> edges)
>
It would compute the values are available along each edge already, and
> insert a no-cost phi to merge them.
>
> In particular, if PRE saw this as
a = load gep_ptr_a
b = load gep_ptr_b
br cond, A, B
block A
c = gep_ptr a
goto C
block B
d = gep_ptr b
goto C
block C
e = phi(c, d)
load e
It should *already* insert a phi that merges (a, b) and uses it to replace
load e, without you doing anything.
(or at least, GVN-PRE definitely will).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150324/d5a4cc43/attachment.html>
More information about the llvm-commits
mailing list