If TBAA is on an intrinsic and it gets upgraded, it'll delete the call
instruction that we collected in a vector. Even if we were to use
WeakVH, it'll drop the TBAA and we'll hit the assert on the upgrade
path.
r263673 gave a shot to make sure the TBAA upgrade happens before
intrinsics upgrade, but failed to account for all cases.
Instead of collecting instructions in a vector, this patch makes it
just upgrade the TBAA on the fly, because metadata are always
already loaded at this point.
Differential Revision: https://reviews.llvm.org/D24533
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281549
91177308-0d34-0410-b5e6-
96231b3b80d8
/// module is modified.
bool UpgradeModuleFlags(Module &M);
- /// If the TBAA tag for the given instruction uses the scalar TBAA format,
- /// we upgrade it to the struct-path aware TBAA format.
- void UpgradeInstWithTBAATag(Instruction *I);
+ /// If the given TBAA tag uses the scalar TBAA format, create a new node
+ /// corresponding to the upgrade to the struct-path aware TBAA format.
+ /// Otherwise return the \p TBAANode itself.
+ MDNode *UpgradeTBAANode(MDNode &TBAANode);
/// This is an auto-upgrade for bitcast between pointers with different
/// address spaces: the instruction is replaced by a pair ptrtoint+inttoptr.
N.second->resolveCycles();
}
- for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++)
- UpgradeInstWithTBAATag(InstsWithTBAATag[I]);
+ for (auto *Inst : InstsWithTBAATag) {
+ MDNode *MD = Inst->getMetadata(LLVMContext::MD_tbaa);
+ assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag");
+ auto *UpgradedMD = UpgradeTBAANode(*MD);
+ if (MD != UpgradedMD)
+ Inst->setMetadata(LLVMContext::MD_tbaa, UpgradedMD);
+ }
// Look for intrinsic functions and CallInst that need to be upgraded
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns;
- SmallVector<Instruction*, 64> InstsWithTBAATag;
-
bool HasSeenOldLoopTags = false;
/// The set of attributes by index. Index zero in the file is for null, and
if (HasSeenOldLoopTags && I->second == LLVMContext::MD_loop)
MD = upgradeInstructionLoopAttachment(*MD);
- Inst->setMetadata(I->second, MD);
if (I->second == LLVMContext::MD_tbaa) {
- InstsWithTBAATag.push_back(Inst);
- continue;
+ assert(!MD->isTemporary() && "should load MDs before attachments");
+ MD = UpgradeTBAANode(*MD);
}
+ Inst->setMetadata(I->second, MD);
}
break;
}
if (!BasicBlockFwdRefs.empty())
return error("Never resolved function from blockaddress");
- // Upgrading intrinsic calls before TBAA can cause TBAA metadata to be lost,
- // to prevent this instructions with TBAA tags should be upgraded first.
- for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++)
- UpgradeInstWithTBAATag(InstsWithTBAATag[I]);
-
// Upgrade any intrinsic calls that slipped through (should not happen!) and
// delete the old functions to clean up. We can't do this unless the entire
// module is materialized because there could always be another function body
}
}
-void llvm::UpgradeInstWithTBAATag(Instruction *I) {
- MDNode *MD = I->getMetadata(LLVMContext::MD_tbaa);
- assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag");
+MDNode *llvm::UpgradeTBAANode(MDNode &MD) {
// Check if the tag uses struct-path aware TBAA format.
- if (isa<MDNode>(MD->getOperand(0)) && MD->getNumOperands() >= 3)
- return;
+ if (isa<MDNode>(MD.getOperand(0)) && MD.getNumOperands() >= 3)
+ return &MD;
- if (MD->getNumOperands() == 3) {
- Metadata *Elts[] = {MD->getOperand(0), MD->getOperand(1)};
- MDNode *ScalarType = MDNode::get(I->getContext(), Elts);
+ auto &Context = MD.getContext();
+ if (MD.getNumOperands() == 3) {
+ Metadata *Elts[] = {MD.getOperand(0), MD.getOperand(1)};
+ MDNode *ScalarType = MDNode::get(Context, Elts);
// Create a MDNode <ScalarType, ScalarType, offset 0, const>
Metadata *Elts2[] = {ScalarType, ScalarType,
- ConstantAsMetadata::get(Constant::getNullValue(
- Type::getInt64Ty(I->getContext()))),
- MD->getOperand(2)};
- I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts2));
- } else {
- // Create a MDNode <MD, MD, offset 0>
- Metadata *Elts[] = {MD, MD, ConstantAsMetadata::get(Constant::getNullValue(
- Type::getInt64Ty(I->getContext())))};
- I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts));
+ ConstantAsMetadata::get(
+ Constant::getNullValue(Type::getInt64Ty(Context))),
+ MD.getOperand(2)};
+ return MDNode::get(Context, Elts2);
}
+ // Create a MDNode <MD, MD, offset 0>
+ Metadata *Elts[] = {&MD, &MD, ConstantAsMetadata::get(Constant::getNullValue(
+ Type::getInt64Ty(Context)))};
+ return MDNode::get(Context, Elts);
}
Instruction *llvm::UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
--- /dev/null
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+%some_named_struct = type { i8, i8 }
+
+define void @bar(%some_named_struct*) {
+ ret void
+}
--- /dev/null
+; RUN: llvm-as %s -o %t1.bc
+; RUN: llvm-as %p/Inputs/remangle_intrinsics_tbaa.ll -o %t2.bc
+; RUN: llvm-link -disable-lazy-loading %t2.bc %t1.bc -S | FileCheck %s
+
+; Verify that we correctly rename the intrinsic and don't crash
+; CHECK: @llvm.masked.store.v4p0some_named_struct.0.p0v4p0some_named_struct.0
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+%some_named_struct = type { i8 }
+
+define void @foo(%some_named_struct*) {
+ call void @llvm.masked.store.v4p0some_named_struct.p0v4p0some_named_struct(<4 x %some_named_struct*> undef, <4 x %some_named_struct*>* undef, i32 8, <4 x i1> undef), !tbaa !5
+ ret void
+}
+
+declare void @llvm.masked.store.v4p0some_named_struct.p0v4p0some_named_struct(<4 x %some_named_struct*>, <4 x %some_named_struct*>*, i32, <4 x i1>) #1
+
+!5 = !{!6, !6, i64 0}
+!6 = !{!"any pointer", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
Force("f", cl::desc("Enable binary output on terminals"));
static cl::opt<bool>
-OutputAssembly("S",
- cl::desc("Write output as LLVM assembly"), cl::Hidden);
+ DisableLazyLoad("disable-lazy-loading",
+ cl::desc("Enable binary output on terminals"));
+
+static cl::opt<bool>
+ OutputAssembly("S", cl::desc("Write output as LLVM assembly"), cl::Hidden);
static cl::opt<bool>
Verbose("v", cl::desc("Print information about actions taken"));
bool MaterializeMetadata = true) {
SMDiagnostic Err;
if (Verbose) errs() << "Loading '" << FN << "'\n";
- std::unique_ptr<Module> Result =
- getLazyIRFileModule(FN, Err, Context, !MaterializeMetadata);
+ std::unique_ptr<Module> Result;
+ if (DisableLazyLoad)
+ Result = parseIRFile(FN, Err, Context);
+ else
+ Result = getLazyIRFileModule(FN, Err, Context, !MaterializeMetadata);
+
if (!Result) {
Err.print(argv0, errs());
return nullptr;