[BitCode] Autoupgrade inline asm elementtype attribute
This is the autoupgrade part of D116531. If old bitcode is missing the elementtype attribute for indirect inline asm constraints, automatically add it. As usual, this only works when upgrading in typed mode, we haven't figured out upgrade in opaque mode yet.
This commit is contained in:
parent
2c4a56c418
commit
eddd5be1df
|
@ -3923,6 +3923,25 @@ void BitcodeReader::propagateAttributeTypes(CallBase *CB,
|
|||
}
|
||||
}
|
||||
|
||||
if (CB->isInlineAsm()) {
|
||||
const InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
|
||||
unsigned ArgNo = 0;
|
||||
for (const InlineAsm::ConstraintInfo &CI : IA->ParseConstraints()) {
|
||||
bool HasArg = CI.Type == InlineAsm::isInput ||
|
||||
(CI.Type == InlineAsm::isOutput && CI.isIndirect);
|
||||
if (!HasArg)
|
||||
continue;
|
||||
|
||||
if (CI.isIndirect && !CB->getAttributes().getParamElementType(ArgNo)) {
|
||||
Type *ElemTy = ArgsTys[ArgNo]->getPointerElementType();
|
||||
CB->addParamAttr(
|
||||
ArgNo, Attribute::get(Context, Attribute::ElementType, ElemTy));
|
||||
}
|
||||
|
||||
ArgNo++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (CB->getIntrinsicID()) {
|
||||
case Intrinsic::preserve_array_access_index:
|
||||
case Intrinsic::preserve_struct_access_index:
|
||||
|
@ -4826,15 +4845,18 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|||
return error("Insufficient operands to call");
|
||||
|
||||
SmallVector<Value*, 16> Args;
|
||||
SmallVector<Type *, 16> ArgsTys;
|
||||
// Read the fixed params.
|
||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
|
||||
Value *Arg;
|
||||
if (FTy->getParamType(i)->isLabelTy())
|
||||
Args.push_back(getBasicBlock(Record[OpNum]));
|
||||
Arg = getBasicBlock(Record[OpNum]);
|
||||
else
|
||||
Args.push_back(getValue(Record, OpNum, NextValueNo,
|
||||
FTy->getParamType(i)));
|
||||
if (!Args.back())
|
||||
Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i));
|
||||
if (!Arg)
|
||||
return error("Invalid record");
|
||||
Args.push_back(Arg);
|
||||
ArgsTys.push_back(Arg->getType());
|
||||
}
|
||||
|
||||
// Read type/value pairs for varargs params.
|
||||
|
@ -4847,6 +4869,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|||
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
||||
return error("Invalid record");
|
||||
Args.push_back(Op);
|
||||
ArgsTys.push_back(Op->getType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4857,6 +4880,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|||
cast<CallBrInst>(I)->setCallingConv(
|
||||
static_cast<CallingConv::ID>((0x7ff & CCInfo) >> bitc::CALL_CCONV));
|
||||
cast<CallBrInst>(I)->setAttributes(PAL);
|
||||
propagateAttributeTypes(cast<CallBase>(I), ArgsTys);
|
||||
break;
|
||||
}
|
||||
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
; RUN: llvm-dis < %s.bc | FileCheck %s
|
||||
|
||||
; CHECK: call void asm "", "=*rm,r"(i32* elementtype(i32) %p1, i32* %p2)
|
||||
define void @test_call(i32* %p1, i32* %p2) {
|
||||
call void asm "", "=*rm,r"(i32* %p1, i32* %p2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: invoke void asm "", "=*rm,r"(i32* elementtype(i32) %p1, i32* %p2)
|
||||
define void @test_invoke(i32* %p1, i32* %p2) personality i8* null {
|
||||
invoke void asm "", "=*rm,r"(i32* %p1, i32* %p2)
|
||||
to label %cont unwind label %lpad
|
||||
|
||||
lpad:
|
||||
%lp = landingpad i32
|
||||
cleanup
|
||||
ret void
|
||||
|
||||
cont:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: callbr void asm "", "=*rm,r"(i32* elementtype(i32) %p1, i32* %p2)
|
||||
define void @test_callbr(i32* %p1, i32* %p2) {
|
||||
callbr void asm "", "=*rm,r"(i32* %p1, i32* %p2)
|
||||
to label %cont []
|
||||
|
||||
cont:
|
||||
ret void
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue