On Thu, Jan 8, 2015 at 6:09 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > The recent ifcvt changes result in movcc being attempted with > comparisons like (ltgt (reg:CCFPU flags) (const_int 0)). > I see several issues with the current ix86_expand_int_movcc code: > 1) the code was unprepared to handle *reverse_condition* failures > (returns of UNKNOWN) > 2) for CCFP/CCFPU modes, I think it should be treated like scalar > float comparisons, ix86_reverse_condition seems to do the job here > 3) compare_code in the second hunk was a dead computation, because > the variable is not used afterwards until it is unconditionally overwritten > (set to UNKNOWN). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2015-01-08 Jakub Jelinek <ja...@redhat.com> > > PR target/64338 > * config/i386/i386.c (ix86_expand_int_movcc): Don't reverse > compare_code when it is unconditionally overwritten afterwards. > Use ix86_reverse_condition instead of reverse_condition. Don't > change code if *reverse_condition* returned UNKNOWN and don't > swap ct/cf and negate diff in that case. > > * g++.dg/opt/pr64338.C: New test.
OK with two small nits inline. Thanks, Uros. > > --- gcc/config/i386/i386.c.jj 2015-01-06 09:14:05.000000000 +0100 > +++ gcc/config/i386/i386.c 2015-01-07 09:59:09.297790590 +0100 > @@ -20830,9 +20830,7 @@ ix86_expand_int_movcc (rtx operands[]) > if (diff < 0) > { > machine_mode cmp_mode = GET_MODE (op0); > - > - std::swap (ct, cf); > - diff = -diff; > + enum rtx_code new_code; > > if (SCALAR_FLOAT_MODE_P (cmp_mode)) > { > @@ -20842,13 +20840,15 @@ ix86_expand_int_movcc (rtx operands[]) > is not valid in general (we may convert non-trapping > condition > to trapping one), however on i386 we currently emit all > comparisons unordered. */ > - compare_code = reverse_condition_maybe_unordered (compare_code); > - code = reverse_condition_maybe_unordered (code); > + new_code = reverse_condition_maybe_unordered (code); > } > else > + new_code = ix86_reverse_condition (code, cmp_mode); > + if (new_code != UNKNOWN) > { > - compare_code = reverse_condition (compare_code); > - code = reverse_condition (code); > + code = new_code; > + std::swap (ct, cf); > + diff = -diff; Please put std::swap at the top, above code= assignment. Cosmetic, but I noticed this during std::swap conversion. ;) > } > } > > @@ -20986,9 +20986,7 @@ ix86_expand_int_movcc (rtx operands[]) > if (cf == 0) > { > machine_mode cmp_mode = GET_MODE (op0); > - > - cf = ct; > - ct = 0; > + enum rtx_code new_code; > > if (SCALAR_FLOAT_MODE_P (cmp_mode)) > { > @@ -20998,14 +20996,21 @@ ix86_expand_int_movcc (rtx operands[]) > that is not valid in general (we may convert non-trapping > condition to trapping one), however on i386 we currently > emit all comparisons unordered. */ > - code = reverse_condition_maybe_unordered (code); > + new_code = reverse_condition_maybe_unordered (code); > } > else > { > - code = reverse_condition (code); > - if (compare_code != UNKNOWN) > + new_code = ix86_reverse_condition (code, cmp_mode); > + if (compare_code != UNKNOWN && new_code != UNKNOWN) > compare_code = reverse_condition (compare_code); > } > + > + if (new_code != UNKNOWN) > + { > + code = new_code; > + cf = ct; > + ct = 0; > + } > } > > if (compare_code != UNKNOWN) > --- gcc/testsuite/g++.dg/opt/pr64338.C.jj 2015-01-07 10:18:04.740275018 > +0100 > +++ gcc/testsuite/g++.dg/opt/pr64338.C 2015-01-07 10:17:50.000000000 +0100 > @@ -0,0 +1,29 @@ > +// PR target/64338 > +// { dg-do compile } > +// { dg-options "-O2" } > +// { dg-additional-options "-mtune=generic -march=i586" { target { { > i?86-*-* x86_64-*-* } && ia32 } } } Please use -mtune=i686, generic tuning setting changes over time ... > +enum O {}; > +struct A { A (); }; > +struct B { int fn1 (); }; > +struct C { struct D; D *fn2 (); void fn3 (); int fn4 (); }; > +struct F { void fn5 (const int & = 0); }; > +struct G { F *fn6 (); }; > +struct H { int h; }; > +struct C::D { friend class C; G *fn7 (); }; > +O a; > + > +void > +C::fn3 () > +{ > + int b = a; > + H c; > + if (b) > + fn2 ()->fn7 ()->fn6 ()->fn5 (); > + double d; > + if (fn4 ()) > + d = c.h > 0; > + A e (b ? A () : A ()); > + B f; > + f.fn1 () && d && fn2 (); > +} > > Jakub