While reworking the transitive relation processing, I discovered the
transitive tables were incorrect for EQUAL and NOT_EQUAL.
It was a missed opportunity rather than an incorrect code situation.
x == y, y != z, returned VR_VARYING rather than determining that x !=
z. And the inverse as well:
x != y, y == z did not produce x != z.
Fixed by adjusting the table entries, and providing a testcase.
Bootstrapped on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From 22837c2d1a0e6d1706e0a90d2d7b3f5b15f9f286 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Thu, 10 Sep 2026 14:17:58 -0400
Subject: [PATCH 1/3] Fix ranger transitive table.
The transitive relation table was incorrect for equal and not equal.
x == y, y != z was producing no relation for x,z rather than x != z.
Likewise x != y, y == z was not producing x != z.
gcc/
* value-relation.cc (rr_transitive_table): Update.
gcc/testsuite/
* gcc.dg/tree-ssa/evrp-trans3.c: New.
---
gcc/testsuite/gcc.dg/tree-ssa/evrp-trans3.c | 23 +++++++++++++++++++++
gcc/value-relation.cc | 4 ++--
2 files changed, 25 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/evrp-trans3.c
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp-trans3.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp-trans3.c
new file mode 100644
index 00000000000..fb6cfc41107
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp-trans3.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void link_error ();
+
+/* The transitive table was incorrect for x == y, y != z. */
+void test1 (int x, int y, int z)
+{
+ if (x == y)
+ if (y != z)
+ if (x == z)
+ link_error ();
+}
+
+/* The transitive table was incorrect for x != y, y == z. */
+void test2 (int x, int y, int z)
+{
+ if (x != y)
+ if (y == z)
+ if (x == z)
+ link_error ();
+}
+/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */
diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index 2e95d12b578..afe78ed50b7 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -169,10 +169,10 @@ static const unsigned char rr_transitive_table[VREL_LAST][VREL_LAST] = {
VREL_GE, VREL_VARYING },
// VREL_EQ
{ VREL_VARYING, VREL_VARYING, VREL_LT, VREL_LE, VREL_GT, VREL_GE, VREL_EQ,
- VREL_VARYING },
+ VREL_NE },
// VREL_NE
{ VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING, VREL_VARYING,
- VREL_VARYING, VREL_VARYING, VREL_VARYING } };
+ VREL_VARYING, VREL_NE, VREL_VARYING } };
// Apply transitive operation between relation R1 and relation R2, and
// return the resulting relation, if any.
--
2.55.0