summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2019-08-10 04:28:52 +0000
committerCraig Topper <craig.topper@intel.com>2019-08-10 04:28:52 +0000
commita8e5e7371173cd13813bdefef537d502c0ecbe58 (patch)
tree3014ba2237e6806898d36c63e0712635c0a4f019 /llvm/lib/Target
parent8d1646bf6670a0ce59ff3431383e86fec293baeb (diff)
downloadbcm5719-llvm-a8e5e7371173cd13813bdefef537d502c0ecbe58.tar.gz
bcm5719-llvm-a8e5e7371173cd13813bdefef537d502c0ecbe58.zip
[X86] Improve the diagnostic for larger than 4-bit immediate for vpermil2pd/ps. Only allow MCConstantExprs.
llvm-svn: 368505
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp18
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86Operand.h6
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td1
3 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 95cbf46d37e..c369c16428b 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -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);
diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index 591e6f4102f..37479954a70 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -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());
}
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 7b765a1d30f..5a5df5edd6d 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -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
OpenPOWER on IntegriCloud