[llvm] 24532d0 - [LoongArch] Check msb is not less than lsb for the bstr{ins/pick}.{w/d} instructions

Weining Lu via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 18:38:02 PDT 2022


Author: Weining Lu
Date: 2022-05-12T09:31:44+08:00
New Revision: 24532d05f8da67058c41ea4ad885c96ee918aa57

URL: https://github.com/llvm/llvm-project/commit/24532d05f8da67058c41ea4ad885c96ee918aa57
DIFF: https://github.com/llvm/llvm-project/commit/24532d05f8da67058c41ea4ad885c96ee918aa57.diff

LOG: [LoongArch] Check msb is not less than lsb for the bstr{ins/pick}.{w/d} instructions

Differential Revision: https://reviews.llvm.org/D124825

Added: 
    

Modified: 
    llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
    llvm/test/MC/LoongArch/Basic/Integer/invalid.s
    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 8f6331d7d699f..0c9518233751b 100644
--- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
+++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
@@ -43,6 +43,8 @@ class LoongArchAsmParser : public MCTargetAsmParser {
                                uint64_t &ErrorInfo,
                                bool MatchingInlineAsm) override;
 
+  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
+
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
 
@@ -66,6 +68,7 @@ class LoongArchAsmParser : public MCTargetAsmParser {
 public:
   enum LoongArchMatchResultTy {
     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
+    Match_RequiresMsbNotLessThanLsb,
 #define GET_OPERAND_DIAGNOSTIC_TYPES
 #include "LoongArchGenAsmMatcher.inc"
 #undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -369,6 +372,32 @@ bool LoongArchAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
   return false;
 }
 
+unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
+  switch (Inst.getOpcode()) {
+  default:
+    break;
+  case LoongArch::BSTRINS_W:
+  case LoongArch::BSTRINS_D:
+  case LoongArch::BSTRPICK_W:
+  case LoongArch::BSTRPICK_D: {
+    unsigned Opc = Inst.getOpcode();
+    const signed Msb =
+        (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
+            ? Inst.getOperand(3).getImm()
+            : Inst.getOperand(2).getImm();
+    const signed Lsb =
+        (Opc == LoongArch::BSTRINS_W || Opc == LoongArch::BSTRINS_D)
+            ? Inst.getOperand(4).getImm()
+            : Inst.getOperand(3).getImm();
+    if (Msb < Lsb)
+      return Match_RequiresMsbNotLessThanLsb;
+    return Match_Success;
+  }
+  }
+
+  return Match_Success;
+}
+
 unsigned
 LoongArchAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
                                                unsigned Kind) {
@@ -455,6 +484,11 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   switch (Result) {
   default:
     break;
+  case Match_RequiresMsbNotLessThanLsb: {
+    SMLoc ErrorStart = Operands[3]->getStartLoc();
+    return Error(ErrorStart, "msb is less than lsb",
+                 SMRange(ErrorStart, Operands[4]->getEndLoc()));
+  }
   case Match_InvalidUImm2:
     return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0,
                                       /*Upper=*/(1 << 2) - 1);

diff  --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
index bd01eb49d11cd..94b3976f5bfd0 100644
--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
+++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s
@@ -180,3 +180,12 @@ fadd.d $fa0, $fa0, $fa0
 ## Using floating point registers when integer registers are expected
 sll.w $a0, $a0, $fa0
 # CHECK: :[[#@LINE-1]]:18: error: invalid operand for instruction
+
+## msbw < lsbw
+# CHECK: :[[#@LINE+1]]:21: error: msb is less than lsb
+bstrins.w $a0, $a0, 1, 2
+# CHECK:            ^~~~
+
+# CHECK: :[[#@LINE+1]]:22: error: msb is less than lsb
+bstrpick.w $a0, $a0, 30, 31
+# CHECK:             ^~~~~~

diff  --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
index e5249f04f4920..e7e6fb09840b3 100644
--- a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
+++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s
@@ -64,3 +64,12 @@ lu32i.d $a0, -0x80001
 # CHECK: :[[#@LINE-1]]:14: error: immediate must be an integer in the range [-524288, 524287]
 pcaddu18i $a0, 0x80000
 # CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287]
+
+## msbd < lsbd
+# CHECK: :[[#@LINE+1]]:21: error: msb is less than lsb
+bstrins.d $a0, $a0, 1, 2
+# CHECK:            ^~~~
+
+# CHECK: :[[#@LINE+1]]:22: error: msb is less than lsb
+bstrpick.d $a0, $a0, 32, 63
+# CHECK:             ^~~~~~


        


More information about the llvm-commits mailing list