https://gcc.gnu.org/g:c6a3791ccb1b46bfd6a353b8750ab57ab6f0a169
commit r16-9666-gc6a3791ccb1b46bfd6a353b8750ab57ab6f0a169 Author: Richard Biener <[email protected]> Date: Mon Aug 24 13:54:44 2026 +0200 tree-optimization/127000 - ICE with bogus match pattern 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. 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. (cherry picked from commit 82b5610085b3b5e4d19d864d8f2a151461ce49a8) Diff: --- 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(-) diff --git a/gcc/match.pd b/gcc/match.pd index eb64403123a1..933f66125ad7 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3263,10 +3263,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 000000000000..ba4827af746a --- /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 f0553e54d20c..0da9e250b521 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -2569,8 +2569,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);
