aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-01-13 09:43:52 +0100
committerRichard Biener <rguenther@suse.de>2021-01-13 11:13:33 +0100
commitffd28c265e6d611983cd27e9332dc799039a3f04 (patch)
treec4cc185c351fc1a6805b62c9ea3740ce1835b876 /gcc/tree-ssa-sccvn.c
parent5d057bfeff70e5b8d00e521844c476f62d51e22c (diff)
downloadgcc-ffd28c265e6d611983cd27e9332dc799039a3f04.zip
gcc-ffd28c265e6d611983cd27e9332dc799039a3f04.tar.gz
gcc-ffd28c265e6d611983cd27e9332dc799039a3f04.tar.bz2
tree-optimization/98640 - fix bogus sign-extension with VN
VN tried to express a sign extension from int to long of a trucated quantity with a plain conversion but that loses the truncation. Since there's no single operand doing truncate plus sign extend (there was a proposed SEXT_EXPR to do that at some point mapping to RTL sign_extract) don't bother to appropriately model this with two ops (which the VN insert machinery doesn't handle and which is unlikely to CSE fully). 2021-01-13 Richard Biener <rguenther@suse.de> PR tree-optimization/98640 * tree-ssa-sccvn.c (visit_nary_op): Do not try to handle plus or minus from a truncated operand to be sign-extended. * gcc.dg/torture/pr98640.c: New testcase.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 0ba846f..588f1b8 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4681,7 +4681,7 @@ visit_copy (tree lhs, tree rhs)
is the same. */
static tree
-valueized_wider_op (tree wide_type, tree op)
+valueized_wider_op (tree wide_type, tree op, bool allow_truncate)
{
if (TREE_CODE (op) == SSA_NAME)
op = vn_valueize (op);
@@ -4695,7 +4695,7 @@ valueized_wider_op (tree wide_type, tree op)
return tem;
/* Or the op is truncated from some existing value. */
- if (TREE_CODE (op) == SSA_NAME)
+ if (allow_truncate && TREE_CODE (op) == SSA_NAME)
{
gimple *def = SSA_NAME_DEF_STMT (op);
if (is_gimple_assign (def)
@@ -4760,12 +4760,15 @@ visit_nary_op (tree lhs, gassign *stmt)
|| gimple_assign_rhs_code (def) == MULT_EXPR))
{
tree ops[3] = {};
+ /* When requiring a sign-extension we cannot model a
+ previous truncation with a single op so don't bother. */
+ bool allow_truncate = TYPE_UNSIGNED (TREE_TYPE (rhs1));
/* Either we have the op widened available. */
- ops[0] = valueized_wider_op (type,
- gimple_assign_rhs1 (def));
+ ops[0] = valueized_wider_op (type, gimple_assign_rhs1 (def),
+ allow_truncate);
if (ops[0])
- ops[1] = valueized_wider_op (type,
- gimple_assign_rhs2 (def));
+ ops[1] = valueized_wider_op (type, gimple_assign_rhs2 (def),
+ allow_truncate);
if (ops[0] && ops[1])
{
ops[0] = vn_nary_op_lookup_pieces