From be672e08bbe0d9f210285ec6f3eccf4ff0469d0e Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 3 Apr 2013 13:18:09 -0600 Subject: [PATCH] re PR tree-optimization/56799 (Runfail after r197060+r197082.) PR tree-optimization/56799 * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Bring back test for widening conversion erroneously dropped in prior change. PR tree-optimization/56799 * gcc.c-torture/execute/pr56799.c: New test. From-SVN: r197453 --- gcc/ChangeLog | 8 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/pr56799.c | 43 +++++++++++++++++++ gcc/tree-ssa-dom.c | 10 ++++- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr56799.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e25a822067..a3b60c93e3d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-04-03 Jeff Law + + PR tree-optimization/56799 + * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Bring + back test for widening conversion erroneously dropped in prior + change. + 2013-04-03 Kyrylo Tkachov PR target/56809 @@ -896,6 +903,7 @@ * config/tilegx/tilepro.h (PROFILE_BEFORE_PROLOGUE): Define. 2013-03-25 Jeff Law + * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Add missing check for INTEGRAL_TYPE_P that was missing due to checking in wrong version of prior patch. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2cc5fa8ed44..dc0b74533f4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-03 Jeff Law + + PR tree-optimization/56799 + * gcc.c-torture/execute/pr56799.c: New test. + 2013-04-03 Paolo Carlini PR c++/56815 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr56799.c b/gcc/testsuite/gcc.c-torture/execute/pr56799.c new file mode 100644 index 00000000000..d9ee26bc27f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr56799.c @@ -0,0 +1,43 @@ + +#include +typedef struct { int x; int y;} S; +extern int foo(S*); +int hi = 0, lo = 0; + +int main() +{ + S a; + int r; + a.x = (int) 0x00010000; + a.y = 1; + r = foo (&a); + if (r == 2 && lo==0 && hi==1) + { + exit (0); + } + abort (); +} + +typedef unsigned short u16; + +__attribute__ ((noinline)) int foo (S* ptr) +{ + int a = ptr->x; + int c = 0; + u16 b = (u16) a; + if (b != 0) + { + lo = 1; + c += ptr->y; + } + b = a >> 16; + if (b != 0) + { + hi = 1; + c+= ptr->y; + } + c += ptr->y; + return c; +} + + diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 29d2bb4f3e1..d98a646aa4f 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1151,9 +1151,15 @@ record_equivalences_from_incoming_edge (basic_block bb) { tree old_rhs = gimple_assign_rhs1 (defstmt); - /* If the constant is in the range of the type of OLD_RHS, - then convert the constant and record the equivalence. */ + /* If the conversion widens the original value and + the constant is in the range of the type of OLD_RHS, + then convert the constant and record the equivalence. + + Note that int_fits_type_p does not check the precision + if the upper and lower bounds are OK. */ if (INTEGRAL_TYPE_P (TREE_TYPE (old_rhs)) + && (TYPE_PRECISION (TREE_TYPE (lhs)) + > TYPE_PRECISION (TREE_TYPE (old_rhs))) && int_fits_type_p (rhs, TREE_TYPE (old_rhs))) { tree newval = fold_convert (TREE_TYPE (old_rhs), rhs);