diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index a7fbf4aeb7449..e0373322ef8c4 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -816,9 +816,11 @@ class AsmPrinter : public MachineFunctionPass { /// Print the specified operand of MI, an INLINEASM instruction, using the /// specified assembler variant. Targets should override this to format as - /// appropriate. This method can return true if the operand is erroneous. + /// appropriate. This method can return true if the operand is erroneous, + /// method can provide helpful diagnostic message in some case. virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS); + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg); /// Print the specified operand of MI, an INLINEASM instruction, using the /// specified assembler variant as an address. Targets should override this to diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index d0ef3e5a19391..c5f56a91e8406 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -285,6 +285,7 @@ static void EmitInlineAsmStr(const char *AsmStr, const MachineInstr *MI, // We may have a location metadata attached to the end of the // instruction, and at no point should see metadata at any // other point while processing. It's an error if so. + std::string ErrorMsg; if (OpNo >= MI->getNumOperands() || MI->getOperand(OpNo).isMetadata()) { Error = true; } else { @@ -306,14 +307,15 @@ static void EmitInlineAsmStr(const char *AsmStr, const MachineInstr *MI, Error = AP->PrintAsmMemoryOperand( MI, OpNo, Modifier[0] ? Modifier : nullptr, OS); } else { - Error = AP->PrintAsmOperand(MI, OpNo, - Modifier[0] ? Modifier : nullptr, OS); + Error = AP->PrintAsmOperand( + MI, OpNo, Modifier[0] ? Modifier : nullptr, OS, ErrorMsg); } } if (Error) { std::string msg; raw_string_ostream Msg(msg); - Msg << "invalid operand in inline asm: '" << AsmStr << "'"; + Msg << "invalid operand in inline asm: '" << AsmStr << "'" + << ErrorMsg; MMI->getModule()->getContext().emitError(LocCookie, Msg.str()); } } @@ -466,7 +468,8 @@ void AsmPrinter::PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS) { /// override this to format as appropriate for machine specific ExtraCodes /// or when the arch-independent handling would be too complex otherwise. bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 4fa719ad67cf3..73edcfc4deb6a 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -177,7 +177,8 @@ class AArch64AsmPrinter : public AsmPrinter { raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; @@ -910,11 +911,12 @@ bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO, } bool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { const MachineOperand &MO = MI->getOperand(OpNum); // First try the generic code, which knows about modifiers like 'c' and 'n'. - if (!AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O, ErrorMsg)) return false; // Does this asm operand have a single letter operand modifier? diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp index 72e8b59e0a409..8f174a2a32bbe 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp @@ -1235,9 +1235,10 @@ void AMDGPUAsmPrinter::getAmdKernelCode(amd_kernel_code_t &Out, } bool AMDGPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // First try the generic code, which knows about modifiers like 'c' and 'n'. - if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg)) return false; if (ExtraCode && ExtraCode[0]) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h index 79326cd3d3289..d9d3ec4f7d1ce 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h @@ -129,7 +129,8 @@ class AMDGPUAsmPrinter final : public AsmPrinter { void emitEndOfAsmFile(Module &M) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; protected: void getAnalysisUsage(AnalysisUsage &AU) const override; diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 642739a29d6b0..51377adc7fc49 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -284,7 +284,8 @@ GetARMJTIPICJumpTableLabel(unsigned uid) const { } bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -292,7 +293,7 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O, ErrorMsg); case 'P': // Print a VFP double precision register. case 'q': // Print a NEON quad precision register. printOperand(MI, OpNum, O); diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.h b/llvm/lib/Target/ARM/ARMAsmPrinter.h index 33b4417aa9b80..bcb591703679e 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.h +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.h @@ -77,7 +77,8 @@ class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter { void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index 1c8213b668f71..5a77f97f5eee6 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -52,7 +52,8 @@ class AVRAsmPrinter : public AsmPrinter { void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; @@ -98,10 +99,11 @@ void AVRAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, } bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Default asm printer can only deal with some extra codes, // so try it first. - if (!AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O, ErrorMsg)) return false; const MachineOperand &MO = MI->getOperand(OpNum); diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp index c8849bd50464c..73011a947648d 100644 --- a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp +++ b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp @@ -44,7 +44,8 @@ class BPFAsmPrinter : public AsmPrinter { bool doInitialization(Module &M) override; void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; @@ -108,9 +109,10 @@ void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, } bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { if (ExtraCode && ExtraCode[0]) - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); printOperand(MI, OpNo, O); return false; diff --git a/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp b/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp index 7d121b8d24f05..85c4a0232617a 100644 --- a/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp +++ b/llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp @@ -261,9 +261,10 @@ void CSKYAsmPrinter::emitAttributes() { } bool CSKYAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) { + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) { // First try the generic code, which knows about modifiers like 'c' and 'n'. - if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg)) return false; const MachineOperand &MO = MI->getOperand(OpNo); diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp index d2f64ac9e90b0..59242c147d235 100644 --- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -113,8 +113,8 @@ bool HexagonAsmPrinter::isBlockOnlyReachableByFallthrough( /// PrintAsmOperand - Print out an operand for an inline asm expression. bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, - raw_ostream &OS) { + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) @@ -123,7 +123,7 @@ bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg); case 'L': case 'H': { // The highest-numbered register of a pair. const MachineOperand &MO = MI->getOperand(OpNo); diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h index b555c88596503..71104a13aae9c 100644 --- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h +++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h @@ -67,7 +67,8 @@ class TargetMachine; void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; void emitStartOfAsmFile(Module &M) override; diff --git a/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp b/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp index c66d9166828c1..7af0268a54f4c 100644 --- a/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp +++ b/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp @@ -50,7 +50,8 @@ class LanaiAsmPrinter : public AsmPrinter { void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; void emitInstruction(const MachineInstr *MI) override; bool isBlockOnlyReachableByFallthrough( const MachineBasicBlock *MBB) const override; @@ -109,7 +110,8 @@ void LanaiAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, // PrintAsmOperand - Print out an operand for an inline asm expression. bool LanaiAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1]) @@ -138,7 +140,7 @@ bool LanaiAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return false; } default: - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); } } printOperand(MI, OpNo, O); diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp index 27979a830b10e..d089bb875ae1e 100644 --- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp @@ -56,9 +56,10 @@ void LoongArchAsmPrinter::emitInstruction(const MachineInstr *MI) { bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, - raw_ostream &OS) { + raw_ostream &OS, + std::string &ErrorMsg) { // First try the generic code, which knows about modifiers like 'c' and 'n'. - if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg)) return false; const MachineOperand &MO = MI->getOperand(OpNo); diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h index 693456443c7a4..03f9febf8490e 100644 --- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h +++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h @@ -37,7 +37,8 @@ class LLVM_LIBRARY_VISIBILITY LoongArchAsmPrinter : public AsmPrinter { void emitInstruction(const MachineInstr *MI) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; diff --git a/llvm/lib/Target/M68k/M68kAsmPrinter.cpp b/llvm/lib/Target/M68k/M68kAsmPrinter.cpp index f748450c170aa..e8a5e8020b618 100644 --- a/llvm/lib/Target/M68k/M68kAsmPrinter.cpp +++ b/llvm/lib/Target/M68k/M68kAsmPrinter.cpp @@ -65,7 +65,8 @@ void M68kAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, } bool M68kAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) { + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) { // Print the operand if there is no operand modifier. if (!ExtraCode || !ExtraCode[0]) { printOperand(MI, OpNo, OS); @@ -73,7 +74,7 @@ bool M68kAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, } // Fallback to the default implementation. - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg); } void M68kAsmPrinter::printDisp(const MachineInstr *MI, unsigned opNum, diff --git a/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp b/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp index 9cd2cbe89e461..de04c1b986730 100644 --- a/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp +++ b/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp @@ -54,7 +54,8 @@ namespace { void printSrcMemOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override; void emitInstruction(const MachineInstr *MI) override; @@ -127,10 +128,11 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum, /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); printOperand(MI, OpNo, O); return false; diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 66b2b0de8d52a..51645b6fad88f 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -473,7 +473,8 @@ void MipsAsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) { // Print out an operand for an inline asm expression. bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -482,7 +483,7 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O, ErrorMsg); case 'X': // hex const int if (!MO.isImm()) return true; diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.h b/llvm/lib/Target/Mips/MipsAsmPrinter.h index 0b55089385d79..e2c59a44cee05 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.h +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.h @@ -143,7 +143,8 @@ class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter { void emitFunctionBodyEnd() override; void emitBasicBlockEnd(const MachineBasicBlock &MBB) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 2783b1e0ec73e..24a7b2567dee8 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -2169,7 +2169,8 @@ void NVPTXAsmPrinter::printMCExpr(const MCExpr &Expr, raw_ostream &OS) { /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool NVPTXAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -2177,7 +2178,7 @@ bool NVPTXAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); case 'r': break; } diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h index 979d185a97f79..a55428665a83f 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h +++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.h @@ -184,7 +184,8 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter { void printReturnValStr(const Function *, raw_ostream &O); void printReturnValStr(const MachineFunction &MF, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &) override; + const char *ExtraCode, raw_ostream &, + std::string &ErrorMsg) override; void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O); bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &) override; diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 16942c6893a16..613ec92b60c3d 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -197,7 +197,8 @@ class PPCAsmPrinter : public AsmPrinter { void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override; @@ -356,7 +357,8 @@ void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -364,7 +366,7 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); case 'L': // Write second word of DImode reference. // Verify that this operand has two consecutive registers. if (!MI->getOperand(OpNo).isReg() || diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 5bf594c0b5eae..9cbe3e955d62f 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -76,7 +76,8 @@ class RISCVAsmPrinter : public AsmPrinter { void emitInstruction(const MachineInstr *MI) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; @@ -261,9 +262,10 @@ void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) { } bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) { + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) { // First try the generic code, which knows about modifiers like 'c' and 'n'. - if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg)) return false; const MachineOperand &MO = MI->getOperand(OpNo); diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index 4eee8062f2824..2d334fe430e61 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -54,7 +54,8 @@ class SPIRVAsmPrinter : public AsmPrinter { StringRef getPassName() const override { return "SPIRV Assembly Printer"; } void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; void outputMCInst(MCInst &Inst); void outputInstruction(const MachineInstr *MI); @@ -218,7 +219,8 @@ void SPIRVAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, } bool SPIRVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { if (ExtraCode && ExtraCode[0]) return true; // Invalid instruction - SPIR-V does not have special modifiers diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp index 215a8ea831904..ba620f413ddf1 100644 --- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -61,7 +61,8 @@ namespace { } bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override; @@ -425,15 +426,15 @@ void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, - raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); case 'f': case 'r': break; diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 5696ae117d69f..f72b4e1c04751 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -926,8 +926,8 @@ static void printAddress(const MCAsmInfo *MAI, unsigned Base, } bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, - raw_ostream &OS) { + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) { const MCRegisterInfo &MRI = *TM.getMCRegisterInfo(); const MachineOperand &MO = MI->getOperand(OpNo); MCOperand MCOp; @@ -937,7 +937,7 @@ bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, MCOp = MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64)); else - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg); } else { SystemZMCInstLower Lower(MF->getContext(), *this); MCOp = Lower.lowerOperand(MO); diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h index 303cce1a1b658..7cafb5718048a 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -107,7 +107,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; void emitEndOfAsmFile(Module &M) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; diff --git a/llvm/lib/Target/VE/VEAsmPrinter.cpp b/llvm/lib/Target/VE/VEAsmPrinter.cpp index bdbc29f984b4c..144188ed6b54b 100644 --- a/llvm/lib/Target/VE/VEAsmPrinter.cpp +++ b/llvm/lib/Target/VE/VEAsmPrinter.cpp @@ -62,7 +62,8 @@ class VEAsmPrinter : public AsmPrinter { } void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &OS); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override; }; @@ -374,7 +375,8 @@ void VEAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, // PrintAsmOperand - Print out an operand for an inline asm expression. bool VEAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -382,7 +384,7 @@ bool VEAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); case 'r': case 'v': break; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 03897b551ecae..c562164e6db44 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -696,9 +696,10 @@ void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) { bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, - raw_ostream &OS) { + raw_ostream &OS, + std::string &ErrorMsg) { // First try the generic code, which knows about modifiers like 'c' and 'n'. - if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS)) + if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS, ErrorMsg)) return false; if (!ExtraCode) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h index c30e0155c81e7..133788e3122f2 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h @@ -74,7 +74,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter { void emitFunctionBodyStart() override; void emitInstruction(const MachineInstr *MI) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &OS) override; + const char *ExtraCode, raw_ostream &OS, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override; diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 3395a13545e45..60e3386eafe7d 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -695,7 +695,8 @@ static bool printAsmVRegister(const MachineOperand &MO, char Mode, /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -705,7 +706,7 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); case 'a': // This is an address. Currently only 'i' and 'r' are expected. switch (MO.getType()) { default: @@ -794,6 +795,11 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return false; } O << '-'; + break; + case 'H': + ErrorMsg += " 'H' modifier used on an operand that is a non-offsetable" + " memory reference."; + return true; } } diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h index 693021eca3295..77060ef808640 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.h +++ b/llvm/lib/Target/X86/X86AsmPrinter.h @@ -144,7 +144,8 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { void emitBasicBlockEnd(const MachineBasicBlock &MBB) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override; diff --git a/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp b/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp index 363ab0efdeb91..a61a1a9eaa18b 100644 --- a/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp +++ b/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -67,7 +67,8 @@ namespace { } void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) override; + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) override; bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override; @@ -230,7 +231,8 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - const char *ExtraCode, raw_ostream &O) { + const char *ExtraCode, raw_ostream &O, + std::string &ErrorMsg) { // Print the operand if there is no operand modifier. if (!ExtraCode || !ExtraCode[0]) { printOperand(MI, OpNo, O); @@ -238,7 +240,7 @@ bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, } // Otherwise fallback on the default implementation. - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O, ErrorMsg); } bool XCoreAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, diff --git a/llvm/test/CodeGen/X86/inline-asm-modifier-error.ll b/llvm/test/CodeGen/X86/inline-asm-modifier-error.ll new file mode 100644 index 0000000000000..7804f3d8789b5 --- /dev/null +++ b/llvm/test/CodeGen/X86/inline-asm-modifier-error.ll @@ -0,0 +1,8 @@ +; RUN: not llc -march x86 < %s 2>&1 | FileCheck %s + +; CHECK: error: invalid operand in inline asm: 'movl $0, ${1:H}' 'H' modifier used on an operand that is a non-offsetable memory reference. +define void @H() { +entry: + tail call void asm sideeffect "movl $0, ${1:H}", "i,i,~{dirflag},~{fpsr},~{flags}"(i32 1, i32 2) + ret void +} \ No newline at end of file