diff options
author | Craig Topper <craig.topper@intel.com> | 2019-08-07 05:34:27 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2019-08-07 05:34:27 +0000 |
commit | 29688f4da0b62e760dcd65d607aa9a56cb1557e0 (patch) | |
tree | 293a2cc5eb55bffe628ebba214b1c5562757c15c /llvm | |
parent | 989679c3711a239c73057fb5446eef937935f4ba (diff) | |
download | bcm5719-llvm-29688f4da0b62e760dcd65d607aa9a56cb1557e0.tar.gz bcm5719-llvm-29688f4da0b62e760dcd65d607aa9a56cb1557e0.zip |
[X86] Limit vpermil2pd/vpermil2ps immediates to 4 bits in the assembly parser.
The upper 4 bits of the immediate byte are used to encode a
register. We need to limit the explicit immediate to fit in the
remaining 4 bits.
Fixes PR42899.
llvm-svn: 368123
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParserCommon.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86Operand.h | 9 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 14 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrXOP.td | 8 | ||||
-rw-r--r-- | llvm/test/MC/X86/x86_errors.s | 4 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/X86/BdVer2/xop-super-registers-2.s | 12 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/X86/Generic/xop-super-registers-2.s | 12 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.cpp | 2 |
8 files changed, 49 insertions, 16 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParserCommon.h b/llvm/lib/Target/X86/AsmParser/X86AsmParserCommon.h index 5bc979d1f18..e9be28ca77b 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParserCommon.h +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParserCommon.h @@ -35,6 +35,10 @@ inline bool isImmUnsignedi8Value(uint64_t Value) { return isUInt<8>(Value) || isInt<8>(Value); } +inline bool isImmUnsignedi4Value(uint64_t Value) { + return isUInt<4>(Value); +} + } // End of namespace llvm #endif diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h index a771ba36631..591e6f4102f 100644 --- a/llvm/lib/Target/X86/AsmParser/X86Operand.h +++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h @@ -260,6 +260,15 @@ struct X86Operand final : public MCParsedAsmOperand { return isImmSExti64i32Value(CE->getValue()); } + bool isImmUnsignedi4() const { + if (!isImm()) return false; + // If this isn't a constant expr, just assume it fits and let relaxation + // handle it. + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) return true; + return isImmUnsignedi4Value(CE->getValue()); + } + bool isImmUnsignedi8() const { if (!isImm()) return false; // If this isn't a constant expr, just assume it fits and let relaxation diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 8e05dd8ec5c..06514b33d41 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -673,6 +673,13 @@ def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass { ImmSExti64i32AsmOperand]; } +// 4-bit immediate used by some XOP instructions +// [0, 0xF] +def ImmUnsignedi4AsmOperand : AsmOperandClass { + let Name = "ImmUnsignedi4"; + let RenderMethod = "addImmOperands"; +} + // Unsigned immediate used by SSE/AVX instructions // [0, 0xFF] // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] @@ -705,6 +712,13 @@ def i64i8imm : Operand<i64> { let OperandType = "OPERAND_IMMEDIATE"; } +// Unsigned 4-bit immediate used by some XOP instructions. +def u4imm : Operand<i8> { + let PrintMethod = "printU8Imm"; + let ParserMatchClass = ImmUnsignedi4AsmOperand; + let OperandType = "OPERAND_IMMEDIATE"; +} + // Unsigned 8-bit immediate used by SSE/AVX instructions. def u8imm : Operand<i8> { let PrintMethod = "printU8Imm"; diff --git a/llvm/lib/Target/X86/X86InstrXOP.td b/llvm/lib/Target/X86/X86InstrXOP.td index 66ca78556b8..9a972a9adf9 100644 --- a/llvm/lib/Target/X86/X86InstrXOP.td +++ b/llvm/lib/Target/X86/X86InstrXOP.td @@ -418,14 +418,14 @@ multiclass xop_vpermil2<bits<8> Opc, string OpcodeStr, RegisterClass RC, ValueType VT, PatFrag FPLdFrag, PatFrag IntLdFrag, X86FoldableSchedWrite sched> { def rr : IXOP5<Opc, MRMSrcReg, (outs RC:$dst), - (ins RC:$src1, RC:$src2, RC:$src3, u8imm:$src4), + (ins RC:$src1, RC:$src2, RC:$src3, u4imm:$src4), !strconcat(OpcodeStr, "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), [(set RC:$dst, (VT (X86vpermil2 RC:$src1, RC:$src2, RC:$src3, (i8 imm:$src4))))]>, Sched<[sched]>; def rm : IXOP5<Opc, MRMSrcMemOp4, (outs RC:$dst), - (ins RC:$src1, RC:$src2, intmemop:$src3, u8imm:$src4), + (ins RC:$src1, RC:$src2, intmemop:$src3, u4imm:$src4), !strconcat(OpcodeStr, "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), [(set RC:$dst, @@ -433,7 +433,7 @@ multiclass xop_vpermil2<bits<8> Opc, string OpcodeStr, RegisterClass RC, (i8 imm:$src4))))]>, VEX_W, Sched<[sched.Folded, sched.ReadAfterFold, sched.ReadAfterFold]>; def mr : IXOP5<Opc, MRMSrcMem, (outs RC:$dst), - (ins RC:$src1, fpmemop:$src2, RC:$src3, u8imm:$src4), + (ins RC:$src1, fpmemop:$src2, RC:$src3, u4imm:$src4), !strconcat(OpcodeStr, "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), [(set RC:$dst, @@ -447,7 +447,7 @@ multiclass xop_vpermil2<bits<8> Opc, string OpcodeStr, RegisterClass RC, // For disassembler let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in def rr_REV : IXOP5<Opc, MRMSrcRegOp4, (outs RC:$dst), - (ins RC:$src1, RC:$src2, RC:$src3, u8imm:$src4), + (ins RC:$src1, RC:$src2, RC:$src3, u4imm:$src4), !strconcat(OpcodeStr, "\t{$src4, $src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3, $src4}"), []>, VEX_W, Sched<[sched]>, FoldGenData<NAME#rr>; diff --git a/llvm/test/MC/X86/x86_errors.s b/llvm/test/MC/X86/x86_errors.s index c7d563bfda7..5e44aaa0942 100644 --- a/llvm/test/MC/X86/x86_errors.s +++ b/llvm/test/MC/X86/x86_errors.s @@ -179,3 +179,7 @@ cmpxchg16b (%eax) // 32: error: unsupported instruction // 64: error: unsupported instruction {evex} vmovdqu %xmm0, %xmm0 + +// 32: 12: error: invalid operand for instruction +// 64: 12: error: invalid operand for instruction +vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 diff --git a/llvm/test/tools/llvm-mca/X86/BdVer2/xop-super-registers-2.s b/llvm/test/tools/llvm-mca/X86/BdVer2/xop-super-registers-2.s index 2ddc7690ff0..af3b709bb4e 100644 --- a/llvm/test/tools/llvm-mca/X86/BdVer2/xop-super-registers-2.s +++ b/llvm/test/tools/llvm-mca/X86/BdVer2/xop-super-registers-2.s @@ -2,7 +2,7 @@ # RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=bdver2 -timeline -timeline-max-iterations=2 < %s | FileCheck %s vmulps %ymm0, %ymm1, %ymm2 - vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 + vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 vmulps %ymm2, %ymm3, %ymm4 vaddps %ymm4, %ymm5, %ymm6 vmulps %ymm6, %ymm3, %ymm4 @@ -28,7 +28,7 @@ # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 2 5 1.00 vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: 1 3 1.00 vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: 1 3 1.00 vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: 2 5 1.00 vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: 2 5 1.00 vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: 2 5 1.00 vmulps %ymm6, %ymm3, %ymm4 @@ -66,7 +66,7 @@ # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0.0] [0.1] [1] [2] [3] [4] [5] [6] [7.0] [7.1] [8.0] [8.1] [9] [10] [11] [12] [13] [14] [15] [16.0] [16.1] [17] [18] Instructions: # CHECK-NEXT: - - - - - - - - 1.58 0.42 - - - - - 1.00 - - - - - - - vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: - - - - - - - - 0.44 1.56 - - - - 0.61 0.39 - - - - - - - vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: - - - - - - - - 0.44 1.56 - - - - 0.61 0.39 - - - - - - - vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: - - - - - - - - 1.58 0.42 - - - - - 1.00 - - - - - - - vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: - - - - - - - - 0.40 1.60 - - - - 1.00 - - - - - - - - vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: - - - - - - - - 1.58 0.42 - - - - - 1.00 - - - - - - - vmulps %ymm6, %ymm3, %ymm4 @@ -77,13 +77,13 @@ # CHECK-NEXT: Index 0123456789 0123456789 # CHECK: [0,0] DeeeeeER . . . . .. vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: [0,1] DeeeE--R . . . . .. vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: [0,1] DeeeE--R . . . . .. vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: [0,2] .D==eeeeeER . . . .. vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: [0,3] .D=======eeeeeER . . .. vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: [0,4] . D===========eeeeeER . .. vmulps %ymm6, %ymm3, %ymm4 # CHECK-NEXT: [0,5] . D================eeeeeER .. vaddps %ymm4, %ymm5, %ymm0 # CHECK-NEXT: [1,0] . D====================eeeeeER. vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: [1,1] . DeeeE----------------------R. vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: [1,1] . DeeeE----------------------R. vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: [1,2] . D==eeeeeE-----------------R. vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: [1,3] . D=======eeeeeE------------R. vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: [1,4] . D===========eeeeeE--------R vmulps %ymm6, %ymm3, %ymm4 @@ -97,7 +97,7 @@ # CHECK: [0] [1] [2] [3] # CHECK-NEXT: 0. 2 11.0 0.5 0.0 vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: 1. 2 1.0 1.0 12.0 vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: 1. 2 1.0 1.0 12.0 vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: 2. 2 3.0 0.0 8.5 vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: 3. 2 8.0 0.0 6.0 vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: 4. 2 12.0 0.0 4.0 vmulps %ymm6, %ymm3, %ymm4 diff --git a/llvm/test/tools/llvm-mca/X86/Generic/xop-super-registers-2.s b/llvm/test/tools/llvm-mca/X86/Generic/xop-super-registers-2.s index ba59a86a048..a32bbc6fb0e 100644 --- a/llvm/test/tools/llvm-mca/X86/Generic/xop-super-registers-2.s +++ b/llvm/test/tools/llvm-mca/X86/Generic/xop-super-registers-2.s @@ -2,7 +2,7 @@ # RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -timeline -timeline-max-iterations=2 < %s | FileCheck %s vmulps %ymm0, %ymm1, %ymm2 - vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 + vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 vmulps %ymm2, %ymm3, %ymm4 vaddps %ymm4, %ymm5, %ymm6 vmulps %ymm6, %ymm3, %ymm4 @@ -28,7 +28,7 @@ # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 5 1.00 vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: 1 1 1.00 vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: 1 1 1.00 vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: 1 5 1.00 vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: 1 3 1.00 vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: 1 5 1.00 vmulps %ymm6, %ymm3, %ymm4 @@ -51,7 +51,7 @@ # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions: # CHECK-NEXT: - - 1.00 - - - - - vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: - - - - - 1.00 - - vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: - - - - - 1.00 - - vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: - - 1.00 - - - - - vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: - - - 1.00 - - - - vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: - - 1.00 - - - - - vmulps %ymm6, %ymm3, %ymm4 @@ -62,13 +62,13 @@ # CHECK-NEXT: Index 0123456789 01234 # CHECK: [0,0] DeeeeeER . . . . vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: [0,1] DeE----R . . . . vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: [0,1] DeE----R . . . . vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: [0,2] D=eeeeeER . . . . vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: [0,3] D======eeeER . . . vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: [0,4] .D========eeeeeER . . vmulps %ymm6, %ymm3, %ymm4 # CHECK-NEXT: [0,5] .D=============eeeER. . vaddps %ymm4, %ymm5, %ymm0 # CHECK-NEXT: [1,0] .D================eeeeeER vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: [1,1] .DeE--------------------R vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: [1,1] .DeE--------------------R vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: [1,2] . DeeeeeE---------------R vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: [1,3] . D=====eeeE------------R vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: [1,4] . D========eeeeeE-------R vmulps %ymm6, %ymm3, %ymm4 @@ -82,7 +82,7 @@ # CHECK: [0] [1] [2] [3] # CHECK-NEXT: 0. 2 9.0 0.5 0.0 vmulps %ymm0, %ymm1, %ymm2 -# CHECK-NEXT: 1. 2 1.0 1.0 12.0 vpermil2pd $16, %xmm3, %xmm5, %xmm1, %xmm2 +# CHECK-NEXT: 1. 2 1.0 1.0 12.0 vpermil2pd $15, %xmm3, %xmm5, %xmm1, %xmm2 # CHECK-NEXT: 2. 2 1.5 0.0 7.5 vmulps %ymm2, %ymm3, %ymm4 # CHECK-NEXT: 3. 2 6.5 0.0 6.0 vaddps %ymm4, %ymm5, %ymm6 # CHECK-NEXT: 4. 2 9.0 0.0 3.5 vmulps %ymm6, %ymm3, %ymm4 diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index ab8a8855c47..37bf3b82b01 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -854,6 +854,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("GR64", TYPE_R64) TYPE("i8mem", TYPE_M) TYPE("i8imm", TYPE_IMM) + TYPE("u4imm", TYPE_UIMM8) TYPE("u8imm", TYPE_UIMM8) TYPE("i16u8imm", TYPE_UIMM8) TYPE("i32u8imm", TYPE_UIMM8) @@ -973,6 +974,7 @@ RecognizableInstr::immediateEncodingFromString(const std::string &s, ENCODING("i64i32imm", ENCODING_ID) ENCODING("i64i8imm", ENCODING_IB) ENCODING("i8imm", ENCODING_IB) + ENCODING("u4imm", ENCODING_IB) ENCODING("u8imm", ENCODING_IB) ENCODING("i16u8imm", ENCODING_IB) ENCODING("i32u8imm", ENCODING_IB) |