From 46db43240f0f24e76ab903db8086f53a7dddbedf Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 21 Jun 2021 17:41:47 -0700 Subject: [PATCH] [llvm-diff] Explicitly check ConstantArrays Global initializers may be ConstantArrays. They need to be checked explicitly, because different-yet-still-equivalent type names may be used for each, and/or a GEP instruction may appear in one. --- llvm/test/tools/llvm-diff/initializers.ll | 12 ++++++++++++ llvm/tools/llvm-diff/DifferenceEngine.cpp | 22 +++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 llvm/test/tools/llvm-diff/initializers.ll diff --git a/llvm/test/tools/llvm-diff/initializers.ll b/llvm/test/tools/llvm-diff/initializers.ll new file mode 100644 index 0000000..7f59e65 --- /dev/null +++ b/llvm/test/tools/llvm-diff/initializers.ll @@ -0,0 +1,12 @@ +; RUN: llvm-diff %s %s + +; An initializer that has a GEP instruction in it won't match itself in +; llvm-diff unless the a deep comparison is done on the initializer. + +@gv1 = external dso_local global [28 x i16], align 16 +@gv2 = private unnamed_addr constant [2 x i16*] [i16* getelementptr inbounds ([28 x i16], [28 x i16]* @gv1, i32 0, i32 0), i16* poison], align 16 + +define void @foo() { + %1 = getelementptr [2 x i16*], [2 x i16*]* @gv2, i64 0, i64 undef + ret void +} diff --git a/llvm/tools/llvm-diff/DifferenceEngine.cpp b/llvm/tools/llvm-diff/DifferenceEngine.cpp index 326d572..cc9dce0 100644 --- a/llvm/tools/llvm-diff/DifferenceEngine.cpp +++ b/llvm/tools/llvm-diff/DifferenceEngine.cpp @@ -404,6 +404,7 @@ class FunctionDifferenceEngine { return false; } +public: bool equivalentAsOperands(const Constant *L, const Constant *R) { // Use equality as a preliminary filter. if (L == R) @@ -446,6 +447,24 @@ class FunctionDifferenceEngine { return true; } + // If L and R are ConstantArrays, compare the element count and types. + if (isa(L)) { + const ConstantArray *CAL = cast(L); + const ConstantArray *CAR = cast(R); + // Sometimes a type may be equivalent, but not uniquified---e.g. it may + // contain a GEP instruction. Do a deeper comparison of the types. + if (CAL->getType()->getNumElements() != CAR->getType()->getNumElements()) + return false; + + for (unsigned I = 0; I < CAL->getType()->getNumElements(); ++I) { + if (!equivalentAsOperands(CAL->getAggregateElement(I), + CAR->getAggregateElement(I))) + return false; + } + + return true; + } + return false; } @@ -766,7 +785,8 @@ bool DifferenceEngine::equivalentAsOperands(const GlobalValue *L, const GlobalVariable *GVR = cast(R); if (GVL->hasLocalLinkage() && GVL->hasUniqueInitializer() && GVR->hasLocalLinkage() && GVR->hasUniqueInitializer()) - return GVL->getInitializer() == GVR->getInitializer(); + return FunctionDifferenceEngine(*this).equivalentAsOperands( + GVL->getInitializer(), GVR->getInitializer()); } return L->getName() == R->getName(); -- 2.7.4