[PATCH] tree-optimization/126658 - TARGET_MEM_REF and non-null infering
Richard Biener <[email protected]> Thu, 6 Aug 2026 13:13:11 +0200 (CEST)
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
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.
I'm leaving this a bit to give people the chance to comment but
plan to push this after a while.
Thanks,
Richard.
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.
---
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(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr126658.c
diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index ecd197cf859..65c10ac1cb4 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 9d359ef84e6..ceef422495c 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 c791e041243..648400aa444 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 00000000000..c11d637d199
--- /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 ();
+}
--
2.51.0