diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 22ba5ed36e683..a43b453178d86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-03-12 Richard Biener + + PR tree-optimization/94103 + * tree-ssa-sccvn.c (visit_reference_op_load): Avoid type + punning when the mode precision is not sufficient. + 2020-03-12 H.J. Lu PR target/89229 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a1f0e3a18c5c1..a5730ebbbc070 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-12 Richard Biener + + PR tree-optimization/94103 + * gcc.target/i386/pr94103.c: New testcase. + 2020-03-12 Tobias Burnus PR middle-end/94120 diff --git a/gcc/testsuite/gcc.target/i386/pr94103.c b/gcc/testsuite/gcc.target/i386/pr94103.c new file mode 100644 index 0000000000000..91b5fc64b5e07 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr94103.c @@ -0,0 +1,17 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O3" } */ + +int main() +{ + long double x; + unsigned long u[2] = {0xEEEEEEEEEEEEEEEEUL, 0xEEEEEEEEEEEEEEEEUL}; + __builtin_memcpy(&x, &u, sizeof x); + __builtin_memcpy(&u, &x, sizeof u); + ++*(unsigned char *)&x; + (void)-x; + __builtin_memcpy(&u, &x, sizeof u); + if (u[1] != 0xEEEEEEEEEEEEEEEEUL + || u[0] != 0xEEEEEEEEEEEEEEEFUL) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index b7174cd603ff0..150ddad3e69f7 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4899,13 +4899,22 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt) if (result && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op))) { - /* We will be setting the value number of lhs to the value number - of VIEW_CONVERT_EXPR (result). - So first simplify and lookup this expression to see if it - is already available. */ - gimple_match_op res_op (gimple_match_cond::UNCOND, - VIEW_CONVERT_EXPR, TREE_TYPE (op), result); - result = vn_nary_build_or_lookup (&res_op); + /* Avoid the type punning in case the result mode has padding where + the op we lookup has not. */ + if (maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))), + GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op))))) + result = NULL_TREE; + else + { + /* We will be setting the value number of lhs to the value number + of VIEW_CONVERT_EXPR (result). + So first simplify and lookup this expression to see if it + is already available. */ + gimple_match_op res_op (gimple_match_cond::UNCOND, + VIEW_CONVERT_EXPR, TREE_TYPE (op), result); + result = vn_nary_build_or_lookup (&res_op); + } + /* When building the conversion fails avoid inserting the reference again. */ if (!result)