Skip to content

Commit 1cd2165

Browse files
authored
[SCEV] Take global variable linkage into account when comparing values (#148071)
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.
1 parent 15c3793 commit 1cd2165

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ static int CompareValueComplexity(const LoopInfo *const LI, Value *LV,
601601
if (const auto *LGV = dyn_cast<GlobalValue>(LV)) {
602602
const auto *RGV = cast<GlobalValue>(RV);
603603

604+
if (auto L = LGV->getLinkage() - RGV->getLinkage())
605+
return L;
606+
604607
const auto IsGVNameSemantic = [&](const GlobalValue *GV) {
605608
auto LT = GV->getLinkage();
606609
return !(GlobalValue::isPrivateLinkage(LT) ||

llvm/unittests/Analysis/ScalarEvolutionTest.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,4 +1738,34 @@ TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering2) {
17381738
SE.getAddExpr(Ops);
17391739
}
17401740

1741+
TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering3) {
1742+
Type *Int64Ty = Type::getInt64Ty(Context);
1743+
Constant *Init = Constant::getNullValue(Int64Ty);
1744+
Type *PtrTy = PointerType::get(Context, 0);
1745+
Constant *Null = Constant::getNullValue(PtrTy);
1746+
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), {}, false);
1747+
1748+
Value *V0 = new GlobalVariable(M, Int64Ty, false,
1749+
GlobalValue::ExternalLinkage, Init, "V0");
1750+
Value *V1 = new GlobalVariable(M, Int64Ty, false,
1751+
GlobalValue::ExternalLinkage, Init, "V1");
1752+
Value *V2 = new GlobalVariable(M, Int64Ty, false,
1753+
GlobalValue::InternalLinkage, Init, "V2");
1754+
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
1755+
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
1756+
Value *C0 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V0, Null,
1757+
"c0", BB);
1758+
Value *C1 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V1, Null,
1759+
"c1", BB);
1760+
Value *C2 = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, V2, Null,
1761+
"c2", BB);
1762+
Value *Or0 = BinaryOperator::CreateOr(C0, C1, "or0", BB);
1763+
Value *Or1 = BinaryOperator::CreateOr(Or0, C2, "or1", BB);
1764+
ReturnInst::Create(Context, nullptr, BB);
1765+
ScalarEvolution SE = buildSE(*F);
1766+
// When _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG, this will
1767+
// crash if the comparator is inconsistent about global variable linkage.
1768+
SE.getSCEV(Or1);
1769+
}
1770+
17411771
} // end namespace llvm

0 commit comments

Comments
 (0)