[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