diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index b1dc1844b0de63..ff482f3a333397 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8250,7 +8250,8 @@ class SDISelAsmOperandInfo : public TargetLowering::AsmOperandInfo { /// 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(CallOperandVal)) @@ -8262,10 +8263,8 @@ class SDISelAsmOperandInfo : public TargetLowering::AsmOperandInfo { // If this is an indirect operand, the operand is a pointer to the // accessed type. if (isIndirect) { - PointerType *PtrTy = dyn_cast(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(Call) && - ArgNo - 1 >= (cast(&Call)->arg_size() - + ArgNo >= (cast(&Call)->arg_size() - cast(&Call)->getNumIndirectDests() - NumMatchingOps) && (NumMatchingOps == 0 || - ArgNo - 1 < - (cast(&Call)->arg_size() - NumMatchingOps))) { + ArgNo < (cast(&Call)->arg_size() - NumMatchingOps))) { const auto *BA = cast(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. diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 787493ac898b7f..7ebe64c2b5518b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -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(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++; } } diff --git a/llvm/test/CodeGen/X86/opaque-ptr.ll b/llvm/test/CodeGen/X86/opaque-ptr.ll new file mode 100644 index 00000000000000..b2364f2d7a5304 --- /dev/null +++ b/llvm/test/CodeGen/X86/opaque-ptr.ll @@ -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 +}