The following fixes up the (T *)(ptr - ptr_cst) pattern to not
rely on build_fold_addr_expr_with_type which can add unwanted
casts. It also guards VN against such (sofar unexpected) results
of simplification.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/127000
* match.pd ((T *)(ptr - ptr_cst)): Use build1 to build
an ADDR_EXPR.
* tree-ssa-sccvn.cc (vn_nary_build_or_lookup_1): Avoid
creating GIMPLE_SINGLE_RHS to insert stmts.
* gcc.dg/torture/pr127000.c: New testcase.
---
gcc/match.pd | 8 ++++----
gcc/testsuite/gcc.dg/torture/pr127000.c | 14 ++++++++++++++
gcc/tree-ssa-sccvn.cc | 8 ++++++--
3 files changed, 24 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr127000.c
diff --git a/gcc/match.pd b/gcc/match.pd
index bcfc7f0e8ce..1cd35ef2e2d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3565,10 +3565,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
(convert (pointer_diff @0 INTEGER_CST@1))
(if (POINTER_TYPE_P (type))
- { build_fold_addr_expr_with_type
- (build2 (MEM_REF, char_type_node, @0,
- wide_int_to_tree (ptr_type_node, wi::neg (wi::to_wide (@1)))),
- type); }))
+ { build1 (ADDR_EXPR, type,
+ build2 (MEM_REF, char_type_node, @0,
+ wide_int_to_tree (ptr_type_node,
+ wi::neg (wi::to_wide (@1))))); }))
/* If arg0 is derived from the address of an object or function, we may
be able to fold this expression using the object or function's
diff --git a/gcc/testsuite/gcc.dg/torture/pr127000.c
b/gcc/testsuite/gcc.dg/torture/pr127000.c
new file mode 100644
index 00000000000..ba4827af746
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr127000.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+typedef void *fp_t_2;
+void *g8, *g11, *g19;
+fp_t_2 f18f31_fp3;
+void f18f31(uint64_t a0)
+{
+ g8 = 0;
+ a0 = (char *)g11 - (char *)g8;
+ *(uint64_t *)g19 = a0;
+ f18f31_fp3 = *(fp_t_2 *)g19;
+}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 840bcf70e0a..dbb19e4a498 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2571,8 +2571,12 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool
insert,
tree val = vn_lookup_simplify_result (res_op);
/* ??? In weird cases we can end up with internal-fn calls,
but this isn't expected so throw the result away. See
- PR123040 for an example. */
- if (!val && insert && res_op->code.is_tree_code ())
+ PR123040 for an example. Likewise we can end up with
+ &MEM[ptr_1 + CST] which would be a vn_reference (PR127000). */
+ if (!val
+ && insert
+ && res_op->code.is_tree_code ()
+ && (tree_code) res_op->code != ADDR_EXPR)
{
gimple_seq stmts = NULL;
result = maybe_push_res_to_seq (res_op, &stmts);
--
2.51.0