On December 5, 2019 2:03:24 PM GMT+01:00, Marc Glisse <marc.gli...@inria.fr> wrote: >On Wed, 4 Dec 2019, Jakub Jelinek wrote: > >> --- gcc/match.pd.jj 2019-12-03 10:20:00.244913801 +0100 >> +++ gcc/match.pd 2019-12-03 13:36:01.084435697 +0100 >> @@ -2159,20 +2159,26 @@ (define_operator_list COND_TERNARY >> /* A - (A +- B) -> -+ B */ >> /* A +- (B -+ A) -> +- B */ >> (simplify >> - (minus (plus:c @0 @1) @0) >> - @1) >> + (minus (nop_convert (plus:c (nop_convert @0) @1)) @0) >> + (view_convert @1)) > >I know I introduced nop_convert, and it can be convenient, but IIRC it >also has some limitations. > >int f(int b,unsigned c){ > int a=c; > int d=a+b; > return d-a; >} >int g(int a, int b){ > int d=(unsigned)a+b; > return d-a; >} >int h(int b,int a){ > int d=a+b; > return d-a; >} > >While g and h are properly optimized during forwprop1, f isn't, because > >nop_convert sees that 'a' comes from a conversion, and only returns d >(unlike 'convert?' which would try both a and d). > >When inside nop_convert we have an operation, say (nop_convert (plus >...)), there is no ambiguity, so we are fine. With just (nop_convert >@0), >less so. > >It happens that during EVRP, for some reason (different valuization >function?), nop_convert does not match the conversion, and we do >optimize >f. But that almost looks like an accident. > >convert? with explicit checks would probably work better for the inner >conversion, except that handling the vector view_convert case may >become >painful. I didn't think too hard about possible fancy tricks like a >second >nop_convert: > >(minus (nop_convert (plus:c (nop_convert @0) @1)) (nop_convert @0))
If use gets more and more we can make nop_convert a first class citizen and allow a? Variant. Or handle all predicates as? Variant. Richard.