[llvm] c98add7 - [LoongArch] Report error in AsmParser when rd == rk or rd == rj for AM* instructions
Weining Lu via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 20 19:46:39 PDT 2022
Author: Weining Lu
Date: 2022-10-21T09:56:45+08:00
New Revision: c98add7a11ff35d42fee860f9c9d301601ff5861
URL: https://github.com/llvm/llvm-project/commit/c98add7a11ff35d42fee860f9c9d301601ff5861
DIFF: https://github.com/llvm/llvm-project/commit/c98add7a11ff35d42fee860f9c9d301601ff5861.diff
LOG: [LoongArch] Report error in AsmParser when rd == rk or rd == rj for AM* instructions
Do this check because the ISA manual says (edited from the original translation):
> If the AM* instruction has its rd == rj, an Instruction Non-defined Exception will be triggered when the instruction is executed.
>
> If the AM* instruction has its rd == rk, the execution result is unpredictable. It is software's responsibility to avoid this situation.
Note that binutils does the same check except when rd == r0 but this
is undocumented.
Differential Revision: https://reviews.llvm.org/D136076
Added:
Modified:
llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
index 10b4660fa1988..77f431bafa2b2 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -74,6 +74,7 @@ class LoongArchAsmParser : public MCTargetAsmParser {
Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
Match_RequiresMsbNotLessThanLsb,
Match_RequiresOpnd2NotR0R1,
+ Match_RequiresAMORdDifferRkRj,
#define GET_OPERAND_DIAGNOSTIC_TYPES
#include "LoongArchGenAsmMatcher.inc"
#undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -667,8 +668,16 @@ bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
}
unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
- switch (Inst.getOpcode()) {
+ unsigned Opc = Inst.getOpcode();
+ switch (Opc) {
default:
+ if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
+ unsigned Rd = Inst.getOperand(0).getReg();
+ unsigned Rk = Inst.getOperand(1).getReg();
+ unsigned Rj = Inst.getOperand(2).getReg();
+ if (Rd == Rk || Rd == Rj)
+ return Match_RequiresAMORdDifferRkRj;
+ }
break;
case LoongArch::CSRXCHG: {
unsigned Rj = Inst.getOperand(2).getReg();
@@ -791,6 +800,9 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
}
case Match_RequiresOpnd2NotR0R1:
return Error(Operands[2]->getStartLoc(), "must not be $r0 or $r1");
+ case Match_RequiresAMORdDifferRkRj:
+ return Error(Operands[1]->getStartLoc(),
+ "$rd must be
diff erent from both $rk and $rj");
case Match_InvalidUImm2:
return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
/*Upper=*/(1 << 2) - 1);
diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
index 5ee9659cdb7bf..7e67a19e917bc 100644
--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
+++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
@@ -79,3 +79,17 @@ bstrins.d $a0, $a0, 1, 2
# CHECK: :[[#@LINE+1]]:22: error: msb is less than lsb
bstrpick.d $a0, $a0, 32, 63
# CHECK: ^~~~~~
+
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be
diff erent from both $rk and $rj
+amadd.d $zero, $zero, $zero
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be
diff erent from both $rk and $rj
+ammin.w $zero, $zero, $a0
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be
diff erent from both $rk and $rj
+amxor.w $zero, $a0, $zero
+
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be
diff erent from both $rk and $rj
+amadd.d $a0, $a0, $a0
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be
diff erent from both $rk and $rj
+ammin.w $a0, $a0, $a1
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be
diff erent from both $rk and $rj
+amxor.w $a0, $a1, $a0
More information about the llvm-commits
mailing list