[PATCH] D136076: [LoongArch] Report error in AsmParser when rd == rk or rd == rj for AM* instructions

Lu Weining via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 17 06:09:58 PDT 2022


SixWeining created this revision.
SixWeining added reviewers: xen0n, xry111, MaskRay, wangleiat, gonglingqin.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
SixWeining requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Do this check because the ISA manual says:

  If the AM* atomic memory access instruction has the same register number
  as rd and rj, the execution will trigger an Instruction Non-defined
  Exception.
  
  If the AM* atomic memory access instruction has the same register number
  as rd and rk, the execution result is uncertain. Please software to
  avoid this situation.

Note that binutils does the same check except when rd == r0 but this
is undocumented.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136076

Files:
  llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
  llvm/test/MC/LoongArch/Basic/Integer/invalid64.s


Index: llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
===================================================================
--- llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
+++ llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
@@ -79,3 +79,17 @@
 # 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 different from both $rk and $rj
+amadd.d $zero, $zero, $zero
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj
+ammin.w $zero, $zero, $a0
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj
+amxor.w $zero, $a0, $zero
+
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj
+amadd.d $a0, $a0, $a0
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj
+ammin.w $a0, $a0, $a1
+# CHECK: :[[#@LINE+1]]:10: error: $rd must be different from both $rk and $rj
+amxor.w $a0, $a1, $a0
Index: llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
===================================================================
--- llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -74,6 +74,7 @@
     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 @@
 }
 
 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 @@
   }
   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 different from both $rk and $rj");
   case Match_InvalidUImm2:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 2) - 1);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D136076.468183.patch
Type: text/x-patch
Size: 2580 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221017/d03ad40a/attachment.bin>


More information about the llvm-commits mailing list