[llvm] [llvm-diff] Also diff alloca's allocated type and alignment (PR #84781)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 14 08:57:34 PDT 2024
https://github.com/YanWQ-monad updated https://github.com/llvm/llvm-project/pull/84781
>From 431bdd42855c957eb0efefc4a03ac4adacd4c5c8 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 11 Mar 2024 23:59:47 +0800
Subject: [PATCH 1/6] Diff alloca allocated type and alignment
---
llvm/tools/llvm-diff/lib/DifferenceEngine.cpp | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
index 64b5051af14892..b34fd2acaa5368 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
@@ -527,6 +527,20 @@ class FunctionDifferenceEngine {
Difference = true;
}
return Difference;
+ } else if (isa<AllocaInst>(L)) {
+ const AllocaInst *LI = cast<AllocaInst>(L);
+ const AllocaInst *RI = cast<AllocaInst>(R);
+
+ if (LI->getAllocatedType() != RI->getAllocatedType()) {
+ if (Complain)
+ Engine.log("alloca allocated type differ");
+ return true;
+ }
+ if (LI->getAlign() != RI->getAlign()) {
+ if (Complain)
+ Engine.log("alloca alignment differ");
+ return true;
+ }
} else if (isa<UnreachableInst>(L)) {
return false;
}
>From d2fcbccfa11f90f19e536352d7bd8427bb2b6b29 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Tue, 12 Mar 2024 00:31:31 +0800
Subject: [PATCH 2/6] Use `hasSameSpecialState` instead
---
llvm/tools/llvm-diff/lib/DifferenceEngine.cpp | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
index b34fd2acaa5368..d8622159151230 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
@@ -377,6 +377,9 @@ class FunctionDifferenceEngine {
return true;
}
+ if (!L->hasSameSpecialState(R))
+ return true;
+
if (isa<CmpInst>(L)) {
if (cast<CmpInst>(L)->getPredicate()
!= cast<CmpInst>(R)->getPredicate()) {
@@ -527,20 +530,6 @@ class FunctionDifferenceEngine {
Difference = true;
}
return Difference;
- } else if (isa<AllocaInst>(L)) {
- const AllocaInst *LI = cast<AllocaInst>(L);
- const AllocaInst *RI = cast<AllocaInst>(R);
-
- if (LI->getAllocatedType() != RI->getAllocatedType()) {
- if (Complain)
- Engine.log("alloca allocated type differ");
- return true;
- }
- if (LI->getAlign() != RI->getAlign()) {
- if (Complain)
- Engine.log("alloca alignment differ");
- return true;
- }
} else if (isa<UnreachableInst>(L)) {
return false;
}
>From 34e6fdb39bef6cd5cf04967e588a6bd37306b8a5 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Tue, 12 Mar 2024 00:33:45 +0800
Subject: [PATCH 3/6] Add complain log
---
llvm/tools/llvm-diff/lib/DifferenceEngine.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
index d8622159151230..5b91e317a85b60 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
@@ -377,8 +377,11 @@ class FunctionDifferenceEngine {
return true;
}
- if (!L->hasSameSpecialState(R))
+ if (!L->hasSameSpecialState(R)) {
+ if (Complain)
+ Engine.log("special states differ");
return true;
+ }
if (isa<CmpInst>(L)) {
if (cast<CmpInst>(L)->getPredicate()
>From 8aded1f825f7a113b516e527ba5382a5b292d6a9 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Tue, 12 Mar 2024 01:04:54 +0800
Subject: [PATCH 4/6] Diff load's type
---
llvm/tools/llvm-diff/lib/DifferenceEngine.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
index 5b91e317a85b60..3b629dbe974eb6 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
@@ -389,6 +389,12 @@ class FunctionDifferenceEngine {
if (Complain) Engine.log("different predicates");
return true;
}
+ } else if (isa<LoadInst>(L)) {
+ if (cast<LoadInst>(L)->getType() != cast<LoadInst>(R)->getType()) {
+ if (Complain)
+ Engine.log("load types differ");
+ return true;
+ }
} else if (isa<CallInst>(L)) {
return diffCallSites(cast<CallInst>(*L), cast<CallInst>(*R), Complain);
} else if (isa<PHINode>(L)) {
>From 8825b7d6d821057f67e352ae59c98ba1f40c7c56 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Thu, 14 Mar 2024 23:56:46 +0800
Subject: [PATCH 5/6] Identify the same type on both sides
---
llvm/tools/llvm-diff/lib/DifferenceEngine.cpp | 82 +++++++++++++++++--
1 file changed, 75 insertions(+), 7 deletions(-)
diff --git a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
index 3b629dbe974eb6..4b6f7102e0bbaf 100644
--- a/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
+++ b/llvm/tools/llvm-diff/lib/DifferenceEngine.cpp
@@ -131,6 +131,9 @@ class FunctionDifferenceEngine {
// committed to the Values map.
DenseSet<std::pair<const Value *, const Value *>> TentativeValues;
+ // The current mapping of whether a type pair is the same
+ DenseMap<std::pair<const Type *, const Type *>, bool> IsSameTypes;
+
// Equivalence Assumptions
//
// For basic blocks in loops, some values in phi nodes may depend on
@@ -219,6 +222,42 @@ class FunctionDifferenceEngine {
});
}
+ bool isSameType(const Type *LT, const Type *RT) {
+ if (LT == RT)
+ return true;
+ if (LT->getTypeID() != RT->getTypeID())
+ return false;
+
+ auto Key = std::make_pair(LT, RT);
+ if (auto It = IsSameTypes.find(Key); It != IsSameTypes.end())
+ return It->second;
+
+ bool IsSame;
+ if (isa<StructType>(LT)) {
+ auto *LST = dyn_cast<StructType>(LT);
+ auto *RST = dyn_cast<StructType>(RT);
+ IsSame = std::equal(
+ LST->element_begin(), LST->element_end(), RST->element_begin(),
+ RST->element_end(),
+ [this](const Type *L, const Type *R) { return isSameType(L, R); });
+ } else if (isa<VectorType>(LT)) {
+ auto *LVT = dyn_cast<VectorType>(LT);
+ auto *RVT = dyn_cast<VectorType>(RT);
+ IsSame = LVT->getElementCount() == RVT->getElementCount() &&
+ isSameType(LVT->getElementType(), RVT->getElementType());
+ } else if (isa<ArrayType>(LT)) {
+ auto *LAT = dyn_cast<ArrayType>(LT);
+ auto *RAT = dyn_cast<ArrayType>(RT);
+ IsSame = LAT->getNumElements() == RAT->getNumElements() &&
+ isSameType(LAT->getElementType(), RAT->getElementType());
+ } else {
+ return false;
+ }
+
+ IsSameTypes[Key] = IsSame;
+ return IsSame;
+ }
+
typedef std::pair<const BasicBlock *, const BasicBlock *> BlockPair;
/// A type which sorts a priority queue by the number of unprocessed
@@ -307,6 +346,7 @@ class FunctionDifferenceEngine {
do {
assert(LI != LE && RI != R->end());
const Instruction *LeftI = &*LI, *RightI = &*RI;
+ Engine.logf("diff %l, %r") << LeftI << RightI;
// If the instructions differ, start the more sophisticated diff
// algorithm at the start of the block.
@@ -377,12 +417,6 @@ class FunctionDifferenceEngine {
return true;
}
- if (!L->hasSameSpecialState(R)) {
- if (Complain)
- Engine.log("special states differ");
- return true;
- }
-
if (isa<CmpInst>(L)) {
if (cast<CmpInst>(L)->getPredicate()
!= cast<CmpInst>(R)->getPredicate()) {
@@ -390,11 +424,39 @@ class FunctionDifferenceEngine {
return true;
}
} else if (isa<LoadInst>(L)) {
- if (cast<LoadInst>(L)->getType() != cast<LoadInst>(R)->getType()) {
+ if (!isSameType(cast<LoadInst>(L)->getType(),
+ cast<LoadInst>(R)->getType())) {
if (Complain)
Engine.log("load types differ");
return true;
}
+
+ if (!L->hasSameSpecialState(R)) {
+ if (Complain)
+ Engine.log("special states differ");
+ return true;
+ }
+ } else if (isa<AllocaInst>(L)) {
+ const AllocaInst *LI = cast<AllocaInst>(L);
+ const AllocaInst *RI = cast<AllocaInst>(R);
+
+ if (!isSameType(LI->getAllocatedType(), RI->getAllocatedType())) {
+ if (Complain)
+ Engine.log("alloca allocated type differ");
+ return true;
+ }
+ if (LI->getAlign() != RI->getAlign()) {
+ if (Complain)
+ Engine.log("alloca alignment differ");
+ return true;
+ }
+ } else if (isa<GetElementPtrInst>(L)) {
+ if (!isSameType(cast<GetElementPtrInst>(L)->getSourceElementType(),
+ cast<GetElementPtrInst>(R)->getSourceElementType())) {
+ if (Complain)
+ Engine.log("getelementptr source element type differ");
+ return true;
+ }
} else if (isa<CallInst>(L)) {
return diffCallSites(cast<CallInst>(*L), cast<CallInst>(*R), Complain);
} else if (isa<PHINode>(L)) {
@@ -541,6 +603,12 @@ class FunctionDifferenceEngine {
return Difference;
} else if (isa<UnreachableInst>(L)) {
return false;
+ } else {
+ if (!L->hasSameSpecialState(R)) {
+ if (Complain)
+ Engine.log("special states differ");
+ return true;
+ }
}
if (L->getNumOperands() != R->getNumOperands()) {
>From a83471e5bbc596fb072b5f3579cf6b62adce12ee Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Thu, 14 Mar 2024 23:56:59 +0800
Subject: [PATCH 6/6] Add test case
---
llvm/test/tools/llvm-diff/special-state.ll | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 llvm/test/tools/llvm-diff/special-state.ll
diff --git a/llvm/test/tools/llvm-diff/special-state.ll b/llvm/test/tools/llvm-diff/special-state.ll
new file mode 100644
index 00000000000000..913049d3b5b553
--- /dev/null
+++ b/llvm/test/tools/llvm-diff/special-state.ll
@@ -0,0 +1,42 @@
+; Diff file with itself, assert no difference by return code
+; RUN: llvm-diff %s %s
+
+; Replace %newvar1 with %newvar2 in the phi node. This can only
+; be detected to be different once BB1 has been processed.
+; RUN: rm -f %t.ll
+; RUN: cat %s | sed -e 's/i16/i8/' > %t.ll
+; RUN: not llvm-diff %s %t.ll 2>&1 | FileCheck %s
+
+; CHECK: in function alloca:
+; CHECK-NEXT: in block %0 / %0:
+; CHECK-NEXT: > %1 = alloca i8, align 1
+; CHECK-NEXT: > ret ptr %1
+; CHECK-NEXT: < %1 = alloca i16, align 1
+; CHECK-NEXT: < ret ptr %1
+
+define ptr @alloca() {
+ %1 = alloca i16, align 1
+ ret ptr %1
+}
+
+; CHECK: in function load:
+; CHECK-NEXT: in block %0 / %0:
+; CHECK-NEXT: > %1 = load i8, ptr %addr, align 4
+; CHECK-NEXT: < %1 = load i16, ptr %addr, align 4
+
+define void @load(ptr %addr) {
+ %1 = load i16, ptr %addr, align 4
+ ret void
+}
+
+; CHECK: in function gep:
+; CHECK-NEXT: in block %0 / %0:
+; CHECK-NEXT: > %1 = getelementptr %struct.ty1.0, ptr %addr, i32 0
+; CHECK-NEXT: < %1 = getelementptr %struct.ty1, ptr %addr, i32 0
+
+%struct.ty1 = type { i16 }
+
+define void @gep(ptr %addr) {
+ %1 = getelementptr %struct.ty1, ptr %addr, i32 0
+ ret void
+}
More information about the llvm-commits
mailing list