From d11be094c716885475a4a1562a967e4a127ecece Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 17 Nov 2018 16:10:48 +0100 Subject: [PATCH] re PR tree-optimization/87546 (Gcc miscompiles at -O3 on valid code) PR tree-optimization/87546 * tree-vect-patterns.c (vect_look_through_possible_promotion): Add min_precision variable, initially set it to orig_precision, only does something if op_type's precision is <= min_precision and update min_precision whenever calling set_op. * gcc.dg/vect/O3-pr87546.c: New test. From-SVN: r266237 --- gcc/ChangeLog | 8 ++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/vect/O3-pr87546.c | 29 +++++++++++++++++++++++++++++ gcc/tree-vect-patterns.c | 8 ++++++-- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/O3-pr87546.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6097fde67c..3392f8f498a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-11-17 Jakub Jelinek + + PR tree-optimization/87546 + * tree-vect-patterns.c (vect_look_through_possible_promotion): Add + min_precision variable, initially set it to orig_precision, only does + something if op_type's precision is <= min_precision and update + min_precision whenever calling set_op. + 2018-11-16 Jan Hubicka PR ipa/87957 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0a237beca3..30386c6fa89 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-17 Jakub Jelinek + + PR tree-optimization/87546 + * gcc.dg/vect/O3-pr87546.c: New test. + 2018-11-17 Jozef Lawrynowicz PR middle-end/87854 diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr87546.c b/gcc/testsuite/gcc.dg/vect/O3-pr87546.c new file mode 100644 index 00000000000..0d3b71474c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-pr87546.c @@ -0,0 +1,29 @@ +#include "tree-vect.h" + +int a; +long b, f; +signed char c, g; +short int d = 219; +int e[64]; + +__attribute__((noipa)) void +foo (void) +{ + asm volatile ("" : : "g" (&a), "g" (&d) : "memory"); + for (c = 0; c < 64; c++) + { + g = d < 0 ? d : d >> a; + f = g + b; + e[c] = f; + } + if (e[1] != (signed char) d) + __builtin_abort (); +} + +int +main () +{ + check_vect (); + foo (); + return 0; +} diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 3053642b241..2b56d85afc5 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -367,6 +367,7 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op, tree res = NULL_TREE; tree op_type = TREE_TYPE (op); unsigned int orig_precision = TYPE_PRECISION (op_type); + unsigned int min_precision = orig_precision; stmt_vec_info caster = NULL; while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type)) { @@ -385,7 +386,7 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op, This copes with cases such as the result of an arithmetic operation being truncated before being stored, and where that arithmetic operation has been recognized as an over-widened one. */ - if (TYPE_PRECISION (op_type) <= orig_precision) + if (TYPE_PRECISION (op_type) <= min_precision) { /* Use OP as the UNPROM described above if we haven't yet found a promotion, or if using the new input preserves the @@ -393,7 +394,10 @@ vect_look_through_possible_promotion (vec_info *vinfo, tree op, if (!res || TYPE_PRECISION (unprom->type) == orig_precision || TYPE_SIGN (unprom->type) == TYPE_SIGN (op_type)) - unprom->set_op (op, dt, caster); + { + unprom->set_op (op, dt, caster); + min_precision = TYPE_PRECISION (op_type); + } /* Stop if we've already seen a promotion and if this conversion does more than change the sign. */ else if (TYPE_PRECISION (op_type) -- 2.11.4.GIT