[AVX512] Add vpermil variable version
[oota-llvm.git] / lib / Target / X86 / X86InstrAVX512.td
1 // Group template arguments that can be derived from the vector type (EltNum x
2 // EltVT).  These are things like the register class for the writemask, etc.
3 // The idea is to pass one of these as the template argument rather than the
4 // individual arguments.
5 class X86VectorVTInfo<int numelts, ValueType EltVT, RegisterClass rc,
6                       string suffix = ""> {
7   RegisterClass RC = rc;
8   int NumElts = numelts;
9
10   // Corresponding mask register class.
11   RegisterClass KRC = !cast<RegisterClass>("VK" # NumElts);
12
13   // Corresponding write-mask register class.
14   RegisterClass KRCWM = !cast<RegisterClass>("VK" # NumElts # "WM");
15
16   // The GPR register class that can hold the write mask.  Use GR8 for fewer
17   // than 8 elements.  Use shift-right and equal to work around the lack of
18   // !lt in tablegen.
19   RegisterClass MRC =
20     !cast<RegisterClass>("GR" #
21                          !if (!eq (!srl(NumElts, 3), 0), 8, NumElts));
22
23   // Suffix used in the instruction mnemonic.
24   string Suffix = suffix;
25
26   string VTName = "v" # NumElts # EltVT;
27
28   // The vector VT.
29   ValueType VT = !cast<ValueType>(VTName);
30
31   string EltTypeName = !cast<string>(EltVT);
32   // Size of the element type in bits, e.g. 32 for v16i32.
33   string EltSizeName = !subst("i", "", !subst("f", "", EltTypeName));
34   int EltSize = EltVT.Size;
35
36   // "i" for integer types and "f" for floating-point types
37   string TypeVariantName = !subst(EltSizeName, "", EltTypeName);
38
39   // Size of RC in bits, e.g. 512 for VR512.
40   int Size = VT.Size;
41
42   // The corresponding memory operand, e.g. i512mem for VR512.
43   X86MemOperand MemOp = !cast<X86MemOperand>(TypeVariantName # Size # "mem");
44   X86MemOperand ScalarMemOp = !cast<X86MemOperand>(EltVT # "mem");
45
46   // Load patterns
47   // Note: For 128/256-bit integer VT we choose loadv2i64/loadv4i64
48   //       due to load promotion during legalization
49   PatFrag LdFrag = !cast<PatFrag>("load" #
50                                   !if (!eq (TypeVariantName, "i"),
51                                        !if (!eq (Size, 128), "v2i64",
52                                        !if (!eq (Size, 256), "v4i64",
53                                             VTName)), VTName));
54   PatFrag ScalarLdFrag = !cast<PatFrag>("load" # EltVT);
55
56   // Load patterns used for memory operands.  We only have this defined in
57   // case of i64 element types for sub-512 integer vectors.  For now, keep
58   // MemOpFrag undefined in these cases.
59   PatFrag MemOpFrag =
60     !if (!eq (TypeVariantName, "f"), !cast<PatFrag>("memop" # VTName),
61     !if (!eq (EltTypeName, "i64"),   !cast<PatFrag>("memop" # VTName),
62     !if (!eq (VTName, "v16i32"),     !cast<PatFrag>("memop" # VTName), ?)));
63
64   // The corresponding float type, e.g. v16f32 for v16i32
65   // Note: For EltSize < 32, FloatVT is illegal and TableGen
66   //       fails to compile, so we choose FloatVT = VT
67   ValueType FloatVT = !cast<ValueType>(
68                         !if (!eq (!srl(EltSize,5),0),
69                              VTName,
70                              !if (!eq(TypeVariantName, "i"),
71                                   "v" # NumElts # "f" # EltSize,
72                                   VTName)));
73
74   // The string to specify embedded broadcast in assembly.
75   string BroadcastStr = "{1to" # NumElts # "}";
76
77   // 8-bit compressed displacement tuple/subvector format.  This is only
78   // defined for NumElts <= 8.
79   CD8VForm CD8TupleForm = !if (!eq (!srl(NumElts, 4), 0),
80                                !cast<CD8VForm>("CD8VT" # NumElts), ?);
81
82   SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm,
83                           !if (!eq (Size, 256), sub_ymm, ?));
84
85   Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle,
86                      !if (!eq (EltTypeName, "f64"), SSEPackedDouble,
87                      SSEPackedInt));
88
89   // A vector type of the same width with element type i32.  This is used to
90   // create the canonical constant zero node ImmAllZerosV.
91   ValueType i32VT = !cast<ValueType>("v" # !srl(Size, 5) # "i32");
92   dag ImmAllZerosV = (VT (bitconvert (i32VT immAllZerosV)));
93 }
94
95 def v64i8_info  : X86VectorVTInfo<64,  i8, VR512, "b">;
96 def v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">;
97 def v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">;
98 def v8i64_info  : X86VectorVTInfo<8,  i64, VR512, "q">;
99 def v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">;
100 def v8f64_info  : X86VectorVTInfo<8,  f64, VR512, "pd">;
101
102 // "x" in v32i8x_info means RC = VR256X
103 def v32i8x_info  : X86VectorVTInfo<32,  i8, VR256X, "b">;
104 def v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">;
105 def v8i32x_info  : X86VectorVTInfo<8,  i32, VR256X, "d">;
106 def v4i64x_info  : X86VectorVTInfo<4,  i64, VR256X, "q">;
107
108 def v16i8x_info  : X86VectorVTInfo<16,  i8, VR128X, "b">;
109 def v8i16x_info  : X86VectorVTInfo<8,  i16, VR128X, "w">;
110 def v4i32x_info  : X86VectorVTInfo<4,  i32, VR128X, "d">;
111 def v2i64x_info  : X86VectorVTInfo<2,  i64, VR128X, "q">;
112
113 class AVX512VLVectorVTInfo<X86VectorVTInfo i512, X86VectorVTInfo i256,
114                            X86VectorVTInfo i128> {
115   X86VectorVTInfo info512 = i512;
116   X86VectorVTInfo info256 = i256;
117   X86VectorVTInfo info128 = i128;
118 }
119
120 def avx512vl_i8_info  : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
121                                              v16i8x_info>;
122 def avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
123                                              v8i16x_info>;
124 def avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
125                                              v4i32x_info>;
126 def avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
127                                              v2i64x_info>;
128
129 // This multiclass generates the masking variants from the non-masking
130 // variant.  It only provides the assembly pieces for the masking variants.
131 // It assumes custom ISel patterns for masking which can be provided as
132 // template arguments.
133 multiclass AVX512_maskable_custom<bits<8> O, Format F,
134                                   dag Outs,
135                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
136                                   string OpcodeStr,
137                                   string AttSrcAsm, string IntelSrcAsm,
138                                   list<dag> Pattern,
139                                   list<dag> MaskingPattern,
140                                   list<dag> ZeroMaskingPattern,
141                                   string MaskingConstraint = "",
142                                   InstrItinClass itin = NoItinerary,
143                                   bit IsCommutable = 0> {
144   let isCommutable = IsCommutable in
145     def NAME: AVX512<O, F, Outs, Ins,
146                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
147                                      "$dst, "#IntelSrcAsm#"}",
148                        Pattern, itin>;
149
150   // Prefer over VMOV*rrk Pat<>
151   let AddedComplexity = 20 in
152     def NAME#k: AVX512<O, F, Outs, MaskingIns,
153                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
154                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
155                        MaskingPattern, itin>,
156               EVEX_K {
157       // In case of the 3src subclass this is overridden with a let.
158       string Constraints = MaskingConstraint;
159   }
160   let AddedComplexity = 30 in // Prefer over VMOV*rrkz Pat<>
161     def NAME#kz: AVX512<O, F, Outs, ZeroMaskingIns,
162                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}} {z}|"#
163                                      "$dst {${mask}} {z}, "#IntelSrcAsm#"}",
164                        ZeroMaskingPattern,
165                        itin>,
166               EVEX_KZ;
167 }
168
169
170 // Common base class of AVX512_maskable and AVX512_maskable_3src.
171 multiclass AVX512_maskable_common<bits<8> O, Format F, X86VectorVTInfo _,
172                                   dag Outs,
173                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
174                                   string OpcodeStr,
175                                   string AttSrcAsm, string IntelSrcAsm,
176                                   dag RHS, dag MaskingRHS,
177                                   string MaskingConstraint = "",
178                                   InstrItinClass itin = NoItinerary,
179                                   bit IsCommutable = 0> :
180   AVX512_maskable_custom<O, F, Outs, Ins, MaskingIns, ZeroMaskingIns, OpcodeStr,
181                          AttSrcAsm, IntelSrcAsm,
182                          [(set _.RC:$dst, RHS)],
183                          [(set _.RC:$dst, MaskingRHS)],
184                          [(set _.RC:$dst,
185                                (vselect _.KRCWM:$mask, RHS, _.ImmAllZerosV))],
186                          MaskingConstraint, NoItinerary, IsCommutable>;
187
188 // This multiclass generates the unconditional/non-masking, the masking and
189 // the zero-masking variant of the instruction.  In the masking case, the
190 // perserved vector elements come from a new dummy input operand tied to $dst.
191 multiclass AVX512_maskable<bits<8> O, Format F, X86VectorVTInfo _,
192                            dag Outs, dag Ins, string OpcodeStr,
193                            string AttSrcAsm, string IntelSrcAsm,
194                            dag RHS, InstrItinClass itin = NoItinerary,
195                            bit IsCommutable = 0> :
196    AVX512_maskable_common<O, F, _, Outs, Ins,
197                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
198                           !con((ins _.KRCWM:$mask), Ins),
199                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
200                           (vselect _.KRCWM:$mask, RHS, _.RC:$src0),
201                           "$src0 = $dst", itin, IsCommutable>;
202
203 // Similar to AVX512_maskable but in this case one of the source operands
204 // ($src1) is already tied to $dst so we just use that for the preserved
205 // vector elements.  NOTE that the NonTiedIns (the ins dag) should exclude
206 // $src1.
207 multiclass AVX512_maskable_3src<bits<8> O, Format F, X86VectorVTInfo _,
208                                 dag Outs, dag NonTiedIns, string OpcodeStr,
209                                 string AttSrcAsm, string IntelSrcAsm,
210                                 dag RHS> :
211    AVX512_maskable_common<O, F, _, Outs,
212                           !con((ins _.RC:$src1), NonTiedIns),
213                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
214                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
215                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
216                           (vselect _.KRCWM:$mask, RHS, _.RC:$src1)>;
217
218
219 multiclass AVX512_maskable_in_asm<bits<8> O, Format F, X86VectorVTInfo _,
220                                   dag Outs, dag Ins,
221                                   string OpcodeStr,
222                                   string AttSrcAsm, string IntelSrcAsm,
223                                   list<dag> Pattern> :
224    AVX512_maskable_custom<O, F, Outs, Ins,
225                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
226                           !con((ins _.KRCWM:$mask), Ins),
227                           OpcodeStr, AttSrcAsm, IntelSrcAsm, Pattern, [], [],
228                           "$src0 = $dst">;
229
230 // Bitcasts between 512-bit vector types. Return the original type since
231 // no instruction is needed for the conversion
232 let Predicates = [HasAVX512] in {
233   def : Pat<(v8f64  (bitconvert (v8i64 VR512:$src))),  (v8f64 VR512:$src)>;
234   def : Pat<(v8f64  (bitconvert (v16i32 VR512:$src))), (v8f64 VR512:$src)>;
235   def : Pat<(v8f64  (bitconvert (v32i16 VR512:$src))),  (v8f64 VR512:$src)>;
236   def : Pat<(v8f64  (bitconvert (v64i8 VR512:$src))), (v8f64 VR512:$src)>;
237   def : Pat<(v8f64  (bitconvert (v16f32 VR512:$src))), (v8f64 VR512:$src)>;
238   def : Pat<(v16f32 (bitconvert (v8i64 VR512:$src))),  (v16f32 VR512:$src)>;
239   def : Pat<(v16f32 (bitconvert (v16i32 VR512:$src))), (v16f32 VR512:$src)>;
240   def : Pat<(v16f32 (bitconvert (v32i16 VR512:$src))), (v16f32 VR512:$src)>;
241   def : Pat<(v16f32 (bitconvert (v64i8 VR512:$src))), (v16f32 VR512:$src)>;
242   def : Pat<(v16f32 (bitconvert (v8f64 VR512:$src))),  (v16f32 VR512:$src)>;
243   def : Pat<(v8i64  (bitconvert (v16i32 VR512:$src))), (v8i64 VR512:$src)>;
244   def : Pat<(v8i64  (bitconvert (v32i16 VR512:$src))), (v8i64 VR512:$src)>;
245   def : Pat<(v8i64  (bitconvert (v64i8 VR512:$src))), (v8i64 VR512:$src)>;
246   def : Pat<(v8i64  (bitconvert (v8f64 VR512:$src))),  (v8i64 VR512:$src)>;
247   def : Pat<(v8i64  (bitconvert (v16f32 VR512:$src))), (v8i64 VR512:$src)>;
248   def : Pat<(v16i32 (bitconvert (v8i64 VR512:$src))), (v16i32 VR512:$src)>;
249   def : Pat<(v16i32 (bitconvert (v16f32 VR512:$src))), (v16i32 VR512:$src)>;
250   def : Pat<(v16i32 (bitconvert (v32i16 VR512:$src))),  (v16i32 VR512:$src)>;
251   def : Pat<(v16i32 (bitconvert (v64i8 VR512:$src))),  (v16i32 VR512:$src)>;
252   def : Pat<(v16i32 (bitconvert (v8f64 VR512:$src))),  (v16i32 VR512:$src)>;
253   def : Pat<(v32i16 (bitconvert (v8i64 VR512:$src))), (v32i16 VR512:$src)>;
254   def : Pat<(v32i16 (bitconvert (v16i32 VR512:$src))),  (v32i16 VR512:$src)>;
255   def : Pat<(v32i16 (bitconvert (v64i8 VR512:$src))),  (v32i16 VR512:$src)>;
256   def : Pat<(v32i16 (bitconvert (v8f64 VR512:$src))),  (v32i16 VR512:$src)>;
257   def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
258   def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
259   def : Pat<(v64i8  (bitconvert (v8i64 VR512:$src))), (v64i8 VR512:$src)>;
260   def : Pat<(v64i8  (bitconvert (v16i32 VR512:$src))), (v64i8 VR512:$src)>;
261   def : Pat<(v64i8  (bitconvert (v32i16 VR512:$src))), (v64i8 VR512:$src)>;
262   def : Pat<(v64i8  (bitconvert (v8f64 VR512:$src))),  (v64i8 VR512:$src)>;
263   def : Pat<(v64i8  (bitconvert (v16f32 VR512:$src))), (v64i8 VR512:$src)>;
264
265   def : Pat<(v2i64 (bitconvert (v4i32 VR128X:$src))), (v2i64 VR128X:$src)>;
266   def : Pat<(v2i64 (bitconvert (v8i16 VR128X:$src))), (v2i64 VR128X:$src)>;
267   def : Pat<(v2i64 (bitconvert (v16i8 VR128X:$src))), (v2i64 VR128X:$src)>;
268   def : Pat<(v2i64 (bitconvert (v2f64 VR128X:$src))), (v2i64 VR128X:$src)>;
269   def : Pat<(v2i64 (bitconvert (v4f32 VR128X:$src))), (v2i64 VR128X:$src)>;
270   def : Pat<(v4i32 (bitconvert (v2i64 VR128X:$src))), (v4i32 VR128X:$src)>;
271   def : Pat<(v4i32 (bitconvert (v8i16 VR128X:$src))), (v4i32 VR128X:$src)>;
272   def : Pat<(v4i32 (bitconvert (v16i8 VR128X:$src))), (v4i32 VR128X:$src)>;
273   def : Pat<(v4i32 (bitconvert (v2f64 VR128X:$src))), (v4i32 VR128X:$src)>;
274   def : Pat<(v4i32 (bitconvert (v4f32 VR128X:$src))), (v4i32 VR128X:$src)>;
275   def : Pat<(v8i16 (bitconvert (v2i64 VR128X:$src))), (v8i16 VR128X:$src)>;
276   def : Pat<(v8i16 (bitconvert (v4i32 VR128X:$src))), (v8i16 VR128X:$src)>;
277   def : Pat<(v8i16 (bitconvert (v16i8 VR128X:$src))), (v8i16 VR128X:$src)>;
278   def : Pat<(v8i16 (bitconvert (v2f64 VR128X:$src))), (v8i16 VR128X:$src)>;
279   def : Pat<(v8i16 (bitconvert (v4f32 VR128X:$src))), (v8i16 VR128X:$src)>;
280   def : Pat<(v16i8 (bitconvert (v2i64 VR128X:$src))), (v16i8 VR128X:$src)>;
281   def : Pat<(v16i8 (bitconvert (v4i32 VR128X:$src))), (v16i8 VR128X:$src)>;
282   def : Pat<(v16i8 (bitconvert (v8i16 VR128X:$src))), (v16i8 VR128X:$src)>;
283   def : Pat<(v16i8 (bitconvert (v2f64 VR128X:$src))), (v16i8 VR128X:$src)>;
284   def : Pat<(v16i8 (bitconvert (v4f32 VR128X:$src))), (v16i8 VR128X:$src)>;
285   def : Pat<(v4f32 (bitconvert (v2i64 VR128X:$src))), (v4f32 VR128X:$src)>;
286   def : Pat<(v4f32 (bitconvert (v4i32 VR128X:$src))), (v4f32 VR128X:$src)>;
287   def : Pat<(v4f32 (bitconvert (v8i16 VR128X:$src))), (v4f32 VR128X:$src)>;
288   def : Pat<(v4f32 (bitconvert (v16i8 VR128X:$src))), (v4f32 VR128X:$src)>;
289   def : Pat<(v4f32 (bitconvert (v2f64 VR128X:$src))), (v4f32 VR128X:$src)>;
290   def : Pat<(v2f64 (bitconvert (v2i64 VR128X:$src))), (v2f64 VR128X:$src)>;
291   def : Pat<(v2f64 (bitconvert (v4i32 VR128X:$src))), (v2f64 VR128X:$src)>;
292   def : Pat<(v2f64 (bitconvert (v8i16 VR128X:$src))), (v2f64 VR128X:$src)>;
293   def : Pat<(v2f64 (bitconvert (v16i8 VR128X:$src))), (v2f64 VR128X:$src)>;
294   def : Pat<(v2f64 (bitconvert (v4f32 VR128X:$src))), (v2f64 VR128X:$src)>;
295
296 // Bitcasts between 256-bit vector types. Return the original type since
297 // no instruction is needed for the conversion
298   def : Pat<(v4f64  (bitconvert (v8f32 VR256X:$src))),  (v4f64 VR256X:$src)>;
299   def : Pat<(v4f64  (bitconvert (v8i32 VR256X:$src))),  (v4f64 VR256X:$src)>;
300   def : Pat<(v4f64  (bitconvert (v4i64 VR256X:$src))),  (v4f64 VR256X:$src)>;
301   def : Pat<(v4f64  (bitconvert (v16i16 VR256X:$src))), (v4f64 VR256X:$src)>;
302   def : Pat<(v4f64  (bitconvert (v32i8 VR256X:$src))),  (v4f64 VR256X:$src)>;
303   def : Pat<(v8f32  (bitconvert (v8i32 VR256X:$src))),  (v8f32 VR256X:$src)>;
304   def : Pat<(v8f32  (bitconvert (v4i64 VR256X:$src))),  (v8f32 VR256X:$src)>;
305   def : Pat<(v8f32  (bitconvert (v4f64 VR256X:$src))),  (v8f32 VR256X:$src)>;
306   def : Pat<(v8f32  (bitconvert (v32i8 VR256X:$src))),  (v8f32 VR256X:$src)>;
307   def : Pat<(v8f32  (bitconvert (v16i16 VR256X:$src))), (v8f32 VR256X:$src)>;
308   def : Pat<(v4i64  (bitconvert (v8f32 VR256X:$src))),  (v4i64 VR256X:$src)>;
309   def : Pat<(v4i64  (bitconvert (v8i32 VR256X:$src))),  (v4i64 VR256X:$src)>;
310   def : Pat<(v4i64  (bitconvert (v4f64 VR256X:$src))),  (v4i64 VR256X:$src)>;
311   def : Pat<(v4i64  (bitconvert (v32i8 VR256X:$src))),  (v4i64 VR256X:$src)>;
312   def : Pat<(v4i64  (bitconvert (v16i16 VR256X:$src))), (v4i64 VR256X:$src)>;
313   def : Pat<(v32i8  (bitconvert (v4f64 VR256X:$src))),  (v32i8 VR256X:$src)>;
314   def : Pat<(v32i8  (bitconvert (v4i64 VR256X:$src))),  (v32i8 VR256X:$src)>;
315   def : Pat<(v32i8  (bitconvert (v8f32 VR256X:$src))),  (v32i8 VR256X:$src)>;
316   def : Pat<(v32i8  (bitconvert (v8i32 VR256X:$src))),  (v32i8 VR256X:$src)>;
317   def : Pat<(v32i8  (bitconvert (v16i16 VR256X:$src))), (v32i8 VR256X:$src)>;
318   def : Pat<(v8i32  (bitconvert (v32i8 VR256X:$src))),  (v8i32 VR256X:$src)>;
319   def : Pat<(v8i32  (bitconvert (v16i16 VR256X:$src))), (v8i32 VR256X:$src)>;
320   def : Pat<(v8i32  (bitconvert (v8f32 VR256X:$src))),  (v8i32 VR256X:$src)>;
321   def : Pat<(v8i32  (bitconvert (v4i64 VR256X:$src))),  (v8i32 VR256X:$src)>;
322   def : Pat<(v8i32  (bitconvert (v4f64 VR256X:$src))),  (v8i32 VR256X:$src)>;
323   def : Pat<(v16i16 (bitconvert (v8f32 VR256X:$src))),  (v16i16 VR256X:$src)>;
324   def : Pat<(v16i16 (bitconvert (v8i32 VR256X:$src))),  (v16i16 VR256X:$src)>;
325   def : Pat<(v16i16 (bitconvert (v4i64 VR256X:$src))),  (v16i16 VR256X:$src)>;
326   def : Pat<(v16i16 (bitconvert (v4f64 VR256X:$src))),  (v16i16 VR256X:$src)>;
327   def : Pat<(v16i16 (bitconvert (v32i8 VR256X:$src))),  (v16i16 VR256X:$src)>;
328 }
329
330 //
331 // AVX-512: VPXOR instruction writes zero to its upper part, it's safe build zeros.
332 //
333
334 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
335     isPseudo = 1, Predicates = [HasAVX512] in {
336 def AVX512_512_SET0 : I<0, Pseudo, (outs VR512:$dst), (ins), "",
337                [(set VR512:$dst, (v16f32 immAllZerosV))]>;
338 }
339
340 let Predicates = [HasAVX512] in {
341 def : Pat<(v8i64 immAllZerosV), (AVX512_512_SET0)>;
342 def : Pat<(v16i32 immAllZerosV), (AVX512_512_SET0)>;
343 def : Pat<(v8f64 immAllZerosV), (AVX512_512_SET0)>;
344 }
345
346 //===----------------------------------------------------------------------===//
347 // AVX-512 - VECTOR INSERT
348 //
349
350 multiclass vinsert_for_size_no_alt<int Opcode,
351                                    X86VectorVTInfo From, X86VectorVTInfo To,
352                                    PatFrag vinsert_insert,
353                                    SDNodeXForm INSERT_get_vinsert_imm> {
354   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
355     def rr : AVX512AIi8<Opcode, MRMSrcReg, (outs VR512:$dst),
356                (ins VR512:$src1, From.RC:$src2, i8imm:$src3),
357                "vinsert" # From.EltTypeName # "x" # From.NumElts #
358                                                 "\t{$src3, $src2, $src1, $dst|"
359                                                    "$dst, $src1, $src2, $src3}",
360                [(set To.RC:$dst, (vinsert_insert:$src3 (To.VT VR512:$src1),
361                                                        (From.VT From.RC:$src2),
362                                                        (iPTR imm)))]>,
363              EVEX_4V, EVEX_V512;
364
365     let mayLoad = 1 in
366     def rm : AVX512AIi8<Opcode, MRMSrcMem, (outs VR512:$dst),
367                (ins VR512:$src1, From.MemOp:$src2, i8imm:$src3),
368                "vinsert" # From.EltTypeName # "x" # From.NumElts #
369                                                 "\t{$src3, $src2, $src1, $dst|"
370                                                    "$dst, $src1, $src2, $src3}",
371                []>,
372              EVEX_4V, EVEX_V512, EVEX_CD8<From.EltSize, From.CD8TupleForm>;
373   }
374 }
375
376 multiclass vinsert_for_size<int Opcode,
377                             X86VectorVTInfo From, X86VectorVTInfo To,
378                             X86VectorVTInfo AltFrom, X86VectorVTInfo AltTo,
379                             PatFrag vinsert_insert,
380                             SDNodeXForm INSERT_get_vinsert_imm> :
381   vinsert_for_size_no_alt<Opcode, From, To,
382                           vinsert_insert, INSERT_get_vinsert_imm> {
383   // Codegen pattern with the alternative types, e.g. v2i64 -> v8i64 for
384   // vinserti32x4.  Only add this if 64x2 and friends are not supported
385   // natively via AVX512DQ.
386   let Predicates = [NoDQI] in
387     def : Pat<(vinsert_insert:$ins
388                  (AltTo.VT VR512:$src1), (AltFrom.VT From.RC:$src2), (iPTR imm)),
389               (AltTo.VT (!cast<Instruction>(NAME # From.EltSize # "x4rr")
390                             VR512:$src1, From.RC:$src2,
391                             (INSERT_get_vinsert_imm VR512:$ins)))>;
392 }
393
394 multiclass vinsert_for_type<ValueType EltVT32, int Opcode128,
395                             ValueType EltVT64, int Opcode256> {
396   defm NAME # "32x4" : vinsert_for_size<Opcode128,
397                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
398                                  X86VectorVTInfo<16, EltVT32, VR512>,
399                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
400                                  X86VectorVTInfo< 8, EltVT64, VR512>,
401                                  vinsert128_insert,
402                                  INSERT_get_vinsert128_imm>;
403   let Predicates = [HasDQI] in
404     defm NAME # "64x2" : vinsert_for_size_no_alt<Opcode128,
405                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
406                                  X86VectorVTInfo< 8, EltVT64, VR512>,
407                                  vinsert128_insert,
408                                  INSERT_get_vinsert128_imm>, VEX_W;
409   defm NAME # "64x4" : vinsert_for_size<Opcode256,
410                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
411                                  X86VectorVTInfo< 8, EltVT64, VR512>,
412                                  X86VectorVTInfo< 8, EltVT32, VR256>,
413                                  X86VectorVTInfo<16, EltVT32, VR512>,
414                                  vinsert256_insert,
415                                  INSERT_get_vinsert256_imm>, VEX_W;
416   let Predicates = [HasDQI] in
417     defm NAME # "32x8" : vinsert_for_size_no_alt<Opcode256,
418                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
419                                  X86VectorVTInfo<16, EltVT32, VR512>,
420                                  vinsert256_insert,
421                                  INSERT_get_vinsert256_imm>;
422 }
423
424 defm VINSERTF : vinsert_for_type<f32, 0x18, f64, 0x1a>;
425 defm VINSERTI : vinsert_for_type<i32, 0x38, i64, 0x3a>;
426
427 // vinsertps - insert f32 to XMM
428 def VINSERTPSzrr : AVX512AIi8<0x21, MRMSrcReg, (outs VR128X:$dst),
429       (ins VR128X:$src1, VR128X:$src2, i8imm:$src3),
430       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
431       [(set VR128X:$dst, (X86insertps VR128X:$src1, VR128X:$src2, imm:$src3))]>,
432       EVEX_4V;
433 def VINSERTPSzrm: AVX512AIi8<0x21, MRMSrcMem, (outs VR128X:$dst),
434       (ins VR128X:$src1, f32mem:$src2, i8imm:$src3),
435       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
436       [(set VR128X:$dst, (X86insertps VR128X:$src1,
437                           (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
438                           imm:$src3))]>, EVEX_4V, EVEX_CD8<32, CD8VT1>;
439
440 //===----------------------------------------------------------------------===//
441 // AVX-512 VECTOR EXTRACT
442 //---
443
444 multiclass vextract_for_size<int Opcode,
445                              X86VectorVTInfo From, X86VectorVTInfo To,
446                              X86VectorVTInfo AltFrom, X86VectorVTInfo AltTo,
447                              PatFrag vextract_extract,
448                              SDNodeXForm EXTRACT_get_vextract_imm> {
449   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
450     defm rr : AVX512_maskable_in_asm<Opcode, MRMDestReg, To, (outs To.RC:$dst),
451                 (ins VR512:$src1, i8imm:$idx),
452                 "vextract" # To.EltTypeName # "x4",
453                 "$idx, $src1", "$src1, $idx",
454                 [(set To.RC:$dst, (vextract_extract:$idx (From.VT VR512:$src1),
455                                                          (iPTR imm)))]>,
456               AVX512AIi8Base, EVEX, EVEX_V512;
457     let mayStore = 1 in
458     def rm : AVX512AIi8<Opcode, MRMDestMem, (outs),
459             (ins To.MemOp:$dst, VR512:$src1, i8imm:$src2),
460             "vextract" # To.EltTypeName # "x4\t{$src2, $src1, $dst|"
461                                                "$dst, $src1, $src2}",
462             []>, EVEX, EVEX_V512, EVEX_CD8<To.EltSize, CD8VT4>;
463   }
464
465   // Codegen pattern with the alternative types, e.g. v8i64 -> v2i64 for
466   // vextracti32x4
467   def : Pat<(vextract_extract:$ext (AltFrom.VT VR512:$src1), (iPTR imm)),
468             (AltTo.VT (!cast<Instruction>(NAME # To.EltSize # "x4rr")
469                           VR512:$src1,
470                           (EXTRACT_get_vextract_imm To.RC:$ext)))>;
471
472   // A 128/256-bit subvector extract from the first 512-bit vector position is
473   // a subregister copy that needs no instruction.
474   def : Pat<(To.VT (extract_subvector (From.VT VR512:$src), (iPTR 0))),
475             (To.VT
476                (EXTRACT_SUBREG (From.VT VR512:$src), To.SubRegIdx))>;
477
478   // And for the alternative types.
479   def : Pat<(AltTo.VT (extract_subvector (AltFrom.VT VR512:$src), (iPTR 0))),
480             (AltTo.VT
481                (EXTRACT_SUBREG (AltFrom.VT VR512:$src), AltTo.SubRegIdx))>;
482
483   // Intrinsic call with masking.
484   def : Pat<(!cast<Intrinsic>("int_x86_avx512_mask_vextract" # To.EltTypeName #
485                               "x4_512")
486                 VR512:$src1, (iPTR imm:$idx), To.RC:$src0, GR8:$mask),
487             (!cast<Instruction>(NAME # To.EltSize # "x4rrk") To.RC:$src0,
488                 (v4i1 (COPY_TO_REGCLASS GR8:$mask, VK4WM)),
489                 VR512:$src1, imm:$idx)>;
490
491   // Intrinsic call with zero-masking.
492   def : Pat<(!cast<Intrinsic>("int_x86_avx512_mask_vextract" # To.EltTypeName #
493                               "x4_512")
494                 VR512:$src1, (iPTR imm:$idx), To.ImmAllZerosV, GR8:$mask),
495             (!cast<Instruction>(NAME # To.EltSize # "x4rrkz")
496                 (v4i1 (COPY_TO_REGCLASS GR8:$mask, VK4WM)),
497                 VR512:$src1, imm:$idx)>;
498
499   // Intrinsic call without masking.
500   def : Pat<(!cast<Intrinsic>("int_x86_avx512_mask_vextract" # To.EltTypeName #
501                               "x4_512")
502                 VR512:$src1, (iPTR imm:$idx), To.ImmAllZerosV, (i8 -1)),
503             (!cast<Instruction>(NAME # To.EltSize # "x4rr")
504                 VR512:$src1, imm:$idx)>;
505 }
506
507 multiclass vextract_for_type<ValueType EltVT32, int Opcode32,
508                              ValueType EltVT64, int Opcode64> {
509   defm NAME # "32x4" : vextract_for_size<Opcode32,
510                                  X86VectorVTInfo<16, EltVT32, VR512>,
511                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
512                                  X86VectorVTInfo< 8, EltVT64, VR512>,
513                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
514                                  vextract128_extract,
515                                  EXTRACT_get_vextract128_imm>;
516   defm NAME # "64x4" : vextract_for_size<Opcode64,
517                                  X86VectorVTInfo< 8, EltVT64, VR512>,
518                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
519                                  X86VectorVTInfo<16, EltVT32, VR512>,
520                                  X86VectorVTInfo< 8, EltVT32, VR256>,
521                                  vextract256_extract,
522                                  EXTRACT_get_vextract256_imm>, VEX_W;
523 }
524
525 defm VEXTRACTF : vextract_for_type<f32, 0x19, f64, 0x1b>;
526 defm VEXTRACTI : vextract_for_type<i32, 0x39, i64, 0x3b>;
527
528 // A 128-bit subvector insert to the first 512-bit vector position
529 // is a subregister copy that needs no instruction.
530 def : Pat<(insert_subvector undef, (v2i64 VR128X:$src), (iPTR 0)),
531           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)),
532           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
533           sub_ymm)>;
534 def : Pat<(insert_subvector undef, (v2f64 VR128X:$src), (iPTR 0)),
535           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)),
536           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
537           sub_ymm)>;
538 def : Pat<(insert_subvector undef, (v4i32 VR128X:$src), (iPTR 0)),
539           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
540           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
541           sub_ymm)>;
542 def : Pat<(insert_subvector undef, (v4f32 VR128X:$src), (iPTR 0)),
543           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
544           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
545           sub_ymm)>;
546
547 def : Pat<(insert_subvector undef, (v4i64 VR256X:$src), (iPTR 0)),
548           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
549 def : Pat<(insert_subvector undef, (v4f64 VR256X:$src), (iPTR 0)),
550           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
551 def : Pat<(insert_subvector undef, (v8i32 VR256X:$src), (iPTR 0)),
552           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
553 def : Pat<(insert_subvector undef, (v8f32 VR256X:$src), (iPTR 0)),
554           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
555
556 // vextractps - extract 32 bits from XMM
557 def VEXTRACTPSzrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32:$dst),
558       (ins VR128X:$src1, i32i8imm:$src2),
559       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
560       [(set GR32:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
561       EVEX;
562
563 def VEXTRACTPSzmr : AVX512AIi8<0x17, MRMDestMem, (outs),
564       (ins f32mem:$dst, VR128X:$src1, i32i8imm:$src2),
565       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
566       [(store (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2),
567                           addr:$dst)]>, EVEX, EVEX_CD8<32, CD8VT1>;
568
569 //===---------------------------------------------------------------------===//
570 // AVX-512 BROADCAST
571 //---
572 multiclass avx512_fp_broadcast<bits<8> opc, string OpcodeStr, 
573                          RegisterClass DestRC,
574                          RegisterClass SrcRC, X86MemOperand x86memop> {
575   def rr : AVX5128I<opc, MRMSrcReg, (outs DestRC:$dst), (ins SrcRC:$src),
576          !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
577          []>, EVEX;
578   def rm : AVX5128I<opc, MRMSrcMem, (outs DestRC:$dst), (ins x86memop:$src),
579         !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),[]>, EVEX;
580 }
581 let ExeDomain = SSEPackedSingle in {
582   defm VBROADCASTSSZ  : avx512_fp_broadcast<0x18, "vbroadcastss", VR512,
583                                        VR128X, f32mem>,
584                                        EVEX_V512, EVEX_CD8<32, CD8VT1>;
585 }
586
587 let ExeDomain = SSEPackedDouble in {
588   defm VBROADCASTSDZ  : avx512_fp_broadcast<0x19, "vbroadcastsd", VR512,
589                                        VR128X, f64mem>,
590                                        EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
591 }
592
593 def : Pat<(v16f32 (X86VBroadcast (loadf32 addr:$src))),
594           (VBROADCASTSSZrm addr:$src)>;
595 def : Pat<(v8f64 (X86VBroadcast (loadf64 addr:$src))),
596           (VBROADCASTSDZrm addr:$src)>;
597
598 def : Pat<(int_x86_avx512_vbroadcast_ss_512 addr:$src),
599           (VBROADCASTSSZrm addr:$src)>;
600 def : Pat<(int_x86_avx512_vbroadcast_sd_512 addr:$src),
601           (VBROADCASTSDZrm addr:$src)>;
602
603 multiclass avx512_int_broadcast_reg<bits<8> opc, string OpcodeStr,
604                           RegisterClass SrcRC, RegisterClass KRC> {
605   def Zrr : AVX5128I<opc, MRMSrcReg, (outs VR512:$dst), (ins SrcRC:$src),
606                    !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
607                    []>, EVEX, EVEX_V512;
608   def Zkrr : AVX5128I<opc, MRMSrcReg, (outs VR512:$dst), 
609                    (ins KRC:$mask, SrcRC:$src),
610                    !strconcat(OpcodeStr, 
611                         " \t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}"),
612                    []>, EVEX, EVEX_V512, EVEX_KZ;
613 }
614
615 defm VPBROADCASTDr  : avx512_int_broadcast_reg<0x7C, "vpbroadcastd", GR32, VK16WM>;
616 defm VPBROADCASTQr  : avx512_int_broadcast_reg<0x7C, "vpbroadcastq", GR64, VK8WM>,
617                                             VEX_W;
618                                             
619 def : Pat <(v16i32 (X86vzext VK16WM:$mask)),
620            (VPBROADCASTDrZkrr VK16WM:$mask, (i32 (MOV32ri 0x1)))>;
621
622 def : Pat <(v8i64 (X86vzext VK8WM:$mask)),
623            (VPBROADCASTQrZkrr VK8WM:$mask, (i64 (MOV64ri 0x1)))>;
624
625 def : Pat<(v16i32 (X86VBroadcast (i32 GR32:$src))),
626         (VPBROADCASTDrZrr GR32:$src)>;
627 def : Pat<(v16i32 (X86VBroadcastm VK16WM:$mask, (i32 GR32:$src))),
628         (VPBROADCASTDrZkrr VK16WM:$mask, GR32:$src)>;
629 def : Pat<(v8i64 (X86VBroadcast (i64 GR64:$src))),
630         (VPBROADCASTQrZrr GR64:$src)>;
631 def : Pat<(v8i64 (X86VBroadcastm VK8WM:$mask, (i64 GR64:$src))),
632         (VPBROADCASTQrZkrr VK8WM:$mask, GR64:$src)>;
633
634 def : Pat<(v16i32 (int_x86_avx512_pbroadcastd_i32_512 (i32 GR32:$src))),
635         (VPBROADCASTDrZrr GR32:$src)>;
636 def : Pat<(v8i64 (int_x86_avx512_pbroadcastq_i64_512 (i64 GR64:$src))),
637         (VPBROADCASTQrZrr GR64:$src)>;
638
639 def : Pat<(v16i32 (int_x86_avx512_mask_pbroadcast_d_gpr_512 (i32 GR32:$src),
640                    (v16i32 immAllZerosV), (i16 GR16:$mask))),
641           (VPBROADCASTDrZkrr (COPY_TO_REGCLASS GR16:$mask, VK16WM), GR32:$src)>;
642 def : Pat<(v8i64 (int_x86_avx512_mask_pbroadcast_q_gpr_512 (i64 GR64:$src),
643                    (bc_v8i64 (v16i32 immAllZerosV)), (i8 GR8:$mask))),
644           (VPBROADCASTQrZkrr (COPY_TO_REGCLASS GR8:$mask, VK8WM), GR64:$src)>;
645
646 multiclass avx512_int_broadcast_rm<bits<8> opc, string OpcodeStr,
647                           X86MemOperand x86memop, PatFrag ld_frag,
648                           RegisterClass DstRC, ValueType OpVT, ValueType SrcVT,
649                           RegisterClass KRC> {
650   def rr : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins VR128X:$src),
651                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
652                   [(set DstRC:$dst,
653                     (OpVT (X86VBroadcast (SrcVT VR128X:$src))))]>, EVEX;
654   def krr : AVX5128I<opc, MRMSrcReg, (outs DstRC:$dst), (ins KRC:$mask,
655                                                          VR128X:$src),
656                     !strconcat(OpcodeStr, 
657                     " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
658                     [(set DstRC:$dst,
659                       (OpVT (X86VBroadcastm KRC:$mask, (SrcVT VR128X:$src))))]>,
660                     EVEX, EVEX_KZ;
661   let mayLoad = 1 in {
662   def rm : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
663                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
664                   [(set DstRC:$dst, 
665                     (OpVT (X86VBroadcast (ld_frag addr:$src))))]>, EVEX;
666   def krm : AVX5128I<opc, MRMSrcMem, (outs DstRC:$dst), (ins KRC:$mask,
667                                                          x86memop:$src),
668                   !strconcat(OpcodeStr, 
669                       " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
670                   [(set DstRC:$dst, (OpVT (X86VBroadcastm KRC:$mask, 
671                                      (ld_frag addr:$src))))]>, EVEX, EVEX_KZ;
672   }
673 }
674
675 defm VPBROADCASTDZ  : avx512_int_broadcast_rm<0x58, "vpbroadcastd", i32mem,
676                       loadi32, VR512, v16i32, v4i32, VK16WM>,
677                       EVEX_V512, EVEX_CD8<32, CD8VT1>;
678 defm VPBROADCASTQZ  : avx512_int_broadcast_rm<0x59, "vpbroadcastq", i64mem,
679                       loadi64, VR512, v8i64, v2i64, VK8WM>,  EVEX_V512, VEX_W,
680                       EVEX_CD8<64, CD8VT1>;
681
682 multiclass avx512_int_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
683                           X86MemOperand x86memop, PatFrag ld_frag,
684                           RegisterClass KRC> {
685   let mayLoad = 1 in {
686   def rm : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst), (ins x86memop:$src),
687                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
688                   []>, EVEX;
689   def krm : AVX5128I<opc, MRMSrcMem, (outs VR512:$dst), (ins KRC:$mask,
690                                                          x86memop:$src),
691                   !strconcat(OpcodeStr,
692                       " \t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
693                   []>, EVEX, EVEX_KZ;
694   }
695 }
696
697 defm VBROADCASTI32X4 : avx512_int_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
698                        i128mem, loadv2i64, VK16WM>,
699                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
700 defm VBROADCASTI64X4 : avx512_int_subvec_broadcast_rm<0x5b, "vbroadcasti64x4",
701                        i256mem, loadv4i64, VK16WM>, VEX_W,
702                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
703
704 def : Pat<(v16i32 (int_x86_avx512_pbroadcastd_512 (v4i32 VR128X:$src))),
705           (VPBROADCASTDZrr VR128X:$src)>;
706 def : Pat<(v8i64 (int_x86_avx512_pbroadcastq_512 (v2i64 VR128X:$src))),
707           (VPBROADCASTQZrr VR128X:$src)>;
708
709 def : Pat<(v16f32 (X86VBroadcast (v4f32 VR128X:$src))),
710           (VBROADCASTSSZrr VR128X:$src)>;
711 def : Pat<(v8f64 (X86VBroadcast (v2f64 VR128X:$src))),
712           (VBROADCASTSDZrr VR128X:$src)>;
713
714 def : Pat<(v16f32 (int_x86_avx512_vbroadcast_ss_ps_512 (v4f32 VR128X:$src))),
715           (VBROADCASTSSZrr VR128X:$src)>;
716 def : Pat<(v8f64 (int_x86_avx512_vbroadcast_sd_pd_512 (v2f64 VR128X:$src))),
717           (VBROADCASTSDZrr VR128X:$src)>;
718     
719 // Provide fallback in case the load node that is used in the patterns above
720 // is used by additional users, which prevents the pattern selection.
721 def : Pat<(v16f32 (X86VBroadcast FR32X:$src)),
722           (VBROADCASTSSZrr (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
723 def : Pat<(v8f64 (X86VBroadcast FR64X:$src)),
724           (VBROADCASTSDZrr (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
725
726
727 let Predicates = [HasAVX512] in {
728 def : Pat<(v8i32 (X86VBroadcastm (v8i1 VK8WM:$mask), (loadi32 addr:$src))),
729            (EXTRACT_SUBREG 
730               (v16i32 (VPBROADCASTDZkrm (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
731                        addr:$src)), sub_ymm)>;
732 }
733 //===----------------------------------------------------------------------===//
734 // AVX-512 BROADCAST MASK TO VECTOR REGISTER
735 //---
736
737 multiclass avx512_mask_broadcast<bits<8> opc, string OpcodeStr,
738                        RegisterClass KRC> {
739 let Predicates = [HasCDI] in
740 def Zrr : AVX512XS8I<opc, MRMSrcReg, (outs VR512:$dst), (ins KRC:$src),
741                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
742                   []>, EVEX, EVEX_V512;
743                   
744 let Predicates = [HasCDI, HasVLX] in {
745 def Z128rr : AVX512XS8I<opc, MRMSrcReg, (outs VR128:$dst), (ins KRC:$src),
746                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
747                   []>, EVEX, EVEX_V128;
748 def Z256rr : AVX512XS8I<opc, MRMSrcReg, (outs VR256:$dst), (ins KRC:$src),
749                   !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
750                   []>, EVEX, EVEX_V256;
751 }
752 }
753
754 let Predicates = [HasCDI] in {
755 defm VPBROADCASTMW2D : avx512_mask_broadcast<0x3A, "vpbroadcastmw2d",
756                                              VK16>;
757 defm VPBROADCASTMB2Q : avx512_mask_broadcast<0x2A, "vpbroadcastmb2q",
758                                              VK8>, VEX_W;
759 }
760
761 //===----------------------------------------------------------------------===//
762 // AVX-512 - VPERM
763 //
764 // -- immediate form --
765 multiclass avx512_perm_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
766                            X86VectorVTInfo _> {
767   let ExeDomain = _.ExeDomain in {
768   def ri : AVX512AIi8<opc, MRMSrcReg, (outs _.RC:$dst),
769                      (ins _.RC:$src1, i8imm:$src2),
770                      !strconcat(OpcodeStr,
771                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
772                      [(set _.RC:$dst,
773                        (_.VT (OpNode _.RC:$src1, (i8 imm:$src2))))]>,
774                      EVEX;
775   def mi : AVX512AIi8<opc, MRMSrcMem, (outs _.RC:$dst),
776                      (ins _.MemOp:$src1, i8imm:$src2),
777                      !strconcat(OpcodeStr,
778                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
779                      [(set _.RC:$dst,
780                        (_.VT (OpNode (_.MemOpFrag addr:$src1),
781                               (i8 imm:$src2))))]>,
782            EVEX, EVEX_CD8<_.EltSize, CD8VF>;
783 }
784 }
785
786 multiclass avx512_permil<bits<8> OpcImm, bits<8> OpcVar, X86VectorVTInfo _,
787                          X86VectorVTInfo Ctrl> :
788      avx512_perm_imm<OpcImm, "vpermil" # _.Suffix, X86VPermilpi, _> {
789   let ExeDomain = _.ExeDomain in {
790     def rr : AVX5128I<OpcVar, MRMSrcReg, (outs _.RC:$dst),
791                      (ins _.RC:$src1, _.RC:$src2),
792                      !strconcat("vpermil" # _.Suffix,
793                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
794                      [(set _.RC:$dst,
795                          (_.VT (X86VPermilpv _.RC:$src1,
796                                   (Ctrl.VT Ctrl.RC:$src2))))]>,
797              EVEX_4V;
798     def rm : AVX5128I<OpcVar, MRMSrcMem, (outs _.RC:$dst),
799                      (ins _.RC:$src1, Ctrl.MemOp:$src2),
800                      !strconcat("vpermil" # _.Suffix,
801                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
802                      [(set _.RC:$dst,
803                          (_.VT (X86VPermilpv _.RC:$src1,
804                                   (Ctrl.VT (Ctrl.MemOpFrag addr:$src2)))))]>,
805              EVEX_4V;
806   }
807 }
808
809 defm VPERMQZ :    avx512_perm_imm<0x00, "vpermq", X86VPermi, v8i64_info>,
810                   EVEX_V512, VEX_W;
811 defm VPERMPDZ :   avx512_perm_imm<0x01, "vpermpd", X86VPermi, v8f64_info>,
812                   EVEX_V512, VEX_W;
813
814 defm VPERMILPSZ : avx512_permil<0x04, 0x0C, v16f32_info, v16i32_info>,
815                   EVEX_V512;
816 defm VPERMILPDZ : avx512_permil<0x05, 0x0D, v8f64_info, v8i64_info>,
817                   EVEX_V512, VEX_W;
818
819 def : Pat<(v16i32 (X86VPermilpi VR512:$src1, (i8 imm:$imm))),
820           (VPERMILPSZri VR512:$src1, imm:$imm)>;
821 def : Pat<(v8i64 (X86VPermilpi VR512:$src1, (i8 imm:$imm))),
822           (VPERMILPDZri VR512:$src1, imm:$imm)>;
823
824 // -- VPERM - register form --
825 multiclass avx512_perm<bits<8> opc, string OpcodeStr, RegisterClass RC, 
826                      PatFrag mem_frag, X86MemOperand x86memop, ValueType OpVT> {
827
828   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
829                    (ins RC:$src1, RC:$src2),
830                    !strconcat(OpcodeStr,
831                        " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
832                    [(set RC:$dst,
833                      (OpVT (X86VPermv RC:$src1, RC:$src2)))]>, EVEX_4V;
834
835   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
836                    (ins RC:$src1, x86memop:$src2),
837                    !strconcat(OpcodeStr,
838                        " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
839                    [(set RC:$dst,
840                      (OpVT (X86VPermv RC:$src1, (mem_frag addr:$src2))))]>,
841                      EVEX_4V;
842 }
843
844 defm VPERMDZ   : avx512_perm<0x36, "vpermd",  VR512,  memopv16i32, i512mem,
845                            v16i32>, EVEX_V512, EVEX_CD8<32, CD8VF>;
846 defm VPERMQZ   : avx512_perm<0x36, "vpermq",  VR512,  memopv8i64,  i512mem, 
847                            v8i64>,  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
848 let ExeDomain = SSEPackedSingle in
849 defm VPERMPSZ  : avx512_perm<0x16, "vpermps", VR512,  memopv16f32, f512mem,
850                            v16f32>, EVEX_V512, EVEX_CD8<32, CD8VF>;
851 let ExeDomain = SSEPackedDouble in
852 defm VPERMPDZ  : avx512_perm<0x16, "vpermpd", VR512,  memopv8f64, f512mem, 
853                            v8f64>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
854
855 // -- VPERM2I - 3 source operands form --
856 multiclass avx512_perm_3src<bits<8> opc, string OpcodeStr, RegisterClass RC,
857                           PatFrag mem_frag, X86MemOperand x86memop,
858                           SDNode OpNode, ValueType OpVT, RegisterClass KRC> {
859 let Constraints = "$src1 = $dst" in {
860   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
861                    (ins RC:$src1, RC:$src2, RC:$src3),
862                    !strconcat(OpcodeStr,
863                        " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
864                    [(set RC:$dst,
865                      (OpVT (OpNode RC:$src1, RC:$src2, RC:$src3)))]>,
866                     EVEX_4V;
867
868   def rrk : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
869                    (ins RC:$src1, KRC:$mask, RC:$src2, RC:$src3),
870                    !strconcat(OpcodeStr,
871                        " \t{$src3, $src2, $dst {${mask}}|"
872                        "$dst {${mask}}, $src2, $src3}"),
873                    [(set RC:$dst, (OpVT (vselect KRC:$mask,
874                                            (OpNode RC:$src1, RC:$src2,
875                                               RC:$src3),
876                                            RC:$src1)))]>,
877                     EVEX_4V, EVEX_K;
878
879   let AddedComplexity = 30 in // Prefer over VMOV*rrkz Pat<>
880     def rrkz : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
881                    (ins RC:$src1, KRC:$mask, RC:$src2, RC:$src3),
882                    !strconcat(OpcodeStr,
883                        " \t{$src3, $src2, $dst {${mask}} {z} |",
884                        "$dst {${mask}} {z}, $src2, $src3}"),
885                    [(set RC:$dst, (OpVT (vselect KRC:$mask,
886                                            (OpNode RC:$src1, RC:$src2,
887                                               RC:$src3),
888                                            (OpVT (bitconvert
889                                               (v16i32 immAllZerosV))))))]>,
890                     EVEX_4V, EVEX_KZ;
891
892   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
893                    (ins RC:$src1, RC:$src2, x86memop:$src3),
894                    !strconcat(OpcodeStr,
895                     " \t{$src3, $src2, $dst|$dst, $src2, $src3}"),
896                    [(set RC:$dst,
897                      (OpVT (OpNode RC:$src1, RC:$src2,
898                       (mem_frag addr:$src3))))]>, EVEX_4V;
899
900   def rmk : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
901                    (ins RC:$src1, KRC:$mask, RC:$src2, x86memop:$src3),
902                    !strconcat(OpcodeStr,
903                     " \t{$src3, $src2, $dst {${mask}}|"
904                     "$dst {${mask}}, $src2, $src3}"),
905                    [(set RC:$dst,
906                        (OpVT (vselect KRC:$mask,
907                                       (OpNode RC:$src1, RC:$src2,
908                                          (mem_frag addr:$src3)),
909                                       RC:$src1)))]>,
910                     EVEX_4V, EVEX_K;
911
912   let AddedComplexity = 10 in // Prefer over the rrkz variant
913     def rmkz : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
914                    (ins RC:$src1, KRC:$mask, RC:$src2, x86memop:$src3),
915                    !strconcat(OpcodeStr,
916                     " \t{$src3, $src2, $dst {${mask}} {z}|"
917                     "$dst {${mask}} {z}, $src2, $src3}"),
918                    [(set RC:$dst,
919                      (OpVT (vselect KRC:$mask,
920                                     (OpNode RC:$src1, RC:$src2,
921                                             (mem_frag addr:$src3)),
922                                     (OpVT (bitconvert
923                                        (v16i32 immAllZerosV))))))]>,
924                     EVEX_4V, EVEX_KZ;
925   }
926 }
927 defm VPERMI2D  : avx512_perm_3src<0x76, "vpermi2d",  VR512, memopv16i32,
928                                   i512mem, X86VPermiv3, v16i32, VK16WM>,
929                  EVEX_V512, EVEX_CD8<32, CD8VF>;
930 defm VPERMI2Q  : avx512_perm_3src<0x76, "vpermi2q",  VR512, memopv8i64,
931                                   i512mem, X86VPermiv3, v8i64, VK8WM>,
932                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
933 defm VPERMI2PS : avx512_perm_3src<0x77, "vpermi2ps",  VR512, memopv16f32,
934                                   i512mem, X86VPermiv3, v16f32, VK16WM>,
935                  EVEX_V512, EVEX_CD8<32, CD8VF>;
936 defm VPERMI2PD : avx512_perm_3src<0x77, "vpermi2pd",  VR512, memopv8f64,
937                                   i512mem, X86VPermiv3, v8f64, VK8WM>,
938                   EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
939
940 multiclass avx512_perm_table_3src<bits<8> opc, string Suffix, RegisterClass RC,
941                           PatFrag mem_frag, X86MemOperand x86memop,
942                           SDNode OpNode, ValueType OpVT, RegisterClass KRC,
943                           ValueType MaskVT, RegisterClass MRC> :
944         avx512_perm_3src<opc, "vpermt2"##Suffix, RC, mem_frag, x86memop, OpNode,
945                          OpVT, KRC> {
946   def : Pat<(OpVT (!cast<Intrinsic>("int_x86_avx512_mask_vpermt_"##Suffix##"_512")
947                      VR512:$idx, VR512:$src1, VR512:$src2, -1)),
948             (!cast<Instruction>(NAME#rr) VR512:$src1, VR512:$idx, VR512:$src2)>;
949
950   def : Pat<(OpVT (!cast<Intrinsic>("int_x86_avx512_mask_vpermt_"##Suffix##"_512")
951                      VR512:$idx, VR512:$src1, VR512:$src2, MRC:$mask)),
952             (!cast<Instruction>(NAME#rrk) VR512:$src1,
953               (MaskVT (COPY_TO_REGCLASS MRC:$mask, KRC)), VR512:$idx, VR512:$src2)>;
954 }
955
956 defm VPERMT2D  : avx512_perm_table_3src<0x7E, "d",  VR512, memopv16i32, i512mem,
957                                X86VPermv3, v16i32, VK16WM, v16i1, GR16>,
958                  EVEX_V512, EVEX_CD8<32, CD8VF>;
959 defm VPERMT2Q  : avx512_perm_table_3src<0x7E, "q",  VR512, memopv8i64, i512mem,
960                                X86VPermv3, v8i64, VK8WM, v8i1, GR8>,
961                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
962 defm VPERMT2PS : avx512_perm_table_3src<0x7F, "ps",  VR512, memopv16f32, i512mem,
963                                X86VPermv3, v16f32, VK16WM, v16i1, GR16>,
964                  EVEX_V512, EVEX_CD8<32, CD8VF>;
965 defm VPERMT2PD : avx512_perm_table_3src<0x7F, "pd",  VR512, memopv8f64, i512mem,
966                                X86VPermv3, v8f64, VK8WM, v8i1, GR8>,
967                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
968
969 //===----------------------------------------------------------------------===//
970 // AVX-512 - BLEND using mask
971 //
972 multiclass avx512_blendmask<bits<8> opc, string OpcodeStr,
973                           RegisterClass KRC, RegisterClass RC,
974                           X86MemOperand x86memop, PatFrag mem_frag,
975                           SDNode OpNode, ValueType vt> {
976   def rr : AVX5128I<opc, MRMSrcReg, (outs RC:$dst),
977              (ins KRC:$mask, RC:$src1, RC:$src2),
978              !strconcat(OpcodeStr,
979              " \t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
980              [(set RC:$dst, (OpNode KRC:$mask, (vt RC:$src2),
981                  (vt RC:$src1)))]>, EVEX_4V, EVEX_K;
982   let mayLoad = 1 in
983   def rm : AVX5128I<opc, MRMSrcMem, (outs RC:$dst),
984              (ins KRC:$mask, RC:$src1, x86memop:$src2),
985              !strconcat(OpcodeStr,
986              " \t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
987              []>, EVEX_4V, EVEX_K;
988 }
989
990 let ExeDomain = SSEPackedSingle in
991 defm VBLENDMPSZ : avx512_blendmask<0x65, "vblendmps", 
992                               VK16WM, VR512, f512mem,
993                               memopv16f32, vselect, v16f32>, 
994                               EVEX_CD8<32, CD8VF>, EVEX_V512;
995 let ExeDomain = SSEPackedDouble in
996 defm VBLENDMPDZ : avx512_blendmask<0x65, "vblendmpd", 
997                               VK8WM, VR512, f512mem,
998                               memopv8f64, vselect, v8f64>, 
999                               VEX_W, EVEX_CD8<64, CD8VF>, EVEX_V512;
1000
1001 def : Pat<(v16f32 (int_x86_avx512_mask_blend_ps_512 (v16f32 VR512:$src1),
1002                  (v16f32 VR512:$src2), (i16 GR16:$mask))),
1003         (VBLENDMPSZrr (COPY_TO_REGCLASS GR16:$mask, VK16WM),
1004          VR512:$src1, VR512:$src2)>;
1005
1006 def : Pat<(v8f64 (int_x86_avx512_mask_blend_pd_512 (v8f64 VR512:$src1),
1007                  (v8f64 VR512:$src2), (i8 GR8:$mask))),
1008         (VBLENDMPDZrr (COPY_TO_REGCLASS GR8:$mask, VK8WM),
1009          VR512:$src1, VR512:$src2)>;
1010
1011 defm VPBLENDMDZ : avx512_blendmask<0x64, "vpblendmd", 
1012                               VK16WM, VR512, f512mem, 
1013                               memopv16i32, vselect, v16i32>, 
1014                               EVEX_CD8<32, CD8VF>, EVEX_V512;
1015
1016 defm VPBLENDMQZ : avx512_blendmask<0x64, "vpblendmq", 
1017                               VK8WM, VR512, f512mem, 
1018                               memopv8i64, vselect, v8i64>, 
1019                               VEX_W, EVEX_CD8<64, CD8VF>, EVEX_V512;
1020
1021 def : Pat<(v16i32 (int_x86_avx512_mask_blend_d_512 (v16i32 VR512:$src1),
1022                  (v16i32 VR512:$src2), (i16 GR16:$mask))),
1023         (VPBLENDMDZrr (COPY_TO_REGCLASS GR16:$mask, VK16),
1024          VR512:$src1, VR512:$src2)>;
1025
1026 def : Pat<(v8i64 (int_x86_avx512_mask_blend_q_512 (v8i64 VR512:$src1),
1027                  (v8i64 VR512:$src2), (i8 GR8:$mask))),
1028         (VPBLENDMQZrr (COPY_TO_REGCLASS GR8:$mask, VK8),
1029          VR512:$src1, VR512:$src2)>;
1030
1031 let Predicates = [HasAVX512] in {
1032 def : Pat<(v8f32 (vselect (v8i1 VK8WM:$mask), (v8f32 VR256X:$src1),
1033                             (v8f32 VR256X:$src2))),
1034             (EXTRACT_SUBREG 
1035               (v16f32 (VBLENDMPSZrr (COPY_TO_REGCLASS VK8WM:$mask, VK16WM), 
1036             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1037             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
1038
1039 def : Pat<(v8i32 (vselect (v8i1 VK8WM:$mask), (v8i32 VR256X:$src1),
1040                             (v8i32 VR256X:$src2))),
1041             (EXTRACT_SUBREG 
1042                 (v16i32 (VPBLENDMDZrr (COPY_TO_REGCLASS VK8WM:$mask, VK16WM), 
1043             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1044             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)))), sub_ymm)>;
1045 }
1046 //===----------------------------------------------------------------------===//
1047 // Compare Instructions
1048 //===----------------------------------------------------------------------===//
1049
1050 // avx512_cmp_scalar - AVX512 CMPSS and CMPSD
1051 multiclass avx512_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
1052                             Operand CC, SDNode OpNode, ValueType VT,
1053                             PatFrag ld_frag, string asm, string asm_alt> {
1054   def rr : AVX512Ii8<0xC2, MRMSrcReg,
1055                 (outs VK1:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
1056                 [(set VK1:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],
1057                 IIC_SSE_ALU_F32S_RR>, EVEX_4V;
1058   def rm : AVX512Ii8<0xC2, MRMSrcMem,
1059                 (outs VK1:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
1060                 [(set VK1:$dst, (OpNode (VT RC:$src1),
1061                 (ld_frag addr:$src2), imm:$cc))], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1062   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1063     def rri_alt : AVX512Ii8<0xC2, MRMSrcReg,
1064                (outs VK1:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
1065                asm_alt, [], IIC_SSE_ALU_F32S_RR>, EVEX_4V;
1066     def rmi_alt : AVX512Ii8<0xC2, MRMSrcMem,
1067                (outs VK1:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
1068                asm_alt, [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1069   }
1070 }
1071
1072 let Predicates = [HasAVX512] in {
1073 defm VCMPSSZ : avx512_cmp_scalar<FR32X, f32mem, AVXCC, X86cmpms, f32, loadf32,
1074                  "vcmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1075                  "vcmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
1076                  XS;
1077 defm VCMPSDZ : avx512_cmp_scalar<FR64X, f64mem, AVXCC, X86cmpms, f64, loadf64,
1078                  "vcmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1079                  "vcmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
1080                  XD, VEX_W;
1081 }
1082
1083 multiclass avx512_icmp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
1084               X86VectorVTInfo _> {
1085   def rr : AVX512BI<opc, MRMSrcReg,
1086              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2),
1087              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1088              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2)))],
1089              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1090   let mayLoad = 1 in
1091   def rm : AVX512BI<opc, MRMSrcMem,
1092              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2),
1093              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1094              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1095                                      (_.VT (bitconvert (_.LdFrag addr:$src2)))))],
1096              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1097   def rrk : AVX512BI<opc, MRMSrcReg,
1098               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1099               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1100                           "$dst {${mask}}, $src1, $src2}"),
1101               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1102                                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))))],
1103               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1104   let mayLoad = 1 in
1105   def rmk : AVX512BI<opc, MRMSrcMem,
1106               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1107               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1108                           "$dst {${mask}}, $src1, $src2}"),
1109               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1110                                    (OpNode (_.VT _.RC:$src1),
1111                                        (_.VT (bitconvert
1112                                               (_.LdFrag addr:$src2))))))],
1113               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1114 }
1115
1116 multiclass avx512_icmp_packed_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
1117               X86VectorVTInfo _> :
1118            avx512_icmp_packed<opc, OpcodeStr, OpNode, _> {
1119   let mayLoad = 1 in {
1120   def rmb : AVX512BI<opc, MRMSrcMem,
1121               (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2),
1122               !strconcat(OpcodeStr, "\t{${src2}", _.BroadcastStr, ", $src1, $dst",
1123                                     "|$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1124               [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1125                               (X86VBroadcast (_.ScalarLdFrag addr:$src2))))],
1126               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1127   def rmbk : AVX512BI<opc, MRMSrcMem,
1128                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1129                                        _.ScalarMemOp:$src2),
1130                !strconcat(OpcodeStr,
1131                           "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1132                           "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1133                [(set _.KRC:$dst, (and _.KRCWM:$mask,
1134                                       (OpNode (_.VT _.RC:$src1),
1135                                         (X86VBroadcast
1136                                           (_.ScalarLdFrag addr:$src2)))))],
1137                IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1138   }
1139 }
1140
1141 multiclass avx512_icmp_packed_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
1142                                  AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1143   let Predicates = [prd] in
1144   defm Z : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info512>,
1145            EVEX_V512;
1146
1147   let Predicates = [prd, HasVLX] in {
1148     defm Z256 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info256>,
1149                 EVEX_V256;
1150     defm Z128 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info128>,
1151                 EVEX_V128;
1152   }
1153 }
1154
1155 multiclass avx512_icmp_packed_rmb_vl<bits<8> opc, string OpcodeStr,
1156                                   SDNode OpNode, AVX512VLVectorVTInfo VTInfo,
1157                                   Predicate prd> {
1158   let Predicates = [prd] in
1159   defm Z : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
1160            EVEX_V512;
1161
1162   let Predicates = [prd, HasVLX] in {
1163     defm Z256 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
1164                 EVEX_V256;
1165     defm Z128 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
1166                 EVEX_V128;
1167   }
1168 }
1169
1170 defm VPCMPEQB : avx512_icmp_packed_vl<0x74, "vpcmpeqb", X86pcmpeqm,
1171                       avx512vl_i8_info, HasBWI>,
1172                 EVEX_CD8<8, CD8VF>;
1173
1174 defm VPCMPEQW : avx512_icmp_packed_vl<0x75, "vpcmpeqw", X86pcmpeqm,
1175                       avx512vl_i16_info, HasBWI>,
1176                 EVEX_CD8<16, CD8VF>;
1177
1178 defm VPCMPEQD : avx512_icmp_packed_rmb_vl<0x76, "vpcmpeqd", X86pcmpeqm,
1179                       avx512vl_i32_info, HasAVX512>,
1180                 EVEX_CD8<32, CD8VF>;
1181
1182 defm VPCMPEQQ : avx512_icmp_packed_rmb_vl<0x29, "vpcmpeqq", X86pcmpeqm,
1183                       avx512vl_i64_info, HasAVX512>,
1184                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1185
1186 defm VPCMPGTB : avx512_icmp_packed_vl<0x64, "vpcmpgtb", X86pcmpgtm,
1187                       avx512vl_i8_info, HasBWI>,
1188                 EVEX_CD8<8, CD8VF>;
1189
1190 defm VPCMPGTW : avx512_icmp_packed_vl<0x65, "vpcmpgtw", X86pcmpgtm,
1191                       avx512vl_i16_info, HasBWI>,
1192                 EVEX_CD8<16, CD8VF>;
1193
1194 defm VPCMPGTD : avx512_icmp_packed_rmb_vl<0x66, "vpcmpgtd", X86pcmpgtm,
1195                       avx512vl_i32_info, HasAVX512>,
1196                 EVEX_CD8<32, CD8VF>;
1197
1198 defm VPCMPGTQ : avx512_icmp_packed_rmb_vl<0x37, "vpcmpgtq", X86pcmpgtm,
1199                       avx512vl_i64_info, HasAVX512>,
1200                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1201
1202 def : Pat<(v8i1 (X86pcmpgtm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1203             (COPY_TO_REGCLASS (VPCMPGTDZrr
1204             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1205             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm))), VK8)>;
1206
1207 def : Pat<(v8i1 (X86pcmpeqm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1208             (COPY_TO_REGCLASS (VPCMPEQDZrr
1209             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1210             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm))), VK8)>;
1211
1212 multiclass avx512_icmp_cc<bits<8> opc, string Suffix, SDNode OpNode,
1213                           X86VectorVTInfo _> {
1214   def rri : AVX512AIi8<opc, MRMSrcReg,
1215              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1216              !strconcat("vpcmp${cc}", Suffix,
1217                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1218              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1219                                        imm:$cc))],
1220              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1221   let mayLoad = 1 in
1222   def rmi : AVX512AIi8<opc, MRMSrcMem,
1223              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, AVXCC:$cc),
1224              !strconcat("vpcmp${cc}", Suffix,
1225                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1226              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1227                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
1228                               imm:$cc))],
1229              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1230   def rrik : AVX512AIi8<opc, MRMSrcReg,
1231               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1232                                       AVXCC:$cc),
1233               !strconcat("vpcmp${cc}", Suffix,
1234                          "\t{$src2, $src1, $dst {${mask}}|",
1235                          "$dst {${mask}}, $src1, $src2}"),
1236               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1237                                   (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1238                                           imm:$cc)))],
1239               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1240   let mayLoad = 1 in
1241   def rmik : AVX512AIi8<opc, MRMSrcMem,
1242               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1243                                     AVXCC:$cc),
1244               !strconcat("vpcmp${cc}", Suffix,
1245                          "\t{$src2, $src1, $dst {${mask}}|",
1246                          "$dst {${mask}}, $src1, $src2}"),
1247               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1248                                    (OpNode (_.VT _.RC:$src1),
1249                                       (_.VT (bitconvert (_.LdFrag addr:$src2))),
1250                                       imm:$cc)))],
1251               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1252
1253   // Accept explicit immediate argument form instead of comparison code.
1254   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1255     def rri_alt : AVX512AIi8<opc, MRMSrcReg,
1256                (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, i8imm:$cc),
1257                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1258                           "$dst, $src1, $src2, $cc}"),
1259                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1260     def rmi_alt : AVX512AIi8<opc, MRMSrcMem,
1261                (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, i8imm:$cc),
1262                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1263                           "$dst, $src1, $src2, $cc}"),
1264                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1265     def rrik_alt : AVX512AIi8<opc, MRMSrcReg,
1266                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1267                                        i8imm:$cc),
1268                !strconcat("vpcmp", Suffix,
1269                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1270                           "$dst {${mask}}, $src1, $src2, $cc}"),
1271                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1272     def rmik_alt : AVX512AIi8<opc, MRMSrcMem,
1273                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1274                                        i8imm:$cc),
1275                !strconcat("vpcmp", Suffix,
1276                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1277                           "$dst {${mask}}, $src1, $src2, $cc}"),
1278                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1279   }
1280 }
1281
1282 multiclass avx512_icmp_cc_rmb<bits<8> opc, string Suffix, SDNode OpNode,
1283                               X86VectorVTInfo _> :
1284            avx512_icmp_cc<opc, Suffix, OpNode, _> {
1285   let mayLoad = 1 in {
1286   def rmib : AVX512AIi8<opc, MRMSrcMem,
1287              (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1288                                      AVXCC:$cc),
1289              !strconcat("vpcmp${cc}", Suffix,
1290                         "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1291                         "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1292              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1293                                (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1294                                imm:$cc))],
1295              IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1296   def rmibk : AVX512AIi8<opc, MRMSrcMem,
1297               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1298                                        _.ScalarMemOp:$src2, AVXCC:$cc),
1299               !strconcat("vpcmp${cc}", Suffix,
1300                        "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1301                        "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1302               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1303                                   (OpNode (_.VT _.RC:$src1),
1304                                     (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1305                                     imm:$cc)))],
1306               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1307   }
1308
1309   // Accept explicit immediate argument form instead of comparison code.
1310   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1311     def rmib_alt : AVX512AIi8<opc, MRMSrcMem,
1312                (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1313                                        i8imm:$cc),
1314                !strconcat("vpcmp", Suffix,
1315                    "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst|",
1316                    "$dst, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1317                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1318     def rmibk_alt : AVX512AIi8<opc, MRMSrcMem,
1319                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1320                                        _.ScalarMemOp:$src2, i8imm:$cc),
1321                !strconcat("vpcmp", Suffix,
1322                   "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1323                   "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1324                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1325   }
1326 }
1327
1328 multiclass avx512_icmp_cc_vl<bits<8> opc, string Suffix, SDNode OpNode,
1329                              AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1330   let Predicates = [prd] in
1331   defm Z : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info512>, EVEX_V512;
1332
1333   let Predicates = [prd, HasVLX] in {
1334     defm Z256 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info256>, EVEX_V256;
1335     defm Z128 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info128>, EVEX_V128;
1336   }
1337 }
1338
1339 multiclass avx512_icmp_cc_rmb_vl<bits<8> opc, string Suffix, SDNode OpNode,
1340                                 AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1341   let Predicates = [prd] in
1342   defm Z : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info512>,
1343            EVEX_V512;
1344
1345   let Predicates = [prd, HasVLX] in {
1346     defm Z256 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info256>,
1347                 EVEX_V256;
1348     defm Z128 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info128>,
1349                 EVEX_V128;
1350   }
1351 }
1352
1353 defm VPCMPB : avx512_icmp_cc_vl<0x3F, "b", X86cmpm, avx512vl_i8_info,
1354                                 HasBWI>, EVEX_CD8<8, CD8VF>;
1355 defm VPCMPUB : avx512_icmp_cc_vl<0x3E, "ub", X86cmpmu, avx512vl_i8_info,
1356                                  HasBWI>, EVEX_CD8<8, CD8VF>;
1357
1358 defm VPCMPW : avx512_icmp_cc_vl<0x3F, "w", X86cmpm, avx512vl_i16_info,
1359                                 HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1360 defm VPCMPUW : avx512_icmp_cc_vl<0x3E, "uw", X86cmpmu, avx512vl_i16_info,
1361                                  HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1362
1363 defm VPCMPD : avx512_icmp_cc_rmb_vl<0x1F, "d", X86cmpm, avx512vl_i32_info,
1364                                     HasAVX512>, EVEX_CD8<32, CD8VF>;
1365 defm VPCMPUD : avx512_icmp_cc_rmb_vl<0x1E, "ud", X86cmpmu, avx512vl_i32_info,
1366                                      HasAVX512>, EVEX_CD8<32, CD8VF>;
1367
1368 defm VPCMPQ : avx512_icmp_cc_rmb_vl<0x1F, "q", X86cmpm, avx512vl_i64_info,
1369                                     HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1370 defm VPCMPUQ : avx512_icmp_cc_rmb_vl<0x1E, "uq", X86cmpmu, avx512vl_i64_info,
1371                                      HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1372
1373 // avx512_cmp_packed - compare packed instructions
1374 multiclass avx512_cmp_packed<RegisterClass KRC, RegisterClass RC,
1375                            X86MemOperand x86memop, ValueType vt,
1376                            string suffix, Domain d> {
1377   def rri : AVX512PIi8<0xC2, MRMSrcReg,
1378              (outs KRC:$dst), (ins RC:$src1, RC:$src2, AVXCC:$cc),
1379              !strconcat("vcmp${cc}", suffix,
1380                         " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1381              [(set KRC:$dst, (X86cmpm (vt RC:$src1), (vt RC:$src2), imm:$cc))], d>;
1382   def rrib: AVX512PIi8<0xC2, MRMSrcReg,
1383              (outs KRC:$dst), (ins RC:$src1, RC:$src2, AVXCC:$cc),
1384      !strconcat("vcmp${cc}", suffix,
1385                 " \t{{sae}, $src2, $src1, $dst|$dst, $src1, $src2, {sae}}"),
1386                 [], d>, EVEX_B;
1387   def rmi : AVX512PIi8<0xC2, MRMSrcMem,
1388              (outs KRC:$dst), (ins RC:$src1, x86memop:$src2, AVXCC:$cc),
1389               !strconcat("vcmp${cc}", suffix,
1390                          " \t{$src2, $src1, $dst|$dst, $src1, $src2, $cc}"),
1391              [(set KRC:$dst,
1392               (X86cmpm (vt RC:$src1), (memop addr:$src2), imm:$cc))], d>;
1393
1394   // Accept explicit immediate argument form instead of comparison code.
1395   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1396     def rri_alt : AVX512PIi8<0xC2, MRMSrcReg,
1397                (outs KRC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
1398               !strconcat("vcmp", suffix,
1399                         " \t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
1400     def rmi_alt : AVX512PIi8<0xC2, MRMSrcMem,
1401                (outs KRC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
1402               !strconcat("vcmp", suffix,
1403                         " \t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}"), [], d>;
1404   }
1405 }
1406
1407 defm VCMPPSZ : avx512_cmp_packed<VK16, VR512, f512mem, v16f32,
1408                "ps", SSEPackedSingle>, PS, EVEX_4V, EVEX_V512,
1409                EVEX_CD8<32, CD8VF>;
1410 defm VCMPPDZ : avx512_cmp_packed<VK8, VR512, f512mem, v8f64,
1411                "pd", SSEPackedDouble>, PD, EVEX_4V, VEX_W, EVEX_V512,
1412                EVEX_CD8<64, CD8VF>;
1413
1414 def : Pat<(v8i1 (X86cmpm (v8f32 VR256X:$src1), (v8f32 VR256X:$src2), imm:$cc)),
1415           (COPY_TO_REGCLASS (VCMPPSZrri
1416             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1417             (v16f32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1418             imm:$cc), VK8)>;
1419 def : Pat<(v8i1 (X86cmpm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
1420           (COPY_TO_REGCLASS (VPCMPDZrri
1421             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1422             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1423             imm:$cc), VK8)>;
1424 def : Pat<(v8i1 (X86cmpmu (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
1425           (COPY_TO_REGCLASS (VPCMPUDZrri
1426             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src1, sub_ymm)),
1427             (v16i32 (SUBREG_TO_REG (i32 0), VR256X:$src2, sub_ymm)),
1428             imm:$cc), VK8)>;
1429
1430 def : Pat<(i16 (int_x86_avx512_mask_cmp_ps_512 (v16f32 VR512:$src1),
1431                 (v16f32 VR512:$src2), imm:$cc, (i16 -1),
1432                  FROUND_NO_EXC)),
1433           (COPY_TO_REGCLASS (VCMPPSZrrib VR512:$src1, VR512:$src2,
1434                              (I8Imm imm:$cc)), GR16)>;
1435            
1436 def : Pat<(i8 (int_x86_avx512_mask_cmp_pd_512 (v8f64 VR512:$src1),
1437                 (v8f64 VR512:$src2), imm:$cc, (i8 -1),
1438                  FROUND_NO_EXC)),
1439           (COPY_TO_REGCLASS (VCMPPDZrrib VR512:$src1, VR512:$src2,
1440                              (I8Imm imm:$cc)), GR8)>;
1441
1442 def : Pat<(i16 (int_x86_avx512_mask_cmp_ps_512 (v16f32 VR512:$src1),
1443                 (v16f32 VR512:$src2), imm:$cc, (i16 -1),
1444                 FROUND_CURRENT)),
1445           (COPY_TO_REGCLASS (VCMPPSZrri VR512:$src1, VR512:$src2,
1446                              (I8Imm imm:$cc)), GR16)>;
1447
1448 def : Pat<(i8 (int_x86_avx512_mask_cmp_pd_512 (v8f64 VR512:$src1),
1449                 (v8f64 VR512:$src2), imm:$cc, (i8 -1),
1450                  FROUND_CURRENT)),
1451           (COPY_TO_REGCLASS (VCMPPDZrri VR512:$src1, VR512:$src2,
1452                              (I8Imm imm:$cc)), GR8)>;
1453
1454 // Mask register copy, including
1455 // - copy between mask registers
1456 // - load/store mask registers
1457 // - copy from GPR to mask register and vice versa
1458 //
1459 multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
1460                          string OpcodeStr, RegisterClass KRC,
1461                          ValueType vvt, ValueType ivt, X86MemOperand x86memop> {
1462   let hasSideEffects = 0 in {
1463     def kk : I<opc_kk, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
1464                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1465     let mayLoad = 1 in
1466     def km : I<opc_km, MRMSrcMem, (outs KRC:$dst), (ins x86memop:$src),
1467                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
1468                [(set KRC:$dst, (vvt (bitconvert (ivt (load addr:$src)))))]>;
1469     let mayStore = 1 in
1470     def mk : I<opc_mk, MRMDestMem, (outs), (ins x86memop:$dst, KRC:$src),
1471                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1472   }
1473 }
1474
1475 multiclass avx512_mask_mov_gpr<bits<8> opc_kr, bits<8> opc_rk,
1476                              string OpcodeStr,
1477                              RegisterClass KRC, RegisterClass GRC> {
1478   let hasSideEffects = 0 in {
1479     def kr : I<opc_kr, MRMSrcReg, (outs KRC:$dst), (ins GRC:$src),
1480                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1481     def rk : I<opc_rk, MRMSrcReg, (outs GRC:$dst), (ins KRC:$src),
1482                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"), []>;
1483   }
1484 }
1485
1486 let Predicates = [HasDQI] in
1487   defm KMOVB : avx512_mask_mov<0x90, 0x90, 0x91, "kmovb", VK8, v8i1, i8,
1488                                i8mem>,
1489                avx512_mask_mov_gpr<0x92, 0x93, "kmovb", VK8, GR32>,
1490                VEX, PD;
1491
1492 let Predicates = [HasAVX512] in
1493   defm KMOVW : avx512_mask_mov<0x90, 0x90, 0x91, "kmovw", VK16, v16i1, i16,
1494                                i16mem>,
1495                avx512_mask_mov_gpr<0x92, 0x93, "kmovw", VK16, GR32>,
1496                VEX, PS;
1497
1498 let Predicates = [HasBWI] in {
1499   defm KMOVD : avx512_mask_mov<0x90, 0x90, 0x91, "kmovd", VK32, v32i1, i32,
1500                                i32mem>, VEX, PD, VEX_W;
1501   defm KMOVD : avx512_mask_mov_gpr<0x92, 0x93, "kmovd", VK32, GR32>,
1502                VEX, XD;
1503 }
1504
1505 let Predicates = [HasBWI] in {
1506   defm KMOVQ : avx512_mask_mov<0x90, 0x90, 0x91, "kmovq", VK64, v64i1, i64,
1507                                i64mem>, VEX, PS, VEX_W;
1508   defm KMOVQ : avx512_mask_mov_gpr<0x92, 0x93, "kmovq", VK64, GR64>,
1509                VEX, XD, VEX_W;
1510 }
1511
1512 // GR from/to mask register
1513 let Predicates = [HasDQI] in {
1514   def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
1515             (KMOVBkr (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit))>;
1516   def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
1517             (EXTRACT_SUBREG (KMOVBrk VK8:$src), sub_8bit)>;
1518 }
1519 let Predicates = [HasAVX512] in {
1520   def : Pat<(v16i1 (bitconvert (i16 GR16:$src))),
1521             (KMOVWkr (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit))>;
1522   def : Pat<(i16 (bitconvert (v16i1 VK16:$src))),
1523             (EXTRACT_SUBREG (KMOVWrk VK16:$src), sub_16bit)>;
1524 }
1525 let Predicates = [HasBWI] in {
1526   def : Pat<(v32i1 (bitconvert (i32 GR32:$src))), (KMOVDkr GR32:$src)>;
1527   def : Pat<(i32 (bitconvert (v32i1 VK32:$src))), (KMOVDrk VK32:$src)>;
1528 }
1529 let Predicates = [HasBWI] in {
1530   def : Pat<(v64i1 (bitconvert (i64 GR64:$src))), (KMOVQkr GR64:$src)>;
1531   def : Pat<(i64 (bitconvert (v64i1 VK64:$src))), (KMOVQrk VK64:$src)>;
1532 }
1533
1534 // Load/store kreg
1535 let Predicates = [HasDQI] in {
1536   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
1537             (KMOVBmk addr:$dst, VK8:$src)>;
1538 }
1539 let Predicates = [HasAVX512] in {
1540   def : Pat<(store (i16 (bitconvert (v16i1 VK16:$src))), addr:$dst),
1541             (KMOVWmk addr:$dst, VK16:$src)>;
1542   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
1543             (KMOVWmk addr:$dst, (COPY_TO_REGCLASS VK8:$src, VK16))>;
1544   def : Pat<(i1 (load addr:$src)),
1545             (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK1)>;
1546   def : Pat<(v8i1 (bitconvert (i8 (load addr:$src)))),
1547             (COPY_TO_REGCLASS (KMOVWkm addr:$src), VK8)>;
1548 }
1549 let Predicates = [HasBWI] in {
1550   def : Pat<(store (i32 (bitconvert (v32i1 VK32:$src))), addr:$dst),
1551             (KMOVDmk addr:$dst, VK32:$src)>;
1552 }
1553 let Predicates = [HasBWI] in {
1554   def : Pat<(store (i64 (bitconvert (v64i1 VK64:$src))), addr:$dst),
1555             (KMOVQmk addr:$dst, VK64:$src)>;
1556 }
1557
1558 let Predicates = [HasAVX512] in {
1559   def : Pat<(i1 (trunc (i64 GR64:$src))),
1560             (COPY_TO_REGCLASS (KMOVWkr (AND32ri (EXTRACT_SUBREG $src, sub_32bit),
1561                                         (i32 1))), VK1)>;
1562
1563   def : Pat<(i1 (trunc (i32 GR32:$src))),
1564             (COPY_TO_REGCLASS (KMOVWkr (AND32ri $src, (i32 1))), VK1)>;
1565
1566   def : Pat<(i1 (trunc (i8 GR8:$src))),
1567        (COPY_TO_REGCLASS
1568         (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit), (i32 1))),
1569        VK1)>;
1570   def : Pat<(i1 (trunc (i16 GR16:$src))),
1571        (COPY_TO_REGCLASS
1572         (KMOVWkr (AND32ri (SUBREG_TO_REG (i32 0), $src, sub_16bit), (i32 1))),
1573        VK1)>;
1574
1575   def : Pat<(i32 (zext VK1:$src)),
1576             (AND32ri (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1))>;
1577   def : Pat<(i8 (zext VK1:$src)),
1578             (EXTRACT_SUBREG
1579              (AND32ri (KMOVWrk
1580                        (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)), sub_8bit)>;
1581   def : Pat<(i64 (zext VK1:$src)),
1582             (AND64ri8 (SUBREG_TO_REG (i64 0),
1583              (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), sub_32bit), (i64 1))>;
1584   def : Pat<(i16 (zext VK1:$src)),
1585             (EXTRACT_SUBREG
1586              (AND32ri (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)),
1587               sub_16bit)>;
1588   def : Pat<(v16i1 (scalar_to_vector VK1:$src)),
1589             (COPY_TO_REGCLASS VK1:$src, VK16)>;
1590   def : Pat<(v8i1 (scalar_to_vector VK1:$src)),
1591             (COPY_TO_REGCLASS VK1:$src, VK8)>;
1592 }
1593 let Predicates = [HasBWI] in {
1594   def : Pat<(v32i1 (scalar_to_vector VK1:$src)),
1595             (COPY_TO_REGCLASS VK1:$src, VK32)>;
1596   def : Pat<(v64i1 (scalar_to_vector VK1:$src)),
1597             (COPY_TO_REGCLASS VK1:$src, VK64)>;
1598 }
1599
1600
1601 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
1602 let Predicates = [HasAVX512] in {
1603   // GR from/to 8-bit mask without native support
1604   def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
1605             (COPY_TO_REGCLASS
1606               (KMOVWkr (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
1607               VK8)>;
1608   def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
1609             (EXTRACT_SUBREG
1610               (KMOVWrk (COPY_TO_REGCLASS VK8:$src, VK16)),
1611               sub_8bit)>;
1612
1613   def : Pat<(i1 (X86Vextract VK16:$src, (iPTR 0))),
1614             (COPY_TO_REGCLASS VK16:$src, VK1)>;
1615   def : Pat<(i1 (X86Vextract VK8:$src, (iPTR 0))),
1616             (COPY_TO_REGCLASS VK8:$src, VK1)>;
1617 }
1618 let Predicates = [HasBWI] in {
1619   def : Pat<(i1 (X86Vextract VK32:$src, (iPTR 0))),
1620             (COPY_TO_REGCLASS VK32:$src, VK1)>;
1621   def : Pat<(i1 (X86Vextract VK64:$src, (iPTR 0))),
1622             (COPY_TO_REGCLASS VK64:$src, VK1)>;
1623 }
1624
1625 // Mask unary operation
1626 // - KNOT
1627 multiclass avx512_mask_unop<bits<8> opc, string OpcodeStr,
1628                             RegisterClass KRC, SDPatternOperator OpNode,
1629                             Predicate prd> {
1630   let Predicates = [prd] in
1631     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
1632                !strconcat(OpcodeStr, " \t{$src, $dst|$dst, $src}"),
1633                [(set KRC:$dst, (OpNode KRC:$src))]>;
1634 }
1635
1636 multiclass avx512_mask_unop_all<bits<8> opc, string OpcodeStr,
1637                                 SDPatternOperator OpNode> {
1638   defm B : avx512_mask_unop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
1639                             HasDQI>, VEX, PD;
1640   defm W : avx512_mask_unop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
1641                             HasAVX512>, VEX, PS;
1642   defm D : avx512_mask_unop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
1643                             HasBWI>, VEX, PD, VEX_W;
1644   defm Q : avx512_mask_unop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
1645                             HasBWI>, VEX, PS, VEX_W;
1646 }
1647
1648 defm KNOT : avx512_mask_unop_all<0x44, "knot", not>;
1649
1650 multiclass avx512_mask_unop_int<string IntName, string InstName> {
1651   let Predicates = [HasAVX512] in
1652     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
1653                 (i16 GR16:$src)),
1654               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
1655               (v16i1 (COPY_TO_REGCLASS GR16:$src, VK16))), GR16)>;
1656 }
1657 defm : avx512_mask_unop_int<"knot", "KNOT">;
1658
1659 let Predicates = [HasDQI] in
1660 def : Pat<(xor VK8:$src1, (v8i1 immAllOnesV)), (KNOTBrr VK8:$src1)>;
1661 let Predicates = [HasAVX512] in
1662 def : Pat<(xor VK16:$src1, (v16i1 immAllOnesV)), (KNOTWrr VK16:$src1)>;
1663 let Predicates = [HasBWI] in
1664 def : Pat<(xor VK32:$src1, (v32i1 immAllOnesV)), (KNOTDrr VK32:$src1)>;
1665 let Predicates = [HasBWI] in
1666 def : Pat<(xor VK64:$src1, (v64i1 immAllOnesV)), (KNOTQrr VK64:$src1)>;
1667
1668 // KNL does not support KMOVB, 8-bit mask is promoted to 16-bit
1669 let Predicates = [HasAVX512] in {
1670 def : Pat<(xor VK8:$src1,  (v8i1 immAllOnesV)),
1671           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$src1, VK16)), VK8)>;
1672
1673 def : Pat<(not VK8:$src),
1674           (COPY_TO_REGCLASS
1675             (KNOTWrr (COPY_TO_REGCLASS VK8:$src, VK16)), VK8)>;
1676 }
1677
1678 // Mask binary operation
1679 // - KAND, KANDN, KOR, KXNOR, KXOR
1680 multiclass avx512_mask_binop<bits<8> opc, string OpcodeStr,
1681                            RegisterClass KRC, SDPatternOperator OpNode,
1682                            Predicate prd> {
1683   let Predicates = [prd] in
1684     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
1685                !strconcat(OpcodeStr,
1686                           " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1687                [(set KRC:$dst, (OpNode KRC:$src1, KRC:$src2))]>;
1688 }
1689
1690 multiclass avx512_mask_binop_all<bits<8> opc, string OpcodeStr,
1691                                SDPatternOperator OpNode> {
1692   defm B : avx512_mask_binop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
1693                              HasDQI>, VEX_4V, VEX_L, PD;
1694   defm W : avx512_mask_binop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
1695                              HasAVX512>, VEX_4V, VEX_L, PS;
1696   defm D : avx512_mask_binop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
1697                              HasBWI>, VEX_4V, VEX_L, VEX_W, PD;
1698   defm Q : avx512_mask_binop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
1699                              HasBWI>, VEX_4V, VEX_L, VEX_W, PS;
1700 }
1701
1702 def andn : PatFrag<(ops node:$i0, node:$i1), (and (not node:$i0), node:$i1)>;
1703 def xnor : PatFrag<(ops node:$i0, node:$i1), (not (xor node:$i0, node:$i1))>;
1704
1705 let isCommutable = 1 in {
1706   defm KAND  : avx512_mask_binop_all<0x41, "kand",  and>;
1707   defm KOR   : avx512_mask_binop_all<0x45, "kor",   or>;
1708   defm KXNOR : avx512_mask_binop_all<0x46, "kxnor", xnor>;
1709   defm KXOR  : avx512_mask_binop_all<0x47, "kxor",  xor>;
1710 }
1711 let isCommutable = 0 in
1712   defm KANDN : avx512_mask_binop_all<0x42, "kandn", andn>;
1713
1714 def : Pat<(xor VK1:$src1, VK1:$src2),
1715      (COPY_TO_REGCLASS (KXORWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1716                                 (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
1717
1718 def : Pat<(or VK1:$src1, VK1:$src2),
1719      (COPY_TO_REGCLASS (KORWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1720                                (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
1721
1722 def : Pat<(and VK1:$src1, VK1:$src2),
1723      (COPY_TO_REGCLASS (KANDWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1724                                 (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
1725
1726 multiclass avx512_mask_binop_int<string IntName, string InstName> {
1727   let Predicates = [HasAVX512] in
1728     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
1729                 (i16 GR16:$src1), (i16 GR16:$src2)),
1730               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
1731               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
1732               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
1733 }
1734
1735 defm : avx512_mask_binop_int<"kand",  "KAND">;
1736 defm : avx512_mask_binop_int<"kandn", "KANDN">;
1737 defm : avx512_mask_binop_int<"kor",   "KOR">;
1738 defm : avx512_mask_binop_int<"kxnor", "KXNOR">;
1739 defm : avx512_mask_binop_int<"kxor",  "KXOR">;
1740
1741 // With AVX-512, 8-bit mask is promoted to 16-bit mask.
1742 multiclass avx512_binop_pat<SDPatternOperator OpNode, Instruction Inst> {
1743   let Predicates = [HasAVX512] in
1744     def : Pat<(OpNode VK8:$src1, VK8:$src2),
1745               (COPY_TO_REGCLASS
1746                 (Inst (COPY_TO_REGCLASS VK8:$src1, VK16),
1747                       (COPY_TO_REGCLASS VK8:$src2, VK16)), VK8)>;
1748 }
1749
1750 defm : avx512_binop_pat<and,  KANDWrr>;
1751 defm : avx512_binop_pat<andn, KANDNWrr>;
1752 defm : avx512_binop_pat<or,   KORWrr>;
1753 defm : avx512_binop_pat<xnor, KXNORWrr>;
1754 defm : avx512_binop_pat<xor,  KXORWrr>;
1755
1756 // Mask unpacking
1757 multiclass avx512_mask_unpck<bits<8> opc, string OpcodeStr,
1758                            RegisterClass KRC> {
1759   let Predicates = [HasAVX512] in
1760     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
1761                !strconcat(OpcodeStr,
1762                           " \t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
1763 }
1764
1765 multiclass avx512_mask_unpck_bw<bits<8> opc, string OpcodeStr> {
1766   defm BW : avx512_mask_unpck<opc, !strconcat(OpcodeStr, "bw"), VK16>,
1767                             VEX_4V, VEX_L, PD;
1768 }
1769
1770 defm KUNPCK : avx512_mask_unpck_bw<0x4b, "kunpck">;
1771 def : Pat<(v16i1 (concat_vectors (v8i1 VK8:$src1), (v8i1 VK8:$src2))),
1772           (KUNPCKBWrr (COPY_TO_REGCLASS VK8:$src2, VK16),
1773                   (COPY_TO_REGCLASS VK8:$src1, VK16))>;
1774
1775
1776 multiclass avx512_mask_unpck_int<string IntName, string InstName> {
1777   let Predicates = [HasAVX512] in
1778     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_bw")
1779                 (i16 GR16:$src1), (i16 GR16:$src2)),
1780               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"BWrr")
1781               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
1782               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
1783 }
1784 defm : avx512_mask_unpck_int<"kunpck",  "KUNPCK">;
1785
1786 // Mask bit testing
1787 multiclass avx512_mask_testop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
1788                             SDNode OpNode> {
1789   let Predicates = [HasAVX512], Defs = [EFLAGS] in
1790     def rr : I<opc, MRMSrcReg, (outs), (ins KRC:$src1, KRC:$src2),
1791                !strconcat(OpcodeStr, " \t{$src2, $src1|$src1, $src2}"),
1792                [(set EFLAGS, (OpNode KRC:$src1, KRC:$src2))]>;
1793 }
1794
1795 multiclass avx512_mask_testop_w<bits<8> opc, string OpcodeStr, SDNode OpNode> {
1796   defm W : avx512_mask_testop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
1797                             VEX, PS;
1798 }
1799
1800 defm KORTEST : avx512_mask_testop_w<0x98, "kortest", X86kortest>;
1801
1802 def : Pat<(X86cmp VK1:$src1, (i1 0)),
1803           (KORTESTWrr (COPY_TO_REGCLASS VK1:$src1, VK16),
1804            (COPY_TO_REGCLASS VK1:$src1, VK16))>;
1805
1806 // Mask shift
1807 multiclass avx512_mask_shiftop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
1808                              SDNode OpNode> {
1809   let Predicates = [HasAVX512] in
1810     def ri : Ii8<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src, i8imm:$imm),
1811                  !strconcat(OpcodeStr,
1812                             " \t{$imm, $src, $dst|$dst, $src, $imm}"),
1813                             [(set KRC:$dst, (OpNode KRC:$src, (i8 imm:$imm)))]>;
1814 }
1815
1816 multiclass avx512_mask_shiftop_w<bits<8> opc1, bits<8> opc2, string OpcodeStr,
1817                                SDNode OpNode> {
1818   defm W : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
1819                              VEX, TAPD, VEX_W;
1820 }
1821
1822 defm KSHIFTL : avx512_mask_shiftop_w<0x32, 0x33, "kshiftl", X86vshli>;
1823 defm KSHIFTR : avx512_mask_shiftop_w<0x30, 0x31, "kshiftr", X86vsrli>;
1824
1825 // Mask setting all 0s or 1s
1826 multiclass avx512_mask_setop<RegisterClass KRC, ValueType VT, PatFrag Val> {
1827   let Predicates = [HasAVX512] in
1828     let isReMaterializable = 1, isAsCheapAsAMove = 1, isPseudo = 1 in
1829       def #NAME# : I<0, Pseudo, (outs KRC:$dst), (ins), "",
1830                      [(set KRC:$dst, (VT Val))]>;
1831 }
1832
1833 multiclass avx512_mask_setop_w<PatFrag Val> {
1834   defm B : avx512_mask_setop<VK8,   v8i1, Val>;
1835   defm W : avx512_mask_setop<VK16, v16i1, Val>;
1836 }
1837
1838 defm KSET0 : avx512_mask_setop_w<immAllZerosV>;
1839 defm KSET1 : avx512_mask_setop_w<immAllOnesV>;
1840
1841 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
1842 let Predicates = [HasAVX512] in {
1843   def : Pat<(v8i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK8)>;
1844   def : Pat<(v8i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK8)>;
1845   def : Pat<(i1 0), (COPY_TO_REGCLASS (KSET0W), VK1)>;
1846   def : Pat<(i1 1), (COPY_TO_REGCLASS (KSET1W), VK1)>;
1847   def : Pat<(i1 -1), (COPY_TO_REGCLASS (KSET1W), VK1)>;
1848 }
1849 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 0))),
1850           (v8i1 (COPY_TO_REGCLASS VK16:$src, VK8))>;
1851
1852 def : Pat<(v16i1 (insert_subvector undef, (v8i1 VK8:$src), (iPTR 0))),
1853           (v16i1 (COPY_TO_REGCLASS VK8:$src, VK16))>;
1854
1855 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 8))),
1856           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri VK16:$src, (i8 8)), VK8))>;
1857
1858 let Predicates = [HasVLX] in {
1859   def : Pat<(v8i1 (insert_subvector undef, (v4i1 VK4:$src), (iPTR 0))),
1860             (v8i1 (COPY_TO_REGCLASS VK4:$src, VK8))>;
1861   def : Pat<(v8i1 (insert_subvector undef, (v2i1 VK2:$src), (iPTR 0))),
1862             (v8i1 (COPY_TO_REGCLASS VK2:$src, VK8))>;
1863   def : Pat<(v4i1 (extract_subvector (v8i1 VK8:$src), (iPTR 0))),
1864             (v4i1 (COPY_TO_REGCLASS VK8:$src, VK4))>;
1865   def : Pat<(v2i1 (extract_subvector (v8i1 VK8:$src), (iPTR 0))),
1866             (v2i1 (COPY_TO_REGCLASS VK8:$src, VK2))>;
1867 }
1868
1869 def : Pat<(v8i1 (X86vshli VK8:$src, (i8 imm:$imm))),
1870           (v8i1 (COPY_TO_REGCLASS (KSHIFTLWri (COPY_TO_REGCLASS VK8:$src, VK16), (I8Imm $imm)), VK8))>;
1871
1872 def : Pat<(v8i1 (X86vsrli VK8:$src, (i8 imm:$imm))),
1873           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri (COPY_TO_REGCLASS VK8:$src, VK16), (I8Imm $imm)), VK8))>;
1874 //===----------------------------------------------------------------------===//
1875 // AVX-512 - Aligned and unaligned load and store
1876 //
1877
1878 multiclass avx512_load<bits<8> opc, string OpcodeStr, PatFrag ld_frag,
1879                        RegisterClass KRC, RegisterClass RC,
1880                        ValueType vt, ValueType zvt, X86MemOperand memop,
1881                        Domain d, bit IsReMaterializable = 1> {
1882 let hasSideEffects = 0 in {
1883   def rr : AVX512PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
1884                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [],
1885                     d>, EVEX;
1886   def rrkz : AVX512PI<opc, MRMSrcReg, (outs RC:$dst), (ins KRC:$mask, RC:$src),
1887                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
1888                        "${dst} {${mask}} {z}, $src}"), [], d>, EVEX, EVEX_KZ;
1889   }
1890   let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable,
1891       SchedRW = [WriteLoad] in
1892   def rm : AVX512PI<opc, MRMSrcMem, (outs RC:$dst), (ins memop:$src),
1893                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1894                     [(set RC:$dst, (vt (bitconvert (ld_frag addr:$src))))],
1895                     d>, EVEX;
1896
1897   let AddedComplexity = 20 in {
1898   let Constraints = "$src0 = $dst",  hasSideEffects = 0 in {
1899   let hasSideEffects = 0 in
1900     def rrk : AVX512PI<opc, MRMSrcReg, (outs RC:$dst),
1901                      (ins RC:$src0, KRC:$mask, RC:$src1),
1902                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
1903                       "${dst} {${mask}}, $src1}"),
1904                      [(set RC:$dst, (vt (vselect KRC:$mask,
1905                                           (vt RC:$src1),
1906                                           (vt RC:$src0))))],
1907                      d>, EVEX, EVEX_K;
1908   let mayLoad = 1, SchedRW = [WriteLoad] in
1909     def rmk : AVX512PI<opc, MRMSrcMem, (outs RC:$dst),
1910                      (ins RC:$src0, KRC:$mask, memop:$src1),
1911                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
1912                       "${dst} {${mask}}, $src1}"),
1913                      [(set RC:$dst, (vt
1914                          (vselect KRC:$mask,
1915                                  (vt (bitconvert (ld_frag addr:$src1))),
1916                                  (vt RC:$src0))))],
1917                      d>, EVEX, EVEX_K;
1918   }
1919   let mayLoad = 1, SchedRW = [WriteLoad] in
1920     def rmkz : AVX512PI<opc, MRMSrcMem, (outs RC:$dst),
1921                       (ins KRC:$mask, memop:$src),
1922                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
1923                        "${dst} {${mask}} {z}, $src}"),
1924                       [(set RC:$dst, (vt
1925                            (vselect KRC:$mask,
1926                                      (vt (bitconvert (ld_frag addr:$src))),
1927                                      (vt (bitconvert (zvt immAllZerosV))))))],
1928                       d>, EVEX, EVEX_KZ;
1929   }
1930 }
1931
1932 multiclass avx512_load_vl<bits<8> opc, string OpcodeStr, string ld_pat,
1933                           string elty, string elsz, string vsz512,
1934                           string vsz256, string vsz128, Domain d,
1935                           Predicate prd, bit IsReMaterializable = 1> {
1936   let Predicates = [prd] in
1937   defm Z : avx512_load<opc, OpcodeStr,
1938                        !cast<PatFrag>(ld_pat##"v"##vsz512##elty##elsz),
1939                        !cast<RegisterClass>("VK"##vsz512##"WM"), VR512,
1940                        !cast<ValueType>("v"##vsz512##elty##elsz), v16i32,
1941                        !cast<X86MemOperand>(elty##"512mem"), d,
1942                        IsReMaterializable>, EVEX_V512;
1943
1944   let Predicates = [prd, HasVLX] in {
1945     defm Z256 : avx512_load<opc, OpcodeStr,
1946                        !cast<PatFrag>(ld_pat##!if(!eq(elty,"f"),
1947                              "v"##vsz256##elty##elsz, "v4i64")),
1948                        !cast<RegisterClass>("VK"##vsz256##"WM"), VR256X,
1949                        !cast<ValueType>("v"##vsz256##elty##elsz), v8i32,
1950                        !cast<X86MemOperand>(elty##"256mem"), d,
1951                        IsReMaterializable>, EVEX_V256;
1952
1953     defm Z128 : avx512_load<opc, OpcodeStr,
1954                        !cast<PatFrag>(ld_pat##!if(!eq(elty,"f"),
1955                              "v"##vsz128##elty##elsz, "v2i64")),
1956                        !cast<RegisterClass>("VK"##vsz128##"WM"), VR128X,
1957                        !cast<ValueType>("v"##vsz128##elty##elsz), v4i32,
1958                        !cast<X86MemOperand>(elty##"128mem"), d,
1959                        IsReMaterializable>, EVEX_V128;
1960   }
1961 }
1962
1963
1964 multiclass avx512_store<bits<8> opc, string OpcodeStr, PatFrag st_frag,
1965                         ValueType OpVT, RegisterClass KRC, RegisterClass RC,
1966                         X86MemOperand memop, Domain d> {
1967   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1968   def rr_alt : AVX512PI<opc, MRMDestReg, (outs RC:$dst), (ins RC:$src),
1969               !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [], d>,
1970               EVEX;
1971   let Constraints = "$src1 = $dst" in
1972   def rrk_alt : AVX512PI<opc, MRMDestReg, (outs  RC:$dst),
1973                                           (ins RC:$src1, KRC:$mask, RC:$src2),
1974               !strconcat(OpcodeStr,
1975               "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"), [], d>,
1976               EVEX, EVEX_K;
1977   def rrkz_alt : AVX512PI<opc, MRMDestReg, (outs  RC:$dst),
1978                                            (ins KRC:$mask, RC:$src),
1979               !strconcat(OpcodeStr,
1980               "\t{$src, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src}"),
1981               [], d>, EVEX, EVEX_KZ;
1982   }
1983   let mayStore = 1 in {
1984   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins memop:$dst, RC:$src),
1985                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1986                     [(st_frag (OpVT RC:$src), addr:$dst)], d>, EVEX;
1987   def mrk : AVX512PI<opc, MRMDestMem, (outs),
1988                                       (ins memop:$dst, KRC:$mask, RC:$src),
1989               !strconcat(OpcodeStr,
1990               "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
1991                [], d>, EVEX, EVEX_K;
1992   }
1993 }
1994
1995
1996 multiclass avx512_store_vl<bits<8> opc, string OpcodeStr, string st_pat,
1997                            string st_suff_512, string st_suff_256,
1998                            string st_suff_128, string elty, string elsz,
1999                            string vsz512, string vsz256, string vsz128,
2000                            Domain d, Predicate prd> {
2001   let Predicates = [prd] in
2002   defm Z : avx512_store<opc, OpcodeStr, !cast<PatFrag>(st_pat##st_suff_512),
2003                         !cast<ValueType>("v"##vsz512##elty##elsz),
2004                         !cast<RegisterClass>("VK"##vsz512##"WM"), VR512,
2005                         !cast<X86MemOperand>(elty##"512mem"), d>, EVEX_V512;
2006
2007   let Predicates = [prd, HasVLX] in {
2008     defm Z256 : avx512_store<opc, OpcodeStr, !cast<PatFrag>(st_pat##st_suff_256),
2009                              !cast<ValueType>("v"##vsz256##elty##elsz),
2010                              !cast<RegisterClass>("VK"##vsz256##"WM"), VR256X,
2011                              !cast<X86MemOperand>(elty##"256mem"), d>, EVEX_V256;
2012
2013     defm Z128 : avx512_store<opc, OpcodeStr, !cast<PatFrag>(st_pat##st_suff_128),
2014                              !cast<ValueType>("v"##vsz128##elty##elsz),
2015                              !cast<RegisterClass>("VK"##vsz128##"WM"), VR128X,
2016                              !cast<X86MemOperand>(elty##"128mem"), d>, EVEX_V128;
2017   }
2018 }
2019
2020 defm VMOVAPS : avx512_load_vl<0x28, "vmovaps", "alignedload", "f", "32",
2021                               "16", "8", "4", SSEPackedSingle, HasAVX512>,
2022                avx512_store_vl<0x29, "vmovaps", "alignedstore",
2023                                "512", "256", "", "f", "32", "16", "8", "4",
2024                                SSEPackedSingle, HasAVX512>,
2025                               PS, EVEX_CD8<32, CD8VF>;
2026
2027 defm VMOVAPD : avx512_load_vl<0x28, "vmovapd", "alignedload", "f", "64",
2028                               "8", "4", "2", SSEPackedDouble, HasAVX512>,
2029                avx512_store_vl<0x29, "vmovapd", "alignedstore",
2030                                "512", "256", "", "f", "64", "8", "4", "2",
2031                                SSEPackedDouble, HasAVX512>,
2032                               PD, VEX_W, EVEX_CD8<64, CD8VF>;
2033
2034 defm VMOVUPS : avx512_load_vl<0x10, "vmovups", "load", "f", "32",
2035                               "16", "8", "4", SSEPackedSingle, HasAVX512>,
2036                avx512_store_vl<0x11, "vmovups", "store", "", "", "", "f", "32",
2037                               "16", "8", "4", SSEPackedSingle, HasAVX512>,
2038                               PS, EVEX_CD8<32, CD8VF>;
2039
2040 defm VMOVUPD : avx512_load_vl<0x10, "vmovupd", "load", "f", "64",
2041                               "8", "4", "2", SSEPackedDouble, HasAVX512, 0>,
2042                avx512_store_vl<0x11, "vmovupd", "store", "", "", "", "f", "64",
2043                               "8", "4", "2", SSEPackedDouble, HasAVX512>,
2044                              PD, VEX_W, EVEX_CD8<64, CD8VF>;
2045
2046 def: Pat<(v8f64 (int_x86_avx512_mask_loadu_pd_512 addr:$ptr,
2047                 (bc_v8f64 (v16i32 immAllZerosV)), GR8:$mask)),
2048        (VMOVUPDZrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
2049
2050 def: Pat<(v16f32 (int_x86_avx512_mask_loadu_ps_512 addr:$ptr,
2051                  (bc_v16f32 (v16i32 immAllZerosV)), GR16:$mask)),
2052        (VMOVUPSZrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
2053
2054 def: Pat<(int_x86_avx512_mask_storeu_ps_512 addr:$ptr, (v16f32 VR512:$src),
2055           GR16:$mask),
2056          (VMOVUPSZmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
2057             VR512:$src)>;
2058 def: Pat<(int_x86_avx512_mask_storeu_pd_512 addr:$ptr, (v8f64 VR512:$src),
2059           GR8:$mask),
2060          (VMOVUPDZmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
2061             VR512:$src)>;
2062
2063 defm VMOVDQA32 : avx512_load_vl<0x6F, "vmovdqa32", "alignedload", "i", "32",
2064                                 "16", "8", "4", SSEPackedInt, HasAVX512>,
2065                  avx512_store_vl<0x7F, "vmovdqa32", "alignedstore",
2066                                  "512", "256", "", "i", "32", "16", "8", "4",
2067                                  SSEPackedInt, HasAVX512>,
2068                                 PD, EVEX_CD8<32, CD8VF>;
2069
2070 defm VMOVDQA64 : avx512_load_vl<0x6F, "vmovdqa64", "alignedload", "i", "64",
2071                                 "8", "4", "2", SSEPackedInt, HasAVX512>,
2072                  avx512_store_vl<0x7F, "vmovdqa64", "alignedstore",
2073                                  "512", "256", "", "i", "64", "8", "4", "2",
2074                                  SSEPackedInt, HasAVX512>,
2075                                 PD, VEX_W, EVEX_CD8<64, CD8VF>;
2076
2077 defm VMOVDQU8 : avx512_load_vl<0x6F, "vmovdqu8", "load", "i", "8",
2078                                "64", "32", "16", SSEPackedInt, HasBWI>,
2079                  avx512_store_vl<0x7F, "vmovdqu8", "store", "", "", "",
2080                                  "i", "8", "64", "32", "16", SSEPackedInt,
2081                                  HasBWI>, XD, EVEX_CD8<8, CD8VF>;
2082
2083 defm VMOVDQU16 : avx512_load_vl<0x6F, "vmovdqu16", "load", "i", "16",
2084                                 "32", "16", "8", SSEPackedInt, HasBWI>,
2085                  avx512_store_vl<0x7F, "vmovdqu16", "store", "", "", "",
2086                                  "i", "16", "32", "16", "8", SSEPackedInt,
2087                                  HasBWI>, XD, VEX_W, EVEX_CD8<16, CD8VF>;
2088
2089 defm VMOVDQU32 : avx512_load_vl<0x6F, "vmovdqu32", "load", "i", "32",
2090                                 "16", "8", "4", SSEPackedInt, HasAVX512>,
2091                  avx512_store_vl<0x7F, "vmovdqu32", "store", "", "", "",
2092                                  "i", "32", "16", "8", "4", SSEPackedInt,
2093                                  HasAVX512>, XS, EVEX_CD8<32, CD8VF>;
2094
2095 defm VMOVDQU64 : avx512_load_vl<0x6F, "vmovdqu64", "load", "i", "64",
2096                                 "8", "4", "2", SSEPackedInt, HasAVX512>,
2097                  avx512_store_vl<0x7F, "vmovdqu64", "store", "", "", "",
2098                                  "i", "64", "8", "4", "2", SSEPackedInt,
2099                                  HasAVX512>, XS, VEX_W, EVEX_CD8<64, CD8VF>;
2100
2101 def: Pat<(v16i32 (int_x86_avx512_mask_loadu_d_512 addr:$ptr,
2102                  (v16i32 immAllZerosV), GR16:$mask)),
2103        (VMOVDQU32Zrmkz (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)), addr:$ptr)>;
2104
2105 def: Pat<(v8i64 (int_x86_avx512_mask_loadu_q_512 addr:$ptr,
2106                 (bc_v8i64 (v16i32 immAllZerosV)), GR8:$mask)),
2107        (VMOVDQU64Zrmkz (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)), addr:$ptr)>;
2108
2109 def: Pat<(int_x86_avx512_mask_storeu_d_512 addr:$ptr, (v16i32 VR512:$src),
2110             GR16:$mask),
2111          (VMOVDQU32Zmrk addr:$ptr, (v16i1 (COPY_TO_REGCLASS GR16:$mask, VK16WM)),
2112             VR512:$src)>;
2113 def: Pat<(int_x86_avx512_mask_storeu_q_512 addr:$ptr, (v8i64 VR512:$src),
2114             GR8:$mask),
2115          (VMOVDQU64Zmrk addr:$ptr, (v8i1 (COPY_TO_REGCLASS GR8:$mask, VK8WM)),
2116             VR512:$src)>;
2117
2118 let AddedComplexity = 20 in {
2119 def : Pat<(v8i64 (vselect VK8WM:$mask, (v8i64 VR512:$src),
2120                           (bc_v8i64 (v16i32 immAllZerosV)))),
2121                   (VMOVDQU64Zrrkz VK8WM:$mask, VR512:$src)>;
2122
2123 def : Pat<(v8i64 (vselect VK8WM:$mask, (bc_v8i64 (v16i32 immAllZerosV)),
2124                           (v8i64 VR512:$src))),
2125    (VMOVDQU64Zrrkz (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$mask, VK16)),
2126                                               VK8), VR512:$src)>;
2127
2128 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 VR512:$src),
2129                            (v16i32 immAllZerosV))),
2130                   (VMOVDQU32Zrrkz VK16WM:$mask, VR512:$src)>;
2131
2132 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 immAllZerosV),
2133                            (v16i32 VR512:$src))),
2134                   (VMOVDQU32Zrrkz (KNOTWrr VK16WM:$mask), VR512:$src)>;
2135 }
2136
2137 // Move Int Doubleword to Packed Double Int
2138 //
2139 def VMOVDI2PDIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR32:$src),
2140                       "vmovd\t{$src, $dst|$dst, $src}",
2141                       [(set VR128X:$dst,
2142                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
2143                         EVEX, VEX_LIG;
2144 def VMOVDI2PDIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst), (ins i32mem:$src),
2145                       "vmovd\t{$src, $dst|$dst, $src}",
2146                       [(set VR128X:$dst,
2147                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
2148                         IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2149 def VMOV64toPQIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR64:$src),
2150                       "vmovq\t{$src, $dst|$dst, $src}",
2151                         [(set VR128X:$dst,
2152                           (v2i64 (scalar_to_vector GR64:$src)))],
2153                           IIC_SSE_MOVDQ>, EVEX, VEX_W, VEX_LIG;
2154 let isCodeGenOnly = 1 in {
2155 def VMOV64toSDZrr : AVX512BI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
2156                        "vmovq\t{$src, $dst|$dst, $src}",
2157                        [(set FR64:$dst, (bitconvert GR64:$src))],
2158                        IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
2159 def VMOVSDto64Zrr : AVX512BI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
2160                          "vmovq\t{$src, $dst|$dst, $src}",
2161                          [(set GR64:$dst, (bitconvert FR64:$src))],
2162                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
2163 }
2164 def VMOVSDto64Zmr : AVX512BI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
2165                          "vmovq\t{$src, $dst|$dst, $src}",
2166                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
2167                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteStore]>,
2168                          EVEX_CD8<64, CD8VT1>;
2169
2170 // Move Int Doubleword to Single Scalar
2171 //
2172 let isCodeGenOnly = 1 in {
2173 def VMOVDI2SSZrr  : AVX512BI<0x6E, MRMSrcReg, (outs FR32X:$dst), (ins GR32:$src),
2174                       "vmovd\t{$src, $dst|$dst, $src}",
2175                       [(set FR32X:$dst, (bitconvert GR32:$src))],
2176                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG;
2177
2178 def VMOVDI2SSZrm  : AVX512BI<0x6E, MRMSrcMem, (outs FR32X:$dst), (ins i32mem:$src),
2179                       "vmovd\t{$src, $dst|$dst, $src}",
2180                       [(set FR32X:$dst, (bitconvert (loadi32 addr:$src)))],
2181                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2182 }
2183
2184 // Move doubleword from xmm register to r/m32
2185 //
2186 def VMOVPDI2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128X:$src),
2187                        "vmovd\t{$src, $dst|$dst, $src}",
2188                        [(set GR32:$dst, (vector_extract (v4i32 VR128X:$src),
2189                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
2190                        EVEX, VEX_LIG;
2191 def VMOVPDI2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
2192                        (ins i32mem:$dst, VR128X:$src),
2193                        "vmovd\t{$src, $dst|$dst, $src}",
2194                        [(store (i32 (vector_extract (v4i32 VR128X:$src),
2195                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
2196                        EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2197
2198 // Move quadword from xmm1 register to r/m64
2199 //
2200 def VMOVPQIto64Zrr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128X:$src),
2201                       "vmovq\t{$src, $dst|$dst, $src}",
2202                       [(set GR64:$dst, (extractelt (v2i64 VR128X:$src),
2203                                                    (iPTR 0)))],
2204                       IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_LIG, VEX_W,
2205                       Requires<[HasAVX512, In64BitMode]>;
2206
2207 def VMOVPQIto64Zmr : I<0xD6, MRMDestMem, (outs),
2208                        (ins i64mem:$dst, VR128X:$src),
2209                        "vmovq\t{$src, $dst|$dst, $src}",
2210                        [(store (extractelt (v2i64 VR128X:$src), (iPTR 0)),
2211                                addr:$dst)], IIC_SSE_MOVDQ>,
2212                        EVEX, PD, VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>,
2213                        Sched<[WriteStore]>, Requires<[HasAVX512, In64BitMode]>;
2214
2215 // Move Scalar Single to Double Int
2216 //
2217 let isCodeGenOnly = 1 in {
2218 def VMOVSS2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst),
2219                       (ins FR32X:$src),
2220                       "vmovd\t{$src, $dst|$dst, $src}",
2221                       [(set GR32:$dst, (bitconvert FR32X:$src))],
2222                       IIC_SSE_MOVD_ToGP>, EVEX, VEX_LIG;
2223 def VMOVSS2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
2224                       (ins i32mem:$dst, FR32X:$src),
2225                       "vmovd\t{$src, $dst|$dst, $src}",
2226                       [(store (i32 (bitconvert FR32X:$src)), addr:$dst)],
2227                       IIC_SSE_MOVDQ>, EVEX, VEX_LIG, EVEX_CD8<32, CD8VT1>;
2228 }
2229
2230 // Move Quadword Int to Packed Quadword Int
2231 //
2232 def VMOVQI2PQIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst),
2233                       (ins i64mem:$src),
2234                       "vmovq\t{$src, $dst|$dst, $src}",
2235                       [(set VR128X:$dst,
2236                         (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>,
2237                       EVEX, VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
2238
2239 //===----------------------------------------------------------------------===//
2240 // AVX-512  MOVSS, MOVSD
2241 //===----------------------------------------------------------------------===//
2242
2243 multiclass avx512_move_scalar <string asm, RegisterClass RC, 
2244                               SDNode OpNode, ValueType vt,
2245                               X86MemOperand x86memop, PatFrag mem_pat> {
2246   let hasSideEffects = 0 in {
2247   def rr : SI<0x10, MRMSrcReg, (outs VR128X:$dst), (ins VR128X:$src1, RC:$src2), 
2248               !strconcat(asm, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2249               [(set VR128X:$dst, (vt (OpNode VR128X:$src1,
2250                                       (scalar_to_vector RC:$src2))))],
2251               IIC_SSE_MOV_S_RR>, EVEX_4V, VEX_LIG;
2252   let Constraints = "$src1 = $dst" in
2253   def rrk : SI<0x10, MRMSrcReg, (outs VR128X:$dst),
2254               (ins VR128X:$src1, VK1WM:$mask, RC:$src2, RC:$src3),
2255               !strconcat(asm,
2256                 " \t{$src3, $src2, $dst {${mask}}|$dst {${mask}}, $src2, $src3}"),
2257               [], IIC_SSE_MOV_S_RR>, EVEX_4V, VEX_LIG, EVEX_K;
2258   def rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
2259               !strconcat(asm, " \t{$src, $dst|$dst, $src}"),
2260               [(set RC:$dst, (mem_pat addr:$src))], IIC_SSE_MOV_S_RM>,
2261               EVEX, VEX_LIG;
2262   let mayStore = 1 in {
2263   def mr: SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
2264              !strconcat(asm, " \t{$src, $dst|$dst, $src}"),
2265              [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
2266              EVEX, VEX_LIG;
2267   def mrk: SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, VK1WM:$mask, RC:$src),
2268              !strconcat(asm, " \t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
2269              [], IIC_SSE_MOV_S_MR>,
2270              EVEX, VEX_LIG, EVEX_K;
2271   } // mayStore
2272   } //hasSideEffects = 0
2273 }
2274
2275 let ExeDomain = SSEPackedSingle in
2276 defm VMOVSSZ : avx512_move_scalar<"movss", FR32X, X86Movss, v4f32, f32mem,
2277                                  loadf32>, XS, EVEX_CD8<32, CD8VT1>;
2278
2279 let ExeDomain = SSEPackedDouble in
2280 defm VMOVSDZ : avx512_move_scalar<"movsd", FR64X, X86Movsd, v2f64, f64mem,
2281                                  loadf64>, XD, VEX_W, EVEX_CD8<64, CD8VT1>;
2282
2283 def : Pat<(f32 (X86select VK1WM:$mask, (f32 FR32X:$src1), (f32 FR32X:$src2))),
2284           (COPY_TO_REGCLASS (VMOVSSZrrk (COPY_TO_REGCLASS FR32X:$src2, VR128X),
2285            VK1WM:$mask, (f32 (IMPLICIT_DEF)), FR32X:$src1), FR32X)>;
2286
2287 def : Pat<(f64 (X86select VK1WM:$mask, (f64 FR64X:$src1), (f64 FR64X:$src2))),
2288           (COPY_TO_REGCLASS (VMOVSDZrrk (COPY_TO_REGCLASS FR64X:$src2, VR128X),
2289            VK1WM:$mask, (f64 (IMPLICIT_DEF)), FR64X:$src1), FR64X)>;
2290
2291 def : Pat<(int_x86_avx512_mask_store_ss addr:$dst, VR128X:$src, GR8:$mask),
2292           (VMOVSSZmrk addr:$dst, (i1 (COPY_TO_REGCLASS GR8:$mask, VK1WM)),
2293            (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2294
2295 // For the disassembler
2296 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
2297   def VMOVSSZrr_REV : SI<0x11, MRMDestReg, (outs VR128X:$dst),
2298                         (ins VR128X:$src1, FR32X:$src2),
2299                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
2300                         IIC_SSE_MOV_S_RR>,
2301                         XS, EVEX_4V, VEX_LIG;
2302   def VMOVSDZrr_REV : SI<0x11, MRMDestReg, (outs VR128X:$dst),
2303                         (ins VR128X:$src1, FR64X:$src2),
2304                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
2305                         IIC_SSE_MOV_S_RR>,
2306                         XD, EVEX_4V, VEX_LIG, VEX_W;
2307 }
2308
2309 let Predicates = [HasAVX512] in {
2310   let AddedComplexity = 15 in {
2311   // Move scalar to XMM zero-extended, zeroing a VR128X then do a
2312   // MOVS{S,D} to the lower bits.
2313   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32X:$src)))),
2314             (VMOVSSZrr (v4f32 (V_SET0)), FR32X:$src)>;
2315   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128X:$src))),
2316             (VMOVSSZrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2317   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128X:$src))),
2318             (VMOVSSZrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
2319   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64X:$src)))),
2320             (VMOVSDZrr (v2f64 (V_SET0)), FR64X:$src)>;
2321
2322   // Move low f32 and clear high bits.
2323   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256X:$src))),
2324             (SUBREG_TO_REG (i32 0),
2325              (VMOVSSZrr (v4f32 (V_SET0)), 
2326               (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm)), sub_xmm)>;
2327   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256X:$src))),
2328             (SUBREG_TO_REG (i32 0),
2329              (VMOVSSZrr (v4i32 (V_SET0)),
2330                        (EXTRACT_SUBREG (v8i32 VR256X:$src), sub_xmm)), sub_xmm)>;
2331   }
2332
2333   let AddedComplexity = 20 in {
2334   // MOVSSrm zeros the high parts of the register; represent this
2335   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
2336   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
2337             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2338   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
2339             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2340   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
2341             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
2342
2343   // MOVSDrm zeros the high parts of the register; represent this
2344   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
2345   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
2346             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2347   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
2348             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2349   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
2350             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2351   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
2352             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2353   def : Pat<(v2f64 (X86vzload addr:$src)),
2354             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
2355
2356   // Represent the same patterns above but in the form they appear for
2357   // 256-bit types
2358   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
2359                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
2360             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
2361   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
2362                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
2363             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
2364   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
2365                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
2366             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
2367   }
2368   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
2369                    (v4f32 (scalar_to_vector FR32X:$src)), (iPTR 0)))),
2370             (SUBREG_TO_REG (i32 0), (v4f32 (VMOVSSZrr (v4f32 (V_SET0)),
2371                                             FR32X:$src)), sub_xmm)>;
2372   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
2373                    (v2f64 (scalar_to_vector FR64X:$src)), (iPTR 0)))),
2374             (SUBREG_TO_REG (i64 0), (v2f64 (VMOVSDZrr (v2f64 (V_SET0)),
2375                                      FR64X:$src)), sub_xmm)>;
2376   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
2377                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
2378             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
2379
2380   // Move low f64 and clear high bits.
2381   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256X:$src))),
2382             (SUBREG_TO_REG (i32 0),
2383              (VMOVSDZrr (v2f64 (V_SET0)),
2384                        (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm)), sub_xmm)>;
2385
2386   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256X:$src))),
2387             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (V_SET0)),
2388                        (EXTRACT_SUBREG (v4i64 VR256X:$src), sub_xmm)), sub_xmm)>;
2389
2390   // Extract and store.
2391   def : Pat<(store (f32 (vector_extract (v4f32 VR128X:$src), (iPTR 0))),
2392                    addr:$dst),
2393             (VMOVSSZmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128X:$src), FR32X))>;
2394   def : Pat<(store (f64 (vector_extract (v2f64 VR128X:$src), (iPTR 0))),
2395                    addr:$dst),
2396             (VMOVSDZmr addr:$dst, (COPY_TO_REGCLASS (v2f64 VR128X:$src), FR64X))>;
2397
2398   // Shuffle with VMOVSS
2399   def : Pat<(v4i32 (X86Movss VR128X:$src1, VR128X:$src2)),
2400             (VMOVSSZrr (v4i32 VR128X:$src1),
2401                       (COPY_TO_REGCLASS (v4i32 VR128X:$src2), FR32X))>;
2402   def : Pat<(v4f32 (X86Movss VR128X:$src1, VR128X:$src2)),
2403             (VMOVSSZrr (v4f32 VR128X:$src1),
2404                       (COPY_TO_REGCLASS (v4f32 VR128X:$src2), FR32X))>;
2405
2406   // 256-bit variants
2407   def : Pat<(v8i32 (X86Movss VR256X:$src1, VR256X:$src2)),
2408             (SUBREG_TO_REG (i32 0),
2409               (VMOVSSZrr (EXTRACT_SUBREG (v8i32 VR256X:$src1), sub_xmm),
2410                         (EXTRACT_SUBREG (v8i32 VR256X:$src2), sub_xmm)),
2411               sub_xmm)>;
2412   def : Pat<(v8f32 (X86Movss VR256X:$src1, VR256X:$src2)),
2413             (SUBREG_TO_REG (i32 0),
2414               (VMOVSSZrr (EXTRACT_SUBREG (v8f32 VR256X:$src1), sub_xmm),
2415                         (EXTRACT_SUBREG (v8f32 VR256X:$src2), sub_xmm)),
2416               sub_xmm)>;
2417
2418   // Shuffle with VMOVSD
2419   def : Pat<(v2i64 (X86Movsd VR128X:$src1, VR128X:$src2)),
2420             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2421   def : Pat<(v2f64 (X86Movsd VR128X:$src1, VR128X:$src2)),
2422             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2423   def : Pat<(v4f32 (X86Movsd VR128X:$src1, VR128X:$src2)),
2424             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2425   def : Pat<(v4i32 (X86Movsd VR128X:$src1, VR128X:$src2)),
2426             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2427
2428   // 256-bit variants
2429   def : Pat<(v4i64 (X86Movsd VR256X:$src1, VR256X:$src2)),
2430             (SUBREG_TO_REG (i32 0),
2431               (VMOVSDZrr (EXTRACT_SUBREG (v4i64 VR256X:$src1), sub_xmm),
2432                         (EXTRACT_SUBREG (v4i64 VR256X:$src2), sub_xmm)),
2433               sub_xmm)>;
2434   def : Pat<(v4f64 (X86Movsd VR256X:$src1, VR256X:$src2)),
2435             (SUBREG_TO_REG (i32 0),
2436               (VMOVSDZrr (EXTRACT_SUBREG (v4f64 VR256X:$src1), sub_xmm),
2437                         (EXTRACT_SUBREG (v4f64 VR256X:$src2), sub_xmm)),
2438               sub_xmm)>;
2439
2440   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
2441             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2442   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
2443             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2444   def : Pat<(v4f32 (X86Movlps VR128X:$src1, VR128X:$src2)),
2445             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2446   def : Pat<(v4i32 (X86Movlps VR128X:$src1, VR128X:$src2)),
2447             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
2448 }
2449
2450 let AddedComplexity = 15 in
2451 def VMOVZPQILo2PQIZrr : AVX512XSI<0x7E, MRMSrcReg, (outs VR128X:$dst),
2452                                 (ins VR128X:$src),
2453                                 "vmovq\t{$src, $dst|$dst, $src}",
2454                                 [(set VR128X:$dst, (v2i64 (X86vzmovl 
2455                                                    (v2i64 VR128X:$src))))],
2456                                 IIC_SSE_MOVQ_RR>, EVEX, VEX_W;
2457
2458 let AddedComplexity = 20 in
2459 def VMOVZPQILo2PQIZrm : AVX512XSI<0x7E, MRMSrcMem, (outs VR128X:$dst),
2460                                  (ins i128mem:$src),
2461                                  "vmovq\t{$src, $dst|$dst, $src}",
2462                                  [(set VR128X:$dst, (v2i64 (X86vzmovl
2463                                                      (loadv2i64 addr:$src))))],
2464                                  IIC_SSE_MOVDQ>, EVEX, VEX_W,
2465                                  EVEX_CD8<8, CD8VT8>;
2466
2467 let Predicates = [HasAVX512] in {
2468   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
2469   let AddedComplexity = 20 in {
2470     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
2471               (VMOVDI2PDIZrm addr:$src)>;
2472     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
2473               (VMOV64toPQIZrr GR64:$src)>;
2474     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
2475               (VMOVDI2PDIZrr GR32:$src)>;
2476               
2477     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
2478               (VMOVDI2PDIZrm addr:$src)>;
2479     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
2480               (VMOVDI2PDIZrm addr:$src)>;
2481     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
2482             (VMOVZPQILo2PQIZrm addr:$src)>;
2483     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128X:$src))),
2484             (VMOVZPQILo2PQIZrr VR128X:$src)>;
2485     def : Pat<(v2i64 (X86vzload addr:$src)),
2486             (VMOVZPQILo2PQIZrm addr:$src)>;
2487   }
2488
2489   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
2490   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
2491                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
2492             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
2493   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
2494                                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
2495             (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
2496 }
2497
2498 def : Pat<(v16i32 (X86Vinsert (v16i32 immAllZerosV), GR32:$src2, (iPTR 0))),
2499         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
2500
2501 def : Pat<(v8i64 (X86Vinsert (bc_v8i64 (v16i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
2502         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
2503
2504 def : Pat<(v16i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
2505         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
2506
2507 def : Pat<(v8i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
2508         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
2509
2510 //===----------------------------------------------------------------------===//
2511 // AVX-512 - Non-temporals
2512 //===----------------------------------------------------------------------===//
2513 let SchedRW = [WriteLoad] in {
2514   def VMOVNTDQAZrm : AVX512PI<0x2A, MRMSrcMem, (outs VR512:$dst),
2515                         (ins i512mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}",
2516                         [(set VR512:$dst, (int_x86_avx512_movntdqa addr:$src))],
2517                         SSEPackedInt>, EVEX, T8PD, EVEX_V512,
2518                         EVEX_CD8<64, CD8VF>;
2519
2520   let Predicates = [HasAVX512, HasVLX] in {
2521     def VMOVNTDQAZ256rm : AVX512PI<0x2A, MRMSrcMem, (outs VR256X:$dst),
2522                              (ins i256mem:$src),
2523                              "vmovntdqa\t{$src, $dst|$dst, $src}", [],
2524                              SSEPackedInt>, EVEX, T8PD, EVEX_V256,
2525                              EVEX_CD8<64, CD8VF>;
2526
2527     def VMOVNTDQAZ128rm : AVX512PI<0x2A, MRMSrcMem, (outs VR128X:$dst),
2528                              (ins i128mem:$src),
2529                              "vmovntdqa\t{$src, $dst|$dst, $src}", [],
2530                              SSEPackedInt>, EVEX, T8PD, EVEX_V128,
2531                              EVEX_CD8<64, CD8VF>;
2532   }
2533 }
2534
2535 multiclass avx512_movnt<bits<8> opc, string OpcodeStr, PatFrag st_frag,
2536                         ValueType OpVT, RegisterClass RC, X86MemOperand memop,
2537                         Domain d, InstrItinClass itin = IIC_SSE_MOVNT> {
2538   let SchedRW = [WriteStore], mayStore = 1,
2539       AddedComplexity = 400 in
2540   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins memop:$dst, RC:$src),
2541                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2542                     [(st_frag (OpVT RC:$src), addr:$dst)], d, itin>, EVEX;
2543 }
2544
2545 multiclass avx512_movnt_vl<bits<8> opc, string OpcodeStr, PatFrag st_frag,
2546                            string elty, string elsz, string vsz512,
2547                            string vsz256, string vsz128, Domain d,
2548                            Predicate prd, InstrItinClass itin = IIC_SSE_MOVNT> {
2549   let Predicates = [prd] in
2550   defm Z : avx512_movnt<opc, OpcodeStr, st_frag,
2551                         !cast<ValueType>("v"##vsz512##elty##elsz), VR512,
2552                         !cast<X86MemOperand>(elty##"512mem"), d, itin>,
2553                         EVEX_V512;
2554
2555   let Predicates = [prd, HasVLX] in {
2556     defm Z256 : avx512_movnt<opc, OpcodeStr, st_frag,
2557                              !cast<ValueType>("v"##vsz256##elty##elsz), VR256X,
2558                              !cast<X86MemOperand>(elty##"256mem"), d, itin>,
2559                              EVEX_V256;
2560
2561     defm Z128 : avx512_movnt<opc, OpcodeStr, st_frag,
2562                              !cast<ValueType>("v"##vsz128##elty##elsz), VR128X,
2563                              !cast<X86MemOperand>(elty##"128mem"), d, itin>,
2564                              EVEX_V128;
2565   }
2566 }
2567
2568 defm VMOVNTDQ : avx512_movnt_vl<0xE7, "vmovntdq", alignednontemporalstore,
2569                                 "i", "64", "8", "4", "2", SSEPackedInt,
2570                                 HasAVX512>, PD, EVEX_CD8<64, CD8VF>;
2571
2572 defm VMOVNTPD : avx512_movnt_vl<0x2B, "vmovntpd", alignednontemporalstore,
2573                                 "f", "64", "8", "4", "2", SSEPackedDouble,
2574                                 HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2575
2576 defm VMOVNTPS : avx512_movnt_vl<0x2B, "vmovntps", alignednontemporalstore,
2577                                 "f", "32", "16", "8", "4", SSEPackedSingle,
2578                                 HasAVX512>, PS, EVEX_CD8<32, CD8VF>;
2579
2580 //===----------------------------------------------------------------------===//
2581 // AVX-512 - Integer arithmetic
2582 //
2583 multiclass avx512_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2584                            X86VectorVTInfo _, OpndItins itins,
2585                            bit IsCommutable = 0> {
2586   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
2587                     (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
2588                     "$src2, $src1", "$src1, $src2",
2589                     (_.VT (OpNode _.RC:$src1, _.RC:$src2)),
2590                     itins.rr, IsCommutable>,
2591             AVX512BIBase, EVEX_4V;
2592
2593   let mayLoad = 1 in
2594     defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
2595                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
2596                     "$src2, $src1", "$src1, $src2",
2597                     (_.VT (OpNode _.RC:$src1,
2598                                   (bitconvert (_.LdFrag addr:$src2)))),
2599                     itins.rm>,
2600               AVX512BIBase, EVEX_4V;
2601 }
2602
2603 multiclass avx512_binop_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
2604                             X86VectorVTInfo _, OpndItins itins,
2605                             bit IsCommutable = 0> :
2606            avx512_binop_rm<opc, OpcodeStr, OpNode, _, itins, IsCommutable> {
2607   let mayLoad = 1 in
2608     defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
2609                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
2610                     "${src2}"##_.BroadcastStr##", $src1",
2611                     "$src1, ${src2}"##_.BroadcastStr,
2612                     (_.VT (OpNode _.RC:$src1,
2613                                   (X86VBroadcast
2614                                       (_.ScalarLdFrag addr:$src2)))),
2615                     itins.rm>,
2616                AVX512BIBase, EVEX_4V, EVEX_B;
2617 }
2618
2619 multiclass avx512_binop_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
2620                               AVX512VLVectorVTInfo VTInfo, OpndItins itins,
2621                               Predicate prd, bit IsCommutable = 0> {
2622   let Predicates = [prd] in
2623     defm Z : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
2624                              IsCommutable>, EVEX_V512;
2625
2626   let Predicates = [prd, HasVLX] in {
2627     defm Z256 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
2628                              IsCommutable>, EVEX_V256;
2629     defm Z128 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
2630                              IsCommutable>, EVEX_V128;
2631   }
2632 }
2633
2634 multiclass avx512_binop_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
2635                                AVX512VLVectorVTInfo VTInfo, OpndItins itins,
2636                                Predicate prd, bit IsCommutable = 0> {
2637   let Predicates = [prd] in
2638     defm Z : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
2639                              IsCommutable>, EVEX_V512;
2640
2641   let Predicates = [prd, HasVLX] in {
2642     defm Z256 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
2643                              IsCommutable>, EVEX_V256;
2644     defm Z128 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
2645                              IsCommutable>, EVEX_V128;
2646   }
2647 }
2648
2649 multiclass avx512_binop_rm_vl_q<bits<8> opc, string OpcodeStr, SDNode OpNode,
2650                                 OpndItins itins, Predicate prd,
2651                                 bit IsCommutable = 0> {
2652   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i64_info,
2653                                itins, prd, IsCommutable>,
2654                                VEX_W, EVEX_CD8<64, CD8VF>;
2655 }
2656
2657 multiclass avx512_binop_rm_vl_d<bits<8> opc, string OpcodeStr, SDNode OpNode,
2658                                 OpndItins itins, Predicate prd,
2659                                 bit IsCommutable = 0> {
2660   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i32_info,
2661                                itins, prd, IsCommutable>, EVEX_CD8<32, CD8VF>;
2662 }
2663
2664 multiclass avx512_binop_rm_vl_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
2665                                 OpndItins itins, Predicate prd,
2666                                 bit IsCommutable = 0> {
2667   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i16_info,
2668                               itins, prd, IsCommutable>, EVEX_CD8<16, CD8VF>;
2669 }
2670
2671 multiclass avx512_binop_rm_vl_b<bits<8> opc, string OpcodeStr, SDNode OpNode,
2672                                 OpndItins itins, Predicate prd,
2673                                 bit IsCommutable = 0> {
2674   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i8_info,
2675                               itins, prd, IsCommutable>, EVEX_CD8<8, CD8VF>;
2676 }
2677
2678 multiclass avx512_binop_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
2679                                  SDNode OpNode, OpndItins itins, Predicate prd,
2680                                  bit IsCommutable = 0> {
2681   defm Q : avx512_binop_rm_vl_q<opc_q, OpcodeStr, OpNode, itins, prd,
2682                                    IsCommutable>;
2683
2684   defm D : avx512_binop_rm_vl_d<opc_d, OpcodeStr, OpNode, itins, prd,
2685                                    IsCommutable>;
2686 }
2687
2688 multiclass avx512_binop_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
2689                                  SDNode OpNode, OpndItins itins, Predicate prd,
2690                                  bit IsCommutable = 0> {
2691   defm W : avx512_binop_rm_vl_w<opc_w, OpcodeStr, OpNode, itins, prd,
2692                                    IsCommutable>;
2693
2694   defm B : avx512_binop_rm_vl_b<opc_b, OpcodeStr, OpNode, itins, prd,
2695                                    IsCommutable>;
2696 }
2697
2698 multiclass avx512_binop_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
2699                                   bits<8> opc_d, bits<8> opc_q,
2700                                   string OpcodeStr, SDNode OpNode,
2701                                   OpndItins itins, bit IsCommutable = 0> {
2702   defm NAME : avx512_binop_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
2703                                     itins, HasAVX512, IsCommutable>,
2704               avx512_binop_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
2705                                     itins, HasBWI, IsCommutable>;
2706 }
2707
2708 multiclass avx512_binop_rm2<bits<8> opc, string OpcodeStr, ValueType DstVT,
2709                             ValueType SrcVT, RegisterClass KRC, RegisterClass RC,
2710                             PatFrag memop_frag, X86MemOperand x86memop,
2711                             PatFrag scalar_mfrag, X86MemOperand x86scalar_mop,
2712                             string BrdcstStr, OpndItins itins, bit IsCommutable = 0> {
2713   let isCommutable = IsCommutable in
2714   {
2715     def rr : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2716        (ins RC:$src1, RC:$src2),
2717        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2718        []>, EVEX_4V;
2719     def rrk : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2720                (ins KRC:$mask, RC:$src1, RC:$src2),
2721                !strconcat(OpcodeStr,
2722                   " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2723                [], itins.rr>, EVEX_4V, EVEX_K;
2724     def rrkz : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2725                 (ins KRC:$mask, RC:$src1, RC:$src2),
2726                 !strconcat(OpcodeStr, " \t{$src2, $src1, $dst {${mask}} {z}" ,
2727                     "|$dst {${mask}} {z}, $src1, $src2}"),
2728                 [], itins.rr>, EVEX_4V, EVEX_KZ;
2729   }
2730   let mayLoad = 1 in {
2731     def rm : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2732               (ins RC:$src1, x86memop:$src2),
2733               !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2734               []>, EVEX_4V;
2735     def rmk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2736                (ins KRC:$mask, RC:$src1, x86memop:$src2),
2737                !strconcat(OpcodeStr,
2738                    " \t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}"),
2739                [], itins.rm>, EVEX_4V, EVEX_K;
2740     def rmkz : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2741                 (ins KRC:$mask, RC:$src1, x86memop:$src2),
2742                 !strconcat(OpcodeStr,
2743                     " \t{$src2, $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, $src2}"),
2744                 [], itins.rm>, EVEX_4V, EVEX_KZ;
2745     def rmb : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2746                (ins RC:$src1, x86scalar_mop:$src2),
2747                !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2748                           ", $src1, $dst|$dst, $src1, ${src2}", BrdcstStr, "}"),
2749                [], itins.rm>, EVEX_4V, EVEX_B;
2750     def rmbk : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2751                 (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2),
2752                 !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2753                            ", $src1, $dst {${mask}}|$dst {${mask}}, $src1, ${src2}",
2754                            BrdcstStr, "}"),
2755                 [], itins.rm>, EVEX_4V, EVEX_B, EVEX_K;
2756     def rmbkz : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2757                  (ins KRC:$mask, RC:$src1, x86scalar_mop:$src2),
2758                  !strconcat(OpcodeStr, " \t{${src2}", BrdcstStr,
2759                             ", $src1, $dst {${mask}} {z}|$dst {${mask}} {z}, $src1, ${src2}",
2760                             BrdcstStr, "}"),
2761                  [], itins.rm>, EVEX_4V, EVEX_B, EVEX_KZ;
2762   }
2763 }
2764
2765 defm VPADD : avx512_binop_rm_vl_all<0xFC, 0xFD, 0xFE, 0xD4, "vpadd", add,
2766                                     SSE_INTALU_ITINS_P, 1>;
2767 defm VPSUB : avx512_binop_rm_vl_all<0xF8, 0xF9, 0xFA, 0xFB, "vpsub", sub,
2768                                     SSE_INTALU_ITINS_P, 0>;
2769 defm VPMULLD : avx512_binop_rm_vl_d<0x40, "vpmull", mul,
2770                                    SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
2771 defm VPMULLW : avx512_binop_rm_vl_w<0xD5, "vpmull", mul,
2772                                    SSE_INTALU_ITINS_P, HasBWI, 1>;
2773 defm VPMULLQ : avx512_binop_rm_vl_q<0x40, "vpmull", mul,
2774                                    SSE_INTALU_ITINS_P, HasDQI, 1>, T8PD;
2775
2776 defm VPMULDQZ : avx512_binop_rm2<0x28, "vpmuldq", v8i64, v16i32, VK8WM, VR512,
2777                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2778                    SSE_INTALU_ITINS_P, 1>, T8PD, EVEX_V512,
2779                    EVEX_CD8<64, CD8VF>, VEX_W;
2780
2781 defm VPMULUDQZ : avx512_binop_rm2<0xF4, "vpmuludq", v8i64, v16i32, VK8WM, VR512,
2782                    memopv8i64, i512mem, loadi64, i64mem, "{1to8}",
2783                    SSE_INTMUL_ITINS_P, 1>, EVEX_V512, EVEX_CD8<64, CD8VF>, VEX_W;
2784
2785 def : Pat<(v8i64 (X86pmuludq (v16i32 VR512:$src1), (v16i32 VR512:$src2))),
2786           (VPMULUDQZrr VR512:$src1, VR512:$src2)>;
2787
2788 def : Pat<(v8i64 (int_x86_avx512_mask_pmulu_dq_512 (v16i32 VR512:$src1),
2789            (v16i32 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2790           (VPMULUDQZrr VR512:$src1, VR512:$src2)>;
2791 def : Pat<(v8i64 (int_x86_avx512_mask_pmul_dq_512 (v16i32 VR512:$src1),
2792            (v16i32 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2793           (VPMULDQZrr VR512:$src1, VR512:$src2)>;
2794
2795 defm VPMAXSB : avx512_binop_rm_vl_b<0x3C, "vpmaxs", X86smax,
2796                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
2797 defm VPMAXSW : avx512_binop_rm_vl_w<0xEE, "vpmaxs", X86smax,
2798                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
2799 defm VPMAXS : avx512_binop_rm_vl_dq<0x3D, 0x3D, "vpmaxs", X86smax,
2800                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
2801
2802 defm VPMAXUB : avx512_binop_rm_vl_b<0xDE, "vpmaxu", X86umax,
2803                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
2804 defm VPMAXUW : avx512_binop_rm_vl_w<0x3E, "vpmaxu", X86umax,
2805                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
2806 defm VPMAXU : avx512_binop_rm_vl_dq<0x3F, 0x3F, "vpmaxu", X86umax,
2807                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
2808
2809 defm VPMINSB : avx512_binop_rm_vl_b<0x38, "vpmins", X86smin,
2810                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
2811 defm VPMINSW : avx512_binop_rm_vl_w<0xEA, "vpmins", X86smin,
2812                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
2813 defm VPMINS : avx512_binop_rm_vl_dq<0x39, 0x39, "vpmins", X86smin,
2814                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
2815
2816 defm VPMINUB : avx512_binop_rm_vl_b<0xDA, "vpminu", X86umin,
2817                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
2818 defm VPMINUW : avx512_binop_rm_vl_w<0x3A, "vpminu", X86umin,
2819                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
2820 defm VPMINU : avx512_binop_rm_vl_dq<0x3B, 0x3B, "vpminu", X86umin,
2821                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
2822
2823 def : Pat <(v16i32 (int_x86_avx512_mask_pmaxs_d_512 (v16i32 VR512:$src1),
2824                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2825            (VPMAXSDZrr VR512:$src1, VR512:$src2)>;
2826 def : Pat <(v16i32 (int_x86_avx512_mask_pmaxu_d_512 (v16i32 VR512:$src1),
2827                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2828            (VPMAXUDZrr VR512:$src1, VR512:$src2)>;
2829 def : Pat <(v8i64 (int_x86_avx512_mask_pmaxs_q_512 (v8i64 VR512:$src1),
2830                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2831            (VPMAXSQZrr VR512:$src1, VR512:$src2)>;
2832 def : Pat <(v8i64 (int_x86_avx512_mask_pmaxu_q_512 (v8i64 VR512:$src1),
2833                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2834            (VPMAXUQZrr VR512:$src1, VR512:$src2)>;
2835 def : Pat <(v16i32 (int_x86_avx512_mask_pmins_d_512 (v16i32 VR512:$src1),
2836                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2837            (VPMINSDZrr VR512:$src1, VR512:$src2)>;
2838 def : Pat <(v16i32 (int_x86_avx512_mask_pminu_d_512 (v16i32 VR512:$src1),
2839                     (v16i32 VR512:$src2), (v16i32 immAllZerosV), (i16 -1))),
2840            (VPMINUDZrr VR512:$src1, VR512:$src2)>;
2841 def : Pat <(v8i64 (int_x86_avx512_mask_pmins_q_512 (v8i64 VR512:$src1),
2842                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2843            (VPMINSQZrr VR512:$src1, VR512:$src2)>;
2844 def : Pat <(v8i64 (int_x86_avx512_mask_pminu_q_512 (v8i64 VR512:$src1),
2845                 (v8i64 VR512:$src2), (bc_v8i64 (v16i32 immAllZerosV)), (i8 -1))),
2846            (VPMINUQZrr VR512:$src1, VR512:$src2)>;
2847 //===----------------------------------------------------------------------===//
2848 // AVX-512 - Unpack Instructions
2849 //===----------------------------------------------------------------------===//
2850
2851 multiclass avx512_unpack_fp<bits<8> opc, SDNode OpNode, ValueType vt,
2852                                    PatFrag mem_frag, RegisterClass RC,
2853                                    X86MemOperand x86memop, string asm,
2854                                    Domain d> {
2855     def rr : AVX512PI<opc, MRMSrcReg,
2856                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2857                 asm, [(set RC:$dst,
2858                            (vt (OpNode RC:$src1, RC:$src2)))],
2859                            d>, EVEX_4V;
2860     def rm : AVX512PI<opc, MRMSrcMem,
2861                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2862                 asm, [(set RC:$dst,
2863                        (vt (OpNode RC:$src1,
2864                             (bitconvert (mem_frag addr:$src2)))))],
2865                         d>, EVEX_4V;
2866 }
2867
2868 defm VUNPCKHPSZ: avx512_unpack_fp<0x15, X86Unpckh, v16f32, memopv8f64,
2869       VR512, f512mem, "vunpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2870       SSEPackedSingle>, PS, EVEX_V512, EVEX_CD8<32, CD8VF>;
2871 defm VUNPCKHPDZ: avx512_unpack_fp<0x15, X86Unpckh, v8f64, memopv8f64,
2872       VR512, f512mem, "vunpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2873       SSEPackedDouble>, PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2874 defm VUNPCKLPSZ: avx512_unpack_fp<0x14, X86Unpckl, v16f32, memopv8f64,
2875       VR512, f512mem, "vunpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2876       SSEPackedSingle>, PS, EVEX_V512, EVEX_CD8<32, CD8VF>;
2877 defm VUNPCKLPDZ: avx512_unpack_fp<0x14, X86Unpckl, v8f64, memopv8f64,
2878       VR512, f512mem, "vunpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2879       SSEPackedDouble>, PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
2880
2881 multiclass avx512_unpack_int<bits<8> opc, string OpcodeStr, SDNode OpNode,
2882                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2883                         X86MemOperand x86memop> {
2884   def rr : AVX512BI<opc, MRMSrcReg, (outs RC:$dst),
2885        (ins RC:$src1, RC:$src2),
2886        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2887        [(set RC:$dst, (OpVT (OpNode (OpVT RC:$src1), (OpVT RC:$src2))))], 
2888        IIC_SSE_UNPCK>, EVEX_4V;
2889   def rm : AVX512BI<opc, MRMSrcMem, (outs RC:$dst),
2890        (ins RC:$src1, x86memop:$src2),
2891        !strconcat(OpcodeStr, " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2892        [(set RC:$dst, (OpVT (OpNode (OpVT RC:$src1),
2893                                      (bitconvert (memop_frag addr:$src2)))))],
2894                                      IIC_SSE_UNPCK>, EVEX_4V;
2895 }
2896 defm VPUNPCKLDQZ  : avx512_unpack_int<0x62, "vpunpckldq", X86Unpckl, v16i32,
2897                                 VR512, memopv16i32, i512mem>, EVEX_V512,
2898                                 EVEX_CD8<32, CD8VF>;
2899 defm VPUNPCKLQDQZ : avx512_unpack_int<0x6C, "vpunpcklqdq", X86Unpckl, v8i64,
2900                                 VR512, memopv8i64, i512mem>, EVEX_V512,
2901                                 VEX_W, EVEX_CD8<64, CD8VF>;
2902 defm VPUNPCKHDQZ  : avx512_unpack_int<0x6A, "vpunpckhdq", X86Unpckh, v16i32,
2903                                 VR512, memopv16i32, i512mem>, EVEX_V512,
2904                                 EVEX_CD8<32, CD8VF>;
2905 defm VPUNPCKHQDQZ : avx512_unpack_int<0x6D, "vpunpckhqdq", X86Unpckh, v8i64,
2906                                 VR512, memopv8i64, i512mem>, EVEX_V512,
2907                                 VEX_W, EVEX_CD8<64, CD8VF>;
2908 //===----------------------------------------------------------------------===//
2909 // AVX-512 - PSHUFD
2910 //
2911
2912 multiclass avx512_pshuf_imm<bits<8> opc, string OpcodeStr, RegisterClass RC,
2913                          SDNode OpNode, PatFrag mem_frag, 
2914                          X86MemOperand x86memop, ValueType OpVT> {
2915   def ri : AVX512Ii8<opc, MRMSrcReg, (outs RC:$dst),
2916                      (ins RC:$src1, i8imm:$src2),
2917                      !strconcat(OpcodeStr,
2918                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2919                      [(set RC:$dst,
2920                        (OpVT (OpNode RC:$src1, (i8 imm:$src2))))]>,
2921                      EVEX;
2922   def mi : AVX512Ii8<opc, MRMSrcMem, (outs RC:$dst),
2923                      (ins x86memop:$src1, i8imm:$src2),
2924                      !strconcat(OpcodeStr,
2925                          " \t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2926                      [(set RC:$dst,
2927                        (OpVT (OpNode (mem_frag addr:$src1),
2928                               (i8 imm:$src2))))]>, EVEX;
2929 }
2930
2931 defm VPSHUFDZ : avx512_pshuf_imm<0x70, "vpshufd", VR512, X86PShufd, memopv16i32,
2932                       i512mem, v16i32>, PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
2933
2934 //===----------------------------------------------------------------------===//
2935 // AVX-512  Logical Instructions
2936 //===----------------------------------------------------------------------===//
2937
2938 defm VPAND : avx512_binop_rm_vl_dq<0xDB, 0xDB, "vpand", and,
2939                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
2940 defm VPOR : avx512_binop_rm_vl_dq<0xEB, 0xEB, "vpor", or,
2941                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
2942 defm VPXOR : avx512_binop_rm_vl_dq<0xEF, 0xEF, "vpxor", xor,
2943                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
2944 defm VPANDN : avx512_binop_rm_vl_dq<0xDF, 0xDF, "vpandn", X86andnp,
2945                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
2946
2947 //===----------------------------------------------------------------------===//
2948 // AVX-512  FP arithmetic
2949 //===----------------------------------------------------------------------===//
2950
2951 multiclass avx512_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2952                                   SizeItins itins> {
2953   defm SSZ : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"), OpNode, FR32X,
2954                              f32mem, itins.s, 0>, XS, EVEX_4V, VEX_LIG,
2955                              EVEX_CD8<32, CD8VT1>;
2956   defm SDZ : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"), OpNode, FR64X,
2957                              f64mem, itins.d, 0>, XD, VEX_W, EVEX_4V, VEX_LIG,
2958                              EVEX_CD8<64, CD8VT1>;
2959 }
2960
2961 let isCommutable = 1 in {
2962 defm VADD : avx512_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>;
2963 defm VMUL : avx512_binop_s<0x59, "mul", fmul, SSE_ALU_ITINS_S>;
2964 defm VMIN : avx512_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>;
2965 defm VMAX : avx512_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>;
2966 }
2967 let isCommutable = 0 in {
2968 defm VSUB : avx512_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>;
2969 defm VDIV : avx512_binop_s<0x5E, "div", fdiv, SSE_ALU_ITINS_S>;
2970 }