]> granicus.if.org Git - llvm/commitdiff
[X86] Improve the diagnostic for larger than 4-bit immediate for vpermil2pd/ps. Only...
authorCraig Topper <craig.topper@intel.com>
Sat, 10 Aug 2019 04:28:52 +0000 (04:28 +0000)
committerCraig Topper <craig.topper@intel.com>
Sat, 10 Aug 2019 04:28:52 +0000 (04:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368505 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/AsmParser/X86Operand.h
lib/Target/X86/X86InstrInfo.td
test/MC/X86/x86_errors.s

index 95cbf46d37ed69779809adfe3d4af99035e9f11b..c369c16428b58b50c30c8ceea32d016da99e03cf 100644 (file)
@@ -955,6 +955,8 @@ private:
 public:
   enum X86MatchResultTy {
     Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
+#define GET_OPERAND_DIAGNOSTIC_TYPES
+#include "X86GenAsmMatcher.inc"
   };
 
   X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
@@ -3173,6 +3175,13 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
       EmitInstruction(Inst, Operands, Out);
     Opcode = Inst.getOpcode();
     return false;
+  case Match_InvalidImmUnsignedi4: {
+    SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
+    if (ErrorLoc == SMLoc())
+      ErrorLoc = IDLoc;
+    return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
+                 EmptyRange, MatchingInlineAsm);
+  }
   case Match_MissingFeature:
     return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
   case Match_InvalidOperand:
@@ -3520,6 +3529,15 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
                  MatchingInlineAsm);
   }
 
+  if (std::count(std::begin(Match), std::end(Match),
+                 Match_InvalidImmUnsignedi4) == 1) {
+    SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
+    if (ErrorLoc == SMLoc())
+      ErrorLoc = IDLoc;
+    return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
+                 EmptyRange, MatchingInlineAsm);
+  }
+
   // If all of these were an outright failure, report it in a useless way.
   return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
                MatchingInlineAsm);
index 591e6f4102f50238ff94973a00f91cbfe9a42124..37479954a70708ac80df0aa92d98bf72544e83b1 100644 (file)
@@ -262,10 +262,10 @@ struct X86Operand final : public MCParsedAsmOperand {
 
   bool isImmUnsignedi4() const {
     if (!isImm()) return false;
-    // If this isn't a constant expr, just assume it fits and let relaxation
-    // handle it.
+    // If this isn't a constant expr, reject it. The immediate byte is shared
+    // with a register encoding. We can't have it affected by a relocation.
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
-    if (!CE) return true;
+    if (!CE) return false;
     return isImmUnsignedi4Value(CE->getValue());
   }
 
index 7b765a1d30ff683359f330552a6def2bf522c1fe..5a5df5edd6d9e699d7b7fd3dd9336f7c0d5b1799 100644 (file)
@@ -678,6 +678,7 @@ def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
 def ImmUnsignedi4AsmOperand : AsmOperandClass {
   let Name = "ImmUnsignedi4";
   let RenderMethod = "addImmOperands";
+  let DiagnosticType = "InvalidImmUnsignedi4";
 }
 
 // Unsigned immediate used by SSE/AVX instructions
index 5e44aaa09429f087d3ebbb7c139216e6a671bc10..f9cdc150b667f0bf2f88efdfb26f5e0fe17c6b6b 100644 (file)
@@ -180,6 +180,6 @@ cmpxchg16b (%eax)
 // 64: error: unsupported instruction
 {evex} vmovdqu %xmm0, %xmm0
 
-// 32: 12: error: invalid operand for instruction
-// 64: 12: error: invalid operand for instruction
+// 32: 12: error: immediate must be an integer in range [0, 15]
+// 64: 12: error: immediate must be an integer in range [0, 15]
 vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2