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? 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