forked from OSchip/llvm-project
[CodeGen] Support opaque pointers for inline asm
This is the last part of D116531. Fetch the type of the indirect inline asm operand from the elementtype attribute, rather than the pointer element type. Fixes https://github.com/llvm/llvm-project/issues/52928.
This commit is contained in:
parent
2cd2600aba
commit
0312fe2901
|
@ -8250,7 +8250,8 @@ public:
|
|||
/// corresponds to. If there is no Value* for this operand, it returns
|
||||
/// MVT::Other.
|
||||
EVT getCallOperandValEVT(LLVMContext &Context, const TargetLowering &TLI,
|
||||
const DataLayout &DL) const {
|
||||
const DataLayout &DL,
|
||||
llvm::Type *ParamElemType) const {
|
||||
if (!CallOperandVal) return MVT::Other;
|
||||
|
||||
if (isa<BasicBlock>(CallOperandVal))
|
||||
|
@ -8262,10 +8263,8 @@ public:
|
|||
// If this is an indirect operand, the operand is a pointer to the
|
||||
// accessed type.
|
||||
if (isIndirect) {
|
||||
PointerType *PtrTy = dyn_cast<PointerType>(OpTy);
|
||||
if (!PtrTy)
|
||||
report_fatal_error("Indirect operand for inline asm not a pointer!");
|
||||
OpTy = PtrTy->getElementType();
|
||||
OpTy = ParamElemType;
|
||||
assert(OpTy && "Indirect opernad must have elementtype attribute");
|
||||
}
|
||||
|
||||
// Look for vector wrapped in a struct. e.g. { <16 x i8> }.
|
||||
|
@ -8566,17 +8565,16 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call,
|
|||
|
||||
// Compute the value type for each operand.
|
||||
if (OpInfo.hasArg()) {
|
||||
OpInfo.CallOperandVal = Call.getArgOperand(ArgNo++);
|
||||
OpInfo.CallOperandVal = Call.getArgOperand(ArgNo);
|
||||
|
||||
// Process the call argument. BasicBlocks are labels, currently appearing
|
||||
// only in asm's.
|
||||
if (isa<CallBrInst>(Call) &&
|
||||
ArgNo - 1 >= (cast<CallBrInst>(&Call)->arg_size() -
|
||||
ArgNo >= (cast<CallBrInst>(&Call)->arg_size() -
|
||||
cast<CallBrInst>(&Call)->getNumIndirectDests() -
|
||||
NumMatchingOps) &&
|
||||
(NumMatchingOps == 0 ||
|
||||
ArgNo - 1 <
|
||||
(cast<CallBrInst>(&Call)->arg_size() - NumMatchingOps))) {
|
||||
ArgNo < (cast<CallBrInst>(&Call)->arg_size() - NumMatchingOps))) {
|
||||
const auto *BA = cast<BlockAddress>(OpInfo.CallOperandVal);
|
||||
EVT VT = TLI.getValueType(DAG.getDataLayout(), BA->getType(), true);
|
||||
OpInfo.CallOperand = DAG.getTargetBlockAddress(BA, VT);
|
||||
|
@ -8586,9 +8584,11 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call,
|
|||
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
|
||||
}
|
||||
|
||||
Type *ParamElemTy = Call.getAttributes().getParamElementType(ArgNo);
|
||||
EVT VT = OpInfo.getCallOperandValEVT(*DAG.getContext(), TLI,
|
||||
DAG.getDataLayout());
|
||||
DAG.getDataLayout(), ParamElemTy);
|
||||
OpInfo.ConstraintVT = VT.isSimple() ? VT.getSimpleVT() : MVT::Other;
|
||||
ArgNo++;
|
||||
} else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
|
||||
// The return value of the call is this value. As such, there is no
|
||||
// corresponding argument.
|
||||
|
|
|
@ -4751,7 +4751,7 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
|
|||
case InlineAsm::isOutput:
|
||||
// Indirect outputs just consume an argument.
|
||||
if (OpInfo.isIndirect) {
|
||||
OpInfo.CallOperandVal = Call.getArgOperand(ArgNo++);
|
||||
OpInfo.CallOperandVal = Call.getArgOperand(ArgNo);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4769,7 +4769,7 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
|
|||
++ResNo;
|
||||
break;
|
||||
case InlineAsm::isInput:
|
||||
OpInfo.CallOperandVal = Call.getArgOperand(ArgNo++);
|
||||
OpInfo.CallOperandVal = Call.getArgOperand(ArgNo);
|
||||
break;
|
||||
case InlineAsm::isClobber:
|
||||
// Nothing to do.
|
||||
|
@ -4779,10 +4779,8 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
|
|||
if (OpInfo.CallOperandVal) {
|
||||
llvm::Type *OpTy = OpInfo.CallOperandVal->getType();
|
||||
if (OpInfo.isIndirect) {
|
||||
llvm::PointerType *PtrTy = dyn_cast<PointerType>(OpTy);
|
||||
if (!PtrTy)
|
||||
report_fatal_error("Indirect operand for inline asm not a pointer!");
|
||||
OpTy = PtrTy->getElementType();
|
||||
OpTy = Call.getAttributes().getParamElementType(ArgNo);
|
||||
assert(OpTy && "Indirect opernad must have elementtype attribute");
|
||||
}
|
||||
|
||||
// Look for vector wrapped in a struct. e.g. { <16 x i8> }.
|
||||
|
@ -4812,6 +4810,8 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
|
|||
} else {
|
||||
OpInfo.ConstraintVT = MVT::getVT(OpTy, true);
|
||||
}
|
||||
|
||||
ArgNo++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=x86_64-linux -opaque-pointers < %s | FileCheck %s
|
||||
|
||||
define void @okay(ptr %p, i32 %x) nounwind {
|
||||
; CHECK-LABEL: okay:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: #APP
|
||||
; CHECK-NEXT: addl %esi, %eax
|
||||
; CHECK-NEXT: #NO_APP
|
||||
; CHECK-NEXT: movl %eax, (%rdi)
|
||||
; CHECK-NEXT: retq
|
||||
call void asm "addl $1, $0", "=*r,r"(ptr elementtype(i32) %p, i32 %x)
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue