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

Reply via email to