Re: Fix over-widening handling of COND_EXPRs (PR 86749)

2018-08-01 Thread Richard Biener
On Wed, Aug 1, 2018 at 11:16 AM Richard Sandiford
 wrote:
>
> This PR is a wrong-code bug caused by the over-widening support.
> The minimum input precisions for a COND_EXPR are supposed to apply
> only to the "then" and "else" values, but here we were applying
> them to the operands of a nested COND_EXPR comparison instead.
>
> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
> and x86_64-linux-gnu.  OK to install?

OK.

Richard.

> Richard
>
>
> 2018-08-01  Richard Sandiford  
>
> gcc/
> PR tree-optimization/86749
> * tree-vect-patterns.c (vect_determine_min_output_precision_1):
> If the lhs is used in a COND_EXPR, check that it is being used
> as the "then" or "else" value.
>
> gcc/testsuite/
> PR tree-optimization/86749
> * gcc.dg/vect/pr86749.c: New test.
>
> Index: gcc/tree-vect-patterns.c
> ===
> --- gcc/tree-vect-patterns.c2018-07-31 15:26:37.102461003 +0100
> +++ gcc/tree-vect-patterns.c2018-08-01 10:12:45.865913009 +0100
> @@ -4399,6 +4399,14 @@ vect_determine_min_output_precision_1 (s
>stmt_vec_info use_stmt_info = vinfo->lookup_stmt (use_stmt);
>if (!use_stmt_info || !use_stmt_info->min_input_precision)
> return false;
> +  /* The input precision recorded for COND_EXPRs applies only to the
> +"then" and "else" values.  */
> +  gassign *assign = dyn_cast  (stmt_info->stmt);
> +  if (assign
> + && gimple_assign_rhs_code (assign) == COND_EXPR
> + && use->use != gimple_assign_rhs2_ptr (assign)
> + && use->use != gimple_assign_rhs3_ptr (assign))
> +   return false;
>precision = MAX (precision, use_stmt_info->min_input_precision);
>  }
>
> Index: gcc/testsuite/gcc.dg/vect/pr86749.c
> ===
> --- /dev/null   2018-07-26 10:26:13.137955424 +0100
> +++ gcc/testsuite/gcc.dg/vect/pr86749.c 2018-08-01 10:12:45.865913009 +0100
> @@ -0,0 +1,26 @@
> +/* { dg-additional-options "-O3" } */
> +
> +#include "tree-vect.h"
> +
> +short a, b, f, g;
> +int c = 4, d, e = -1L;
> +long h = 4;
> +
> +int
> +main ()
> +{
> +  check_vect ();
> +
> +  long i;
> +  for (; d <= 55; d++)
> +{
> +  g = c >= 2 ? 0 : b << c;
> +  f = g - a;
> +  i = (f ^ 9223372036854775807) < 0 ? f : h;
> +  e &= i;
> +}
> +  if (e != 4)
> +__builtin_abort ();
> +
> +  return 0;
> +}


Fix over-widening handling of COND_EXPRs (PR 86749)

2018-08-01 Thread Richard Sandiford
This PR is a wrong-code bug caused by the over-widening support.
The minimum input precisions for a COND_EXPR are supposed to apply
only to the "then" and "else" values, but here we were applying
them to the operands of a nested COND_EXPR comparison instead.

Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
and x86_64-linux-gnu.  OK to install?

Richard


2018-08-01  Richard Sandiford  

gcc/
PR tree-optimization/86749
* tree-vect-patterns.c (vect_determine_min_output_precision_1):
If the lhs is used in a COND_EXPR, check that it is being used
as the "then" or "else" value.

gcc/testsuite/
PR tree-optimization/86749
* gcc.dg/vect/pr86749.c: New test.

Index: gcc/tree-vect-patterns.c
===
--- gcc/tree-vect-patterns.c2018-07-31 15:26:37.102461003 +0100
+++ gcc/tree-vect-patterns.c2018-08-01 10:12:45.865913009 +0100
@@ -4399,6 +4399,14 @@ vect_determine_min_output_precision_1 (s
   stmt_vec_info use_stmt_info = vinfo->lookup_stmt (use_stmt);
   if (!use_stmt_info || !use_stmt_info->min_input_precision)
return false;
+  /* The input precision recorded for COND_EXPRs applies only to the
+"then" and "else" values.  */
+  gassign *assign = dyn_cast  (stmt_info->stmt);
+  if (assign
+ && gimple_assign_rhs_code (assign) == COND_EXPR
+ && use->use != gimple_assign_rhs2_ptr (assign)
+ && use->use != gimple_assign_rhs3_ptr (assign))
+   return false;
   precision = MAX (precision, use_stmt_info->min_input_precision);
 }
 
Index: gcc/testsuite/gcc.dg/vect/pr86749.c
===
--- /dev/null   2018-07-26 10:26:13.137955424 +0100
+++ gcc/testsuite/gcc.dg/vect/pr86749.c 2018-08-01 10:12:45.865913009 +0100
@@ -0,0 +1,26 @@
+/* { dg-additional-options "-O3" } */
+
+#include "tree-vect.h"
+
+short a, b, f, g;
+int c = 4, d, e = -1L;
+long h = 4;
+
+int
+main ()
+{
+  check_vect ();
+
+  long i;
+  for (; d <= 55; d++)
+{
+  g = c >= 2 ? 0 : b << c;
+  f = g - a;
+  i = (f ^ 9223372036854775807) < 0 ? f : h;
+  e &= i;
+}
+  if (e != 4)
+__builtin_abort ();
+
+  return 0;
+}