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(LV)) { const auto *RGV = cast(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..678960418d7d7 100644 --- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp +++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp @@ -1738,4 +1738,34 @@ 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