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

Reply via email to