From 047fba343dc9fba211a10058bc423c6373cc57f8 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 1 Aug 2018 14:40:35 +0000 Subject: [PATCH] Fix over-widening handling of COND_EXPRs (PR 86749) 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 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 | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/vect/pr86749.c | 26 ++++++++++++++++++++++++++ gcc/tree-vect-patterns.c | 8 ++++++++ 4 files changed, 46 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr86749.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a710c505506..405298dfd2b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-08-01 Richard Sandiford + + 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 PR target/86800 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7bf890ae8e1..7f75e108268 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-01 Richard Sandiford + + PR tree-optimization/86749 + * gcc.dg/vect/pr86749.c: New test. + 2018-08-01 Paolo Carlini 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 index 00000000000..803bcb0c620 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr86749.c @@ -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; +} diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index eb0e296b484..d41c61a3908 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -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 (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); } -- 2.30.2