common branch conditions - could optimize better

Geoff Keating geoffk@envy.cygnus.com
Thu Dec 16 12:47:00 GMT 1999


Jeffrey A Law <law@cygnus.com> writes:

>   In message <19991216113512.A31064@horac.ta.jcu.cz>you write:
>   > On Thu, Dec 16, 1999 at 02:11:45AM -0700, Jeffrey A Law wrote:
>   > >   In message <Pine.LNX.4.10.9910160739260.1293-100000@first>you write:
>   > >   > Hello GCC people
>   > >   > 
>   > >   > Consider the following code:
>   > >   > 
>   > >   > void f1(void), f2(void), f3(void);
>   > >   > void foo (int x, int y)
>   > >   > {
>   > >   >     if (x*x*x<y*y)
>   > >   > 	f1();
>   > >   >     else
>   > >   > 	f2();
>   > >   >     if (x*x*x<y*y)
>   > >   > 	f3();
>   > >   > }
>   > >   > 
>   > >   > Here the condition x*x*x<y*y could be tested only once.
>   > >   > GCC 2.95.1 does not optimize this - see below the asm,
>   > >   > produced with gcc -O2 -S on i586-linux.
>   > >   > Even x*x*x and y*y are computed twice... what is that gcse thing then
>   > ?
>   > > It's got to be something goofy about the ia32 target, they're removed jus
>   > t
>   > > fine on my PA target.
>   > 
>   > It is because of gcse is unable to handle parallels used by x86 to model
>   > flags. I've made some progress in this path (for cprop only for now),
>   > but first part (to propagate from parallels) got refused (it is not issue
>   > for x86 after my mov patterns cleanups anyway) and second part (to propagat
>   > e
>   > to parallels) wasn't reviewed yet.
> No.  That is not the cause.  Go back to gcc-2.95 and try it like the report
> mentions.  Remember gcc-2.95 did not have the new ia32 backend.

On ppc, this is very interesting.

Under 2.95.2, no folding is done.  We get six multiplies emitted at -O2.

Under 19991215, we get four (count em!) multiplies.  The extra
multiply is of x*temp, where temp was previously computed from x*x.

The RTL that is generated for the multiplies of 'x' is:

(insn 4 53 6 (set (reg/v:SI 82)
        (reg:SI 3 r3)) 426 {movsi+1} (nil)
    (nil))

..

(insn 13 7 58 (set (reg:SI 84)
        (mult:SI (reg/v:SI 82)
            (reg/v:SI 82))) 94 {mulsi3_no_mq} (nil)
    (nil))


// reg 92 is never mentioned other than here.  It is created by GCSE.
(insn 58 13 15 (set (reg:SI 92)
        (reg:SI 84)) -1 (nil)
    (nil))

(insn 15 58 17 (set (reg:SI 85)
        (mult:SI (reg:SI 84)
            (reg/v:SI 82))) 94 {mulsi3_no_mq} (nil)
    (nil))


and then in a basic block far away,

// changed by GCSE from 
// (set (reg:SI 88 (mult:SI (reg/v: SI 82) (reg/v: SI 82))))
(insn 30 48 32 (set (reg:SI 88)
        (reg:SI 84)) 426 {movsi+1} (nil)
    (nil))

(insn 32 30 34 (set (reg:SI 89)
        (mult:SI (reg:SI 88)
            (reg/v:SI 82))) 94 {mulsi3_no_mq} (nil)
    (nil))

GCSE is seeing these multiplies as different simply because they use
different registers.  Probably what we need to do is train GCSE to do a
little no-op set elimination.

-- 
- Geoffrey Keating <geoffk@cygnus.com>


More information about the Gcc mailing list