[llvm] [llvm-diff] Add associative on BinOp (PR #123314)

Serval MARTINOT-LAGARDE via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 17 02:12:01 PST 2025


https://github.com/Serval6 created https://github.com/llvm/llvm-project/pull/123314

Sometimes some LLVM optimizations change the order of instruction parameters, so that two files can differ by only one line, but llvm-diff displays many of them. Because since llvm-diff considers two variables to be different, all uses of those variables are considered different.

```diff
$ llvm-diff test1.ll test2.ll
in function choice:
  in block %entry:
    >   %0 = or i1 %b, %a
    > … // there can be many lines
    >   ret i1 %0
    <   %0 = or i1 %a, %b
    < … // same lines there
    <   ret i1 %0
```

>From 1f693c5ca2ad1d33ea5998a7ad6a25749127140e Mon Sep 17 00:00:00 2001
From: Serval Martinot-Lagarde <serval.martinot-lagarde at sipearl.com>
Date: Thu, 16 Jan 2025 16:38:14 +0100
Subject: [PATCH] [llvm-diff] Add associative on BinOp

---
 llvm/test/tools/llvm-diff/associative.ll      | 19 +++++++++++++++++++
 llvm/tools/llvm-diff/lib/DifferenceEngine.cpp | 15 +++++++++++++++
 2 files changed, 34 insertions(+)
 create mode 100644 llvm/test/tools/llvm-diff/associative.ll

diff --git a/llvm/test/tools/llvm-diff/associative.ll b/llvm/test/tools/llvm-diff/associative.ll
new file mode 100644
index 00000000000000..bdef413340c9c8
--- /dev/null
+++ b/llvm/test/tools/llvm-diff/associative.ll
@@ -0,0 +1,19 @@
+; Check that associative operations are considered equal when parameters are exchanged.
+;
+; Replace '%a, %b' with '%b, %a' in 'or' (associative) and 'sub' (non-associative) operations.
+;
+; RUN: rm -f %t.ll
+; RUN: cat %s | sed -e 's/^\(  .*\) i1 %a, %b$/\1 i1 %b, %a/' > %t.ll
+; RUN: not llvm-diff %s %t.ll 2>&1 | FileCheck %s
+
+; CHECK:      in function choice:
+; CHECK-NEXT:   in block %entry:
+; CHECK-NEXT:     >   %1 = sub i1 %b, %a
+; CHECK-NEXT:     <   %1 = sub i1 %a, %b
+
+define i1 @choice(i1 %a, i1 %b) {
+entry:
+  %0 = or i1 %a, %b
+  %1 = sub i1 %a, %b
+  ret i1 %0
+}
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
index 9be0eec7b73f3e..78a326727abaec 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
@@ -536,6 +536,21 @@ class FunctionDifferenceEngine {
       return true;
     }
 
+    if (L->getNumOperands() == 2 &&
+        Instruction::isAssociative(L->getOpcode())) {
+      Value *LO1 = L->getOperand(0), *RO1 = R->getOperand(0),
+            *LO2 = L->getOperand(1), *RO2 = R->getOperand(1);
+      if ((equivalentAsOperands(LO1, RO1, AC) &&
+           equivalentAsOperands(LO2, RO2, AC)) ||
+          (equivalentAsOperands(LO1, RO2, AC) &&
+           equivalentAsOperands(LO2, RO1, AC)))
+        return false;
+      if (Complain)
+        Engine.logf("operands <%l, %l> and <%r, %r> differ")
+            << LO1 << LO2 << RO1 << RO2;
+      return true;
+    }
+
     for (unsigned I = 0, E = L->getNumOperands(); I != E; ++I) {
       Value *LO = L->getOperand(I), *RO = R->getOperand(I);
       if (!equivalentAsOperands(LO, RO, AC)) {



More information about the llvm-commits mailing list