diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 02f075a85327..b5e46b637563 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -65,7 +65,7 @@ class RISCVAsmParser : public MCTargetAsmParser { OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); - bool parseOperand(OperandVector &Operands); + bool parseOperand(OperandVector &Operands, bool ForceImmediate); public: enum RISCVMatchResultTy { @@ -881,12 +881,15 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { return MatchOperand_Success; } -/// Looks at a token type and creates the relevant operand -/// from this information, adding to Operands. -/// If operand was parsed, returns false, else true. -bool RISCVAsmParser::parseOperand(OperandVector &Operands) { - // Attempt to parse token as register - if (parseRegister(Operands, true) == MatchOperand_Success) +/// Looks at a token type and creates the relevant operand from this +/// information, adding to Operands. If operand was parsed, returns false, else +/// true. If ForceImmediate is true, no attempt will be made to parse the +/// operand as a register, which is needed for pseudoinstructions such as +/// call. +bool RISCVAsmParser::parseOperand(OperandVector &Operands, + bool ForceImmediate) { + // Attempt to parse token as register, unless ForceImmediate. + if (!ForceImmediate && parseRegister(Operands, true) == MatchOperand_Success) return false; // Attempt to parse token as an immediate @@ -913,7 +916,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, return false; // Parse first operand - if (parseOperand(Operands)) + if (parseOperand(Operands, Name == "call")) return true; // Parse until end of statement, consuming commas between operands @@ -922,7 +925,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, getLexer().Lex(); // Parse next operand - if (parseOperand(Operands)) + if (parseOperand(Operands, false)) return true; } diff --git a/llvm/test/MC/RISCV/function-call.s b/llvm/test/MC/RISCV/function-call.s index d52623ed265b..d1a076efef41 100644 --- a/llvm/test/MC/RISCV/function-call.s +++ b/llvm/test/MC/RISCV/function-call.s @@ -17,3 +17,23 @@ call bar # INSTR: auipc ra, 0 # INSTR: jalr ra # FIXUP: fixup A - offset: 0, value: bar, kind: + +# Ensure that calls to functions whose names coincide with register names work. + +call zero +# RELOC: R_RISCV_CALL zero 0x0 +# INSTR: auipc ra, 0 +# INSTR: jalr ra +# FIXUP: fixup A - offset: 0, value: zero, kind: + +call f1 +# RELOC: R_RISCV_CALL f1 0x0 +# INSTR: auipc ra, 0 +# INSTR: jalr ra +# FIXUP: fixup A - offset: 0, value: f1, kind: + +call ra +# RELOC: R_RISCV_CALL ra 0x0 +# INSTR: auipc ra, 0 +# INSTR: jalr ra +# FIXUP: fixup A - offset: 0, value: ra, kind: