[llvm] [SCEV] Take global variable linkage into account when comparing values (PR #148071)
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 11 09:36:06 PDT 2025
https://github.com/aeubanks updated https://github.com/llvm/llvm-project/pull/148071
>From 4f72b2782e7cf0b08c817131d8e41d361973d6aa Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Thu, 10 Jul 2025 22:09:50 +0000
Subject: [PATCH 1/2] [SCEV] Take global variable linkage into account
Current the comparator is inconsistent when we have two external globals and one internal globals due to
```
if (IsGVNameSemantic(LGV) && IsGVNameSemantic(RGV))
return LGV->getName().compare(RGV->getName());
```
The internal global compares equal to (not strictly less than) the external globals, but the external globals are not equal.
Fixes #147862.
---
llvm/lib/Analysis/ScalarEvolution.cpp | 3 +++
.../Analysis/ScalarEvolutionTest.cpp | 27 +++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 1c66f5c877f59..24adfa346c642 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -601,6 +601,9 @@ static int CompareValueComplexity(const LoopInfo *const LI, Value *LV,
if (const auto *LGV = dyn_cast<GlobalValue>(LV)) {
const auto *RGV = cast<GlobalValue>(RV);
+ if (auto L = LGV->getLinkage() - RGV->getLinkage())
+ return L;
+
const auto IsGVNameSemantic = [&](const GlobalValue *GV) {
auto LT = GV->getLinkage();
return !(GlobalValue::isPrivateLinkage(LT) ||
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 9b88e423e802b..6d6bef5477f95 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1738,4 +1738,31 @@ TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering2) {
SE.getAddExpr(Ops);
}
+TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering3) {
+ Type *Int64Ty = Type::getInt64Ty(Context);
+ Constant *Init = Constant::getNullValue(Int64Ty);
+ Type *PtrTy = PointerType::get(Context, 0);
+ Constant *Null = Constant::getNullValue(PtrTy);
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), {}, false);
+
+ Value *V0 = new GlobalVariable(M, Int64Ty, false,
+ GlobalValue::ExternalLinkage, Init, "V0");
+ Value *V1 = new GlobalVariable(M, Int64Ty, false,
+ GlobalValue::ExternalLinkage, Init, "V1");
+ Value *V2 = new GlobalVariable(M, Int64Ty, false,
+ GlobalValue::InternalLinkage, Init, "V2");
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
+ BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
+ Value *C0 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V0, Null, "c0", BB);
+ Value *C1 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V1, Null, "c1", BB);
+ Value *C2 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V2, Null, "c2", BB);
+ Value*Or0 = BinaryOperator::CreateOr(C0, C1, "or0", BB);
+ Value*Or1 = BinaryOperator::CreateOr(Or0, C2, "or1", BB);
+ ReturnInst::Create(Context, nullptr, BB);
+ ScalarEvolution SE = buildSE(*F);
+ // When _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG, this will
+ // crash if the comparator is inconsistent about global variable linkage.
+ SE.getSCEV(Or1);
+}
+
} // end namespace llvm
>From 6bf29320cc417e397008bd29309b281ebfb0c870 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Fri, 11 Jul 2025 16:35:51 +0000
Subject: [PATCH 2/2] format
---
llvm/unittests/Analysis/ScalarEvolutionTest.cpp | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 6d6bef5477f95..678960418d7d7 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1753,11 +1753,14 @@ TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering3) {
GlobalValue::InternalLinkage, Init, "V2");
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
- Value *C0 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V0, Null, "c0", BB);
- Value *C1 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V1, Null, "c1", BB);
- Value *C2 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V2, Null, "c2", BB);
- Value*Or0 = BinaryOperator::CreateOr(C0, C1, "or0", BB);
- Value*Or1 = BinaryOperator::CreateOr(Or0, C2, "or1", BB);
+ Value *C0 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V0, Null,
+ "c0", BB);
+ Value *C1 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V1, Null,
+ "c1", BB);
+ Value *C2 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V2, Null,
+ "c2", BB);
+ Value *Or0 = BinaryOperator::CreateOr(C0, C1, "or0", BB);
+ Value *Or1 = BinaryOperator::CreateOr(Or0, C2, "or1", BB);
ReturnInst::Create(Context, nullptr, BB);
ScalarEvolution SE = buildSE(*F);
// When _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG, this will
More information about the llvm-commits
mailing list