On Mon, 4 Mar 2019, Jakub Jelinek wrote: > Hi! > > As the following testcase shows, these match.pd patterns create temporary > GIMPLE stmts even when they aren't going to result in anything useful > (all targets except aarch64 right now), besides compile time memory > this is bad with -fno-tree-dce because those stmts might not be even valid > for the target and we might ICE during expansion. > > Fixed by guarding them with a vectorized_internal_fn_supported_p test. > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. > Note, I have no idea how to test this on aarch64, Richard S., can you please > do that? Thanks. > > 2019-03-04 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/89570 > * match.pd (vec_cond into cond_op simplification): Guard with > vectorized_internal_fn_supported_p test and #if GIMPLE. > > * gcc.dg/pr89570.c: New test. > > --- gcc/match.pd.jj 2019-01-16 09:35:08.421259263 +0100 > +++ gcc/match.pd 2019-03-04 13:00:02.884284658 +0100 > @@ -5177,17 +5177,24 @@ (define_operator_list COND_TERNARY > if the target can do it in one go. This makes the operation conditional > on c, so could drop potentially-trapping arithmetic, but that's a valid > simplification if the result of the operation isn't needed. */ > +#if GIMPLE > (for uncond_op (UNCOND_BINARY) > cond_op (COND_BINARY) > (simplify > (vec_cond @0 (view_convert? (uncond_op@4 @1 @2)) @3) > - (with { tree op_type = TREE_TYPE (@4); } > - (if (element_precision (type) == element_precision (op_type)) > + (with { tree op_type = TREE_TYPE (@4); > + internal_fn cond_fn = get_conditional_internal_fn (uncond_op); } > + (if (cond_fn != IFN_LAST > + && vectorized_internal_fn_supported_p (cond_fn, op_type) > + && element_precision (type) == element_precision (op_type)) > (view_convert (cond_op @0 @1 @2 (view_convert:op_type @3)))))) > (simplify > (vec_cond @0 @1 (view_convert? (uncond_op@4 @2 @3))) > - (with { tree op_type = TREE_TYPE (@4); } > - (if (element_precision (type) == element_precision (op_type)) > + (with { tree op_type = TREE_TYPE (@4); > + internal_fn cond_fn = get_conditional_internal_fn (uncond_op); } > + (if (cond_fn != IFN_LAST > + && vectorized_internal_fn_supported_p (cond_fn, op_type) > + && element_precision (type) == element_precision (op_type)) > (view_convert (cond_op (bit_not @0) @2 @3 (view_convert:op_type @1))))))) > > /* Same for ternary operations. */ > @@ -5195,15 +5202,24 @@ (define_operator_list COND_TERNARY > cond_op (COND_TERNARY) > (simplify > (vec_cond @0 (view_convert? (uncond_op@5 @1 @2 @3)) @4) > - (with { tree op_type = TREE_TYPE (@5); } > - (if (element_precision (type) == element_precision (op_type)) > + (with { tree op_type = TREE_TYPE (@5); > + internal_fn cond_fn > + = get_conditional_internal_fn (as_internal_fn (uncond_op)); } > + (if (cond_fn != IFN_LAST > + && vectorized_internal_fn_supported_p (cond_fn, op_type) > + && element_precision (type) == element_precision (op_type)) > (view_convert (cond_op @0 @1 @2 @3 (view_convert:op_type @4)))))) > (simplify > (vec_cond @0 @1 (view_convert? (uncond_op@5 @2 @3 @4))) > - (with { tree op_type = TREE_TYPE (@5); } > - (if (element_precision (type) == element_precision (op_type)) > + (with { tree op_type = TREE_TYPE (@5); > + internal_fn cond_fn > + = get_conditional_internal_fn (as_internal_fn (uncond_op)); } > + (if (cond_fn != IFN_LAST > + && vectorized_internal_fn_supported_p (cond_fn, op_type) > + && element_precision (type) == element_precision (op_type)) > (view_convert (cond_op (bit_not @0) @2 @3 @4 > (view_convert:op_type @1))))))) > +#endif > > /* Detect cases in which a VEC_COND_EXPR effectively replaces the > "else" value of an IFN_COND_*. */ > --- gcc/testsuite/gcc.dg/pr89570.c.jj 2019-03-04 13:04:00.459544926 +0100 > +++ gcc/testsuite/gcc.dg/pr89570.c 2019-03-04 13:03:44.157801534 +0100 > @@ -0,0 +1,15 @@ > +/* PR tree-optimization/89570 */ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -ftree-vectorize -fno-trapping-math -fno-tree-dce > -fno-tree-dominator-opts" } */ > +/* { dg-additional-options "-mvsx" { target powerpc_vsx_ok } } */ > + > +void > +foo (double *x, double *y, double *z) > +{ > + int i; > + for (i = 0; i < 7; i += 2) > + { > + x[i] = y[i] ? z[i] / 2.0 : z[i]; > + x[i + 1] = y[i + 1] ? z[i + 1] / 2.0 : z[i + 1]; > + } > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)