Skip to content

Commit

Permalink
[BitCode] Autoupgrade inline asm elementtype attribute
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Jan 6, 2022
1 parent 2c4a56c commit eddd5be
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
32 changes: 28 additions & 4 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Expand Up @@ -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:
Expand Down Expand Up @@ -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.
Expand All @@ -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());
}
}

Expand All @@ -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
Expand Down
30 changes: 30 additions & 0 deletions llvm/test/Bitcode/upgrade-inline-asm-elementtype.ll
@@ -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.

0 comments on commit eddd5be

Please sign in to comment.