Fix over-widening handling of COND_EXPRs (PR 86749)
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 1 Aug 2018 14:40:35 +0000 (14:40 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 1 Aug 2018 14:40:35 +0000 (14:40 +0000)
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.

2018-08-01  Richard Sandiford  <richard.sandiford@arm.com>

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.

From-SVN: r263213

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr86749.c [new file with mode: 0644]
gcc/tree-vect-patterns.c

index a710c50550661ec5b93ed32720bf540ba4b60a84..405298dfd2b9d194e0ad10a67660e06a97e8c752 100644 (file)
@@ -1,3 +1,10 @@
+2018-08-01  Richard Sandiford  <richard.sandiford@arm.com>
+
+       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.
+
 2018-08-01  Tom de Vries  <tdevries@suse.de>
 
        PR target/86800
index 7bf890ae8e1461dcfa9d4b6a14769906c0467a25..7f75e108268bb45429899e52a2572e9ebc37cb42 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-01  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR tree-optimization/86749
+       * gcc.dg/vect/pr86749.c: New test.
+
 2018-08-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/86661
diff --git a/gcc/testsuite/gcc.dg/vect/pr86749.c b/gcc/testsuite/gcc.dg/vect/pr86749.c
new file mode 100644 (file)
index 0000000..803bcb0
--- /dev/null
@@ -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;
+}
index eb0e296b4849388e202153d342a9dfb1d193ab47..d41c61a3908cc758ca262aa97844f57df8351cbd 100644 (file)
@@ -4399,6 +4399,14 @@ vect_determine_min_output_precision_1 (stmt_vec_info stmt_info, tree lhs)
       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 <gassign *> (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);
     }