http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55565



--- Comment #4 from Aldy Hernandez <aldyh at gcc dot gnu.org> 2013-01-10 
17:46:39 UTC ---

I compared the code generated by trunk with the generated code in rev 190339

which broke the test.  The trunk code is more optimal than when the test

"passed", so I suggest either removing the dg-final in the test, or modifying

the regex in the dg-final.



In the testcase we have something functionally equivalent to (where x is the

original function argument passed in f1):



  if (huge + x > 0.0) {

    if ((int)x > 0)

      return 0.0;

    ...

  } else

    return x;



When the test passed, we used to generate:



.L17:

        ld %r8,.LC0@toc(%r2)

        ld %r10,.LC2@toc(%r2)

        lfd %f13,0(%r8)

        lfd %f0,0(%r10)

        fadd %f1,%f1,%f13

        fcmpu %cr7,%f1,%f0

        bng %cr7,.L4           /* if (!(huge + x > 0.0)) return x; */

        ...

        ...



.L4:                           /* return x; */

        std %r9,-8(%r1)

        ori 2,2,0

        lfd %f1,-8(%r1)

        blr



Notice that since we perform the fadd onto %f1, we need to reload %f1 from

memory.



On trunk though, we keep x/%f1 and 0.0/%f0 around so we can return them

directly.  We can return x/%f1 directly in one case, or copy 0.0/%f0 to the

return register (%f1) in the another case.



.L18:

        ld %r8,.LC6@toc(%r2)

        ld %r9,.LC1@toc(%r2)

        lfd %f13,0(%r8)

        lfd %f0,0(%r9)

        fadd %f13,%f1,%f13

        fcmpu %cr7,%f13,%f0

        bnglr %cr7            /* if (!(huge + x > 0.0)) return x; */

        cmpdi %cr7,%r10,0

        fmr %f1,%f0

        bgelr %cr7            /* if (huge+x>0.0 && (int)x >0) return 0.0 */



Bottom line, on trunk we avoid a branch and memory load/stores.



Testing a patch.

Reply via email to