[gcc r17-3179] tree-optimization/126658 - TARGET_MEM_REF and non-null infering

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:b947bd4aac67ba3bdb6030aa4ac2f3eb0204df05

commit r17-3179-gb947bd4aac67ba3bdb6030aa4ac2f3eb0204df05
Author: Richard Biener <[email protected]>
Date:   Thu Aug 6 11:49:20 2026 +0200

    tree-optimization/126658 - TARGET_MEM_REF and non-null infering
    
    The following adjusts three places to avoid infering that operand
    zero of a TARGET_MEM_REF is literally dereferenced and thus may
    not be NULL.  This reflects the fact that within IVOPTs we cannot
    easily guarantee that there'll be a real pointer in TMR_BASE
    and fiddling with IVOPTs proved fragile.
    
    So we are taking a conservative stance here, with carving out
    the likely common case of a scaled index which is unlikely
    going to be a pointer (fingers crossing).
    
    For the testcase at hand the apparent non-NULLness was triggering
    a jump-threading miscompiling the testcase.
    
            PR tree-optimization/126658
            * gimple.cc (check_loadstore): Restrict TARGET_MEM_REF
            handling.
            * gimple-ssa-isolate-paths.cc (check_loadstore): Likewise.
            * gimple-range-infer.cc (non_null_loadstore): Likewise.
    
            * gcc.dg/torture/pr126658.c: New testcase.

Diff:
---
 gcc/gimple-range-infer.cc               | 13 +++++++++++--
 gcc/gimple-ssa-isolate-paths.cc         | 10 +++++++++-
 gcc/gimple.cc                           | 14 +++++++++++---
 gcc/testsuite/gcc.dg/torture/pr126658.c | 26 ++++++++++++++++++++++++++
 4 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index ecd197cf8590..65c10ac1cb43 100644
--- a/gcc/gimple-range-infer.cc
+++ b/gcc/gimple-range-infer.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-walk.h"
 #include "cfganal.h"
 #include "tree-dfa.h"
+#include "fold-const.h"
 
 // Create the global oracle.
 
@@ -61,9 +62,17 @@ private:
 // stmt range inference instance.
 
 static bool
-non_null_loadstore (gimple *, tree op, tree, void *data)
+non_null_loadstore (gimple *stmt, tree op, tree, void *data)
 {
-  if (TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
+  if (TREE_CODE (op) == MEM_REF
+      || (TREE_CODE (op) == TARGET_MEM_REF
+	  && !TMR_INDEX2 (op)
+	  && (!TMR_INDEX (op)
+	      || (TMR_STEP (op)
+		  && expr_not_equal_to (TMR_STEP (op),
+					wi::one (TYPE_PRECISION (TREE_TYPE
+							(TMR_STEP (op)))),
+					stmt)))))
     {
       /* Some address spaces may legitimately dereference zero.  */
       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op));
diff --git a/gcc/gimple-ssa-isolate-paths.cc b/gcc/gimple-ssa-isolate-paths.cc
index 9d359ef84e6a..ceef422495c7 100644
--- a/gcc/gimple-ssa-isolate-paths.cc
+++ b/gcc/gimple-ssa-isolate-paths.cc
@@ -51,7 +51,15 @@ static bool cfg_altered;
 static bool
 check_loadstore (gimple *stmt, tree op, tree, void *data)
 {
-  if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
+  if ((TREE_CODE (op) == MEM_REF
+       || (TREE_CODE (op) == TARGET_MEM_REF
+	   && !TMR_INDEX2 (op)
+	   && (!TMR_INDEX (op)
+	       || (TMR_STEP (op)
+		   && expr_not_equal_to (TMR_STEP (op),
+					 wi::one (TYPE_PRECISION (TREE_TYPE
+							(TMR_STEP (op)))),
+					 stmt)))))
       && operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0))
     {
       TREE_THIS_VOLATILE (op) = 1;
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index c791e0412431..648400aa4445 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -3153,9 +3153,17 @@ nonbarrier_call_p (gimple *call)
    This routine only makes a superficial check for a dereference.  Thus
    it must only be used if it is safe to return a false negative.  */
 static bool
-check_loadstore (gimple *, tree op, tree, void *data)
-{
-  if (TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
+check_loadstore (gimple *stmt, tree op, tree, void *data)
+{
+  if (TREE_CODE (op) == MEM_REF
+      || (TREE_CODE (op) == TARGET_MEM_REF
+	  && !TMR_INDEX2 (op)
+	  && (!TMR_INDEX (op)
+	      || (TMR_STEP (op)
+		  && expr_not_equal_to (TMR_STEP (op),
+					wi::one (TYPE_PRECISION (TREE_TYPE
+							(TMR_STEP (op)))),
+					stmt)))))
     {
       /* Some address spaces may legitimately dereference zero.  */
       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op));
diff --git a/gcc/testsuite/gcc.dg/torture/pr126658.c b/gcc/testsuite/gcc.dg/torture/pr126658.c
new file mode 100644
index 000000000000..c11d637d199f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126658.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+long a, b;
+int c, d;
+long long e[1];
+char __attribute__((noipa))
+f(long long *p1, int i, long long *p3)
+{
+  long long *g;
+  for (; a < i; a++)
+    g = p1 + 1;
+  while (g != p1) {
+    --g;
+    b = g - p1;
+    if (p3[b])
+      c = 3;
+  }
+  return c;
+}
+int main() {
+  long long j[] = {1096435691};
+  d = f(e, 2147483647 - 2147279301, j);
+  if (d != 3)
+    __builtin_abort ();
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.