llvm.org GIT mirror llvm / 700e61c
[RISCV] Diagnose invalid second input register operand when using %tprel_add RISCVMCCodeEmitter::expandAddTPRel asserts that the second operand must be x4/tp. As we are not currently checking this in the RISCVAsmParser, the assert is easy to trigger due to wrong assembly input. This patch does a late check of this constraint. An alternative could be using a singleton register class for x4/tp similar to the current one for sp. Unfortunately it does not result in a good diagnostic. Because add is an overloaded mnemonic, if no matching is possible, the diagnostic of the first failing alternative seems to be used as the diagnostic itself. This means that this case the %tprel_add is diagnosed as an invalid operand (because the real add instruction only has 3 operands). Differential Revision: https://reviews.llvm.org/D60528 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358183 91177308-0d34-0410-b5e6-96231b3b80d8 Roger Ferrer Ibanez 1 year, 7 months ago
2 changed file(s) with 27 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
9595 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
9696 MCStreamer &Out, bool HasTmpReg);
98 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
99 // Enforcing this using a restricted register class for the second input
100 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
101 // 'add' is an overloaded mnemonic.
102 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
98104 /// Helper for processing MC instructions that have been successfully matched
99105 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
100106 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
101107 /// in this method.
102 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
108 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
109 MCStreamer &Out);
104111 // Auto-generated instruction matching functions
793800 default:
794801 break;
795802 case Match_Success:
796 return processInstruction(Inst, IDLoc, Out);
803 return processInstruction(Inst, IDLoc, Operands, Out);
797804 case Match_MissingFeature:
798805 return Error(IDLoc, "instruction use requires an option to be enabled");
799806 case Match_MnemonicFail:
15951602 Opcode, IDLoc, Out);
15961603 }
1605 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
1606 OperandVector &Operands) {
1607 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
1608 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind");
1609 if (Inst.getOperand(2).getReg() != RISCV::X4) {
1610 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
1611 return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
1612 "%tprel_add modifier");
1613 }
1615 return false;
1616 }
15981618 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1619 OperandVector &Operands,
15991620 MCStreamer &Out) {
16001621 Inst.setLoc(IDLoc);
16741695 case RISCV::PseudoFSD:
16751696 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
16761697 return false;
1698 case RISCV::PseudoAddTPRel:
1699 if (checkPseudoAddTPRel(Inst, Operands))
1700 return true;
16771701 }
16791703 emitToStreamer(Out, Inst);
132132 # TP-relative symbol names require a %tprel_add modifier.
133133 add a0, a0, tp, zero # CHECK: :[[@LINE]]:17: error: expected '%' for operand modifier
134134 add a0, a0, tp, %hi(foo) # CHECK: :[[@LINE]]:17: error: operand must be a symbol with %tprel_add modifier
135 add a0, tp, a0, %tprel_add(foo) # CHECK: :[[@LINE]]:13: error: the second input operand must be tp/x4 when using %tprel_add modifier
136137 # Unrecognized operand modifier
137138 addi t0, sp, %modifer(255) # CHECK: :[[@LINE]]:15: error: unrecognized operand modifier