From 1dc00a8ec9aeba86b74b16bff6f171824bb7b4a1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 12 Mar 2020 14:18:35 +0100 Subject: [PATCH] tree-optimization/94103 avoid CSE of loads with padding VN currently replaces a load of a 16 byte entity 128 bits of precision (TImode) with the result of a load of a 16 byte entity with 80 bits of mode precision (XFmode). That will go downhill since if the padding bits are not actually filled with memory contents those bits are missing. 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. * gcc.target/i386/pr94103.c: New testcase. --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr94103.c | 17 +++++++++++++++++ gcc/tree-ssa-sccvn.c | 23 ++++++++++++++++------- 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr94103.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 22ba5ed36e6..a43b453178d 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 a1f0e3a18c5..a5730ebbbc0 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 00000000000..91b5fc64b5e --- /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 b7174cd603f..150ddad3e69 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) -- 2.30.2