diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8392,9 +8392,10 @@ /// /// OpInfo describes the operand /// RefOpInfo describes the matching operand if any, the operand otherwise -static void GetRegistersForValue(SelectionDAG &DAG, const SDLoc &DL, - SDISelAsmOperandInfo &OpInfo, - SDISelAsmOperandInfo &RefOpInfo) { +static llvm::Optional +getRegistersForValue(SelectionDAG &DAG, const SDLoc &DL, + SDISelAsmOperandInfo &OpInfo, + SDISelAsmOperandInfo &RefOpInfo) { LLVMContext &Context = *DAG.getContext(); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); @@ -8404,7 +8405,7 @@ // No work to do for memory operations. if (OpInfo.ConstraintType == TargetLowering::C_Memory) - return; + return None; // If this is a constraint for a single physreg, or a constraint for a // register class, find it. @@ -8414,7 +8415,7 @@ &TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT); // RC is unset only on failure. Return immediately. if (!RC) - return; + return None; // Get the actual register value type. This is important, because the user // may have asked for (e.g.) the AX register in i32 type. We need to @@ -8459,7 +8460,7 @@ // No need to allocate a matching input constraint since the constraint it's // matching to has already been allocated. if (OpInfo.isMatchingInputConstraint()) - return; + return None; EVT ValueVT = OpInfo.ConstraintVT; if (OpInfo.ConstraintVT == MVT::Other) @@ -8482,8 +8483,12 @@ // Do not check for single registers. if (AssignedReg) { - for (; *I != AssignedReg; ++I) - assert(I != RC->end() && "AssignedReg should be member of RC"); + I = std::find(I, RC->end(), AssignedReg); + if (I == RC->end()) { + // RC does not contain the selected register, which indicates a + // mismatch between the register and the required type/bitwidth. + return {AssignedReg}; + } } for (; NumRegs; --NumRegs, ++I) { @@ -8493,6 +8498,7 @@ } OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT); + return None; } static unsigned @@ -8726,7 +8732,18 @@ OpInfo.isMatchingInputConstraint() ? ConstraintOperands[OpInfo.getMatchedOperand()] : OpInfo; - GetRegistersForValue(DAG, getCurSDLoc(), OpInfo, RefOpInfo); + const auto RegError = + getRegistersForValue(DAG, getCurSDLoc(), OpInfo, RefOpInfo); + if (RegError.hasValue()) { + const MachineFunction &MF = DAG.getMachineFunction(); + const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); + const char *RegName = TRI.getName(RegError.getValue()); + emitInlineAsmError(Call, "register '" + Twine(RegName) + + "' allocated for constraint '" + + Twine(OpInfo.ConstraintCode) + + "' does not match required type"); + return; + } auto DetectWriteToReservedRegister = [&]() { const MachineFunction &MF = DAG.getMachineFunction(); diff --git a/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch-avx.ll b/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch-avx.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/asm-reject-reg-type-mismatch-avx.ll @@ -0,0 +1,9 @@ +; RUN: not llc -o /dev/null -mattr=avx %s 2>&1 | FileCheck %s +target triple = "x86_64--" + +; CHECK: error: register 'XMM15' allocated for constraint '{xmm15}' does not match required type +define void @test1() nounwind { +entry: + tail call void asm sideeffect "call dummy", "{xmm15},~{dirflag},~{fpsr},~{flags}"(<8 x i32> ) #1 + ret void +}