-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[SCEV] Take global variable linkage into account when comparing values #148071
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 llvm#147862.
|
@llvm/pr-subscribers-llvm-analysis Author: Arthur Eubanks (aeubanks) ChangesCurrent the comparator is inconsistent when we have two external globals and one internal globals due to The internal global compares equal to (not strictly less than) the external globals, but the external globals are not equal. Fixes #147862. Full diff: https://github.com/llvm/llvm-project/pull/148071.diff 2 Files Affected:
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
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp -- llvm/lib/Analysis/ScalarEvolution.cpp llvm/unittests/Analysis/ScalarEvolutionTest.cppView the diff from clang-format here.diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 6d6bef547..678960418 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
|
nikic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Current the comparator is inconsistent when we have two external globals and one internal globals due to
The internal global compares equal to (not strictly less than) the external globals, but the external globals are not equal.
Fixes #147862.