diff --git a/llvm/test/tools/llvm-diff/initializers.ll b/llvm/test/tools/llvm-diff/initializers.ll new file mode 100644 --- /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 --- a/llvm/tools/llvm-diff/DifferenceEngine.cpp +++ b/llvm/tools/llvm-diff/DifferenceEngine.cpp @@ -404,6 +404,7 @@ return false; } +public: bool equivalentAsOperands(const Constant *L, const Constant *R) { // Use equality as a preliminary filter. if (L == R) @@ -446,6 +447,24 @@ 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 @@ 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();