]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86InstrAVX512.td
Merge ^/head r314178 through r314269.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86InstrAVX512.td
1 //===-- X86InstrAVX512.td - AVX512 Instruction Set ---------*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 AVX512 instruction set, defining the
11 // instructions, and properties of the instructions which are needed for code
12 // generation, machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16 // Group template arguments that can be derived from the vector type (EltNum x
17 // EltVT).  These are things like the register class for the writemask, etc.
18 // The idea is to pass one of these as the template argument rather than the
19 // individual arguments.
20 // The template is also used for scalar types, in this case numelts is 1.
21 class X86VectorVTInfo<int numelts, ValueType eltvt, RegisterClass rc,
22                       string suffix = ""> {
23   RegisterClass RC = rc;
24   ValueType EltVT = eltvt;
25   int NumElts = numelts;
26
27   // Corresponding mask register class.
28   RegisterClass KRC = !cast<RegisterClass>("VK" # NumElts);
29
30   // Corresponding write-mask register class.
31   RegisterClass KRCWM = !cast<RegisterClass>("VK" # NumElts # "WM");
32
33   // The mask VT.
34   ValueType KVT = !cast<ValueType>(!if (!eq (NumElts, 1), "i1",
35                                                           "v" # NumElts # "i1"));
36
37   // The GPR register class that can hold the write mask.  Use GR8 for fewer
38   // than 8 elements.  Use shift-right and equal to work around the lack of
39   // !lt in tablegen.
40   RegisterClass MRC =
41     !cast<RegisterClass>("GR" #
42                          !if (!eq (!srl(NumElts, 3), 0), 8, NumElts));
43
44   // Suffix used in the instruction mnemonic.
45   string Suffix = suffix;
46
47   // VTName is a string name for vector VT. For vector types it will be
48   // v # NumElts # EltVT, so for vector of 8 elements of i32 it will be v8i32
49   // It is a little bit complex for scalar types, where NumElts = 1.
50   // In this case we build v4f32 or v2f64
51   string VTName = "v" # !if (!eq (NumElts, 1),
52                         !if (!eq (EltVT.Size, 32), 4,
53                         !if (!eq (EltVT.Size, 64), 2, NumElts)), NumElts) # EltVT;
54
55   // The vector VT.
56   ValueType VT = !cast<ValueType>(VTName);
57
58   string EltTypeName = !cast<string>(EltVT);
59   // Size of the element type in bits, e.g. 32 for v16i32.
60   string EltSizeName = !subst("i", "", !subst("f", "", EltTypeName));
61   int EltSize = EltVT.Size;
62
63   // "i" for integer types and "f" for floating-point types
64   string TypeVariantName = !subst(EltSizeName, "", EltTypeName);
65
66   // Size of RC in bits, e.g. 512 for VR512.
67   int Size = VT.Size;
68
69   // The corresponding memory operand, e.g. i512mem for VR512.
70   X86MemOperand MemOp = !cast<X86MemOperand>(TypeVariantName # Size # "mem");
71   X86MemOperand ScalarMemOp = !cast<X86MemOperand>(EltVT # "mem");
72
73   // Load patterns
74   // Note: For 128/256-bit integer VT we choose loadv2i64/loadv4i64
75   //       due to load promotion during legalization
76   PatFrag LdFrag = !cast<PatFrag>("load" #
77                                   !if (!eq (TypeVariantName, "i"),
78                                        !if (!eq (Size, 128), "v2i64",
79                                        !if (!eq (Size, 256), "v4i64",
80                                        !if (!eq (Size, 512), "v8i64",
81                                             VTName))), VTName));
82
83   PatFrag AlignedLdFrag = !cast<PatFrag>("alignedload" #
84                                          !if (!eq (TypeVariantName, "i"),
85                                                !if (!eq (Size, 128), "v2i64",
86                                                !if (!eq (Size, 256), "v4i64",
87                                                !if (!eq (Size, 512), "v8i64",
88                                                    VTName))), VTName));
89
90   PatFrag ScalarLdFrag = !cast<PatFrag>("load" # EltVT);
91
92   // The corresponding float type, e.g. v16f32 for v16i32
93   // Note: For EltSize < 32, FloatVT is illegal and TableGen
94   //       fails to compile, so we choose FloatVT = VT
95   ValueType FloatVT = !cast<ValueType>(
96                         !if (!eq (!srl(EltSize,5),0),
97                              VTName,
98                              !if (!eq(TypeVariantName, "i"),
99                                   "v" # NumElts # "f" # EltSize,
100                                   VTName)));
101
102   ValueType IntVT = !cast<ValueType>(
103                         !if (!eq (!srl(EltSize,5),0),
104                              VTName,
105                              !if (!eq(TypeVariantName, "f"),
106                                   "v" # NumElts # "i" # EltSize,
107                                   VTName)));
108   // The string to specify embedded broadcast in assembly.
109   string BroadcastStr = "{1to" # NumElts # "}";
110
111   // 8-bit compressed displacement tuple/subvector format.  This is only
112   // defined for NumElts <= 8.
113   CD8VForm CD8TupleForm = !if (!eq (!srl(NumElts, 4), 0),
114                                !cast<CD8VForm>("CD8VT" # NumElts), ?);
115
116   SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm,
117                           !if (!eq (Size, 256), sub_ymm, ?));
118
119   Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle,
120                      !if (!eq (EltTypeName, "f64"), SSEPackedDouble,
121                      SSEPackedInt));
122
123   RegisterClass FRC = !if (!eq (EltTypeName, "f32"), FR32X, FR64X);
124
125   // A vector tye of the same width with element type i64. This is used to
126   // create patterns for logic ops.
127   ValueType i64VT = !cast<ValueType>("v" # !srl(Size, 6) # "i64");
128
129   // A vector type of the same width with element type i32.  This is used to
130   // create the canonical constant zero node ImmAllZerosV.
131   ValueType i32VT = !cast<ValueType>("v" # !srl(Size, 5) # "i32");
132   dag ImmAllZerosV = (VT (bitconvert (i32VT immAllZerosV)));
133
134   string ZSuffix = !if (!eq (Size, 128), "Z128",
135                    !if (!eq (Size, 256), "Z256", "Z"));
136 }
137
138 def v64i8_info  : X86VectorVTInfo<64,  i8, VR512, "b">;
139 def v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">;
140 def v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">;
141 def v8i64_info  : X86VectorVTInfo<8,  i64, VR512, "q">;
142 def v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">;
143 def v8f64_info  : X86VectorVTInfo<8,  f64, VR512, "pd">;
144
145 // "x" in v32i8x_info means RC = VR256X
146 def v32i8x_info  : X86VectorVTInfo<32,  i8, VR256X, "b">;
147 def v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">;
148 def v8i32x_info  : X86VectorVTInfo<8,  i32, VR256X, "d">;
149 def v4i64x_info  : X86VectorVTInfo<4,  i64, VR256X, "q">;
150 def v8f32x_info  : X86VectorVTInfo<8,  f32, VR256X, "ps">;
151 def v4f64x_info  : X86VectorVTInfo<4,  f64, VR256X, "pd">;
152
153 def v16i8x_info  : X86VectorVTInfo<16,  i8, VR128X, "b">;
154 def v8i16x_info  : X86VectorVTInfo<8,  i16, VR128X, "w">;
155 def v4i32x_info  : X86VectorVTInfo<4,  i32, VR128X, "d">;
156 def v2i64x_info  : X86VectorVTInfo<2,  i64, VR128X, "q">;
157 def v4f32x_info  : X86VectorVTInfo<4,  f32, VR128X, "ps">;
158 def v2f64x_info  : X86VectorVTInfo<2,  f64, VR128X, "pd">;
159
160 // We map scalar types to the smallest (128-bit) vector type
161 // with the appropriate element type. This allows to use the same masking logic.
162 def i32x_info    : X86VectorVTInfo<1,  i32, GR32, "si">;
163 def i64x_info    : X86VectorVTInfo<1,  i64, GR64, "sq">;
164 def f32x_info    : X86VectorVTInfo<1,  f32, VR128X, "ss">;
165 def f64x_info    : X86VectorVTInfo<1,  f64, VR128X, "sd">;
166
167 class AVX512VLVectorVTInfo<X86VectorVTInfo i512, X86VectorVTInfo i256,
168                            X86VectorVTInfo i128> {
169   X86VectorVTInfo info512 = i512;
170   X86VectorVTInfo info256 = i256;
171   X86VectorVTInfo info128 = i128;
172 }
173
174 def avx512vl_i8_info  : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
175                                              v16i8x_info>;
176 def avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
177                                              v8i16x_info>;
178 def avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
179                                              v4i32x_info>;
180 def avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
181                                              v2i64x_info>;
182 def avx512vl_f32_info : AVX512VLVectorVTInfo<v16f32_info, v8f32x_info,
183                                              v4f32x_info>;
184 def avx512vl_f64_info : AVX512VLVectorVTInfo<v8f64_info, v4f64x_info,
185                                              v2f64x_info>;
186
187 // This multiclass generates the masking variants from the non-masking
188 // variant.  It only provides the assembly pieces for the masking variants.
189 // It assumes custom ISel patterns for masking which can be provided as
190 // template arguments.
191 multiclass AVX512_maskable_custom<bits<8> O, Format F,
192                                   dag Outs,
193                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
194                                   string OpcodeStr,
195                                   string AttSrcAsm, string IntelSrcAsm,
196                                   list<dag> Pattern,
197                                   list<dag> MaskingPattern,
198                                   list<dag> ZeroMaskingPattern,
199                                   string MaskingConstraint = "",
200                                   InstrItinClass itin = NoItinerary,
201                                   bit IsCommutable = 0,
202                                   bit IsKCommutable = 0> {
203   let isCommutable = IsCommutable in
204     def NAME: AVX512<O, F, Outs, Ins,
205                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
206                                      "$dst, "#IntelSrcAsm#"}",
207                        Pattern, itin>;
208
209   // Prefer over VMOV*rrk Pat<>
210   let AddedComplexity = 20, isCommutable = IsKCommutable in
211     def NAME#k: AVX512<O, F, Outs, MaskingIns,
212                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
213                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
214                        MaskingPattern, itin>,
215               EVEX_K {
216       // In case of the 3src subclass this is overridden with a let.
217       string Constraints = MaskingConstraint;
218     }
219
220   // Zero mask does not add any restrictions to commute operands transformation.
221   // So, it is Ok to use IsCommutable instead of IsKCommutable.
222   let AddedComplexity = 30, isCommutable = IsCommutable in // Prefer over VMOV*rrkz Pat<>
223     def NAME#kz: AVX512<O, F, Outs, ZeroMaskingIns,
224                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}} {z}|"#
225                                      "$dst {${mask}} {z}, "#IntelSrcAsm#"}",
226                        ZeroMaskingPattern,
227                        itin>,
228               EVEX_KZ;
229 }
230
231
232 // Common base class of AVX512_maskable and AVX512_maskable_3src.
233 multiclass AVX512_maskable_common<bits<8> O, Format F, X86VectorVTInfo _,
234                                   dag Outs,
235                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
236                                   string OpcodeStr,
237                                   string AttSrcAsm, string IntelSrcAsm,
238                                   dag RHS, dag MaskingRHS,
239                                   SDNode Select = vselect,
240                                   string MaskingConstraint = "",
241                                   InstrItinClass itin = NoItinerary,
242                                   bit IsCommutable = 0,
243                                   bit IsKCommutable = 0> :
244   AVX512_maskable_custom<O, F, Outs, Ins, MaskingIns, ZeroMaskingIns, OpcodeStr,
245                          AttSrcAsm, IntelSrcAsm,
246                          [(set _.RC:$dst, RHS)],
247                          [(set _.RC:$dst, MaskingRHS)],
248                          [(set _.RC:$dst,
249                                (Select _.KRCWM:$mask, RHS, _.ImmAllZerosV))],
250                          MaskingConstraint, NoItinerary, IsCommutable,
251                          IsKCommutable>;
252
253 // This multiclass generates the unconditional/non-masking, the masking and
254 // the zero-masking variant of the vector instruction.  In the masking case, the
255 // perserved vector elements come from a new dummy input operand tied to $dst.
256 multiclass AVX512_maskable<bits<8> O, Format F, X86VectorVTInfo _,
257                            dag Outs, dag Ins, string OpcodeStr,
258                            string AttSrcAsm, string IntelSrcAsm,
259                            dag RHS,
260                            InstrItinClass itin = NoItinerary,
261                            bit IsCommutable = 0, bit IsKCommutable = 0,
262                            SDNode Select = vselect> :
263    AVX512_maskable_common<O, F, _, Outs, Ins,
264                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
265                           !con((ins _.KRCWM:$mask), Ins),
266                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
267                           (Select _.KRCWM:$mask, RHS, _.RC:$src0), Select,
268                           "$src0 = $dst", itin, IsCommutable, IsKCommutable>;
269
270 // This multiclass generates the unconditional/non-masking, the masking and
271 // the zero-masking variant of the scalar instruction.
272 multiclass AVX512_maskable_scalar<bits<8> O, Format F, X86VectorVTInfo _,
273                            dag Outs, dag Ins, string OpcodeStr,
274                            string AttSrcAsm, string IntelSrcAsm,
275                            dag RHS,
276                            InstrItinClass itin = NoItinerary,
277                            bit IsCommutable = 0> :
278    AVX512_maskable_common<O, F, _, Outs, Ins,
279                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
280                           !con((ins _.KRCWM:$mask), Ins),
281                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
282                           (X86selects _.KRCWM:$mask, RHS, _.RC:$src0),
283                           X86selects, "$src0 = $dst", itin, IsCommutable>;
284
285 // Similar to AVX512_maskable but in this case one of the source operands
286 // ($src1) is already tied to $dst so we just use that for the preserved
287 // vector elements.  NOTE that the NonTiedIns (the ins dag) should exclude
288 // $src1.
289 multiclass AVX512_maskable_3src<bits<8> O, Format F, X86VectorVTInfo _,
290                                 dag Outs, dag NonTiedIns, string OpcodeStr,
291                                 string AttSrcAsm, string IntelSrcAsm,
292                                 dag RHS, bit IsCommutable = 0,
293                                 bit IsKCommutable = 0> :
294    AVX512_maskable_common<O, F, _, Outs,
295                           !con((ins _.RC:$src1), NonTiedIns),
296                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
297                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
298                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
299                           (vselect _.KRCWM:$mask, RHS, _.RC:$src1),
300                           vselect, "", NoItinerary, IsCommutable, IsKCommutable>;
301
302 multiclass AVX512_maskable_3src_scalar<bits<8> O, Format F, X86VectorVTInfo _,
303                                      dag Outs, dag NonTiedIns, string OpcodeStr,
304                                      string AttSrcAsm, string IntelSrcAsm,
305                                      dag RHS, bit IsCommutable = 0,
306                                      bit IsKCommutable = 0> :
307    AVX512_maskable_common<O, F, _, Outs,
308                           !con((ins _.RC:$src1), NonTiedIns),
309                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
310                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
311                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
312                           (X86selects _.KRCWM:$mask, RHS, _.RC:$src1),
313                           X86selects, "", NoItinerary, IsCommutable,
314                           IsKCommutable>;
315
316 multiclass AVX512_maskable_in_asm<bits<8> O, Format F, X86VectorVTInfo _,
317                                   dag Outs, dag Ins,
318                                   string OpcodeStr,
319                                   string AttSrcAsm, string IntelSrcAsm,
320                                   list<dag> Pattern> :
321    AVX512_maskable_custom<O, F, Outs, Ins,
322                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
323                           !con((ins _.KRCWM:$mask), Ins),
324                           OpcodeStr, AttSrcAsm, IntelSrcAsm, Pattern, [], [],
325                           "$src0 = $dst">;
326
327
328 // Instruction with mask that puts result in mask register,
329 // like "compare" and "vptest"
330 multiclass AVX512_maskable_custom_cmp<bits<8> O, Format F,
331                                   dag Outs,
332                                   dag Ins, dag MaskingIns,
333                                   string OpcodeStr,
334                                   string AttSrcAsm, string IntelSrcAsm,
335                                   list<dag> Pattern,
336                                   list<dag> MaskingPattern,
337                                   bit IsCommutable = 0> {
338     let isCommutable = IsCommutable in
339     def NAME: AVX512<O, F, Outs, Ins,
340                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
341                                      "$dst, "#IntelSrcAsm#"}",
342                        Pattern, NoItinerary>;
343
344     def NAME#k: AVX512<O, F, Outs, MaskingIns,
345                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
346                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
347                        MaskingPattern, NoItinerary>, EVEX_K;
348 }
349
350 multiclass AVX512_maskable_common_cmp<bits<8> O, Format F, X86VectorVTInfo _,
351                                   dag Outs,
352                                   dag Ins, dag MaskingIns,
353                                   string OpcodeStr,
354                                   string AttSrcAsm, string IntelSrcAsm,
355                                   dag RHS, dag MaskingRHS,
356                                   bit IsCommutable = 0> :
357   AVX512_maskable_custom_cmp<O, F, Outs, Ins, MaskingIns, OpcodeStr,
358                          AttSrcAsm, IntelSrcAsm,
359                          [(set _.KRC:$dst, RHS)],
360                          [(set _.KRC:$dst, MaskingRHS)], IsCommutable>;
361
362 multiclass AVX512_maskable_cmp<bits<8> O, Format F, X86VectorVTInfo _,
363                            dag Outs, dag Ins, string OpcodeStr,
364                            string AttSrcAsm, string IntelSrcAsm,
365                            dag RHS, bit IsCommutable = 0> :
366    AVX512_maskable_common_cmp<O, F, _, Outs, Ins,
367                           !con((ins _.KRCWM:$mask), Ins),
368                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
369                           (and _.KRCWM:$mask, RHS), IsCommutable>;
370
371 multiclass AVX512_maskable_cmp_alt<bits<8> O, Format F, X86VectorVTInfo _,
372                            dag Outs, dag Ins, string OpcodeStr,
373                            string AttSrcAsm, string IntelSrcAsm> :
374    AVX512_maskable_custom_cmp<O, F, Outs,
375                              Ins, !con((ins _.KRCWM:$mask),Ins), OpcodeStr,
376                              AttSrcAsm, IntelSrcAsm, [],[]>;
377
378 // This multiclass generates the unconditional/non-masking, the masking and
379 // the zero-masking variant of the vector instruction.  In the masking case, the
380 // perserved vector elements come from a new dummy input operand tied to $dst.
381 multiclass AVX512_maskable_logic<bits<8> O, Format F, X86VectorVTInfo _,
382                            dag Outs, dag Ins, string OpcodeStr,
383                            string AttSrcAsm, string IntelSrcAsm,
384                            dag RHS, dag MaskedRHS,
385                            InstrItinClass itin = NoItinerary,
386                            bit IsCommutable = 0, SDNode Select = vselect> :
387    AVX512_maskable_custom<O, F, Outs, Ins,
388                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
389                           !con((ins _.KRCWM:$mask), Ins),
390                           OpcodeStr, AttSrcAsm, IntelSrcAsm,
391                           [(set _.RC:$dst, RHS)],
392                           [(set _.RC:$dst,
393                                 (Select _.KRCWM:$mask, MaskedRHS, _.RC:$src0))],
394                           [(set _.RC:$dst,
395                                 (Select _.KRCWM:$mask, MaskedRHS,
396                                         _.ImmAllZerosV))],
397                           "$src0 = $dst", itin, IsCommutable>;
398
399 // Bitcasts between 512-bit vector types. Return the original type since
400 // no instruction is needed for the conversion.
401 def : Pat<(v8f64  (bitconvert (v8i64  VR512:$src))), (v8f64  VR512:$src)>;
402 def : Pat<(v8f64  (bitconvert (v16i32 VR512:$src))), (v8f64  VR512:$src)>;
403 def : Pat<(v8f64  (bitconvert (v32i16 VR512:$src))), (v8f64  VR512:$src)>;
404 def : Pat<(v8f64  (bitconvert (v64i8  VR512:$src))), (v8f64  VR512:$src)>;
405 def : Pat<(v8f64  (bitconvert (v16f32 VR512:$src))), (v8f64  VR512:$src)>;
406 def : Pat<(v16f32 (bitconvert (v8i64  VR512:$src))), (v16f32 VR512:$src)>;
407 def : Pat<(v16f32 (bitconvert (v16i32 VR512:$src))), (v16f32 VR512:$src)>;
408 def : Pat<(v16f32 (bitconvert (v32i16 VR512:$src))), (v16f32 VR512:$src)>;
409 def : Pat<(v16f32 (bitconvert (v64i8  VR512:$src))), (v16f32 VR512:$src)>;
410 def : Pat<(v16f32 (bitconvert (v8f64  VR512:$src))), (v16f32 VR512:$src)>;
411 def : Pat<(v8i64  (bitconvert (v16i32 VR512:$src))), (v8i64  VR512:$src)>;
412 def : Pat<(v8i64  (bitconvert (v32i16 VR512:$src))), (v8i64  VR512:$src)>;
413 def : Pat<(v8i64  (bitconvert (v64i8  VR512:$src))), (v8i64  VR512:$src)>;
414 def : Pat<(v8i64  (bitconvert (v8f64  VR512:$src))), (v8i64  VR512:$src)>;
415 def : Pat<(v8i64  (bitconvert (v16f32 VR512:$src))), (v8i64  VR512:$src)>;
416 def : Pat<(v16i32 (bitconvert (v8i64  VR512:$src))), (v16i32 VR512:$src)>;
417 def : Pat<(v16i32 (bitconvert (v16f32 VR512:$src))), (v16i32 VR512:$src)>;
418 def : Pat<(v16i32 (bitconvert (v32i16 VR512:$src))), (v16i32 VR512:$src)>;
419 def : Pat<(v16i32 (bitconvert (v64i8  VR512:$src))), (v16i32 VR512:$src)>;
420 def : Pat<(v16i32 (bitconvert (v8f64  VR512:$src))), (v16i32 VR512:$src)>;
421 def : Pat<(v32i16 (bitconvert (v8i64  VR512:$src))), (v32i16 VR512:$src)>;
422 def : Pat<(v32i16 (bitconvert (v16i32 VR512:$src))), (v32i16 VR512:$src)>;
423 def : Pat<(v32i16 (bitconvert (v64i8  VR512:$src))), (v32i16 VR512:$src)>;
424 def : Pat<(v32i16 (bitconvert (v8f64  VR512:$src))), (v32i16 VR512:$src)>;
425 def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
426 def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
427 def : Pat<(v64i8  (bitconvert (v8i64  VR512:$src))), (v64i8  VR512:$src)>;
428 def : Pat<(v64i8  (bitconvert (v16i32 VR512:$src))), (v64i8  VR512:$src)>;
429 def : Pat<(v64i8  (bitconvert (v32i16 VR512:$src))), (v64i8  VR512:$src)>;
430 def : Pat<(v64i8  (bitconvert (v8f64  VR512:$src))), (v64i8  VR512:$src)>;
431 def : Pat<(v64i8  (bitconvert (v16f32 VR512:$src))), (v64i8  VR512:$src)>;
432
433 // Alias instruction that maps zero vector to pxor / xorp* for AVX-512.
434 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
435 // swizzled by ExecutionDepsFix to pxor.
436 // We set canFoldAsLoad because this can be converted to a constant-pool
437 // load of an all-zeros value if folding it would be beneficial.
438 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
439     isPseudo = 1, Predicates = [HasAVX512], SchedRW = [WriteZero] in {
440 def AVX512_512_SET0 : I<0, Pseudo, (outs VR512:$dst), (ins), "",
441                [(set VR512:$dst, (v16i32 immAllZerosV))]>;
442 def AVX512_512_SETALLONES : I<0, Pseudo, (outs VR512:$dst), (ins), "",
443                [(set VR512:$dst, (v16i32 immAllOnesV))]>;
444 }
445
446 // Alias instructions that allow VPTERNLOG to be used with a mask to create
447 // a mix of all ones and all zeros elements. This is done this way to force
448 // the same register to be used as input for all three sources.
449 let isPseudo = 1, Predicates = [HasAVX512] in {
450 def AVX512_512_SEXT_MASK_32 : I<0, Pseudo, (outs VR512:$dst),
451                                 (ins VK16WM:$mask), "",
452                            [(set VR512:$dst, (vselect (v16i1 VK16WM:$mask),
453                                                       (v16i32 immAllOnesV),
454                                                       (v16i32 immAllZerosV)))]>;
455 def AVX512_512_SEXT_MASK_64 : I<0, Pseudo, (outs VR512:$dst),
456                                 (ins VK8WM:$mask), "",
457                 [(set VR512:$dst, (vselect (v8i1 VK8WM:$mask),
458                                            (bc_v8i64 (v16i32 immAllOnesV)),
459                                            (bc_v8i64 (v16i32 immAllZerosV))))]>;
460 }
461
462 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
463     isPseudo = 1, Predicates = [HasVLX], SchedRW = [WriteZero] in {
464 def AVX512_128_SET0 : I<0, Pseudo, (outs VR128X:$dst), (ins), "",
465                [(set VR128X:$dst, (v4i32 immAllZerosV))]>;
466 def AVX512_256_SET0 : I<0, Pseudo, (outs VR256X:$dst), (ins), "",
467                [(set VR256X:$dst, (v8i32 immAllZerosV))]>;
468 }
469
470 // Alias instructions that map fld0 to xorps for sse or vxorps for avx.
471 // This is expanded by ExpandPostRAPseudos.
472 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
473     isPseudo = 1, SchedRW = [WriteZero], Predicates = [HasVLX, HasDQI] in {
474   def AVX512_FsFLD0SS : I<0, Pseudo, (outs FR32X:$dst), (ins), "",
475                           [(set FR32X:$dst, fp32imm0)]>;
476   def AVX512_FsFLD0SD : I<0, Pseudo, (outs FR64X:$dst), (ins), "",
477                           [(set FR64X:$dst, fpimm0)]>;
478 }
479
480 //===----------------------------------------------------------------------===//
481 // AVX-512 - VECTOR INSERT
482 //
483 multiclass vinsert_for_size<int Opcode, X86VectorVTInfo From, X86VectorVTInfo To,
484                                                        PatFrag vinsert_insert> {
485   let ExeDomain = To.ExeDomain in {
486     defm rr : AVX512_maskable<Opcode, MRMSrcReg, To, (outs To.RC:$dst),
487                    (ins To.RC:$src1, From.RC:$src2, i32u8imm:$src3),
488                    "vinsert" # From.EltTypeName # "x" # From.NumElts,
489                    "$src3, $src2, $src1", "$src1, $src2, $src3",
490                    (vinsert_insert:$src3 (To.VT To.RC:$src1),
491                                          (From.VT From.RC:$src2),
492                                          (iPTR imm))>, AVX512AIi8Base, EVEX_4V;
493
494     defm rm : AVX512_maskable<Opcode, MRMSrcMem, To, (outs To.RC:$dst),
495                    (ins To.RC:$src1, From.MemOp:$src2, i32u8imm:$src3),
496                    "vinsert" # From.EltTypeName # "x" # From.NumElts,
497                    "$src3, $src2, $src1", "$src1, $src2, $src3",
498                    (vinsert_insert:$src3 (To.VT To.RC:$src1),
499                                (From.VT (bitconvert (From.LdFrag addr:$src2))),
500                                (iPTR imm))>, AVX512AIi8Base, EVEX_4V,
501                    EVEX_CD8<From.EltSize, From.CD8TupleForm>;
502   }
503 }
504
505 multiclass vinsert_for_size_lowering<string InstrStr, X86VectorVTInfo From,
506                        X86VectorVTInfo To, PatFrag vinsert_insert,
507                        SDNodeXForm INSERT_get_vinsert_imm , list<Predicate> p> {
508   let Predicates = p in {
509     def : Pat<(vinsert_insert:$ins
510                      (To.VT To.RC:$src1), (From.VT From.RC:$src2), (iPTR imm)),
511               (To.VT (!cast<Instruction>(InstrStr#"rr")
512                      To.RC:$src1, From.RC:$src2,
513                      (INSERT_get_vinsert_imm To.RC:$ins)))>;
514
515     def : Pat<(vinsert_insert:$ins
516                   (To.VT To.RC:$src1),
517                   (From.VT (bitconvert (From.LdFrag addr:$src2))),
518                   (iPTR imm)),
519               (To.VT (!cast<Instruction>(InstrStr#"rm")
520                   To.RC:$src1, addr:$src2,
521                   (INSERT_get_vinsert_imm To.RC:$ins)))>;
522   }
523 }
524
525 multiclass vinsert_for_type<ValueType EltVT32, int Opcode128,
526                             ValueType EltVT64, int Opcode256> {
527
528   let Predicates = [HasVLX] in
529     defm NAME # "32x4Z256" : vinsert_for_size<Opcode128,
530                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
531                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
532                                  vinsert128_insert>, EVEX_V256;
533
534   defm NAME # "32x4Z" : vinsert_for_size<Opcode128,
535                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
536                                  X86VectorVTInfo<16, EltVT32, VR512>,
537                                  vinsert128_insert>, EVEX_V512;
538
539   defm NAME # "64x4Z" : vinsert_for_size<Opcode256,
540                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
541                                  X86VectorVTInfo< 8, EltVT64, VR512>,
542                                  vinsert256_insert>, VEX_W, EVEX_V512;
543
544   let Predicates = [HasVLX, HasDQI] in
545     defm NAME # "64x2Z256" : vinsert_for_size<Opcode128,
546                                    X86VectorVTInfo< 2, EltVT64, VR128X>,
547                                    X86VectorVTInfo< 4, EltVT64, VR256X>,
548                                    vinsert128_insert>, VEX_W, EVEX_V256;
549
550   let Predicates = [HasDQI] in {
551     defm NAME # "64x2Z" : vinsert_for_size<Opcode128,
552                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
553                                  X86VectorVTInfo< 8, EltVT64, VR512>,
554                                  vinsert128_insert>, VEX_W, EVEX_V512;
555
556     defm NAME # "32x8Z" : vinsert_for_size<Opcode256,
557                                    X86VectorVTInfo< 8, EltVT32, VR256X>,
558                                    X86VectorVTInfo<16, EltVT32, VR512>,
559                                    vinsert256_insert>, EVEX_V512;
560   }
561 }
562
563 defm VINSERTF : vinsert_for_type<f32, 0x18, f64, 0x1a>;
564 defm VINSERTI : vinsert_for_type<i32, 0x38, i64, 0x3a>;
565
566 // Codegen pattern with the alternative types,
567 // Only add this if 64x2 and its friends are not supported natively via AVX512DQ.
568 defm : vinsert_for_size_lowering<"VINSERTF32x4Z256", v2f64x_info, v4f64x_info,
569               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX, NoDQI]>;
570 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v2i64x_info, v4i64x_info,
571               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX, NoDQI]>;
572
573 defm : vinsert_for_size_lowering<"VINSERTF32x4Z", v2f64x_info, v8f64_info,
574               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512, NoDQI]>;
575 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v2i64x_info, v8i64_info,
576               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512, NoDQI]>;
577
578 defm : vinsert_for_size_lowering<"VINSERTF64x4Z", v8f32x_info, v16f32_info,
579               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512, NoDQI]>;
580 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v8i32x_info, v16i32_info,
581               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512, NoDQI]>;
582
583 // Codegen pattern with the alternative types insert VEC128 into VEC256
584 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v8i16x_info, v16i16x_info,
585               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX]>;
586 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v16i8x_info, v32i8x_info,
587               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX]>;
588 // Codegen pattern with the alternative types insert VEC128 into VEC512
589 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v8i16x_info, v32i16_info,
590               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512]>;
591 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v16i8x_info, v64i8_info,
592                vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512]>;
593 // Codegen pattern with the alternative types insert VEC256 into VEC512
594 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v16i16x_info, v32i16_info,
595               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512]>;
596 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v32i8x_info, v64i8_info,
597               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512]>;
598
599 // vinsertps - insert f32 to XMM
600 let ExeDomain = SSEPackedSingle in {
601 def VINSERTPSZrr : AVX512AIi8<0x21, MRMSrcReg, (outs VR128X:$dst),
602       (ins VR128X:$src1, VR128X:$src2, u8imm:$src3),
603       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
604       [(set VR128X:$dst, (X86insertps VR128X:$src1, VR128X:$src2, imm:$src3))]>,
605       EVEX_4V;
606 def VINSERTPSZrm: AVX512AIi8<0x21, MRMSrcMem, (outs VR128X:$dst),
607       (ins VR128X:$src1, f32mem:$src2, u8imm:$src3),
608       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
609       [(set VR128X:$dst, (X86insertps VR128X:$src1,
610                           (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
611                           imm:$src3))]>, EVEX_4V, EVEX_CD8<32, CD8VT1>;
612 }
613
614 //===----------------------------------------------------------------------===//
615 // AVX-512 VECTOR EXTRACT
616 //---
617
618 multiclass vextract_for_size<int Opcode,
619                              X86VectorVTInfo From, X86VectorVTInfo To,
620                              PatFrag vextract_extract,
621                              SDNodeXForm EXTRACT_get_vextract_imm> {
622
623   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
624     // use AVX512_maskable_in_asm (AVX512_maskable can't be used due to
625     // vextract_extract), we interesting only in patterns without mask,
626     // intrinsics pattern match generated bellow.
627     defm rr : AVX512_maskable_in_asm<Opcode, MRMDestReg, To, (outs To.RC:$dst),
628                 (ins From.RC:$src1, i32u8imm:$idx),
629                 "vextract" # To.EltTypeName # "x" # To.NumElts,
630                 "$idx, $src1", "$src1, $idx",
631                 [(set To.RC:$dst, (vextract_extract:$idx (From.VT From.RC:$src1),
632                                                          (iPTR imm)))]>,
633               AVX512AIi8Base, EVEX;
634     def mr  : AVX512AIi8<Opcode, MRMDestMem, (outs),
635                     (ins To.MemOp:$dst, From.RC:$src1, i32u8imm:$idx),
636                     "vextract" # To.EltTypeName # "x" # To.NumElts #
637                         "\t{$idx, $src1, $dst|$dst, $src1, $idx}",
638                     [(store (To.VT (vextract_extract:$idx
639                                     (From.VT From.RC:$src1), (iPTR imm))),
640                              addr:$dst)]>, EVEX;
641
642     let mayStore = 1, hasSideEffects = 0 in
643     def mrk : AVX512AIi8<Opcode, MRMDestMem, (outs),
644                     (ins To.MemOp:$dst, To.KRCWM:$mask,
645                                         From.RC:$src1, i32u8imm:$idx),
646                      "vextract" # To.EltTypeName # "x" # To.NumElts #
647                           "\t{$idx, $src1, $dst {${mask}}|"
648                           "$dst {${mask}}, $src1, $idx}",
649                     []>, EVEX_K, EVEX;
650   }
651
652   def : Pat<(To.VT (vselect To.KRCWM:$mask,
653                             (vextract_extract:$ext (From.VT From.RC:$src1),
654                                                    (iPTR imm)),
655                             To.RC:$src0)),
656             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
657                                 From.ZSuffix # "rrk")
658                 To.RC:$src0, To.KRCWM:$mask, From.RC:$src1,
659                 (EXTRACT_get_vextract_imm To.RC:$ext))>;
660
661   def : Pat<(To.VT (vselect To.KRCWM:$mask,
662                             (vextract_extract:$ext (From.VT From.RC:$src1),
663                                                    (iPTR imm)),
664                             To.ImmAllZerosV)),
665             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
666                                 From.ZSuffix # "rrkz")
667                 To.KRCWM:$mask, From.RC:$src1,
668                 (EXTRACT_get_vextract_imm To.RC:$ext))>;
669 }
670
671 // Codegen pattern for the alternative types
672 multiclass vextract_for_size_lowering<string InstrStr, X86VectorVTInfo From,
673                 X86VectorVTInfo To, PatFrag vextract_extract,
674                 SDNodeXForm EXTRACT_get_vextract_imm, list<Predicate> p> {
675   let Predicates = p in {
676      def : Pat<(vextract_extract:$ext (From.VT From.RC:$src1), (iPTR imm)),
677                (To.VT (!cast<Instruction>(InstrStr#"rr")
678                           From.RC:$src1,
679                           (EXTRACT_get_vextract_imm To.RC:$ext)))>;
680      def : Pat<(store (To.VT (vextract_extract:$ext (From.VT From.RC:$src1),
681                               (iPTR imm))), addr:$dst),
682                (!cast<Instruction>(InstrStr#"mr") addr:$dst, From.RC:$src1,
683                 (EXTRACT_get_vextract_imm To.RC:$ext))>;
684   }
685 }
686
687 multiclass vextract_for_type<ValueType EltVT32, int Opcode128,
688                              ValueType EltVT64, int Opcode256> {
689   defm NAME # "32x4Z" : vextract_for_size<Opcode128,
690                                  X86VectorVTInfo<16, EltVT32, VR512>,
691                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
692                                  vextract128_extract,
693                                  EXTRACT_get_vextract128_imm>,
694                                      EVEX_V512, EVEX_CD8<32, CD8VT4>;
695   defm NAME # "64x4Z" : vextract_for_size<Opcode256,
696                                  X86VectorVTInfo< 8, EltVT64, VR512>,
697                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
698                                  vextract256_extract,
699                                  EXTRACT_get_vextract256_imm>,
700                                      VEX_W, EVEX_V512, EVEX_CD8<64, CD8VT4>;
701   let Predicates = [HasVLX] in
702     defm NAME # "32x4Z256" : vextract_for_size<Opcode128,
703                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
704                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
705                                  vextract128_extract,
706                                  EXTRACT_get_vextract128_imm>,
707                                      EVEX_V256, EVEX_CD8<32, CD8VT4>;
708   let Predicates = [HasVLX, HasDQI] in
709     defm NAME # "64x2Z256" : vextract_for_size<Opcode128,
710                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
711                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
712                                  vextract128_extract,
713                                  EXTRACT_get_vextract128_imm>,
714                                      VEX_W, EVEX_V256, EVEX_CD8<64, CD8VT2>;
715   let Predicates = [HasDQI] in {
716     defm NAME # "64x2Z" : vextract_for_size<Opcode128,
717                                  X86VectorVTInfo< 8, EltVT64, VR512>,
718                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
719                                  vextract128_extract,
720                                  EXTRACT_get_vextract128_imm>,
721                                      VEX_W, EVEX_V512, EVEX_CD8<64, CD8VT2>;
722     defm NAME # "32x8Z" : vextract_for_size<Opcode256,
723                                  X86VectorVTInfo<16, EltVT32, VR512>,
724                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
725                                  vextract256_extract,
726                                  EXTRACT_get_vextract256_imm>,
727                                      EVEX_V512, EVEX_CD8<32, CD8VT8>;
728   }
729 }
730
731 defm VEXTRACTF : vextract_for_type<f32, 0x19, f64, 0x1b>;
732 defm VEXTRACTI : vextract_for_type<i32, 0x39, i64, 0x3b>;
733
734 // extract_subvector codegen patterns with the alternative types.
735 // Only add this if 64x2 and its friends are not supported natively via AVX512DQ.
736 defm : vextract_for_size_lowering<"VEXTRACTF32x4Z", v8f64_info, v2f64x_info,
737           vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512, NoDQI]>;
738 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z", v8i64_info, v2i64x_info,
739           vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512, NoDQI]>;
740
741 defm : vextract_for_size_lowering<"VEXTRACTF64x4Z", v16f32_info, v8f32x_info,
742           vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512, NoDQI]>;
743 defm : vextract_for_size_lowering<"VEXTRACTI64x4Z", v16i32_info, v8i32x_info,
744           vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512, NoDQI]>;
745
746 defm : vextract_for_size_lowering<"VEXTRACTF32x4Z256", v4f64x_info, v2f64x_info,
747           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX, NoDQI]>;
748 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z256", v4i64x_info, v2i64x_info,
749           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX, NoDQI]>;
750
751 // Codegen pattern with the alternative types extract VEC128 from VEC256
752 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z256", v16i16x_info, v8i16x_info,
753           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX]>;
754 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z256", v32i8x_info, v16i8x_info,
755           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX]>;
756
757 // Codegen pattern with the alternative types extract VEC128 from VEC512
758 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z", v32i16_info, v8i16x_info,
759                  vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512]>;
760 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z", v64i8_info, v16i8x_info,
761                  vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512]>;
762 // Codegen pattern with the alternative types extract VEC256 from VEC512
763 defm : vextract_for_size_lowering<"VEXTRACTI64x4Z", v32i16_info, v16i16x_info,
764                  vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512]>;
765 defm : vextract_for_size_lowering<"VEXTRACTI64x4Z", v64i8_info, v32i8x_info,
766                  vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512]>;
767
768 // A 128-bit subvector extract from the first 256-bit vector position
769 // is a subregister copy that needs no instruction.
770 def : Pat<(v2i64 (extract_subvector (v8i64 VR512:$src), (iPTR 0))),
771           (v2i64 (EXTRACT_SUBREG (v8i64 VR512:$src), sub_xmm))>;
772 def : Pat<(v2f64 (extract_subvector (v8f64 VR512:$src), (iPTR 0))),
773           (v2f64 (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm))>;
774 def : Pat<(v4i32 (extract_subvector (v16i32 VR512:$src), (iPTR 0))),
775           (v4i32 (EXTRACT_SUBREG (v16i32 VR512:$src), sub_xmm))>;
776 def : Pat<(v4f32 (extract_subvector (v16f32 VR512:$src), (iPTR 0))),
777           (v4f32 (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm))>;
778 def : Pat<(v8i16 (extract_subvector (v32i16 VR512:$src), (iPTR 0))),
779           (v8i16 (EXTRACT_SUBREG (v32i16 VR512:$src), sub_xmm))>;
780 def : Pat<(v16i8 (extract_subvector (v64i8 VR512:$src), (iPTR 0))),
781           (v16i8 (EXTRACT_SUBREG (v64i8 VR512:$src), sub_xmm))>;
782
783 // A 256-bit subvector extract from the first 256-bit vector position
784 // is a subregister copy that needs no instruction.
785 def : Pat<(v4i64 (extract_subvector (v8i64 VR512:$src), (iPTR 0))),
786           (v4i64 (EXTRACT_SUBREG (v8i64 VR512:$src), sub_ymm))>;
787 def : Pat<(v4f64 (extract_subvector (v8f64 VR512:$src), (iPTR 0))),
788           (v4f64 (EXTRACT_SUBREG (v8f64 VR512:$src), sub_ymm))>;
789 def : Pat<(v8i32 (extract_subvector (v16i32 VR512:$src), (iPTR 0))),
790           (v8i32 (EXTRACT_SUBREG (v16i32 VR512:$src), sub_ymm))>;
791 def : Pat<(v8f32 (extract_subvector (v16f32 VR512:$src), (iPTR 0))),
792           (v8f32 (EXTRACT_SUBREG (v16f32 VR512:$src), sub_ymm))>;
793 def : Pat<(v16i16 (extract_subvector (v32i16 VR512:$src), (iPTR 0))),
794           (v16i16 (EXTRACT_SUBREG (v32i16 VR512:$src), sub_ymm))>;
795 def : Pat<(v32i8 (extract_subvector (v64i8 VR512:$src), (iPTR 0))),
796           (v32i8 (EXTRACT_SUBREG (v64i8 VR512:$src), sub_ymm))>;
797
798 let AddedComplexity = 25 in { // to give priority over vinsertf128rm
799 // A 128-bit subvector insert to the first 512-bit vector position
800 // is a subregister copy that needs no instruction.
801 def : Pat<(v8i64 (insert_subvector undef, (v2i64 VR128X:$src), (iPTR 0))),
802           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
803 def : Pat<(v8f64 (insert_subvector undef, (v2f64 VR128X:$src), (iPTR 0))),
804           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
805 def : Pat<(v16i32 (insert_subvector undef, (v4i32 VR128X:$src), (iPTR 0))),
806           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
807 def : Pat<(v16f32 (insert_subvector undef, (v4f32 VR128X:$src), (iPTR 0))),
808           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
809 def : Pat<(v32i16 (insert_subvector undef, (v8i16 VR128X:$src), (iPTR 0))),
810           (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
811 def : Pat<(v64i8 (insert_subvector undef, (v16i8 VR128X:$src), (iPTR 0))),
812           (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
813
814 // A 256-bit subvector insert to the first 512-bit vector position
815 // is a subregister copy that needs no instruction.
816 def : Pat<(v8i64 (insert_subvector undef, (v4i64 VR256X:$src), (iPTR 0))),
817           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
818 def : Pat<(v8f64 (insert_subvector undef, (v4f64 VR256X:$src), (iPTR 0))),
819           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
820 def : Pat<(v16i32 (insert_subvector undef, (v8i32 VR256X:$src), (iPTR 0))),
821           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
822 def : Pat<(v16f32 (insert_subvector undef, (v8f32 VR256X:$src), (iPTR 0))),
823           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
824 def : Pat<(v32i16 (insert_subvector undef, (v16i16 VR256X:$src), (iPTR 0))),
825           (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
826 def : Pat<(v64i8 (insert_subvector undef, (v32i8 VR256X:$src), (iPTR 0))),
827           (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
828 }
829
830 // vextractps - extract 32 bits from XMM
831 def VEXTRACTPSZrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32:$dst),
832       (ins VR128X:$src1, u8imm:$src2),
833       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
834       [(set GR32:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
835       EVEX;
836
837 def VEXTRACTPSZmr : AVX512AIi8<0x17, MRMDestMem, (outs),
838       (ins f32mem:$dst, VR128X:$src1, u8imm:$src2),
839       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
840       [(store (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2),
841                           addr:$dst)]>, EVEX, EVEX_CD8<32, CD8VT1>;
842
843 //===---------------------------------------------------------------------===//
844 // AVX-512 BROADCAST
845 //---
846 // broadcast with a scalar argument.
847 multiclass avx512_broadcast_scalar<bits<8> opc, string OpcodeStr,
848                             X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo> {
849
850   let isCodeGenOnly = 1 in {
851   def r_s : I< opc, MRMSrcReg, (outs DestInfo.RC:$dst),
852                (ins SrcInfo.FRC:$src), OpcodeStr#"\t{$src, $dst|$dst, $src}",
853                [(set DestInfo.RC:$dst, (DestInfo.VT (X86VBroadcast SrcInfo.FRC:$src)))]>,
854                Requires<[HasAVX512]>, T8PD, EVEX;
855
856   let Constraints = "$src0 = $dst" in
857   def rk_s : I< opc, MRMSrcReg, (outs DestInfo.RC:$dst),
858                 (ins DestInfo.RC:$src0, DestInfo.KRCWM:$mask, SrcInfo.FRC:$src),
859                 OpcodeStr#"\t{$src, $dst {${mask}} |$dst {${mask}}, $src}",
860                 [(set DestInfo.RC:$dst,
861                      (vselect DestInfo.KRCWM:$mask,
862                               (DestInfo.VT (X86VBroadcast SrcInfo.FRC:$src)),
863                               DestInfo.RC:$src0))]>,
864               Requires<[HasAVX512]>, T8PD, EVEX, EVEX_K;
865
866   def rkz_s : I< opc, MRMSrcReg, (outs DestInfo.RC:$dst),
867                 (ins DestInfo.KRCWM:$mask, SrcInfo.FRC:$src),
868                 OpcodeStr#"\t{$src, $dst {${mask}} {z}|$dst {${mask}} {z}, $src}",
869                 [(set DestInfo.RC:$dst,
870                      (vselect DestInfo.KRCWM:$mask,
871                               (DestInfo.VT (X86VBroadcast SrcInfo.FRC:$src)),
872                               DestInfo.ImmAllZerosV))]>,
873                 Requires<[HasAVX512]>, T8PD, EVEX, EVEX_KZ;
874   } // let isCodeGenOnly = 1 in
875 }
876
877 multiclass avx512_broadcast_rm<bits<8> opc, string OpcodeStr,
878                             X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo> {
879   let ExeDomain = DestInfo.ExeDomain in {
880   defm r : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
881                    (ins SrcInfo.RC:$src), OpcodeStr, "$src", "$src",
882                    (DestInfo.VT (X86VBroadcast (SrcInfo.VT SrcInfo.RC:$src)))>,
883                    T8PD, EVEX;
884   defm m : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
885                    (ins SrcInfo.ScalarMemOp:$src), OpcodeStr, "$src", "$src",
886                    (DestInfo.VT (X86VBroadcast
887                                    (SrcInfo.ScalarLdFrag addr:$src)))>,
888                    T8PD, EVEX, EVEX_CD8<SrcInfo.EltSize, CD8VT1>;
889   }
890
891   def : Pat<(DestInfo.VT (X86VBroadcast
892                           (SrcInfo.VT (scalar_to_vector
893                                        (SrcInfo.ScalarLdFrag addr:$src))))),
894             (!cast<Instruction>(NAME#DestInfo.ZSuffix#m) addr:$src)>;
895   let AddedComplexity = 20 in
896   def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask,
897                           (X86VBroadcast
898                            (SrcInfo.VT (scalar_to_vector
899                                         (SrcInfo.ScalarLdFrag addr:$src)))),
900                           DestInfo.RC:$src0)),
901             (!cast<Instruction>(NAME#DestInfo.ZSuffix#mk)
902              DestInfo.RC:$src0, DestInfo.KRCWM:$mask, addr:$src)>;
903   let AddedComplexity = 30 in
904   def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask,
905                           (X86VBroadcast
906                            (SrcInfo.VT (scalar_to_vector
907                                         (SrcInfo.ScalarLdFrag addr:$src)))),
908                           DestInfo.ImmAllZerosV)),
909             (!cast<Instruction>(NAME#DestInfo.ZSuffix#mkz)
910              DestInfo.KRCWM:$mask, addr:$src)>;
911 }
912
913 multiclass avx512_fp_broadcast_sd<bits<8> opc, string OpcodeStr,
914                                                        AVX512VLVectorVTInfo _> {
915   let Predicates = [HasAVX512] in
916     defm Z  : avx512_broadcast_rm<opc, OpcodeStr, _.info512, _.info128>,
917               avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128>,
918                                EVEX_V512;
919
920   let Predicates = [HasVLX] in {
921     defm Z256  : avx512_broadcast_rm<opc, OpcodeStr, _.info256, _.info128>,
922                  avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128>,
923                              EVEX_V256;
924   }
925 }
926
927 multiclass avx512_fp_broadcast_ss<bits<8> opc, string OpcodeStr,
928                                                        AVX512VLVectorVTInfo _> {
929   let Predicates = [HasAVX512] in
930     defm Z  : avx512_broadcast_rm<opc, OpcodeStr, _.info512, _.info128>,
931               avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128>,
932                                EVEX_V512;
933
934   let Predicates = [HasVLX] in {
935     defm Z256  : avx512_broadcast_rm<opc, OpcodeStr, _.info256, _.info128>,
936                  avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128>,
937                              EVEX_V256;
938     defm Z128  : avx512_broadcast_rm<opc, OpcodeStr, _.info128, _.info128>,
939                  avx512_broadcast_scalar<opc, OpcodeStr, _.info128, _.info128>,
940                              EVEX_V128;
941   }
942 }
943 defm VBROADCASTSS  : avx512_fp_broadcast_ss<0x18, "vbroadcastss",
944                                        avx512vl_f32_info>;
945 defm VBROADCASTSD  : avx512_fp_broadcast_sd<0x19, "vbroadcastsd",
946                                        avx512vl_f64_info>, VEX_W;
947
948 def : Pat<(int_x86_avx512_vbroadcast_ss_512 addr:$src),
949           (VBROADCASTSSZm addr:$src)>;
950 def : Pat<(int_x86_avx512_vbroadcast_sd_512 addr:$src),
951           (VBROADCASTSDZm addr:$src)>;
952
953 multiclass avx512_int_broadcast_reg<bits<8> opc, X86VectorVTInfo _,
954                                     RegisterClass SrcRC> {
955   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
956                          (ins SrcRC:$src),
957                          "vpbroadcast"##_.Suffix, "$src", "$src",
958                          (_.VT (X86VBroadcast SrcRC:$src))>, T8PD, EVEX;
959 }
960
961 multiclass avx512_int_broadcast_reg_vl<bits<8> opc, AVX512VLVectorVTInfo _,
962                                        RegisterClass SrcRC, Predicate prd> {
963   let Predicates = [prd] in
964     defm Z : avx512_int_broadcast_reg<opc, _.info512, SrcRC>, EVEX_V512;
965   let Predicates = [prd, HasVLX] in {
966     defm Z256 : avx512_int_broadcast_reg<opc, _.info256, SrcRC>, EVEX_V256;
967     defm Z128 : avx512_int_broadcast_reg<opc, _.info128, SrcRC>, EVEX_V128;
968   }
969 }
970
971 let isCodeGenOnly = 1 in {
972 defm VPBROADCASTBr : avx512_int_broadcast_reg_vl<0x7A, avx512vl_i8_info, GR8,
973                                                  HasBWI>;
974 defm VPBROADCASTWr : avx512_int_broadcast_reg_vl<0x7B, avx512vl_i16_info, GR16,
975                                                  HasBWI>;
976 }
977 let isAsmParserOnly = 1 in {
978   defm VPBROADCASTBr_Alt : avx512_int_broadcast_reg_vl<0x7A, avx512vl_i8_info,
979                                                        GR32, HasBWI>;
980   defm VPBROADCASTWr_Alt : avx512_int_broadcast_reg_vl<0x7B, avx512vl_i16_info,
981                                                        GR32, HasBWI>;
982 }
983 defm VPBROADCASTDr : avx512_int_broadcast_reg_vl<0x7C, avx512vl_i32_info, GR32,
984                                                  HasAVX512>;
985 defm VPBROADCASTQr : avx512_int_broadcast_reg_vl<0x7C, avx512vl_i64_info, GR64,
986                                                  HasAVX512>, VEX_W;
987
988 def : Pat <(v16i32 (X86vzext VK16WM:$mask)),
989            (VPBROADCASTDrZrkz VK16WM:$mask, (i32 (MOV32ri 0x1)))>;
990 def : Pat <(v8i64 (X86vzext VK8WM:$mask)),
991            (VPBROADCASTQrZrkz VK8WM:$mask, (i64 (MOV64ri 0x1)))>;
992
993 // Provide aliases for broadcast from the same register class that
994 // automatically does the extract.
995 multiclass avx512_int_broadcast_rm_lowering<X86VectorVTInfo DestInfo,
996                                             X86VectorVTInfo SrcInfo> {
997   def : Pat<(DestInfo.VT (X86VBroadcast (SrcInfo.VT SrcInfo.RC:$src))),
998             (!cast<Instruction>(NAME#DestInfo.ZSuffix#"r")
999                 (EXTRACT_SUBREG (SrcInfo.VT SrcInfo.RC:$src), sub_xmm))>;
1000 }
1001
1002 multiclass avx512_int_broadcast_rm_vl<bits<8> opc, string OpcodeStr,
1003                                         AVX512VLVectorVTInfo _, Predicate prd> {
1004   let Predicates = [prd] in {
1005     defm Z :   avx512_broadcast_rm<opc, OpcodeStr, _.info512, _.info128>,
1006                avx512_int_broadcast_rm_lowering<_.info512, _.info256>,
1007                                   EVEX_V512;
1008     // Defined separately to avoid redefinition.
1009     defm Z_Alt : avx512_int_broadcast_rm_lowering<_.info512, _.info512>;
1010   }
1011   let Predicates = [prd, HasVLX] in {
1012     defm Z256 : avx512_broadcast_rm<opc, OpcodeStr, _.info256, _.info128>,
1013                 avx512_int_broadcast_rm_lowering<_.info256, _.info256>,
1014                                  EVEX_V256;
1015     defm Z128 : avx512_broadcast_rm<opc, OpcodeStr, _.info128, _.info128>,
1016                                  EVEX_V128;
1017   }
1018 }
1019
1020 defm VPBROADCASTB  : avx512_int_broadcast_rm_vl<0x78, "vpbroadcastb",
1021                                            avx512vl_i8_info, HasBWI>;
1022 defm VPBROADCASTW  : avx512_int_broadcast_rm_vl<0x79, "vpbroadcastw",
1023                                            avx512vl_i16_info, HasBWI>;
1024 defm VPBROADCASTD  : avx512_int_broadcast_rm_vl<0x58, "vpbroadcastd",
1025                                            avx512vl_i32_info, HasAVX512>;
1026 defm VPBROADCASTQ  : avx512_int_broadcast_rm_vl<0x59, "vpbroadcastq",
1027                                            avx512vl_i64_info, HasAVX512>, VEX_W;
1028
1029 multiclass avx512_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
1030                           X86VectorVTInfo _Dst, X86VectorVTInfo _Src> {
1031   defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
1032                            (ins _Src.MemOp:$src), OpcodeStr, "$src", "$src",
1033                            (_Dst.VT (X86SubVBroadcast
1034                              (_Src.VT (bitconvert (_Src.LdFrag addr:$src)))))>,
1035                             AVX5128IBase, EVEX;
1036 }
1037
1038 let Predicates = [HasVLX, HasBWI] in {
1039   // loadi16 is tricky to fold, because !isTypeDesirableForOp, justifiably.
1040   // This means we'll encounter truncated i32 loads; match that here.
1041   def : Pat<(v8i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
1042             (VPBROADCASTWZ128m addr:$src)>;
1043   def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
1044             (VPBROADCASTWZ256m addr:$src)>;
1045   def : Pat<(v8i16 (X86VBroadcast
1046               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
1047             (VPBROADCASTWZ128m addr:$src)>;
1048   def : Pat<(v16i16 (X86VBroadcast
1049               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
1050             (VPBROADCASTWZ256m addr:$src)>;
1051 }
1052
1053 //===----------------------------------------------------------------------===//
1054 // AVX-512 BROADCAST SUBVECTORS
1055 //
1056
1057 defm VBROADCASTI32X4 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
1058                        v16i32_info, v4i32x_info>,
1059                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
1060 defm VBROADCASTF32X4 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
1061                        v16f32_info, v4f32x_info>,
1062                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
1063 defm VBROADCASTI64X4 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti64x4",
1064                        v8i64_info, v4i64x_info>, VEX_W,
1065                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
1066 defm VBROADCASTF64X4 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf64x4",
1067                        v8f64_info, v4f64x_info>, VEX_W,
1068                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
1069
1070 let Predicates = [HasAVX512] in {
1071 def : Pat<(v32i16 (X86SubVBroadcast (bc_v16i16 (loadv4i64 addr:$src)))),
1072           (VBROADCASTI64X4rm addr:$src)>;
1073 def : Pat<(v64i8 (X86SubVBroadcast (bc_v32i8 (loadv4i64 addr:$src)))),
1074           (VBROADCASTI64X4rm addr:$src)>;
1075
1076 // Provide fallback in case the load node that is used in the patterns above
1077 // is used by additional users, which prevents the pattern selection.
1078 def : Pat<(v16f32 (X86SubVBroadcast (v8f32 VR256X:$src))),
1079           (VINSERTF64x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1080                            (v8f32 VR256X:$src), 1)>;
1081 def : Pat<(v8f64 (X86SubVBroadcast (v4f64 VR256X:$src))),
1082           (VINSERTF64x4Zrr (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1083                            (v4f64 VR256X:$src), 1)>;
1084 def : Pat<(v8i64 (X86SubVBroadcast (v4i64 VR256X:$src))),
1085           (VINSERTI64x4Zrr (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1086                            (v4i64 VR256X:$src), 1)>;
1087 def : Pat<(v16i32 (X86SubVBroadcast (v8i32 VR256X:$src))),
1088           (VINSERTI64x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1089                            (v8i32 VR256X:$src), 1)>;
1090 def : Pat<(v32i16 (X86SubVBroadcast (v16i16 VR256X:$src))),
1091           (VINSERTI64x4Zrr (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1092                            (v16i16 VR256X:$src), 1)>;
1093 def : Pat<(v64i8 (X86SubVBroadcast (v32i8 VR256X:$src))),
1094           (VINSERTI64x4Zrr (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1095                            (v32i8 VR256X:$src), 1)>;
1096
1097 def : Pat<(v32i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
1098           (VBROADCASTI32X4rm addr:$src)>;
1099 def : Pat<(v64i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
1100           (VBROADCASTI32X4rm addr:$src)>;
1101
1102 // Provide fallback in case the load node that is used in the patterns above
1103 // is used by additional users, which prevents the pattern selection.
1104 def : Pat<(v8f64 (X86SubVBroadcast (v2f64 VR128X:$src))),
1105           (VINSERTF64x4Zrr
1106            (VINSERTF32x4Zrr (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)),
1107                                            VR128X:$src, sub_xmm),
1108                             VR128X:$src, 1),
1109            (EXTRACT_SUBREG
1110             (v8f64 (VINSERTF32x4Zrr (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)),
1111                                                    VR128X:$src, sub_xmm),
1112                                     VR128X:$src, 1)), sub_ymm), 1)>;
1113 def : Pat<(v8i64 (X86SubVBroadcast (v2i64 VR128X:$src))),
1114           (VINSERTI64x4Zrr
1115            (VINSERTI32x4Zrr (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)),
1116                                            VR128X:$src, sub_xmm),
1117                             VR128X:$src, 1),
1118            (EXTRACT_SUBREG
1119             (v8i64 (VINSERTI32x4Zrr (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)),
1120                                                    VR128X:$src, sub_xmm),
1121                                     VR128X:$src, 1)), sub_ymm), 1)>;
1122
1123 def : Pat<(v32i16 (X86SubVBroadcast (v8i16 VR128X:$src))),
1124           (VINSERTI64x4Zrr
1125            (VINSERTI32x4Zrr (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)),
1126                                            VR128X:$src, sub_xmm),
1127                             VR128X:$src, 1),
1128            (EXTRACT_SUBREG
1129             (v32i16 (VINSERTI32x4Zrr (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)),
1130                                                     VR128X:$src, sub_xmm),
1131                                      VR128X:$src, 1)), sub_ymm), 1)>;
1132 def : Pat<(v64i8 (X86SubVBroadcast (v16i8 VR128X:$src))),
1133           (VINSERTI64x4Zrr
1134            (VINSERTI32x4Zrr (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)),
1135                                            VR128X:$src, sub_xmm),
1136                             VR128X:$src, 1),
1137            (EXTRACT_SUBREG
1138             (v64i8 (VINSERTI32x4Zrr (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)),
1139                                                    VR128X:$src, sub_xmm),
1140                                     VR128X:$src, 1)), sub_ymm), 1)>;
1141 }
1142
1143 let Predicates = [HasVLX] in {
1144 defm VBROADCASTI32X4Z256 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
1145                            v8i32x_info, v4i32x_info>,
1146                            EVEX_V256, EVEX_CD8<32, CD8VT4>;
1147 defm VBROADCASTF32X4Z256 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
1148                            v8f32x_info, v4f32x_info>,
1149                            EVEX_V256, EVEX_CD8<32, CD8VT4>;
1150
1151 def : Pat<(v16i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
1152           (VBROADCASTI32X4Z256rm addr:$src)>;
1153 def : Pat<(v32i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
1154           (VBROADCASTI32X4Z256rm addr:$src)>;
1155
1156 // Provide fallback in case the load node that is used in the patterns above
1157 // is used by additional users, which prevents the pattern selection.
1158 def : Pat<(v8f32 (X86SubVBroadcast (v4f32 VR128X:$src))),
1159           (VINSERTF32x4Z256rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1160                               (v4f32 VR128X:$src), 1)>;
1161 def : Pat<(v8i32 (X86SubVBroadcast (v4i32 VR128X:$src))),
1162           (VINSERTI32x4Z256rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1163                               (v4i32 VR128X:$src), 1)>;
1164 def : Pat<(v16i16 (X86SubVBroadcast (v8i16 VR128X:$src))),
1165           (VINSERTI32x4Z256rr (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1166                               (v8i16 VR128X:$src), 1)>;
1167 def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128X:$src))),
1168           (VINSERTI32x4Z256rr (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1169                               (v16i8 VR128X:$src), 1)>;
1170 }
1171
1172 let Predicates = [HasVLX, HasDQI] in {
1173 defm VBROADCASTI64X2Z128 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti64x2",
1174                            v4i64x_info, v2i64x_info>, VEX_W,
1175                            EVEX_V256, EVEX_CD8<64, CD8VT2>;
1176 defm VBROADCASTF64X2Z128 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf64x2",
1177                            v4f64x_info, v2f64x_info>, VEX_W,
1178                            EVEX_V256, EVEX_CD8<64, CD8VT2>;
1179
1180 // Provide fallback in case the load node that is used in the patterns above
1181 // is used by additional users, which prevents the pattern selection.
1182 def : Pat<(v4f64 (X86SubVBroadcast (v2f64 VR128X:$src))),
1183           (VINSERTF64x2Z256rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1184                               (v2f64 VR128X:$src), 1)>;
1185 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128X:$src))),
1186           (VINSERTI64x2Z256rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1187                               (v2i64 VR128X:$src), 1)>;
1188 }
1189
1190 let Predicates = [HasVLX, NoDQI] in {
1191 def : Pat<(v4f64 (X86SubVBroadcast (loadv2f64 addr:$src))),
1192           (VBROADCASTF32X4Z256rm addr:$src)>;
1193 def : Pat<(v4i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
1194           (VBROADCASTI32X4Z256rm addr:$src)>;
1195
1196 // Provide fallback in case the load node that is used in the patterns above
1197 // is used by additional users, which prevents the pattern selection.
1198 def : Pat<(v4f64 (X86SubVBroadcast (v2f64 VR128X:$src))),
1199           (VINSERTF32x4Z256rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1200                               (v2f64 VR128X:$src), 1)>;
1201 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128X:$src))),
1202           (VINSERTI32x4Z256rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1203                               (v2i64 VR128X:$src), 1)>;
1204 }
1205
1206 let Predicates = [HasAVX512, NoDQI] in {
1207 def : Pat<(v8f64 (X86SubVBroadcast (loadv2f64 addr:$src))),
1208           (VBROADCASTF32X4rm addr:$src)>;
1209 def : Pat<(v8i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
1210           (VBROADCASTI32X4rm addr:$src)>;
1211
1212 def : Pat<(v16f32 (X86SubVBroadcast (v4f32 VR128X:$src))),
1213           (VINSERTF64x4Zrr
1214            (VINSERTF32x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
1215                                            VR128X:$src, sub_xmm),
1216                             VR128X:$src, 1),
1217            (EXTRACT_SUBREG
1218             (v16f32 (VINSERTF32x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
1219                                                     VR128X:$src, sub_xmm),
1220                                      VR128X:$src, 1)), sub_ymm), 1)>;
1221 def : Pat<(v16i32 (X86SubVBroadcast (v4i32 VR128X:$src))),
1222           (VINSERTI64x4Zrr
1223            (VINSERTI32x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
1224                                            VR128X:$src, sub_xmm),
1225                             VR128X:$src, 1),
1226            (EXTRACT_SUBREG
1227             (v16i32 (VINSERTI32x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
1228                                                     VR128X:$src, sub_xmm),
1229                                      VR128X:$src, 1)), sub_ymm), 1)>;
1230
1231 def : Pat<(v16f32 (X86SubVBroadcast (loadv8f32 addr:$src))),
1232           (VBROADCASTF64X4rm addr:$src)>;
1233 def : Pat<(v16i32 (X86SubVBroadcast (bc_v8i32 (loadv4i64 addr:$src)))),
1234           (VBROADCASTI64X4rm addr:$src)>;
1235
1236 // Provide fallback in case the load node that is used in the patterns above
1237 // is used by additional users, which prevents the pattern selection.
1238 def : Pat<(v16f32 (X86SubVBroadcast (v8f32 VR256X:$src))),
1239           (VINSERTF64x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1240                            (v8f32 VR256X:$src), 1)>;
1241 def : Pat<(v16i32 (X86SubVBroadcast (v8i32 VR256X:$src))),
1242           (VINSERTI64x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1243                            (v8i32 VR256X:$src), 1)>;
1244 }
1245
1246 let Predicates = [HasDQI] in {
1247 defm VBROADCASTI64X2 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti64x2",
1248                        v8i64_info, v2i64x_info>, VEX_W,
1249                        EVEX_V512, EVEX_CD8<64, CD8VT2>;
1250 defm VBROADCASTI32X8 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti32x8",
1251                        v16i32_info, v8i32x_info>,
1252                        EVEX_V512, EVEX_CD8<32, CD8VT8>;
1253 defm VBROADCASTF64X2 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf64x2",
1254                        v8f64_info, v2f64x_info>, VEX_W,
1255                        EVEX_V512, EVEX_CD8<64, CD8VT2>;
1256 defm VBROADCASTF32X8 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf32x8",
1257                        v16f32_info, v8f32x_info>,
1258                        EVEX_V512, EVEX_CD8<32, CD8VT8>;
1259
1260 // Provide fallback in case the load node that is used in the patterns above
1261 // is used by additional users, which prevents the pattern selection.
1262 def : Pat<(v16f32 (X86SubVBroadcast (v8f32 VR256X:$src))),
1263           (VINSERTF32x8Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1264                            (v8f32 VR256X:$src), 1)>;
1265 def : Pat<(v16i32 (X86SubVBroadcast (v8i32 VR256X:$src))),
1266           (VINSERTI32x8Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1267                            (v8i32 VR256X:$src), 1)>;
1268
1269 def : Pat<(v16f32 (X86SubVBroadcast (v4f32 VR128X:$src))),
1270           (VINSERTF32x8Zrr
1271            (VINSERTF32x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
1272                                            VR128X:$src, sub_xmm),
1273                             VR128X:$src, 1),
1274            (EXTRACT_SUBREG
1275             (v16f32 (VINSERTF32x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
1276                                                     VR128X:$src, sub_xmm),
1277                                      VR128X:$src, 1)), sub_ymm), 1)>;
1278 def : Pat<(v16i32 (X86SubVBroadcast (v4i32 VR128X:$src))),
1279           (VINSERTI32x8Zrr
1280            (VINSERTI32x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
1281                                            VR128X:$src, sub_xmm),
1282                             VR128X:$src, 1),
1283            (EXTRACT_SUBREG
1284             (v16i32 (VINSERTI32x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)),
1285                                                     VR128X:$src, sub_xmm),
1286                                      VR128X:$src, 1)), sub_ymm), 1)>;
1287 }
1288
1289 multiclass avx512_common_broadcast_32x2<bits<8> opc, string OpcodeStr,
1290                          AVX512VLVectorVTInfo _Dst, AVX512VLVectorVTInfo _Src> {
1291   let Predicates = [HasDQI] in
1292     defm Z :    avx512_broadcast_rm<opc, OpcodeStr, _Dst.info512, _Src.info128>,
1293                                   EVEX_V512;
1294   let Predicates = [HasDQI, HasVLX] in
1295     defm Z256 : avx512_broadcast_rm<opc, OpcodeStr, _Dst.info256, _Src.info128>,
1296                                   EVEX_V256;
1297 }
1298
1299 multiclass avx512_common_broadcast_i32x2<bits<8> opc, string OpcodeStr,
1300                          AVX512VLVectorVTInfo _Dst, AVX512VLVectorVTInfo _Src> :
1301   avx512_common_broadcast_32x2<opc, OpcodeStr, _Dst, _Src> {
1302
1303   let Predicates = [HasDQI, HasVLX] in
1304     defm Z128 : avx512_broadcast_rm<opc, OpcodeStr, _Dst.info128, _Src.info128>,
1305                                       EVEX_V128;
1306 }
1307
1308 defm VBROADCASTI32X2  : avx512_common_broadcast_i32x2<0x59, "vbroadcasti32x2",
1309                                           avx512vl_i32_info, avx512vl_i64_info>;
1310 defm VBROADCASTF32X2  : avx512_common_broadcast_32x2<0x19, "vbroadcastf32x2",
1311                                           avx512vl_f32_info, avx512vl_f64_info>;
1312
1313 def : Pat<(v16f32 (X86VBroadcast (v16f32 VR512:$src))),
1314           (VBROADCASTSSZr (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm))>;
1315 def : Pat<(v16f32 (X86VBroadcast (v8f32 VR256X:$src))),
1316           (VBROADCASTSSZr (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm))>;
1317
1318 def : Pat<(v8f64 (X86VBroadcast (v8f64 VR512:$src))),
1319           (VBROADCASTSDZr (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm))>;
1320 def : Pat<(v8f64 (X86VBroadcast (v4f64 VR256X:$src))),
1321           (VBROADCASTSDZr (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm))>;
1322
1323 //===----------------------------------------------------------------------===//
1324 // AVX-512 BROADCAST MASK TO VECTOR REGISTER
1325 //---
1326 multiclass avx512_mask_broadcastm<bits<8> opc, string OpcodeStr,
1327                                   X86VectorVTInfo _, RegisterClass KRC> {
1328   def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.RC:$dst), (ins KRC:$src),
1329                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1330                   [(set _.RC:$dst, (_.VT (X86VBroadcastm KRC:$src)))]>, EVEX;
1331 }
1332
1333 multiclass avx512_mask_broadcast<bits<8> opc, string OpcodeStr,
1334                                  AVX512VLVectorVTInfo VTInfo, RegisterClass KRC> {
1335   let Predicates = [HasCDI] in
1336     defm Z : avx512_mask_broadcastm<opc, OpcodeStr, VTInfo.info512, KRC>, EVEX_V512;
1337   let Predicates = [HasCDI, HasVLX] in {
1338     defm Z256 : avx512_mask_broadcastm<opc, OpcodeStr, VTInfo.info256, KRC>, EVEX_V256;
1339     defm Z128 : avx512_mask_broadcastm<opc, OpcodeStr, VTInfo.info128, KRC>, EVEX_V128;
1340   }
1341 }
1342
1343 defm VPBROADCASTMW2D : avx512_mask_broadcast<0x3A, "vpbroadcastmw2d",
1344                                                avx512vl_i32_info, VK16>;
1345 defm VPBROADCASTMB2Q : avx512_mask_broadcast<0x2A, "vpbroadcastmb2q",
1346                                                avx512vl_i64_info, VK8>, VEX_W;
1347
1348 //===----------------------------------------------------------------------===//
1349 // -- VPERMI2 - 3 source operands form --
1350 multiclass avx512_perm_i<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1351 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
1352   // The index operand in the pattern should really be an integer type. However,
1353   // if we do that and it happens to come from a bitcast, then it becomes
1354   // difficult to find the bitcast needed to convert the index to the
1355   // destination type for the passthru since it will be folded with the bitcast
1356   // of the index operand.
1357   defm rr: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
1358           (ins _.RC:$src2, _.RC:$src3),
1359           OpcodeStr, "$src3, $src2", "$src2, $src3",
1360           (_.VT (X86VPermi2X _.RC:$src1, _.RC:$src2, _.RC:$src3)), 1>, EVEX_4V,
1361          AVX5128IBase;
1362
1363   defm rm: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1364             (ins _.RC:$src2, _.MemOp:$src3),
1365             OpcodeStr, "$src3, $src2", "$src2, $src3",
1366             (_.VT (X86VPermi2X _.RC:$src1, _.RC:$src2,
1367                    (_.VT (bitconvert (_.LdFrag addr:$src3))))), 1>,
1368             EVEX_4V, AVX5128IBase;
1369   }
1370 }
1371 multiclass avx512_perm_i_mb<bits<8> opc, string OpcodeStr,
1372                             X86VectorVTInfo _> {
1373   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
1374   defm rmb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1375               (ins _.RC:$src2, _.ScalarMemOp:$src3),
1376               OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
1377               !strconcat("$src2, ${src3}", _.BroadcastStr ),
1378               (_.VT (X86VPermi2X _.RC:$src1,
1379                _.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))),
1380               1>, AVX5128IBase, EVEX_4V, EVEX_B;
1381 }
1382
1383 multiclass avx512_perm_i_sizes<bits<8> opc, string OpcodeStr,
1384                                AVX512VLVectorVTInfo VTInfo> {
1385   defm NAME: avx512_perm_i<opc, OpcodeStr, VTInfo.info512>,
1386             avx512_perm_i_mb<opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1387   let Predicates = [HasVLX] in {
1388   defm NAME#128: avx512_perm_i<opc, OpcodeStr, VTInfo.info128>,
1389                  avx512_perm_i_mb<opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1390   defm NAME#256: avx512_perm_i<opc, OpcodeStr, VTInfo.info256>,
1391                  avx512_perm_i_mb<opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1392   }
1393 }
1394
1395 multiclass avx512_perm_i_sizes_bw<bits<8> opc, string OpcodeStr,
1396                                  AVX512VLVectorVTInfo VTInfo,
1397                                  Predicate Prd> {
1398   let Predicates = [Prd] in
1399   defm NAME: avx512_perm_i<opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1400   let Predicates = [Prd, HasVLX] in {
1401   defm NAME#128: avx512_perm_i<opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1402   defm NAME#256: avx512_perm_i<opc, OpcodeStr, VTInfo.info256>,  EVEX_V256;
1403   }
1404 }
1405
1406 defm VPERMI2D  : avx512_perm_i_sizes<0x76, "vpermi2d",
1407                   avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1408 defm VPERMI2Q  : avx512_perm_i_sizes<0x76, "vpermi2q",
1409                   avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1410 defm VPERMI2W  : avx512_perm_i_sizes_bw<0x75, "vpermi2w",
1411                   avx512vl_i16_info, HasBWI>,
1412                   VEX_W, EVEX_CD8<16, CD8VF>;
1413 defm VPERMI2B  : avx512_perm_i_sizes_bw<0x75, "vpermi2b",
1414                   avx512vl_i8_info, HasVBMI>,
1415                   EVEX_CD8<8, CD8VF>;
1416 defm VPERMI2PS : avx512_perm_i_sizes<0x77, "vpermi2ps",
1417                   avx512vl_f32_info>, EVEX_CD8<32, CD8VF>;
1418 defm VPERMI2PD : avx512_perm_i_sizes<0x77, "vpermi2pd",
1419                   avx512vl_f64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1420
1421 // VPERMT2
1422 multiclass avx512_perm_t<bits<8> opc, string OpcodeStr,
1423                          X86VectorVTInfo _, X86VectorVTInfo IdxVT> {
1424 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
1425   defm rr: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
1426           (ins IdxVT.RC:$src2, _.RC:$src3),
1427           OpcodeStr, "$src3, $src2", "$src2, $src3",
1428           (_.VT (X86VPermt2 _.RC:$src1, IdxVT.RC:$src2, _.RC:$src3)), 1>,
1429           EVEX_4V, AVX5128IBase;
1430
1431   defm rm: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1432             (ins IdxVT.RC:$src2, _.MemOp:$src3),
1433             OpcodeStr, "$src3, $src2", "$src2, $src3",
1434             (_.VT (X86VPermt2 _.RC:$src1, IdxVT.RC:$src2,
1435                    (bitconvert (_.LdFrag addr:$src3)))), 1>,
1436             EVEX_4V, AVX5128IBase;
1437   }
1438 }
1439 multiclass avx512_perm_t_mb<bits<8> opc, string OpcodeStr,
1440                             X86VectorVTInfo _, X86VectorVTInfo IdxVT> {
1441   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
1442   defm rmb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1443               (ins IdxVT.RC:$src2, _.ScalarMemOp:$src3),
1444               OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
1445               !strconcat("$src2, ${src3}", _.BroadcastStr ),
1446               (_.VT (X86VPermt2 _.RC:$src1,
1447                IdxVT.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))),
1448               1>, AVX5128IBase, EVEX_4V, EVEX_B;
1449 }
1450
1451 multiclass avx512_perm_t_sizes<bits<8> opc, string OpcodeStr,
1452                                AVX512VLVectorVTInfo VTInfo,
1453                                AVX512VLVectorVTInfo ShuffleMask> {
1454   defm NAME: avx512_perm_t<opc, OpcodeStr, VTInfo.info512,
1455                               ShuffleMask.info512>,
1456             avx512_perm_t_mb<opc, OpcodeStr, VTInfo.info512,
1457                               ShuffleMask.info512>, EVEX_V512;
1458   let Predicates = [HasVLX] in {
1459   defm NAME#128: avx512_perm_t<opc, OpcodeStr, VTInfo.info128,
1460                               ShuffleMask.info128>,
1461                  avx512_perm_t_mb<opc, OpcodeStr, VTInfo.info128,
1462                               ShuffleMask.info128>, EVEX_V128;
1463   defm NAME#256: avx512_perm_t<opc, OpcodeStr, VTInfo.info256,
1464                               ShuffleMask.info256>,
1465                  avx512_perm_t_mb<opc, OpcodeStr, VTInfo.info256,
1466                               ShuffleMask.info256>, EVEX_V256;
1467   }
1468 }
1469
1470 multiclass avx512_perm_t_sizes_bw<bits<8> opc, string OpcodeStr,
1471                                  AVX512VLVectorVTInfo VTInfo,
1472                                  AVX512VLVectorVTInfo Idx,
1473                                  Predicate Prd> {
1474   let Predicates = [Prd] in
1475   defm NAME: avx512_perm_t<opc, OpcodeStr, VTInfo.info512,
1476                            Idx.info512>, EVEX_V512;
1477   let Predicates = [Prd, HasVLX] in {
1478   defm NAME#128: avx512_perm_t<opc, OpcodeStr, VTInfo.info128,
1479                                Idx.info128>, EVEX_V128;
1480   defm NAME#256: avx512_perm_t<opc, OpcodeStr, VTInfo.info256,
1481                                Idx.info256>, EVEX_V256;
1482   }
1483 }
1484
1485 defm VPERMT2D  : avx512_perm_t_sizes<0x7E, "vpermt2d",
1486                   avx512vl_i32_info, avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1487 defm VPERMT2Q  : avx512_perm_t_sizes<0x7E, "vpermt2q",
1488                   avx512vl_i64_info, avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1489 defm VPERMT2W  : avx512_perm_t_sizes_bw<0x7D, "vpermt2w",
1490                   avx512vl_i16_info, avx512vl_i16_info, HasBWI>,
1491                   VEX_W, EVEX_CD8<16, CD8VF>;
1492 defm VPERMT2B  : avx512_perm_t_sizes_bw<0x7D, "vpermt2b",
1493                   avx512vl_i8_info, avx512vl_i8_info, HasVBMI>,
1494                   EVEX_CD8<8, CD8VF>;
1495 defm VPERMT2PS : avx512_perm_t_sizes<0x7F, "vpermt2ps",
1496                   avx512vl_f32_info, avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1497 defm VPERMT2PD : avx512_perm_t_sizes<0x7F, "vpermt2pd",
1498                   avx512vl_f64_info, avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1499
1500 //===----------------------------------------------------------------------===//
1501 // AVX-512 - BLEND using mask
1502 //
1503 multiclass avx512_blendmask<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1504   let ExeDomain = _.ExeDomain, hasSideEffects = 0 in {
1505   def rr : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1506              (ins _.RC:$src1, _.RC:$src2),
1507              !strconcat(OpcodeStr,
1508              "\t{$src2, $src1, ${dst}|${dst}, $src1, $src2}"),
1509              []>, EVEX_4V;
1510   def rrk : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1511              (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1512              !strconcat(OpcodeStr,
1513              "\t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
1514              []>, EVEX_4V, EVEX_K;
1515   def rrkz : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1516              (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1517              !strconcat(OpcodeStr,
1518              "\t{$src2, $src1, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src1, $src2}"),
1519              []>, EVEX_4V, EVEX_KZ;
1520   let mayLoad = 1 in {
1521   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1522              (ins _.RC:$src1, _.MemOp:$src2),
1523              !strconcat(OpcodeStr,
1524              "\t{$src2, $src1, ${dst}|${dst}, $src1, $src2}"),
1525              []>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
1526   def rmk : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1527              (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1528              !strconcat(OpcodeStr,
1529              "\t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
1530              []>, EVEX_4V, EVEX_K, EVEX_CD8<_.EltSize, CD8VF>;
1531   def rmkz : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1532              (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1533              !strconcat(OpcodeStr,
1534              "\t{$src2, $src1, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src1, $src2}"),
1535              []>, EVEX_4V, EVEX_KZ, EVEX_CD8<_.EltSize, CD8VF>;
1536   }
1537   }
1538 }
1539 multiclass avx512_blendmask_rmb<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1540
1541   let mayLoad = 1, hasSideEffects = 0 in {
1542   def rmbk : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1543       (ins _.KRCWM:$mask, _.RC:$src1, _.ScalarMemOp:$src2),
1544        !strconcat(OpcodeStr,
1545             "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1546             "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1547       []>, EVEX_4V, EVEX_K, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
1548
1549   def rmb : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1550       (ins _.RC:$src1, _.ScalarMemOp:$src2),
1551        !strconcat(OpcodeStr,
1552             "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1553             "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1554       []>,  EVEX_4V, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
1555   }
1556 }
1557
1558 multiclass blendmask_dq <bits<8> opc, string OpcodeStr,
1559                                  AVX512VLVectorVTInfo VTInfo> {
1560   defm Z : avx512_blendmask      <opc, OpcodeStr, VTInfo.info512>,
1561            avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1562
1563   let Predicates = [HasVLX] in {
1564     defm Z256 : avx512_blendmask<opc, OpcodeStr, VTInfo.info256>,
1565                 avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1566     defm Z128 : avx512_blendmask<opc, OpcodeStr, VTInfo.info128>,
1567                 avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1568   }
1569 }
1570
1571 multiclass blendmask_bw <bits<8> opc, string OpcodeStr,
1572                          AVX512VLVectorVTInfo VTInfo> {
1573   let Predicates = [HasBWI] in
1574     defm Z : avx512_blendmask    <opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1575
1576   let Predicates = [HasBWI, HasVLX] in {
1577     defm Z256 : avx512_blendmask <opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1578     defm Z128 : avx512_blendmask <opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1579   }
1580 }
1581
1582
1583 defm VBLENDMPS : blendmask_dq <0x65, "vblendmps", avx512vl_f32_info>;
1584 defm VBLENDMPD : blendmask_dq <0x65, "vblendmpd", avx512vl_f64_info>, VEX_W;
1585 defm VPBLENDMD : blendmask_dq <0x64, "vpblendmd", avx512vl_i32_info>;
1586 defm VPBLENDMQ : blendmask_dq <0x64, "vpblendmq", avx512vl_i64_info>, VEX_W;
1587 defm VPBLENDMB : blendmask_bw <0x66, "vpblendmb", avx512vl_i8_info>;
1588 defm VPBLENDMW : blendmask_bw <0x66, "vpblendmw", avx512vl_i16_info>, VEX_W;
1589
1590
1591 //===----------------------------------------------------------------------===//
1592 // Compare Instructions
1593 //===----------------------------------------------------------------------===//
1594
1595 // avx512_cmp_scalar - AVX512 CMPSS and CMPSD
1596
1597 multiclass avx512_cmp_scalar<X86VectorVTInfo _, SDNode OpNode, SDNode OpNodeRnd>{
1598
1599   defm  rr_Int  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1600                       (outs _.KRC:$dst),
1601                       (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1602                       "vcmp${cc}"#_.Suffix,
1603                       "$src2, $src1", "$src1, $src2",
1604                       (OpNode (_.VT _.RC:$src1),
1605                               (_.VT _.RC:$src2),
1606                               imm:$cc)>, EVEX_4V;
1607   defm  rm_Int  : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1608                     (outs _.KRC:$dst),
1609                     (ins _.RC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1610                     "vcmp${cc}"#_.Suffix,
1611                     "$src2, $src1", "$src1, $src2",
1612                     (OpNode (_.VT _.RC:$src1),
1613                         (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
1614                         imm:$cc)>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1615
1616   defm  rrb_Int  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1617                      (outs _.KRC:$dst),
1618                      (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1619                      "vcmp${cc}"#_.Suffix,
1620                      "{sae}, $src2, $src1", "$src1, $src2, {sae}",
1621                      (OpNodeRnd (_.VT _.RC:$src1),
1622                                 (_.VT _.RC:$src2),
1623                                 imm:$cc,
1624                                 (i32 FROUND_NO_EXC))>, EVEX_4V, EVEX_B;
1625   // Accept explicit immediate argument form instead of comparison code.
1626   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1627     defm  rri_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1628                         (outs VK1:$dst),
1629                         (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1630                         "vcmp"#_.Suffix,
1631                         "$cc, $src2, $src1", "$src1, $src2, $cc">, EVEX_4V;
1632     defm  rmi_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1633                         (outs _.KRC:$dst),
1634                         (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$cc),
1635                         "vcmp"#_.Suffix,
1636                         "$cc, $src2, $src1", "$src1, $src2, $cc">,
1637                         EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1638
1639     defm  rrb_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1640                        (outs _.KRC:$dst),
1641                        (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1642                        "vcmp"#_.Suffix,
1643                        "$cc, {sae}, $src2, $src1","$src1, $src2, {sae}, $cc">,
1644                        EVEX_4V, EVEX_B;
1645   }// let isAsmParserOnly = 1, hasSideEffects = 0
1646
1647   let isCodeGenOnly = 1 in {
1648     let isCommutable = 1 in
1649     def rr : AVX512Ii8<0xC2, MRMSrcReg,
1650                 (outs _.KRC:$dst), (ins _.FRC:$src1, _.FRC:$src2, AVXCC:$cc),
1651                 !strconcat("vcmp${cc}", _.Suffix,
1652                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1653                 [(set _.KRC:$dst, (OpNode _.FRC:$src1,
1654                                           _.FRC:$src2,
1655                                           imm:$cc))],
1656                 IIC_SSE_ALU_F32S_RR>, EVEX_4V;
1657     def rm : AVX512Ii8<0xC2, MRMSrcMem,
1658               (outs _.KRC:$dst),
1659               (ins _.FRC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1660               !strconcat("vcmp${cc}", _.Suffix,
1661                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1662               [(set _.KRC:$dst, (OpNode _.FRC:$src1,
1663                                         (_.ScalarLdFrag addr:$src2),
1664                                         imm:$cc))],
1665               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1666   }
1667 }
1668
1669 let Predicates = [HasAVX512] in {
1670   defm VCMPSSZ : avx512_cmp_scalar<f32x_info, X86cmpms, X86cmpmsRnd>,
1671                                    AVX512XSIi8Base;
1672   defm VCMPSDZ : avx512_cmp_scalar<f64x_info, X86cmpms, X86cmpmsRnd>,
1673                                    AVX512XDIi8Base, VEX_W;
1674 }
1675
1676 multiclass avx512_icmp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
1677               X86VectorVTInfo _, bit IsCommutable> {
1678   let isCommutable = IsCommutable in
1679   def rr : AVX512BI<opc, MRMSrcReg,
1680              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2),
1681              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1682              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2)))],
1683              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1684   def rm : AVX512BI<opc, MRMSrcMem,
1685              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2),
1686              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1687              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1688                                      (_.VT (bitconvert (_.LdFrag addr:$src2)))))],
1689              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1690   def rrk : AVX512BI<opc, MRMSrcReg,
1691               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1692               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1693                           "$dst {${mask}}, $src1, $src2}"),
1694               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1695                                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))))],
1696               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1697   def rmk : AVX512BI<opc, MRMSrcMem,
1698               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1699               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1700                           "$dst {${mask}}, $src1, $src2}"),
1701               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1702                                    (OpNode (_.VT _.RC:$src1),
1703                                        (_.VT (bitconvert
1704                                               (_.LdFrag addr:$src2))))))],
1705               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1706 }
1707
1708 multiclass avx512_icmp_packed_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
1709               X86VectorVTInfo _, bit IsCommutable> :
1710            avx512_icmp_packed<opc, OpcodeStr, OpNode, _, IsCommutable> {
1711   def rmb : AVX512BI<opc, MRMSrcMem,
1712               (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2),
1713               !strconcat(OpcodeStr, "\t{${src2}", _.BroadcastStr, ", $src1, $dst",
1714                                     "|$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1715               [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1716                               (X86VBroadcast (_.ScalarLdFrag addr:$src2))))],
1717               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1718   def rmbk : AVX512BI<opc, MRMSrcMem,
1719                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1720                                        _.ScalarMemOp:$src2),
1721                !strconcat(OpcodeStr,
1722                           "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1723                           "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1724                [(set _.KRC:$dst, (and _.KRCWM:$mask,
1725                                       (OpNode (_.VT _.RC:$src1),
1726                                         (X86VBroadcast
1727                                           (_.ScalarLdFrag addr:$src2)))))],
1728                IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1729 }
1730
1731 multiclass avx512_icmp_packed_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
1732                                  AVX512VLVectorVTInfo VTInfo, Predicate prd,
1733                                  bit IsCommutable = 0> {
1734   let Predicates = [prd] in
1735   defm Z : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info512,
1736                               IsCommutable>, EVEX_V512;
1737
1738   let Predicates = [prd, HasVLX] in {
1739     defm Z256 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info256,
1740                                    IsCommutable>, EVEX_V256;
1741     defm Z128 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info128,
1742                                    IsCommutable>, EVEX_V128;
1743   }
1744 }
1745
1746 multiclass avx512_icmp_packed_rmb_vl<bits<8> opc, string OpcodeStr,
1747                                   SDNode OpNode, AVX512VLVectorVTInfo VTInfo,
1748                                   Predicate prd, bit IsCommutable = 0> {
1749   let Predicates = [prd] in
1750   defm Z : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info512,
1751                                   IsCommutable>, EVEX_V512;
1752
1753   let Predicates = [prd, HasVLX] in {
1754     defm Z256 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info256,
1755                                        IsCommutable>, EVEX_V256;
1756     defm Z128 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info128,
1757                                        IsCommutable>, EVEX_V128;
1758   }
1759 }
1760
1761 defm VPCMPEQB : avx512_icmp_packed_vl<0x74, "vpcmpeqb", X86pcmpeqm,
1762                       avx512vl_i8_info, HasBWI, 1>,
1763                 EVEX_CD8<8, CD8VF>;
1764
1765 defm VPCMPEQW : avx512_icmp_packed_vl<0x75, "vpcmpeqw", X86pcmpeqm,
1766                       avx512vl_i16_info, HasBWI, 1>,
1767                 EVEX_CD8<16, CD8VF>;
1768
1769 defm VPCMPEQD : avx512_icmp_packed_rmb_vl<0x76, "vpcmpeqd", X86pcmpeqm,
1770                       avx512vl_i32_info, HasAVX512, 1>,
1771                 EVEX_CD8<32, CD8VF>;
1772
1773 defm VPCMPEQQ : avx512_icmp_packed_rmb_vl<0x29, "vpcmpeqq", X86pcmpeqm,
1774                       avx512vl_i64_info, HasAVX512, 1>,
1775                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1776
1777 defm VPCMPGTB : avx512_icmp_packed_vl<0x64, "vpcmpgtb", X86pcmpgtm,
1778                       avx512vl_i8_info, HasBWI>,
1779                 EVEX_CD8<8, CD8VF>;
1780
1781 defm VPCMPGTW : avx512_icmp_packed_vl<0x65, "vpcmpgtw", X86pcmpgtm,
1782                       avx512vl_i16_info, HasBWI>,
1783                 EVEX_CD8<16, CD8VF>;
1784
1785 defm VPCMPGTD : avx512_icmp_packed_rmb_vl<0x66, "vpcmpgtd", X86pcmpgtm,
1786                       avx512vl_i32_info, HasAVX512>,
1787                 EVEX_CD8<32, CD8VF>;
1788
1789 defm VPCMPGTQ : avx512_icmp_packed_rmb_vl<0x37, "vpcmpgtq", X86pcmpgtm,
1790                       avx512vl_i64_info, HasAVX512>,
1791                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1792
1793 let Predicates = [HasAVX512, NoVLX] in {
1794 def : Pat<(v8i1 (X86pcmpgtm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1795             (COPY_TO_REGCLASS (VPCMPGTDZrr
1796             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
1797             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm))), VK8)>;
1798
1799 def : Pat<(v8i1 (X86pcmpeqm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1800             (COPY_TO_REGCLASS (VPCMPEQDZrr
1801             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
1802             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm))), VK8)>;
1803 }
1804
1805 multiclass avx512_icmp_cc<bits<8> opc, string Suffix, SDNode OpNode,
1806                           X86VectorVTInfo _> {
1807   let isCommutable = 1 in
1808   def rri : AVX512AIi8<opc, MRMSrcReg,
1809              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, AVX512ICC:$cc),
1810              !strconcat("vpcmp${cc}", Suffix,
1811                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1812              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1813                                        imm:$cc))],
1814              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1815   def rmi : AVX512AIi8<opc, MRMSrcMem,
1816              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, AVX512ICC:$cc),
1817              !strconcat("vpcmp${cc}", Suffix,
1818                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1819              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1820                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
1821                               imm:$cc))],
1822              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1823   def rrik : AVX512AIi8<opc, MRMSrcReg,
1824               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1825                                       AVX512ICC:$cc),
1826               !strconcat("vpcmp${cc}", Suffix,
1827                          "\t{$src2, $src1, $dst {${mask}}|",
1828                          "$dst {${mask}}, $src1, $src2}"),
1829               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1830                                   (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1831                                           imm:$cc)))],
1832               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1833   def rmik : AVX512AIi8<opc, MRMSrcMem,
1834               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1835                                     AVX512ICC:$cc),
1836               !strconcat("vpcmp${cc}", Suffix,
1837                          "\t{$src2, $src1, $dst {${mask}}|",
1838                          "$dst {${mask}}, $src1, $src2}"),
1839               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1840                                    (OpNode (_.VT _.RC:$src1),
1841                                       (_.VT (bitconvert (_.LdFrag addr:$src2))),
1842                                       imm:$cc)))],
1843               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1844
1845   // Accept explicit immediate argument form instead of comparison code.
1846   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1847     def rri_alt : AVX512AIi8<opc, MRMSrcReg,
1848                (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1849                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1850                           "$dst, $src1, $src2, $cc}"),
1851                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1852     let mayLoad = 1 in
1853     def rmi_alt : AVX512AIi8<opc, MRMSrcMem,
1854                (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
1855                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1856                           "$dst, $src1, $src2, $cc}"),
1857                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1858     def rrik_alt : AVX512AIi8<opc, MRMSrcReg,
1859                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1860                                        u8imm:$cc),
1861                !strconcat("vpcmp", Suffix,
1862                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1863                           "$dst {${mask}}, $src1, $src2, $cc}"),
1864                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1865     let mayLoad = 1 in
1866     def rmik_alt : AVX512AIi8<opc, MRMSrcMem,
1867                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1868                                        u8imm:$cc),
1869                !strconcat("vpcmp", Suffix,
1870                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1871                           "$dst {${mask}}, $src1, $src2, $cc}"),
1872                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1873   }
1874 }
1875
1876 multiclass avx512_icmp_cc_rmb<bits<8> opc, string Suffix, SDNode OpNode,
1877                               X86VectorVTInfo _> :
1878            avx512_icmp_cc<opc, Suffix, OpNode, _> {
1879   def rmib : AVX512AIi8<opc, MRMSrcMem,
1880              (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1881                                      AVX512ICC:$cc),
1882              !strconcat("vpcmp${cc}", Suffix,
1883                         "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1884                         "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1885              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1886                                (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1887                                imm:$cc))],
1888              IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1889   def rmibk : AVX512AIi8<opc, MRMSrcMem,
1890               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1891                                        _.ScalarMemOp:$src2, AVX512ICC:$cc),
1892               !strconcat("vpcmp${cc}", Suffix,
1893                        "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1894                        "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1895               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1896                                   (OpNode (_.VT _.RC:$src1),
1897                                     (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1898                                     imm:$cc)))],
1899               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1900
1901   // Accept explicit immediate argument form instead of comparison code.
1902   let isAsmParserOnly = 1, hasSideEffects = 0, mayLoad = 1 in {
1903     def rmib_alt : AVX512AIi8<opc, MRMSrcMem,
1904                (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1905                                        u8imm:$cc),
1906                !strconcat("vpcmp", Suffix,
1907                    "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst|",
1908                    "$dst, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1909                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1910     def rmibk_alt : AVX512AIi8<opc, MRMSrcMem,
1911                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1912                                        _.ScalarMemOp:$src2, u8imm:$cc),
1913                !strconcat("vpcmp", Suffix,
1914                   "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1915                   "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1916                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1917   }
1918 }
1919
1920 multiclass avx512_icmp_cc_vl<bits<8> opc, string Suffix, SDNode OpNode,
1921                              AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1922   let Predicates = [prd] in
1923   defm Z : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info512>, EVEX_V512;
1924
1925   let Predicates = [prd, HasVLX] in {
1926     defm Z256 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info256>, EVEX_V256;
1927     defm Z128 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info128>, EVEX_V128;
1928   }
1929 }
1930
1931 multiclass avx512_icmp_cc_rmb_vl<bits<8> opc, string Suffix, SDNode OpNode,
1932                                 AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1933   let Predicates = [prd] in
1934   defm Z : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info512>,
1935            EVEX_V512;
1936
1937   let Predicates = [prd, HasVLX] in {
1938     defm Z256 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info256>,
1939                 EVEX_V256;
1940     defm Z128 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info128>,
1941                 EVEX_V128;
1942   }
1943 }
1944
1945 defm VPCMPB : avx512_icmp_cc_vl<0x3F, "b", X86cmpm, avx512vl_i8_info,
1946                                 HasBWI>, EVEX_CD8<8, CD8VF>;
1947 defm VPCMPUB : avx512_icmp_cc_vl<0x3E, "ub", X86cmpmu, avx512vl_i8_info,
1948                                  HasBWI>, EVEX_CD8<8, CD8VF>;
1949
1950 defm VPCMPW : avx512_icmp_cc_vl<0x3F, "w", X86cmpm, avx512vl_i16_info,
1951                                 HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1952 defm VPCMPUW : avx512_icmp_cc_vl<0x3E, "uw", X86cmpmu, avx512vl_i16_info,
1953                                  HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1954
1955 defm VPCMPD : avx512_icmp_cc_rmb_vl<0x1F, "d", X86cmpm, avx512vl_i32_info,
1956                                     HasAVX512>, EVEX_CD8<32, CD8VF>;
1957 defm VPCMPUD : avx512_icmp_cc_rmb_vl<0x1E, "ud", X86cmpmu, avx512vl_i32_info,
1958                                      HasAVX512>, EVEX_CD8<32, CD8VF>;
1959
1960 defm VPCMPQ : avx512_icmp_cc_rmb_vl<0x1F, "q", X86cmpm, avx512vl_i64_info,
1961                                     HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1962 defm VPCMPUQ : avx512_icmp_cc_rmb_vl<0x1E, "uq", X86cmpmu, avx512vl_i64_info,
1963                                      HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1964
1965 multiclass avx512_vcmp_common<X86VectorVTInfo _> {
1966
1967   defm  rri  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1968                    (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2,AVXCC:$cc),
1969                    "vcmp${cc}"#_.Suffix,
1970                    "$src2, $src1", "$src1, $src2",
1971                    (X86cmpm (_.VT _.RC:$src1),
1972                          (_.VT _.RC:$src2),
1973                            imm:$cc), 1>;
1974
1975   defm  rmi  : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1976                 (outs _.KRC:$dst),(ins _.RC:$src1, _.MemOp:$src2, AVXCC:$cc),
1977                 "vcmp${cc}"#_.Suffix,
1978                 "$src2, $src1", "$src1, $src2",
1979                 (X86cmpm (_.VT _.RC:$src1),
1980                         (_.VT (bitconvert (_.LdFrag addr:$src2))),
1981                         imm:$cc)>;
1982
1983   defm  rmbi : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1984                 (outs _.KRC:$dst),
1985                 (ins _.RC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1986                 "vcmp${cc}"#_.Suffix,
1987                 "${src2}"##_.BroadcastStr##", $src1",
1988                 "$src1, ${src2}"##_.BroadcastStr,
1989                 (X86cmpm (_.VT _.RC:$src1),
1990                         (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
1991                         imm:$cc)>,EVEX_B;
1992   // Accept explicit immediate argument form instead of comparison code.
1993   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1994     defm  rri_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1995                          (outs _.KRC:$dst),
1996                          (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1997                          "vcmp"#_.Suffix,
1998                          "$cc, $src2, $src1", "$src1, $src2, $cc">;
1999
2000     let mayLoad = 1 in {
2001       defm rmi_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
2002                              (outs _.KRC:$dst),
2003                              (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
2004                              "vcmp"#_.Suffix,
2005                              "$cc, $src2, $src1", "$src1, $src2, $cc">;
2006
2007       defm  rmbi_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
2008                          (outs _.KRC:$dst),
2009                          (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$cc),
2010                          "vcmp"#_.Suffix,
2011                          "$cc, ${src2}"##_.BroadcastStr##", $src1",
2012                          "$src1, ${src2}"##_.BroadcastStr##", $cc">,EVEX_B;
2013     }
2014  }
2015 }
2016
2017 multiclass avx512_vcmp_sae<X86VectorVTInfo _> {
2018   // comparison code form (VCMP[EQ/LT/LE/...]
2019   defm  rrib  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
2020                      (outs _.KRC:$dst),(ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
2021                      "vcmp${cc}"#_.Suffix,
2022                      "{sae}, $src2, $src1", "$src1, $src2, {sae}",
2023                      (X86cmpmRnd (_.VT _.RC:$src1),
2024                                     (_.VT _.RC:$src2),
2025                                     imm:$cc,
2026                                 (i32 FROUND_NO_EXC))>, EVEX_B;
2027
2028   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2029     defm  rrib_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
2030                          (outs _.KRC:$dst),
2031                          (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
2032                          "vcmp"#_.Suffix,
2033                          "$cc, {sae}, $src2, $src1",
2034                          "$src1, $src2, {sae}, $cc">, EVEX_B;
2035    }
2036 }
2037
2038 multiclass avx512_vcmp<AVX512VLVectorVTInfo _> {
2039   let Predicates = [HasAVX512] in {
2040     defm Z    : avx512_vcmp_common<_.info512>,
2041                 avx512_vcmp_sae<_.info512>, EVEX_V512;
2042
2043   }
2044   let Predicates = [HasAVX512,HasVLX] in {
2045    defm Z128 : avx512_vcmp_common<_.info128>, EVEX_V128;
2046    defm Z256 : avx512_vcmp_common<_.info256>, EVEX_V256;
2047   }
2048 }
2049
2050 defm VCMPPD : avx512_vcmp<avx512vl_f64_info>,
2051                           AVX512PDIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
2052 defm VCMPPS : avx512_vcmp<avx512vl_f32_info>,
2053                           AVX512PSIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
2054
2055 def : Pat<(v8i1 (X86cmpm (v8f32 VR256X:$src1), (v8f32 VR256X:$src2), imm:$cc)),
2056           (COPY_TO_REGCLASS (VCMPPSZrri
2057             (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
2058             (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm)),
2059             imm:$cc), VK8)>;
2060 def : Pat<(v8i1 (X86cmpm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
2061           (COPY_TO_REGCLASS (VPCMPDZrri
2062             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
2063             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm)),
2064             imm:$cc), VK8)>;
2065 def : Pat<(v8i1 (X86cmpmu (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
2066           (COPY_TO_REGCLASS (VPCMPUDZrri
2067             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
2068             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm)),
2069             imm:$cc), VK8)>;
2070
2071 // ----------------------------------------------------------------
2072 // FPClass
2073 //handle fpclass instruction  mask =  op(reg_scalar,imm)
2074 //                                    op(mem_scalar,imm)
2075 multiclass avx512_scalar_fpclass<bits<8> opc, string OpcodeStr, SDNode OpNode,
2076                                  X86VectorVTInfo _, Predicate prd> {
2077   let Predicates = [prd] in {
2078       def rr : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),//_.KRC:$dst),
2079                       (ins _.RC:$src1, i32u8imm:$src2),
2080                       OpcodeStr##_.Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2081                       [(set _.KRC:$dst,(OpNode (_.VT _.RC:$src1),
2082                               (i32 imm:$src2)))], NoItinerary>;
2083       def rrk : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
2084                       (ins _.KRCWM:$mask, _.RC:$src1, i32u8imm:$src2),
2085                       OpcodeStr##_.Suffix#
2086                       "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2087                       [(set _.KRC:$dst,(or _.KRCWM:$mask,
2088                                       (OpNode (_.VT _.RC:$src1),
2089                                       (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2090     let AddedComplexity = 20 in {
2091       def rm : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2092                       (ins _.MemOp:$src1, i32u8imm:$src2),
2093                       OpcodeStr##_.Suffix##
2094                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2095                       [(set _.KRC:$dst,
2096                             (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
2097                                     (i32 imm:$src2)))], NoItinerary>;
2098       def rmk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2099                       (ins _.KRCWM:$mask, _.MemOp:$src1, i32u8imm:$src2),
2100                       OpcodeStr##_.Suffix##
2101                       "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2102                       [(set _.KRC:$dst,(or _.KRCWM:$mask,
2103                           (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
2104                               (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2105     }
2106   }
2107 }
2108
2109 //handle fpclass instruction mask = fpclass(reg_vec, reg_vec, imm)
2110 //                                  fpclass(reg_vec, mem_vec, imm)
2111 //                                  fpclass(reg_vec, broadcast(eltVt), imm)
2112 multiclass avx512_vector_fpclass<bits<8> opc, string OpcodeStr, SDNode OpNode,
2113                                  X86VectorVTInfo _, string mem, string broadcast>{
2114   def rr : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
2115                       (ins _.RC:$src1, i32u8imm:$src2),
2116                       OpcodeStr##_.Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2117                       [(set _.KRC:$dst,(OpNode (_.VT _.RC:$src1),
2118                                        (i32 imm:$src2)))], NoItinerary>;
2119   def rrk : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
2120                       (ins _.KRCWM:$mask, _.RC:$src1, i32u8imm:$src2),
2121                       OpcodeStr##_.Suffix#
2122                       "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2123                       [(set _.KRC:$dst,(or _.KRCWM:$mask,
2124                                        (OpNode (_.VT _.RC:$src1),
2125                                        (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2126   def rm : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2127                     (ins _.MemOp:$src1, i32u8imm:$src2),
2128                     OpcodeStr##_.Suffix##mem#
2129                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2130                     [(set _.KRC:$dst,(OpNode
2131                                      (_.VT (bitconvert (_.LdFrag addr:$src1))),
2132                                      (i32 imm:$src2)))], NoItinerary>;
2133   def rmk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2134                     (ins _.KRCWM:$mask, _.MemOp:$src1, i32u8imm:$src2),
2135                     OpcodeStr##_.Suffix##mem#
2136                     "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2137                     [(set _.KRC:$dst, (or _.KRCWM:$mask, (OpNode
2138                                   (_.VT (bitconvert (_.LdFrag addr:$src1))),
2139                                   (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2140   def rmb : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2141                     (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
2142                     OpcodeStr##_.Suffix##broadcast##"\t{$src2, ${src1}"##
2143                                       _.BroadcastStr##", $dst|$dst, ${src1}"
2144                                                   ##_.BroadcastStr##", $src2}",
2145                     [(set _.KRC:$dst,(OpNode
2146                                      (_.VT (X86VBroadcast
2147                                            (_.ScalarLdFrag addr:$src1))),
2148                                      (i32 imm:$src2)))], NoItinerary>,EVEX_B;
2149   def rmbk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2150                     (ins _.KRCWM:$mask, _.ScalarMemOp:$src1, i32u8imm:$src2),
2151                     OpcodeStr##_.Suffix##broadcast##"\t{$src2, ${src1}"##
2152                           _.BroadcastStr##", $dst {${mask}}|$dst {${mask}}, ${src1}"##
2153                                                    _.BroadcastStr##", $src2}",
2154                     [(set _.KRC:$dst,(or _.KRCWM:$mask, (OpNode
2155                                      (_.VT (X86VBroadcast
2156                                            (_.ScalarLdFrag addr:$src1))),
2157                                      (i32 imm:$src2))))], NoItinerary>,
2158                                                           EVEX_B, EVEX_K;
2159 }
2160
2161 multiclass avx512_vector_fpclass_all<string OpcodeStr,
2162             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd,
2163                                                               string broadcast>{
2164   let Predicates = [prd] in {
2165     defm Z    : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info512, "{z}",
2166                                       broadcast>, EVEX_V512;
2167   }
2168   let Predicates = [prd, HasVLX] in {
2169     defm Z128 : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info128, "{x}",
2170                                       broadcast>, EVEX_V128;
2171     defm Z256 : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info256, "{y}",
2172                                       broadcast>, EVEX_V256;
2173   }
2174 }
2175
2176 multiclass avx512_fp_fpclass_all<string OpcodeStr, bits<8> opcVec,
2177              bits<8> opcScalar, SDNode VecOpNode, SDNode ScalarOpNode, Predicate prd>{
2178   defm PS : avx512_vector_fpclass_all<OpcodeStr,  avx512vl_f32_info, opcVec,
2179                                       VecOpNode, prd, "{l}">, EVEX_CD8<32, CD8VF>;
2180   defm PD : avx512_vector_fpclass_all<OpcodeStr,  avx512vl_f64_info, opcVec,
2181                                       VecOpNode, prd, "{q}">,EVEX_CD8<64, CD8VF> , VEX_W;
2182   defm SS : avx512_scalar_fpclass<opcScalar, OpcodeStr, ScalarOpNode,
2183                                       f32x_info, prd>, EVEX_CD8<32, CD8VT1>;
2184   defm SD : avx512_scalar_fpclass<opcScalar, OpcodeStr, ScalarOpNode,
2185                                       f64x_info, prd>, EVEX_CD8<64, CD8VT1>, VEX_W;
2186 }
2187
2188 defm VFPCLASS : avx512_fp_fpclass_all<"vfpclass", 0x66, 0x67, X86Vfpclass,
2189                                       X86Vfpclasss, HasDQI>, AVX512AIi8Base,EVEX;
2190
2191 //-----------------------------------------------------------------
2192 // Mask register copy, including
2193 // - copy between mask registers
2194 // - load/store mask registers
2195 // - copy from GPR to mask register and vice versa
2196 //
2197 multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
2198                          string OpcodeStr, RegisterClass KRC,
2199                          ValueType vvt, X86MemOperand x86memop> {
2200   let hasSideEffects = 0 in
2201   def kk : I<opc_kk, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
2202              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
2203   def km : I<opc_km, MRMSrcMem, (outs KRC:$dst), (ins x86memop:$src),
2204              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2205              [(set KRC:$dst, (vvt (load addr:$src)))]>;
2206   def mk : I<opc_mk, MRMDestMem, (outs), (ins x86memop:$dst, KRC:$src),
2207              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2208              [(store KRC:$src, addr:$dst)]>;
2209 }
2210
2211 multiclass avx512_mask_mov_gpr<bits<8> opc_kr, bits<8> opc_rk,
2212                              string OpcodeStr,
2213                              RegisterClass KRC, RegisterClass GRC> {
2214   let hasSideEffects = 0 in {
2215     def kr : I<opc_kr, MRMSrcReg, (outs KRC:$dst), (ins GRC:$src),
2216                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
2217     def rk : I<opc_rk, MRMSrcReg, (outs GRC:$dst), (ins KRC:$src),
2218                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
2219   }
2220 }
2221
2222 let Predicates = [HasDQI] in
2223   defm KMOVB : avx512_mask_mov<0x90, 0x90, 0x91, "kmovb", VK8, v8i1, i8mem>,
2224                avx512_mask_mov_gpr<0x92, 0x93, "kmovb", VK8, GR32>,
2225                VEX, PD;
2226
2227 let Predicates = [HasAVX512] in
2228   defm KMOVW : avx512_mask_mov<0x90, 0x90, 0x91, "kmovw", VK16, v16i1, i16mem>,
2229                avx512_mask_mov_gpr<0x92, 0x93, "kmovw", VK16, GR32>,
2230                VEX, PS;
2231
2232 let Predicates = [HasBWI] in {
2233   defm KMOVD : avx512_mask_mov<0x90, 0x90, 0x91, "kmovd", VK32, v32i1,i32mem>,
2234                VEX, PD, VEX_W;
2235   defm KMOVD : avx512_mask_mov_gpr<0x92, 0x93, "kmovd", VK32, GR32>,
2236                VEX, XD;
2237   defm KMOVQ : avx512_mask_mov<0x90, 0x90, 0x91, "kmovq", VK64, v64i1, i64mem>,
2238                VEX, PS, VEX_W;
2239   defm KMOVQ : avx512_mask_mov_gpr<0x92, 0x93, "kmovq", VK64, GR64>,
2240                VEX, XD, VEX_W;
2241 }
2242
2243 // GR from/to mask register
2244 def : Pat<(v16i1 (bitconvert (i16 GR16:$src))),
2245           (COPY_TO_REGCLASS GR16:$src, VK16)>;
2246 def : Pat<(i16 (bitconvert (v16i1 VK16:$src))),
2247           (COPY_TO_REGCLASS VK16:$src, GR16)>;
2248
2249 def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
2250           (COPY_TO_REGCLASS GR8:$src, VK8)>;
2251 def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
2252           (COPY_TO_REGCLASS VK8:$src, GR8)>;
2253
2254 def : Pat<(i32 (zext (i16 (bitconvert (v16i1 VK16:$src))))),
2255           (KMOVWrk VK16:$src)>;
2256 def : Pat<(i32 (anyext (i16 (bitconvert (v16i1 VK16:$src))))),
2257           (i32 (INSERT_SUBREG (IMPLICIT_DEF),
2258                 (i16 (COPY_TO_REGCLASS VK16:$src, GR16)), sub_16bit))>;
2259
2260 def : Pat<(i32 (zext (i8 (bitconvert (v8i1 VK8:$src))))),
2261           (MOVZX32rr8 (COPY_TO_REGCLASS VK8:$src, GR8))>, Requires<[NoDQI]>;
2262 def : Pat<(i32 (zext (i8 (bitconvert (v8i1 VK8:$src))))),
2263           (KMOVBrk VK8:$src)>, Requires<[HasDQI]>;
2264 def : Pat<(i32 (anyext (i8 (bitconvert (v8i1 VK8:$src))))),
2265           (i32 (INSERT_SUBREG (IMPLICIT_DEF),
2266                 (i8 (COPY_TO_REGCLASS VK8:$src, GR8)), sub_8bit))>;
2267
2268 def : Pat<(v32i1 (bitconvert (i32 GR32:$src))),
2269           (COPY_TO_REGCLASS GR32:$src, VK32)>;
2270 def : Pat<(i32 (bitconvert (v32i1 VK32:$src))),
2271           (COPY_TO_REGCLASS VK32:$src, GR32)>;
2272 def : Pat<(v64i1 (bitconvert (i64 GR64:$src))),
2273           (COPY_TO_REGCLASS GR64:$src, VK64)>;
2274 def : Pat<(i64 (bitconvert (v64i1 VK64:$src))),
2275           (COPY_TO_REGCLASS VK64:$src, GR64)>;
2276
2277 // Load/store kreg
2278 let Predicates = [HasDQI] in {
2279   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
2280             (KMOVBmk addr:$dst, VK8:$src)>;
2281   def : Pat<(v8i1 (bitconvert (i8 (load addr:$src)))),
2282             (KMOVBkm addr:$src)>;
2283
2284   def : Pat<(store VK4:$src, addr:$dst),
2285             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK4:$src, VK8))>;
2286   def : Pat<(store VK2:$src, addr:$dst),
2287             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK2:$src, VK8))>;
2288   def : Pat<(store VK1:$src, addr:$dst),
2289             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK1:$src, VK8))>;
2290
2291   def : Pat<(v2i1 (load addr:$src)),
2292             (COPY_TO_REGCLASS (KMOVBkm addr:$src), VK2)>;
2293   def : Pat<(v4i1 (load addr:$src)),
2294             (COPY_TO_REGCLASS (KMOVBkm addr:$src), VK4)>;
2295 }
2296 let Predicates = [HasAVX512, NoDQI] in {
2297   def : Pat<(store VK1:$src, addr:$dst),
2298             (MOV8mr addr:$dst,
2299              (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)),
2300               sub_8bit))>;
2301   def : Pat<(store VK2:$src, addr:$dst),
2302             (MOV8mr addr:$dst,
2303              (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK2:$src, VK16)),
2304               sub_8bit))>;
2305   def : Pat<(store VK4:$src, addr:$dst),
2306             (MOV8mr addr:$dst,
2307              (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK4:$src, VK16)),
2308               sub_8bit))>;
2309   def : Pat<(store VK8:$src, addr:$dst),
2310             (MOV8mr addr:$dst,
2311              (EXTRACT_SUBREG (KMOVWrk (COPY_TO_REGCLASS VK8:$src, VK16)),
2312               sub_8bit))>;
2313
2314   def : Pat<(v8i1 (load addr:$src)),
2315             (COPY_TO_REGCLASS (MOVZX32rm8 addr:$src), VK8)>;
2316   def : Pat<(v2i1 (load addr:$src)),
2317             (COPY_TO_REGCLASS (MOVZX32rm8 addr:$src), VK2)>;
2318   def : Pat<(v4i1 (load addr:$src)),
2319             (COPY_TO_REGCLASS (MOVZX32rm8 addr:$src), VK4)>;
2320 }
2321
2322 let Predicates = [HasAVX512] in {
2323   def : Pat<(store (i16 (bitconvert (v16i1 VK16:$src))), addr:$dst),
2324             (KMOVWmk addr:$dst, VK16:$src)>;
2325   def : Pat<(i1 (load addr:$src)),
2326             (COPY_TO_REGCLASS (AND32ri8 (MOVZX32rm8 addr:$src), (i32 1)), VK1)>;
2327   def : Pat<(v16i1 (bitconvert (i16 (load addr:$src)))),
2328             (KMOVWkm addr:$src)>;
2329 }
2330 let Predicates = [HasBWI] in {
2331   def : Pat<(store (i32 (bitconvert (v32i1 VK32:$src))), addr:$dst),
2332             (KMOVDmk addr:$dst, VK32:$src)>;
2333   def : Pat<(v32i1 (bitconvert (i32 (load addr:$src)))),
2334             (KMOVDkm addr:$src)>;
2335   def : Pat<(store (i64 (bitconvert (v64i1 VK64:$src))), addr:$dst),
2336             (KMOVQmk addr:$dst, VK64:$src)>;
2337   def : Pat<(v64i1 (bitconvert (i64 (load addr:$src)))),
2338             (KMOVQkm addr:$src)>;
2339 }
2340
2341 let Predicates = [HasAVX512] in {
2342   def : Pat<(i1 (trunc (i64 GR64:$src))),
2343             (COPY_TO_REGCLASS (KMOVWkr (AND32ri8 (EXTRACT_SUBREG $src, sub_32bit),
2344                                         (i32 1))), VK1)>;
2345
2346   def : Pat<(i1 (trunc (i32 GR32:$src))),
2347             (COPY_TO_REGCLASS (KMOVWkr (AND32ri8 $src, (i32 1))), VK1)>;
2348
2349   def : Pat<(i1 (trunc (i32 (assertzext_i1 GR32:$src)))),
2350             (COPY_TO_REGCLASS GR32:$src, VK1)>;
2351
2352   def : Pat<(i1 (trunc (i8 GR8:$src))),
2353        (COPY_TO_REGCLASS
2354         (KMOVWkr (AND32ri8 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
2355                                           GR8:$src, sub_8bit), (i32 1))),
2356        VK1)>;
2357
2358   def : Pat<(i1 (trunc (i16 GR16:$src))),
2359        (COPY_TO_REGCLASS
2360         (KMOVWkr (AND32ri8 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
2361                                           GR16:$src, sub_16bit), (i32 1))),
2362        VK1)>;
2363
2364   def : Pat<(i32 (zext VK1:$src)),
2365             (AND32ri8 (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1))>;
2366
2367   def : Pat<(i32 (anyext VK1:$src)),
2368             (COPY_TO_REGCLASS VK1:$src, GR32)>;
2369
2370   def : Pat<(i8 (zext VK1:$src)),
2371             (EXTRACT_SUBREG
2372              (AND32ri8 (KMOVWrk
2373                         (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)), sub_8bit)>;
2374
2375   def : Pat<(i8 (anyext VK1:$src)),
2376             (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK1:$src, GR32)), sub_8bit)>;
2377
2378   def : Pat<(i64 (zext VK1:$src)),
2379             (AND64ri8 (SUBREG_TO_REG (i64 0),
2380              (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), sub_32bit), (i64 1))>;
2381
2382   def : Pat<(i64 (anyext VK1:$src)),
2383             (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2384              (i32 (COPY_TO_REGCLASS VK1:$src, GR32)), sub_32bit)>;
2385
2386   def : Pat<(i16 (zext VK1:$src)),
2387             (EXTRACT_SUBREG
2388              (AND32ri8 (KMOVWrk (COPY_TO_REGCLASS VK1:$src, VK16)), (i32 1)),
2389               sub_16bit)>;
2390
2391   def : Pat<(i16 (anyext VK1:$src)),
2392             (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK1:$src, GR32)), sub_16bit)>;
2393 }
2394 def : Pat<(v16i1 (scalar_to_vector VK1:$src)),
2395           (COPY_TO_REGCLASS VK1:$src, VK16)>;
2396 def : Pat<(v8i1 (scalar_to_vector VK1:$src)),
2397           (COPY_TO_REGCLASS VK1:$src, VK8)>;
2398 def : Pat<(v4i1 (scalar_to_vector VK1:$src)),
2399           (COPY_TO_REGCLASS VK1:$src, VK4)>;
2400 def : Pat<(v2i1 (scalar_to_vector VK1:$src)),
2401           (COPY_TO_REGCLASS VK1:$src, VK2)>;
2402 def : Pat<(v32i1 (scalar_to_vector VK1:$src)),
2403           (COPY_TO_REGCLASS VK1:$src, VK32)>;
2404 def : Pat<(v64i1 (scalar_to_vector VK1:$src)),
2405           (COPY_TO_REGCLASS VK1:$src, VK64)>;
2406
2407 def : Pat<(store (i1 -1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
2408 def : Pat<(store (i1  1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
2409 def : Pat<(store (i1  0), addr:$dst), (MOV8mi addr:$dst, (i8 0))>;
2410
2411 def : Pat<(i1 (X86Vextract VK64:$src, (iPTR 0))), (COPY_TO_REGCLASS VK64:$src, VK1)>;
2412 def : Pat<(i1 (X86Vextract VK32:$src, (iPTR 0))), (COPY_TO_REGCLASS VK32:$src, VK1)>;
2413 def : Pat<(i1 (X86Vextract VK16:$src, (iPTR 0))), (COPY_TO_REGCLASS VK16:$src, VK1)>;
2414 def : Pat<(i1 (X86Vextract VK8:$src,  (iPTR 0))), (COPY_TO_REGCLASS VK8:$src,  VK1)>;
2415 def : Pat<(i1 (X86Vextract VK4:$src,  (iPTR 0))), (COPY_TO_REGCLASS VK4:$src,  VK1)>;
2416 def : Pat<(i1 (X86Vextract VK2:$src,  (iPTR 0))), (COPY_TO_REGCLASS VK2:$src,  VK1)>;
2417
2418 // Mask unary operation
2419 // - KNOT
2420 multiclass avx512_mask_unop<bits<8> opc, string OpcodeStr,
2421                             RegisterClass KRC, SDPatternOperator OpNode,
2422                             Predicate prd> {
2423   let Predicates = [prd] in
2424     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
2425                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2426                [(set KRC:$dst, (OpNode KRC:$src))]>;
2427 }
2428
2429 multiclass avx512_mask_unop_all<bits<8> opc, string OpcodeStr,
2430                                 SDPatternOperator OpNode> {
2431   defm B : avx512_mask_unop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
2432                             HasDQI>, VEX, PD;
2433   defm W : avx512_mask_unop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
2434                             HasAVX512>, VEX, PS;
2435   defm D : avx512_mask_unop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
2436                             HasBWI>, VEX, PD, VEX_W;
2437   defm Q : avx512_mask_unop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
2438                             HasBWI>, VEX, PS, VEX_W;
2439 }
2440
2441 defm KNOT : avx512_mask_unop_all<0x44, "knot", vnot>;
2442
2443 multiclass avx512_mask_unop_int<string IntName, string InstName> {
2444   let Predicates = [HasAVX512] in
2445     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
2446                 (i16 GR16:$src)),
2447               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
2448               (v16i1 (COPY_TO_REGCLASS GR16:$src, VK16))), GR16)>;
2449 }
2450 defm : avx512_mask_unop_int<"knot", "KNOT">;
2451
2452 // KNL does not support KMOVB, 8-bit mask is promoted to 16-bit
2453 let Predicates = [HasAVX512, NoDQI] in
2454 def : Pat<(vnot VK8:$src),
2455           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$src, VK16)), VK8)>;
2456
2457 def : Pat<(vnot VK4:$src),
2458           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK4:$src, VK16)), VK4)>;
2459 def : Pat<(vnot VK2:$src),
2460           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK2:$src, VK16)), VK2)>;
2461
2462 // Mask binary operation
2463 // - KAND, KANDN, KOR, KXNOR, KXOR
2464 multiclass avx512_mask_binop<bits<8> opc, string OpcodeStr,
2465                            RegisterClass KRC, SDPatternOperator OpNode,
2466                            Predicate prd, bit IsCommutable> {
2467   let Predicates = [prd], isCommutable = IsCommutable in
2468     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
2469                !strconcat(OpcodeStr,
2470                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2471                [(set KRC:$dst, (OpNode KRC:$src1, KRC:$src2))]>;
2472 }
2473
2474 multiclass avx512_mask_binop_all<bits<8> opc, string OpcodeStr,
2475                                SDPatternOperator OpNode, bit IsCommutable,
2476                                Predicate prdW = HasAVX512> {
2477   defm B : avx512_mask_binop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
2478                              HasDQI, IsCommutable>, VEX_4V, VEX_L, PD;
2479   defm W : avx512_mask_binop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
2480                              prdW, IsCommutable>, VEX_4V, VEX_L, PS;
2481   defm D : avx512_mask_binop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
2482                              HasBWI, IsCommutable>, VEX_4V, VEX_L, VEX_W, PD;
2483   defm Q : avx512_mask_binop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
2484                              HasBWI, IsCommutable>, VEX_4V, VEX_L, VEX_W, PS;
2485 }
2486
2487 def andn : PatFrag<(ops node:$i0, node:$i1), (and (not node:$i0), node:$i1)>;
2488 def xnor : PatFrag<(ops node:$i0, node:$i1), (not (xor node:$i0, node:$i1))>;
2489 // These nodes use 'vnot' instead of 'not' to support vectors.
2490 def vandn : PatFrag<(ops node:$i0, node:$i1), (and (vnot node:$i0), node:$i1)>;
2491 def vxnor : PatFrag<(ops node:$i0, node:$i1), (vnot (xor node:$i0, node:$i1))>;
2492
2493 defm KAND  : avx512_mask_binop_all<0x41, "kand",  and,   1>;
2494 defm KOR   : avx512_mask_binop_all<0x45, "kor",   or,    1>;
2495 defm KXNOR : avx512_mask_binop_all<0x46, "kxnor", vxnor, 1>;
2496 defm KXOR  : avx512_mask_binop_all<0x47, "kxor",  xor,   1>;
2497 defm KANDN : avx512_mask_binop_all<0x42, "kandn", vandn, 0>;
2498 defm KADD  : avx512_mask_binop_all<0x4A, "kadd",  add,   1, HasDQI>;
2499
2500 multiclass avx512_mask_binop_int<string IntName, string InstName> {
2501   let Predicates = [HasAVX512] in
2502     def : Pat<(!cast<Intrinsic>("int_x86_avx512_"##IntName##"_w")
2503                 (i16 GR16:$src1), (i16 GR16:$src2)),
2504               (COPY_TO_REGCLASS (!cast<Instruction>(InstName##"Wrr")
2505               (v16i1 (COPY_TO_REGCLASS GR16:$src1, VK16)),
2506               (v16i1 (COPY_TO_REGCLASS GR16:$src2, VK16))), GR16)>;
2507 }
2508
2509 defm : avx512_mask_binop_int<"kand",  "KAND">;
2510 defm : avx512_mask_binop_int<"kandn", "KANDN">;
2511 defm : avx512_mask_binop_int<"kor",   "KOR">;
2512 defm : avx512_mask_binop_int<"kxnor", "KXNOR">;
2513 defm : avx512_mask_binop_int<"kxor",  "KXOR">;
2514
2515 multiclass avx512_binop_pat<SDPatternOperator VOpNode, SDPatternOperator OpNode,
2516                             Instruction Inst> {
2517   // With AVX512F, 8-bit mask is promoted to 16-bit mask,
2518   // for the DQI set, this type is legal and KxxxB instruction is used
2519   let Predicates = [NoDQI] in
2520   def : Pat<(VOpNode VK8:$src1, VK8:$src2),
2521             (COPY_TO_REGCLASS
2522               (Inst (COPY_TO_REGCLASS VK8:$src1, VK16),
2523                     (COPY_TO_REGCLASS VK8:$src2, VK16)), VK8)>;
2524
2525   // All types smaller than 8 bits require conversion anyway
2526   def : Pat<(OpNode VK1:$src1, VK1:$src2),
2527         (COPY_TO_REGCLASS (Inst
2528                            (COPY_TO_REGCLASS VK1:$src1, VK16),
2529                            (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
2530   def : Pat<(VOpNode VK2:$src1, VK2:$src2),
2531         (COPY_TO_REGCLASS (Inst
2532                            (COPY_TO_REGCLASS VK2:$src1, VK16),
2533                            (COPY_TO_REGCLASS VK2:$src2, VK16)), VK1)>;
2534   def : Pat<(VOpNode VK4:$src1, VK4:$src2),
2535         (COPY_TO_REGCLASS (Inst
2536                            (COPY_TO_REGCLASS VK4:$src1, VK16),
2537                            (COPY_TO_REGCLASS VK4:$src2, VK16)), VK1)>;
2538 }
2539
2540 defm : avx512_binop_pat<and,   and,  KANDWrr>;
2541 defm : avx512_binop_pat<vandn, andn, KANDNWrr>;
2542 defm : avx512_binop_pat<or,    or,   KORWrr>;
2543 defm : avx512_binop_pat<vxnor, xnor, KXNORWrr>;
2544 defm : avx512_binop_pat<xor,   xor,  KXORWrr>;
2545
2546 // Mask unpacking
2547 multiclass avx512_mask_unpck<string Suffix,RegisterClass KRC, ValueType VT,
2548                              RegisterClass KRCSrc, Predicate prd> {
2549   let Predicates = [prd] in {
2550     let hasSideEffects = 0 in
2551     def rr : I<0x4b, MRMSrcReg, (outs KRC:$dst),
2552                (ins KRC:$src1, KRC:$src2),
2553                "kunpck"#Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
2554                VEX_4V, VEX_L;
2555
2556     def : Pat<(VT (concat_vectors KRCSrc:$src1, KRCSrc:$src2)),
2557               (!cast<Instruction>(NAME##rr)
2558                         (COPY_TO_REGCLASS KRCSrc:$src2, KRC),
2559                         (COPY_TO_REGCLASS KRCSrc:$src1, KRC))>;
2560   }
2561 }
2562
2563 defm KUNPCKBW : avx512_mask_unpck<"bw", VK16, v16i1, VK8, HasAVX512>, PD;
2564 defm KUNPCKWD : avx512_mask_unpck<"wd", VK32, v32i1, VK16, HasBWI>, PS;
2565 defm KUNPCKDQ : avx512_mask_unpck<"dq", VK64, v64i1, VK32, HasBWI>, PS, VEX_W;
2566
2567 // Mask bit testing
2568 multiclass avx512_mask_testop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
2569                               SDNode OpNode, Predicate prd> {
2570   let Predicates = [prd], Defs = [EFLAGS] in
2571     def rr : I<opc, MRMSrcReg, (outs), (ins KRC:$src1, KRC:$src2),
2572                !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2573                [(set EFLAGS, (OpNode KRC:$src1, KRC:$src2))]>;
2574 }
2575
2576 multiclass avx512_mask_testop_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
2577                                 Predicate prdW = HasAVX512> {
2578   defm B : avx512_mask_testop<opc, OpcodeStr#"b", VK8, OpNode, HasDQI>,
2579                                                                 VEX, PD;
2580   defm W : avx512_mask_testop<opc, OpcodeStr#"w", VK16, OpNode, prdW>,
2581                                                                 VEX, PS;
2582   defm Q : avx512_mask_testop<opc, OpcodeStr#"q", VK64, OpNode, HasBWI>,
2583                                                                 VEX, PS, VEX_W;
2584   defm D : avx512_mask_testop<opc, OpcodeStr#"d", VK32, OpNode, HasBWI>,
2585                                                                 VEX, PD, VEX_W;
2586 }
2587
2588 defm KORTEST : avx512_mask_testop_w<0x98, "kortest", X86kortest>;
2589 defm KTEST   : avx512_mask_testop_w<0x99, "ktest", X86ktest, HasDQI>;
2590
2591 // Mask shift
2592 multiclass avx512_mask_shiftop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
2593                              SDNode OpNode> {
2594   let Predicates = [HasAVX512] in
2595     def ri : Ii8<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src, u8imm:$imm),
2596                  !strconcat(OpcodeStr,
2597                             "\t{$imm, $src, $dst|$dst, $src, $imm}"),
2598                             [(set KRC:$dst, (OpNode KRC:$src, (i8 imm:$imm)))]>;
2599 }
2600
2601 multiclass avx512_mask_shiftop_w<bits<8> opc1, bits<8> opc2, string OpcodeStr,
2602                                SDNode OpNode> {
2603   defm W : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
2604                                VEX, TAPD, VEX_W;
2605   let Predicates = [HasDQI] in
2606   defm B : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "b"), VK8, OpNode>,
2607                                VEX, TAPD;
2608   let Predicates = [HasBWI] in {
2609   defm Q : avx512_mask_shiftop<opc2, !strconcat(OpcodeStr, "q"), VK64, OpNode>,
2610                                VEX, TAPD, VEX_W;
2611   defm D : avx512_mask_shiftop<opc2, !strconcat(OpcodeStr, "d"), VK32, OpNode>,
2612                                VEX, TAPD;
2613   }
2614 }
2615
2616 defm KSHIFTL : avx512_mask_shiftop_w<0x32, 0x33, "kshiftl", X86vshli>;
2617 defm KSHIFTR : avx512_mask_shiftop_w<0x30, 0x31, "kshiftr", X86vsrli>;
2618
2619 // Mask setting all 0s or 1s
2620 multiclass avx512_mask_setop<RegisterClass KRC, ValueType VT, PatFrag Val> {
2621   let Predicates = [HasAVX512] in
2622     let isReMaterializable = 1, isAsCheapAsAMove = 1, isPseudo = 1 in
2623       def #NAME# : I<0, Pseudo, (outs KRC:$dst), (ins), "",
2624                      [(set KRC:$dst, (VT Val))]>;
2625 }
2626
2627 multiclass avx512_mask_setop_w<PatFrag Val> {
2628   defm B : avx512_mask_setop<VK8,   v8i1, Val>;
2629   defm W : avx512_mask_setop<VK16, v16i1, Val>;
2630   defm D : avx512_mask_setop<VK32,  v32i1, Val>;
2631   defm Q : avx512_mask_setop<VK64, v64i1, Val>;
2632 }
2633
2634 defm KSET0 : avx512_mask_setop_w<immAllZerosV>;
2635 defm KSET1 : avx512_mask_setop_w<immAllOnesV>;
2636
2637 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
2638 let Predicates = [HasAVX512] in {
2639   def : Pat<(v8i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK8)>;
2640   def : Pat<(v4i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK4)>;
2641   def : Pat<(v2i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK2)>;
2642   def : Pat<(v8i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK8)>;
2643   def : Pat<(v4i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK4)>;
2644   def : Pat<(v2i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK2)>;
2645   def : Pat<(i1 0), (COPY_TO_REGCLASS (KSET0W), VK1)>;
2646   def : Pat<(i1 1), (COPY_TO_REGCLASS (KSHIFTRWri (KSET1W), (i8 15)), VK1)>;
2647   def : Pat<(i1 -1), (COPY_TO_REGCLASS (KSHIFTRWri (KSET1W), (i8 15)), VK1)>;
2648 }
2649
2650 // Patterns for kmask insert_subvector/extract_subvector to/from index=0
2651 multiclass operation_subvector_mask_lowering<RegisterClass subRC, ValueType subVT,
2652                                              RegisterClass RC, ValueType VT> {
2653   def : Pat<(subVT (extract_subvector (VT RC:$src), (iPTR 0))),
2654             (subVT (COPY_TO_REGCLASS RC:$src, subRC))>;
2655
2656   def : Pat<(VT (insert_subvector undef, subRC:$src, (iPTR 0))),
2657             (VT (COPY_TO_REGCLASS subRC:$src, RC))>;
2658 }
2659
2660 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK4,  v4i1>;
2661 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK8,  v8i1>;
2662 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK16, v16i1>;
2663 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK32, v32i1>;
2664 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK64, v64i1>;
2665
2666 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK8,  v8i1>;
2667 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK16, v16i1>;
2668 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK32, v32i1>;
2669 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK64, v64i1>;
2670
2671 defm : operation_subvector_mask_lowering<VK8,  v8i1,  VK16, v16i1>;
2672 defm : operation_subvector_mask_lowering<VK8,  v8i1,  VK32, v32i1>;
2673 defm : operation_subvector_mask_lowering<VK8,  v8i1,  VK64, v64i1>;
2674
2675 defm : operation_subvector_mask_lowering<VK16, v16i1, VK32, v32i1>;
2676 defm : operation_subvector_mask_lowering<VK16, v16i1, VK64, v64i1>;
2677
2678 defm : operation_subvector_mask_lowering<VK32, v32i1, VK64, v64i1>;
2679
2680 def : Pat<(v2i1 (extract_subvector (v4i1 VK4:$src), (iPTR 2))),
2681           (v2i1 (COPY_TO_REGCLASS
2682                   (KSHIFTRWri (COPY_TO_REGCLASS VK4:$src, VK16), (i8 2)),
2683                    VK2))>;
2684 def : Pat<(v4i1 (extract_subvector (v8i1 VK8:$src), (iPTR 4))),
2685           (v4i1 (COPY_TO_REGCLASS
2686                   (KSHIFTRWri (COPY_TO_REGCLASS VK8:$src, VK16), (i8 4)),
2687                    VK4))>;
2688 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 8))),
2689           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri VK16:$src, (i8 8)), VK8))>;
2690 def : Pat<(v16i1 (extract_subvector (v32i1 VK32:$src), (iPTR 16))),
2691           (v16i1 (COPY_TO_REGCLASS (KSHIFTRDri VK32:$src, (i8 16)), VK16))>;
2692 def : Pat<(v32i1 (extract_subvector (v64i1 VK64:$src), (iPTR 32))),
2693           (v32i1 (COPY_TO_REGCLASS (KSHIFTRQri VK64:$src, (i8 32)), VK32))>;
2694
2695
2696 // Patterns for kmask shift
2697 multiclass mask_shift_lowering<RegisterClass RC, ValueType VT> {
2698   def : Pat<(VT (X86vshli RC:$src, (i8 imm:$imm))),
2699             (VT (COPY_TO_REGCLASS
2700                    (KSHIFTLWri (COPY_TO_REGCLASS RC:$src, VK16),
2701                                (I8Imm $imm)),
2702                    RC))>;
2703   def : Pat<(VT (X86vsrli RC:$src, (i8 imm:$imm))),
2704             (VT (COPY_TO_REGCLASS
2705                    (KSHIFTRWri (COPY_TO_REGCLASS RC:$src, VK16),
2706                                (I8Imm $imm)),
2707                    RC))>;
2708 }
2709
2710 defm : mask_shift_lowering<VK8, v8i1>, Requires<[HasAVX512, NoDQI]>;
2711 defm : mask_shift_lowering<VK4, v4i1>, Requires<[HasAVX512]>;
2712 defm : mask_shift_lowering<VK2, v2i1>, Requires<[HasAVX512]>;
2713 //===----------------------------------------------------------------------===//
2714 // AVX-512 - Aligned and unaligned load and store
2715 //
2716
2717
2718 multiclass avx512_load<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
2719                          PatFrag ld_frag, PatFrag mload,
2720                          SDPatternOperator SelectOprr = vselect> {
2721   let hasSideEffects = 0 in {
2722   def rr : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst), (ins _.RC:$src),
2723                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [],
2724                     _.ExeDomain>, EVEX;
2725   def rrkz : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst),
2726                       (ins _.KRCWM:$mask,  _.RC:$src),
2727                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
2728                        "${dst} {${mask}} {z}, $src}"),
2729                        [(set _.RC:$dst, (_.VT (SelectOprr _.KRCWM:$mask,
2730                                            (_.VT _.RC:$src),
2731                                            _.ImmAllZerosV)))], _.ExeDomain>,
2732                        EVEX, EVEX_KZ;
2733
2734   let canFoldAsLoad = 1, isReMaterializable = 1,
2735       SchedRW = [WriteLoad] in
2736   def rm : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst), (ins _.MemOp:$src),
2737                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2738                     [(set _.RC:$dst, (_.VT (bitconvert (ld_frag addr:$src))))],
2739                     _.ExeDomain>, EVEX;
2740
2741   let Constraints = "$src0 = $dst" in {
2742   def rrk : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst),
2743                     (ins _.RC:$src0, _.KRCWM:$mask, _.RC:$src1),
2744                     !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
2745                     "${dst} {${mask}}, $src1}"),
2746                     [(set _.RC:$dst, (_.VT (SelectOprr _.KRCWM:$mask,
2747                                         (_.VT _.RC:$src1),
2748                                         (_.VT _.RC:$src0))))], _.ExeDomain>,
2749                      EVEX, EVEX_K;
2750     let SchedRW = [WriteLoad] in
2751     def rmk : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst),
2752                      (ins _.RC:$src0, _.KRCWM:$mask, _.MemOp:$src1),
2753                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
2754                       "${dst} {${mask}}, $src1}"),
2755                      [(set _.RC:$dst, (_.VT
2756                          (vselect _.KRCWM:$mask,
2757                           (_.VT (bitconvert (ld_frag addr:$src1))),
2758                            (_.VT _.RC:$src0))))], _.ExeDomain>, EVEX, EVEX_K;
2759   }
2760   let SchedRW = [WriteLoad] in
2761   def rmkz : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst),
2762                   (ins _.KRCWM:$mask, _.MemOp:$src),
2763                   OpcodeStr #"\t{$src, ${dst} {${mask}} {z}|"#
2764                                 "${dst} {${mask}} {z}, $src}",
2765                   [(set _.RC:$dst, (_.VT (vselect _.KRCWM:$mask,
2766                     (_.VT (bitconvert (ld_frag addr:$src))), _.ImmAllZerosV)))],
2767                   _.ExeDomain>, EVEX, EVEX_KZ;
2768   }
2769   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, undef)),
2770             (!cast<Instruction>(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>;
2771
2772   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, _.ImmAllZerosV)),
2773             (!cast<Instruction>(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>;
2774
2775   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src0))),
2776             (!cast<Instruction>(NAME#_.ZSuffix##rmk) _.RC:$src0,
2777              _.KRCWM:$mask, addr:$ptr)>;
2778 }
2779
2780 multiclass avx512_alignedload_vl<bits<8> opc, string OpcodeStr,
2781                                   AVX512VLVectorVTInfo _,
2782                                   Predicate prd> {
2783   let Predicates = [prd] in
2784   defm Z : avx512_load<opc, OpcodeStr, _.info512, _.info512.AlignedLdFrag,
2785                        masked_load_aligned512>, EVEX_V512;
2786
2787   let Predicates = [prd, HasVLX] in {
2788   defm Z256 : avx512_load<opc, OpcodeStr, _.info256, _.info256.AlignedLdFrag,
2789                           masked_load_aligned256>, EVEX_V256;
2790   defm Z128 : avx512_load<opc, OpcodeStr, _.info128, _.info128.AlignedLdFrag,
2791                           masked_load_aligned128>, EVEX_V128;
2792   }
2793 }
2794
2795 multiclass avx512_load_vl<bits<8> opc, string OpcodeStr,
2796                                   AVX512VLVectorVTInfo _,
2797                                   Predicate prd,
2798                                   SDPatternOperator SelectOprr = vselect> {
2799   let Predicates = [prd] in
2800   defm Z : avx512_load<opc, OpcodeStr, _.info512, _.info512.LdFrag,
2801                        masked_load_unaligned, SelectOprr>, EVEX_V512;
2802
2803   let Predicates = [prd, HasVLX] in {
2804   defm Z256 : avx512_load<opc, OpcodeStr, _.info256, _.info256.LdFrag,
2805                          masked_load_unaligned, SelectOprr>, EVEX_V256;
2806   defm Z128 : avx512_load<opc, OpcodeStr, _.info128, _.info128.LdFrag,
2807                          masked_load_unaligned, SelectOprr>, EVEX_V128;
2808   }
2809 }
2810
2811 multiclass avx512_store<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
2812                         PatFrag st_frag, PatFrag mstore> {
2813
2814   let hasSideEffects = 0 in {
2815   def rr_REV  : AVX512PI<opc, MRMDestReg, (outs _.RC:$dst), (ins _.RC:$src),
2816                          OpcodeStr # ".s\t{$src, $dst|$dst, $src}",
2817                          [], _.ExeDomain>, EVEX;
2818   def rrk_REV : AVX512PI<opc, MRMDestReg, (outs  _.RC:$dst),
2819                          (ins _.KRCWM:$mask, _.RC:$src),
2820                          OpcodeStr # ".s\t{$src, ${dst} {${mask}}|"#
2821                          "${dst} {${mask}}, $src}",
2822                          [], _.ExeDomain>,  EVEX, EVEX_K;
2823   def rrkz_REV : AVX512PI<opc, MRMDestReg, (outs  _.RC:$dst),
2824                           (ins _.KRCWM:$mask, _.RC:$src),
2825                           OpcodeStr # ".s\t{$src, ${dst} {${mask}} {z}|" #
2826                           "${dst} {${mask}} {z}, $src}",
2827                           [], _.ExeDomain>, EVEX, EVEX_KZ;
2828   }
2829
2830   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins _.MemOp:$dst, _.RC:$src),
2831                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2832                     [(st_frag (_.VT _.RC:$src), addr:$dst)], _.ExeDomain>, EVEX;
2833   def mrk : AVX512PI<opc, MRMDestMem, (outs),
2834                      (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
2835               OpcodeStr # "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}",
2836                [], _.ExeDomain>, EVEX, EVEX_K;
2837
2838   def: Pat<(mstore addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src)),
2839            (!cast<Instruction>(NAME#_.ZSuffix##mrk) addr:$ptr,
2840                                                     _.KRCWM:$mask, _.RC:$src)>;
2841 }
2842
2843
2844 multiclass avx512_store_vl< bits<8> opc, string OpcodeStr,
2845                             AVX512VLVectorVTInfo _, Predicate prd> {
2846   let Predicates = [prd] in
2847   defm Z : avx512_store<opc, OpcodeStr, _.info512, store,
2848                         masked_store_unaligned>, EVEX_V512;
2849
2850   let Predicates = [prd, HasVLX] in {
2851     defm Z256 : avx512_store<opc, OpcodeStr, _.info256, store,
2852                              masked_store_unaligned>, EVEX_V256;
2853     defm Z128 : avx512_store<opc, OpcodeStr, _.info128, store,
2854                              masked_store_unaligned>, EVEX_V128;
2855   }
2856 }
2857
2858 multiclass avx512_alignedstore_vl<bits<8> opc, string OpcodeStr,
2859                                   AVX512VLVectorVTInfo _,  Predicate prd> {
2860   let Predicates = [prd] in
2861   defm Z : avx512_store<opc, OpcodeStr, _.info512, alignedstore512,
2862                         masked_store_aligned512>, EVEX_V512;
2863
2864   let Predicates = [prd, HasVLX] in {
2865     defm Z256 : avx512_store<opc, OpcodeStr, _.info256, alignedstore256,
2866                              masked_store_aligned256>, EVEX_V256;
2867     defm Z128 : avx512_store<opc, OpcodeStr, _.info128, alignedstore,
2868                              masked_store_aligned128>, EVEX_V128;
2869   }
2870 }
2871
2872 defm VMOVAPS : avx512_alignedload_vl<0x28, "vmovaps", avx512vl_f32_info,
2873                                      HasAVX512>,
2874                avx512_alignedstore_vl<0x29, "vmovaps", avx512vl_f32_info,
2875                                       HasAVX512>,  PS, EVEX_CD8<32, CD8VF>;
2876
2877 defm VMOVAPD : avx512_alignedload_vl<0x28, "vmovapd", avx512vl_f64_info,
2878                                      HasAVX512>,
2879                avx512_alignedstore_vl<0x29, "vmovapd", avx512vl_f64_info,
2880                                      HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2881
2882 defm VMOVUPS : avx512_load_vl<0x10, "vmovups", avx512vl_f32_info, HasAVX512,
2883                               null_frag>,
2884                avx512_store_vl<0x11, "vmovups", avx512vl_f32_info, HasAVX512>,
2885                               PS, EVEX_CD8<32, CD8VF>;
2886
2887 defm VMOVUPD : avx512_load_vl<0x10, "vmovupd", avx512vl_f64_info, HasAVX512,
2888                               null_frag>,
2889                avx512_store_vl<0x11, "vmovupd", avx512vl_f64_info, HasAVX512>,
2890                PD, VEX_W, EVEX_CD8<64, CD8VF>;
2891
2892 defm VMOVDQA32 : avx512_alignedload_vl<0x6F, "vmovdqa32", avx512vl_i32_info,
2893                                        HasAVX512>,
2894                  avx512_alignedstore_vl<0x7F, "vmovdqa32", avx512vl_i32_info,
2895                                        HasAVX512>, PD, EVEX_CD8<32, CD8VF>;
2896
2897 defm VMOVDQA64 : avx512_alignedload_vl<0x6F, "vmovdqa64", avx512vl_i64_info,
2898                                        HasAVX512>,
2899                  avx512_alignedstore_vl<0x7F, "vmovdqa64", avx512vl_i64_info,
2900                                     HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2901
2902 defm VMOVDQU8 : avx512_load_vl<0x6F, "vmovdqu8", avx512vl_i8_info, HasBWI>,
2903                  avx512_store_vl<0x7F, "vmovdqu8", avx512vl_i8_info,
2904                                  HasBWI>, XD, EVEX_CD8<8, CD8VF>;
2905
2906 defm VMOVDQU16 : avx512_load_vl<0x6F, "vmovdqu16", avx512vl_i16_info, HasBWI>,
2907                  avx512_store_vl<0x7F, "vmovdqu16", avx512vl_i16_info,
2908                                  HasBWI>, XD, VEX_W, EVEX_CD8<16, CD8VF>;
2909
2910 defm VMOVDQU32 : avx512_load_vl<0x6F, "vmovdqu32", avx512vl_i32_info, HasAVX512,
2911                                 null_frag>,
2912                  avx512_store_vl<0x7F, "vmovdqu32", avx512vl_i32_info,
2913                                  HasAVX512>, XS, EVEX_CD8<32, CD8VF>;
2914
2915 defm VMOVDQU64 : avx512_load_vl<0x6F, "vmovdqu64", avx512vl_i64_info, HasAVX512,
2916                                 null_frag>,
2917                  avx512_store_vl<0x7F, "vmovdqu64", avx512vl_i64_info,
2918                                  HasAVX512>, XS, VEX_W, EVEX_CD8<64, CD8VF>;
2919
2920 // Special instructions to help with spilling when we don't have VLX. We need
2921 // to load or store from a ZMM register instead. These are converted in
2922 // expandPostRAPseudos.
2923 let isReMaterializable = 1, canFoldAsLoad = 1,
2924     isPseudo = 1, SchedRW = [WriteLoad], mayLoad = 1, hasSideEffects = 0 in {
2925 def VMOVAPSZ128rm_NOVLX : I<0, Pseudo, (outs VR128X:$dst), (ins f128mem:$src),
2926                             "", []>;
2927 def VMOVAPSZ256rm_NOVLX : I<0, Pseudo, (outs VR256X:$dst), (ins f256mem:$src),
2928                             "", []>;
2929 def VMOVUPSZ128rm_NOVLX : I<0, Pseudo, (outs VR128X:$dst), (ins f128mem:$src),
2930                             "", []>;
2931 def VMOVUPSZ256rm_NOVLX : I<0, Pseudo, (outs VR256X:$dst), (ins f256mem:$src),
2932                             "", []>;
2933 }
2934
2935 let isPseudo = 1, mayStore = 1, hasSideEffects = 0 in {
2936 def VMOVAPSZ128mr_NOVLX : I<0, Pseudo, (outs), (ins f128mem:$dst, VR128X:$src),
2937                             "", []>;
2938 def VMOVAPSZ256mr_NOVLX : I<0, Pseudo, (outs), (ins f256mem:$dst, VR256X:$src),
2939                             "", []>;
2940 def VMOVUPSZ128mr_NOVLX : I<0, Pseudo, (outs), (ins f128mem:$dst, VR128X:$src),
2941                             "", []>;
2942 def VMOVUPSZ256mr_NOVLX : I<0, Pseudo, (outs), (ins f256mem:$dst, VR256X:$src),
2943                             "", []>;
2944 }
2945
2946 def : Pat<(v8i64 (vselect VK8WM:$mask, (bc_v8i64 (v16i32 immAllZerosV)),
2947                           (v8i64 VR512:$src))),
2948    (VMOVDQA64Zrrkz (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$mask, VK16)),
2949                                               VK8), VR512:$src)>;
2950
2951 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 immAllZerosV),
2952                            (v16i32 VR512:$src))),
2953                   (VMOVDQA32Zrrkz (KNOTWrr VK16WM:$mask), VR512:$src)>;
2954
2955 // These patterns exist to prevent the above patterns from introducing a second
2956 // mask inversion when one already exists.
2957 def : Pat<(v8i64 (vselect (xor VK8:$mask, (v8i1 immAllOnesV)),
2958                           (bc_v8i64 (v16i32 immAllZerosV)),
2959                           (v8i64 VR512:$src))),
2960                  (VMOVDQA64Zrrkz VK8:$mask, VR512:$src)>;
2961 def : Pat<(v16i32 (vselect (xor VK16:$mask, (v16i1 immAllOnesV)),
2962                            (v16i32 immAllZerosV),
2963                            (v16i32 VR512:$src))),
2964                   (VMOVDQA32Zrrkz VK16WM:$mask, VR512:$src)>;
2965
2966 // Patterns for handling v8i1 selects of 256-bit vectors when VLX isn't
2967 // available. Use a 512-bit operation and extract.
2968 let Predicates = [HasAVX512, NoVLX] in {
2969 def : Pat<(v8f32 (vselect (v8i1 VK8WM:$mask), (v8f32 VR256X:$src1),
2970                           (v8f32 VR256X:$src0))),
2971           (EXTRACT_SUBREG
2972            (v16f32
2973             (VMOVAPSZrrk
2974              (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src0, sub_ymm)),
2975              (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
2976              (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)))),
2977            sub_ymm)>;
2978
2979 def : Pat<(v8i32 (vselect (v8i1 VK8WM:$mask), (v8i32 VR256X:$src1),
2980                           (v8i32 VR256X:$src0))),
2981           (EXTRACT_SUBREG
2982            (v16i32
2983             (VMOVDQA32Zrrk
2984              (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src0, sub_ymm)),
2985              (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
2986              (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)))),
2987            sub_ymm)>;
2988 }
2989
2990 let Predicates = [HasVLX, NoBWI] in {
2991   // 128-bit load/store without BWI.
2992   def : Pat<(alignedstore (v8i16 VR128X:$src), addr:$dst),
2993             (VMOVDQA32Z128mr addr:$dst, VR128X:$src)>;
2994   def : Pat<(alignedstore (v16i8 VR128X:$src), addr:$dst),
2995             (VMOVDQA32Z128mr addr:$dst, VR128X:$src)>;
2996   def : Pat<(store (v8i16 VR128X:$src), addr:$dst),
2997             (VMOVDQU32Z128mr addr:$dst, VR128X:$src)>;
2998   def : Pat<(store (v16i8 VR128X:$src), addr:$dst),
2999             (VMOVDQU32Z128mr addr:$dst, VR128X:$src)>;
3000
3001   // 256-bit load/store without BWI.
3002   def : Pat<(alignedstore256 (v16i16 VR256X:$src), addr:$dst),
3003             (VMOVDQA32Z256mr addr:$dst, VR256X:$src)>;
3004   def : Pat<(alignedstore256 (v32i8 VR256X:$src), addr:$dst),
3005             (VMOVDQA32Z256mr addr:$dst, VR256X:$src)>;
3006   def : Pat<(store (v16i16 VR256X:$src), addr:$dst),
3007             (VMOVDQU32Z256mr addr:$dst, VR256X:$src)>;
3008   def : Pat<(store (v32i8 VR256X:$src), addr:$dst),
3009             (VMOVDQU32Z256mr addr:$dst, VR256X:$src)>;
3010 }
3011
3012 let Predicates = [HasVLX] in {
3013   // Special patterns for storing subvector extracts of lower 128-bits of 256.
3014   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
3015   def : Pat<(alignedstore (v2f64 (extract_subvector
3016                                   (v4f64 VR256X:$src), (iPTR 0))), addr:$dst),
3017      (VMOVAPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3018   def : Pat<(alignedstore (v4f32 (extract_subvector
3019                                   (v8f32 VR256X:$src), (iPTR 0))), addr:$dst),
3020      (VMOVAPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3021   def : Pat<(alignedstore (v2i64 (extract_subvector
3022                                   (v4i64 VR256X:$src), (iPTR 0))), addr:$dst),
3023      (VMOVDQA64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3024   def : Pat<(alignedstore (v4i32 (extract_subvector
3025                                   (v8i32 VR256X:$src), (iPTR 0))), addr:$dst),
3026      (VMOVDQA32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3027   def : Pat<(alignedstore (v8i16 (extract_subvector
3028                                   (v16i16 VR256X:$src), (iPTR 0))), addr:$dst),
3029      (VMOVDQA32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3030   def : Pat<(alignedstore (v16i8 (extract_subvector
3031                                   (v32i8 VR256X:$src), (iPTR 0))), addr:$dst),
3032      (VMOVDQA32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3033
3034   def : Pat<(store (v2f64 (extract_subvector
3035                            (v4f64 VR256X:$src), (iPTR 0))), addr:$dst),
3036      (VMOVUPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3037   def : Pat<(store (v4f32 (extract_subvector
3038                            (v8f32 VR256X:$src), (iPTR 0))), addr:$dst),
3039      (VMOVUPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3040   def : Pat<(store (v2i64 (extract_subvector
3041                            (v4i64 VR256X:$src), (iPTR 0))), addr:$dst),
3042      (VMOVDQU64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3043   def : Pat<(store (v4i32 (extract_subvector
3044                            (v8i32 VR256X:$src), (iPTR 0))), addr:$dst),
3045      (VMOVDQU32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3046   def : Pat<(store (v8i16 (extract_subvector
3047                            (v16i16 VR256X:$src), (iPTR 0))), addr:$dst),
3048      (VMOVDQU32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3049   def : Pat<(store (v16i8 (extract_subvector
3050                            (v32i8 VR256X:$src), (iPTR 0))), addr:$dst),
3051      (VMOVDQU32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
3052
3053   // Special patterns for storing subvector extracts of lower 128-bits of 512.
3054   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
3055   def : Pat<(alignedstore (v2f64 (extract_subvector
3056                                   (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
3057      (VMOVAPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3058   def : Pat<(alignedstore (v4f32 (extract_subvector
3059                                   (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
3060      (VMOVAPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3061   def : Pat<(alignedstore (v2i64 (extract_subvector
3062                                   (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
3063      (VMOVDQA64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3064   def : Pat<(alignedstore (v4i32 (extract_subvector
3065                                   (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
3066      (VMOVDQA32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3067   def : Pat<(alignedstore (v8i16 (extract_subvector
3068                                   (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3069      (VMOVDQA32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3070   def : Pat<(alignedstore (v16i8 (extract_subvector
3071                                   (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3072      (VMOVDQA32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3073
3074   def : Pat<(store (v2f64 (extract_subvector
3075                            (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
3076      (VMOVUPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3077   def : Pat<(store (v4f32 (extract_subvector
3078                            (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
3079      (VMOVUPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3080   def : Pat<(store (v2i64 (extract_subvector
3081                            (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
3082      (VMOVDQU64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3083   def : Pat<(store (v4i32 (extract_subvector
3084                            (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
3085      (VMOVDQU32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3086   def : Pat<(store (v8i16 (extract_subvector
3087                            (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3088      (VMOVDQU32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3089   def : Pat<(store (v16i8 (extract_subvector
3090                            (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3091      (VMOVDQU32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3092
3093   // Special patterns for storing subvector extracts of lower 256-bits of 512.
3094   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
3095   def : Pat<(alignedstore256 (v4f64 (extract_subvector
3096                                      (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
3097      (VMOVAPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3098   def : Pat<(alignedstore (v8f32 (extract_subvector
3099                                   (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
3100      (VMOVAPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3101   def : Pat<(alignedstore256 (v4i64 (extract_subvector
3102                                      (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
3103      (VMOVDQA64Z256mr addr:$dst, (v4i64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3104   def : Pat<(alignedstore256 (v8i32 (extract_subvector
3105                                      (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
3106      (VMOVDQA32Z256mr addr:$dst, (v8i32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3107   def : Pat<(alignedstore256 (v16i16 (extract_subvector
3108                                       (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3109      (VMOVDQA32Z256mr addr:$dst, (v16i16 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3110   def : Pat<(alignedstore256 (v32i8 (extract_subvector
3111                                      (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3112      (VMOVDQA32Z256mr addr:$dst, (v32i8 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3113
3114   def : Pat<(store (v4f64 (extract_subvector
3115                            (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
3116      (VMOVUPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3117   def : Pat<(store (v8f32 (extract_subvector
3118                            (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
3119      (VMOVUPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3120   def : Pat<(store (v4i64 (extract_subvector
3121                            (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
3122      (VMOVDQU64Z256mr addr:$dst, (v4i64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3123   def : Pat<(store (v8i32 (extract_subvector
3124                            (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
3125      (VMOVDQU32Z256mr addr:$dst, (v8i32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3126   def : Pat<(store (v16i16 (extract_subvector
3127                             (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3128      (VMOVDQU32Z256mr addr:$dst, (v16i16 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3129   def : Pat<(store (v32i8 (extract_subvector
3130                            (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3131      (VMOVDQU32Z256mr addr:$dst, (v32i8 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3132 }
3133
3134
3135 // Move Int Doubleword to Packed Double Int
3136 //
3137 let ExeDomain = SSEPackedInt in {
3138 def VMOVDI2PDIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR32:$src),
3139                       "vmovd\t{$src, $dst|$dst, $src}",
3140                       [(set VR128X:$dst,
3141                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
3142                         EVEX;
3143 def VMOVDI2PDIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst), (ins i32mem:$src),
3144                       "vmovd\t{$src, $dst|$dst, $src}",
3145                       [(set VR128X:$dst,
3146                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
3147                         IIC_SSE_MOVDQ>, EVEX, EVEX_CD8<32, CD8VT1>;
3148 def VMOV64toPQIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR64:$src),
3149                       "vmovq\t{$src, $dst|$dst, $src}",
3150                         [(set VR128X:$dst,
3151                           (v2i64 (scalar_to_vector GR64:$src)))],
3152                           IIC_SSE_MOVDQ>, EVEX, VEX_W;
3153 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
3154 def VMOV64toPQIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst),
3155                       (ins i64mem:$src),
3156                       "vmovq\t{$src, $dst|$dst, $src}", []>,
3157                       EVEX, VEX_W, EVEX_CD8<64, CD8VT1>;
3158 let isCodeGenOnly = 1 in {
3159 def VMOV64toSDZrr : AVX512BI<0x6E, MRMSrcReg, (outs FR64X:$dst), (ins GR64:$src),
3160                        "vmovq\t{$src, $dst|$dst, $src}",
3161                        [(set FR64X:$dst, (bitconvert GR64:$src))],
3162                        IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
3163 def VMOVSDto64Zrr : AVX512BI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64X:$src),
3164                          "vmovq\t{$src, $dst|$dst, $src}",
3165                          [(set GR64:$dst, (bitconvert FR64X:$src))],
3166                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
3167 def VMOVSDto64Zmr : AVX512BI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64X:$src),
3168                          "vmovq\t{$src, $dst|$dst, $src}",
3169                          [(store (i64 (bitconvert FR64X:$src)), addr:$dst)],
3170                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteStore]>,
3171                          EVEX_CD8<64, CD8VT1>;
3172 }
3173 } // ExeDomain = SSEPackedInt
3174
3175 // Move Int Doubleword to Single Scalar
3176 //
3177 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
3178 def VMOVDI2SSZrr  : AVX512BI<0x6E, MRMSrcReg, (outs FR32X:$dst), (ins GR32:$src),
3179                       "vmovd\t{$src, $dst|$dst, $src}",
3180                       [(set FR32X:$dst, (bitconvert GR32:$src))],
3181                       IIC_SSE_MOVDQ>, EVEX;
3182
3183 def VMOVDI2SSZrm  : AVX512BI<0x6E, MRMSrcMem, (outs FR32X:$dst), (ins i32mem:$src),
3184                       "vmovd\t{$src, $dst|$dst, $src}",
3185                       [(set FR32X:$dst, (bitconvert (loadi32 addr:$src)))],
3186                       IIC_SSE_MOVDQ>, EVEX, EVEX_CD8<32, CD8VT1>;
3187 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
3188
3189 // Move doubleword from xmm register to r/m32
3190 //
3191 let ExeDomain = SSEPackedInt in {
3192 def VMOVPDI2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128X:$src),
3193                        "vmovd\t{$src, $dst|$dst, $src}",
3194                        [(set GR32:$dst, (extractelt (v4i32 VR128X:$src),
3195                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
3196                        EVEX;
3197 def VMOVPDI2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
3198                        (ins i32mem:$dst, VR128X:$src),
3199                        "vmovd\t{$src, $dst|$dst, $src}",
3200                        [(store (i32 (extractelt (v4i32 VR128X:$src),
3201                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
3202                        EVEX, EVEX_CD8<32, CD8VT1>;
3203 } // ExeDomain = SSEPackedInt
3204
3205 // Move quadword from xmm1 register to r/m64
3206 //
3207 let ExeDomain = SSEPackedInt in {
3208 def VMOVPQIto64Zrr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128X:$src),
3209                       "vmovq\t{$src, $dst|$dst, $src}",
3210                       [(set GR64:$dst, (extractelt (v2i64 VR128X:$src),
3211                                                    (iPTR 0)))],
3212                       IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_W,
3213                       Requires<[HasAVX512, In64BitMode]>;
3214
3215 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
3216 def VMOVPQIto64Zmr : I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, VR128X:$src),
3217                       "vmovq\t{$src, $dst|$dst, $src}",
3218                       [], IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_W,
3219                       Requires<[HasAVX512, In64BitMode]>;
3220
3221 def VMOVPQI2QIZmr : I<0xD6, MRMDestMem, (outs),
3222                       (ins i64mem:$dst, VR128X:$src),
3223                       "vmovq\t{$src, $dst|$dst, $src}",
3224                       [(store (extractelt (v2i64 VR128X:$src), (iPTR 0)),
3225                               addr:$dst)], IIC_SSE_MOVDQ>,
3226                       EVEX, PD, VEX_W, EVEX_CD8<64, CD8VT1>,
3227                       Sched<[WriteStore]>, Requires<[HasAVX512, In64BitMode]>;
3228
3229 let hasSideEffects = 0 in
3230 def VMOVPQI2QIZrr : AVX512BI<0xD6, MRMDestReg, (outs VR128X:$dst),
3231                              (ins VR128X:$src),
3232                              "vmovq.s\t{$src, $dst|$dst, $src}",[]>,
3233                              EVEX, VEX_W;
3234 } // ExeDomain = SSEPackedInt
3235
3236 // Move Scalar Single to Double Int
3237 //
3238 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
3239 def VMOVSS2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst),
3240                       (ins FR32X:$src),
3241                       "vmovd\t{$src, $dst|$dst, $src}",
3242                       [(set GR32:$dst, (bitconvert FR32X:$src))],
3243                       IIC_SSE_MOVD_ToGP>, EVEX;
3244 def VMOVSS2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
3245                       (ins i32mem:$dst, FR32X:$src),
3246                       "vmovd\t{$src, $dst|$dst, $src}",
3247                       [(store (i32 (bitconvert FR32X:$src)), addr:$dst)],
3248                       IIC_SSE_MOVDQ>, EVEX, EVEX_CD8<32, CD8VT1>;
3249 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
3250
3251 // Move Quadword Int to Packed Quadword Int
3252 //
3253 let ExeDomain = SSEPackedInt in {
3254 def VMOVQI2PQIZrm : AVX512XSI<0x7E, MRMSrcMem, (outs VR128X:$dst),
3255                       (ins i64mem:$src),
3256                       "vmovq\t{$src, $dst|$dst, $src}",
3257                       [(set VR128X:$dst,
3258                         (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>,
3259                       EVEX, VEX_W, EVEX_CD8<8, CD8VT8>;
3260 } // ExeDomain = SSEPackedInt
3261
3262 //===----------------------------------------------------------------------===//
3263 // AVX-512  MOVSS, MOVSD
3264 //===----------------------------------------------------------------------===//
3265
3266 multiclass avx512_move_scalar<string asm, SDNode OpNode,
3267                               X86VectorVTInfo _> {
3268   def rr : AVX512PI<0x10, MRMSrcReg, (outs _.RC:$dst),
3269              (ins _.RC:$src1, _.FRC:$src2),
3270              !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3271              [(set _.RC:$dst, (_.VT (OpNode _.RC:$src1,
3272                                     (scalar_to_vector _.FRC:$src2))))],
3273              _.ExeDomain,IIC_SSE_MOV_S_RR>, EVEX_4V;
3274   def rrkz : AVX512PI<0x10, MRMSrcReg, (outs _.RC:$dst),
3275               (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
3276               !strconcat(asm, "\t{$src2, $src1, $dst {${mask}} {z}|",
3277               "$dst {${mask}} {z}, $src1, $src2}"),
3278               [(set _.RC:$dst, (_.VT (X86selects _.KRCWM:$mask,
3279                                       (_.VT (OpNode _.RC:$src1, _.RC:$src2)),
3280                                       _.ImmAllZerosV)))],
3281               _.ExeDomain,IIC_SSE_MOV_S_RR>, EVEX_4V, EVEX_KZ;
3282   let Constraints = "$src0 = $dst"  in
3283   def rrk : AVX512PI<0x10, MRMSrcReg, (outs _.RC:$dst),
3284              (ins _.RC:$src0, _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
3285              !strconcat(asm, "\t{$src2, $src1, $dst {${mask}}|",
3286              "$dst {${mask}}, $src1, $src2}"),
3287              [(set _.RC:$dst, (_.VT (X86selects _.KRCWM:$mask,
3288                                      (_.VT (OpNode _.RC:$src1, _.RC:$src2)),
3289                                      (_.VT _.RC:$src0))))],
3290              _.ExeDomain,IIC_SSE_MOV_S_RR>, EVEX_4V, EVEX_K;
3291   let canFoldAsLoad = 1, isReMaterializable = 1 in
3292   def rm : AVX512PI<0x10, MRMSrcMem, (outs _.FRC:$dst), (ins _.ScalarMemOp:$src),
3293              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
3294              [(set _.FRC:$dst, (_.ScalarLdFrag addr:$src))],
3295              _.ExeDomain, IIC_SSE_MOV_S_RM>, EVEX;
3296   let mayLoad = 1, hasSideEffects = 0 in {
3297     let Constraints = "$src0 = $dst" in
3298     def rmk : AVX512PI<0x10, MRMSrcMem, (outs _.RC:$dst),
3299                (ins _.RC:$src0, _.KRCWM:$mask, _.ScalarMemOp:$src),
3300                !strconcat(asm, "\t{$src, $dst {${mask}}|",
3301                "$dst {${mask}}, $src}"),
3302                [], _.ExeDomain, IIC_SSE_MOV_S_RM>, EVEX, EVEX_K;
3303     def rmkz : AVX512PI<0x10, MRMSrcMem, (outs _.RC:$dst),
3304                (ins _.KRCWM:$mask, _.ScalarMemOp:$src),
3305                !strconcat(asm, "\t{$src, $dst {${mask}} {z}|",
3306                "$dst {${mask}} {z}, $src}"),
3307                [], _.ExeDomain, IIC_SSE_MOV_S_RM>, EVEX, EVEX_KZ;
3308   }
3309   def mr: AVX512PI<0x11, MRMDestMem, (outs), (ins _.ScalarMemOp:$dst, _.FRC:$src),
3310              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
3311              [(store _.FRC:$src, addr:$dst)],  _.ExeDomain, IIC_SSE_MOV_S_MR>,
3312              EVEX;
3313   let mayStore = 1, hasSideEffects = 0 in
3314   def mrk: AVX512PI<0x11, MRMDestMem, (outs),
3315               (ins _.ScalarMemOp:$dst, VK1WM:$mask, _.FRC:$src),
3316               !strconcat(asm, "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
3317               [], _.ExeDomain, IIC_SSE_MOV_S_MR>, EVEX, EVEX_K;
3318 }
3319
3320 defm VMOVSSZ : avx512_move_scalar<"vmovss", X86Movss, f32x_info>,
3321                                   VEX_LIG, XS, EVEX_CD8<32, CD8VT1>;
3322
3323 defm VMOVSDZ : avx512_move_scalar<"vmovsd", X86Movsd, f64x_info>,
3324                                   VEX_LIG, XD, VEX_W, EVEX_CD8<64, CD8VT1>;
3325
3326
3327 multiclass avx512_move_scalar_lowering<string InstrStr, SDNode OpNode,
3328                                        PatLeaf ZeroFP, X86VectorVTInfo _> {
3329
3330 def : Pat<(_.VT (OpNode _.RC:$src0,
3331                         (_.VT (scalar_to_vector
3332                                   (_.EltVT (X86selects (i1 (trunc GR32:$mask)),
3333                                                        (_.EltVT _.FRC:$src1),
3334                                                        (_.EltVT _.FRC:$src2))))))),
3335           (COPY_TO_REGCLASS (!cast<Instruction>(InstrStr#rrk)
3336                                           (COPY_TO_REGCLASS _.FRC:$src2, _.RC),
3337                                           (COPY_TO_REGCLASS GR32:$mask, VK1WM),
3338                                           (_.VT _.RC:$src0),
3339                                           (COPY_TO_REGCLASS _.FRC:$src1, _.RC)),
3340                             _.RC)>;
3341
3342 def : Pat<(_.VT (OpNode _.RC:$src0,
3343                         (_.VT (scalar_to_vector
3344                                   (_.EltVT (X86selects (i1 (trunc GR32:$mask)),
3345                                                        (_.EltVT _.FRC:$src1),
3346                                                        (_.EltVT ZeroFP))))))),
3347           (COPY_TO_REGCLASS (!cast<Instruction>(InstrStr#rrkz)
3348                                           (COPY_TO_REGCLASS GR32:$mask, VK1WM),
3349                                           (_.VT _.RC:$src0),
3350                                           (COPY_TO_REGCLASS _.FRC:$src1, _.RC)),
3351                             _.RC)>;
3352
3353 }
3354
3355 multiclass avx512_store_scalar_lowering<string InstrStr, AVX512VLVectorVTInfo _,
3356                                         dag Mask, RegisterClass MaskRC> {
3357
3358 def : Pat<(masked_store addr:$dst, Mask,
3359              (_.info512.VT (insert_subvector undef,
3360                                (_.info256.VT (insert_subvector undef,
3361                                                  (_.info128.VT _.info128.RC:$src),
3362                                                  (i64 0))),
3363                                (i64 0)))),
3364           (!cast<Instruction>(InstrStr#mrk) addr:$dst,
3365                       (i1 (COPY_TO_REGCLASS MaskRC:$mask, VK1WM)),
3366                       (COPY_TO_REGCLASS _.info128.RC:$src, _.info128.FRC))>;
3367
3368 }
3369
3370 multiclass avx512_load_scalar_lowering<string InstrStr, AVX512VLVectorVTInfo _,
3371                                        dag Mask, RegisterClass MaskRC> {
3372
3373 def : Pat<(_.info128.VT (extract_subvector
3374                          (_.info512.VT (masked_load addr:$srcAddr, Mask,
3375                                         (_.info512.VT (bitconvert
3376                                                        (v16i32 immAllZerosV))))),
3377                            (i64 0))),
3378           (!cast<Instruction>(InstrStr#rmkz)
3379                       (i1 (COPY_TO_REGCLASS MaskRC:$mask, VK1WM)),
3380                       addr:$srcAddr)>;
3381
3382 def : Pat<(_.info128.VT (extract_subvector
3383                 (_.info512.VT (masked_load addr:$srcAddr, Mask,
3384                       (_.info512.VT (insert_subvector undef,
3385                             (_.info256.VT (insert_subvector undef,
3386                                   (_.info128.VT (X86vzmovl _.info128.RC:$src)),
3387                                   (i64 0))),
3388                             (i64 0))))),
3389                 (i64 0))),
3390           (!cast<Instruction>(InstrStr#rmk) _.info128.RC:$src,
3391                       (i1 (COPY_TO_REGCLASS MaskRC:$mask, VK1WM)),
3392                       addr:$srcAddr)>;
3393
3394 }
3395
3396 defm : avx512_move_scalar_lowering<"VMOVSSZ", X86Movss, fp32imm0, v4f32x_info>;
3397 defm : avx512_move_scalar_lowering<"VMOVSDZ", X86Movsd, fp64imm0, v2f64x_info>;
3398
3399 defm : avx512_store_scalar_lowering<"VMOVSSZ", avx512vl_f32_info,
3400                    (v16i1 (bitconvert (i16 (trunc (and GR32:$mask, (i32 1)))))), GR32>;
3401 defm : avx512_store_scalar_lowering<"VMOVSSZ", avx512vl_f32_info,
3402                    (v16i1 (bitconvert (i16 (and GR16:$mask, (i16 1))))), GR16>;
3403 defm : avx512_store_scalar_lowering<"VMOVSDZ", avx512vl_f64_info,
3404                    (v8i1 (bitconvert (i8 (and GR8:$mask, (i8 1))))), GR8>;
3405
3406 defm : avx512_load_scalar_lowering<"VMOVSSZ", avx512vl_f32_info,
3407                    (v16i1 (bitconvert (i16 (trunc (and GR32:$mask, (i32 1)))))), GR32>;
3408 defm : avx512_load_scalar_lowering<"VMOVSSZ", avx512vl_f32_info,
3409                    (v16i1 (bitconvert (i16 (and GR16:$mask, (i16 1))))), GR16>;
3410 defm : avx512_load_scalar_lowering<"VMOVSDZ", avx512vl_f64_info,
3411                    (v8i1 (bitconvert (i8 (and GR8:$mask, (i8 1))))), GR8>;
3412
3413 def : Pat<(f32 (X86selects VK1WM:$mask, (f32 FR32X:$src1), (f32 FR32X:$src2))),
3414           (COPY_TO_REGCLASS (VMOVSSZrrk (COPY_TO_REGCLASS FR32X:$src2, VR128X),
3415            VK1WM:$mask, (v4f32 (IMPLICIT_DEF)),(COPY_TO_REGCLASS FR32X:$src1, VR128X)), FR32X)>;
3416
3417 def : Pat<(f64 (X86selects VK1WM:$mask, (f64 FR64X:$src1), (f64 FR64X:$src2))),
3418           (COPY_TO_REGCLASS (VMOVSDZrrk (COPY_TO_REGCLASS FR64X:$src2, VR128X),
3419            VK1WM:$mask, (v2f64 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR64X:$src1, VR128X)), FR64X)>;
3420
3421 def : Pat<(int_x86_avx512_mask_store_ss addr:$dst, VR128X:$src, GR8:$mask),
3422           (VMOVSSZmrk addr:$dst, (i1 (COPY_TO_REGCLASS GR8:$mask, VK1WM)),
3423            (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
3424
3425 let hasSideEffects = 0 in
3426 defm VMOVSSZrr_REV : AVX512_maskable_in_asm<0x11, MRMDestReg, f32x_info,
3427                            (outs VR128X:$dst), (ins VR128X:$src1, VR128X:$src2),
3428                            "vmovss.s", "$src2, $src1", "$src1, $src2", []>,
3429                            XS, EVEX_4V, VEX_LIG;
3430
3431 let hasSideEffects = 0 in
3432 defm VMOVSSDrr_REV : AVX512_maskable_in_asm<0x11, MRMDestReg, f64x_info,
3433                            (outs VR128X:$dst), (ins VR128X:$src1, VR128X:$src2),
3434                            "vmovsd.s", "$src2, $src1", "$src1, $src2", []>,
3435                            XD, EVEX_4V, VEX_LIG, VEX_W;
3436
3437 let Predicates = [HasAVX512] in {
3438   let AddedComplexity = 15 in {
3439   // Move scalar to XMM zero-extended, zeroing a VR128X then do a
3440   // MOVS{S,D} to the lower bits.
3441   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32X:$src)))),
3442             (VMOVSSZrr (v4f32 (V_SET0)), FR32X:$src)>;
3443   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128X:$src))),
3444             (VMOVSSZrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
3445   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128X:$src))),
3446             (VMOVSSZrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
3447   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64X:$src)))),
3448             (VMOVSDZrr (v2f64 (V_SET0)), FR64X:$src)>;
3449   }
3450
3451   // Move low f32 and clear high bits.
3452   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256X:$src))),
3453             (SUBREG_TO_REG (i32 0),
3454              (VMOVSSZrr (v4f32 (V_SET0)),
3455               (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm)), sub_xmm)>;
3456   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256X:$src))),
3457             (SUBREG_TO_REG (i32 0),
3458              (VMOVSSZrr (v4i32 (V_SET0)),
3459               (EXTRACT_SUBREG (v8i32 VR256X:$src), sub_xmm)), sub_xmm)>;
3460   def : Pat<(v16f32 (X86vzmovl (v16f32 VR512:$src))),
3461             (SUBREG_TO_REG (i32 0),
3462              (VMOVSSZrr (v4f32 (V_SET0)),
3463               (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm)), sub_xmm)>;
3464   def : Pat<(v16i32 (X86vzmovl (v16i32 VR512:$src))),
3465             (SUBREG_TO_REG (i32 0),
3466              (VMOVSSZrr (v4i32 (V_SET0)),
3467               (EXTRACT_SUBREG (v16i32 VR512:$src), sub_xmm)), sub_xmm)>;
3468
3469   let AddedComplexity = 20 in {
3470   // MOVSSrm zeros the high parts of the register; represent this
3471   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
3472   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
3473             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3474   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
3475             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3476   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
3477             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3478   def : Pat<(v4f32 (X86vzload addr:$src)),
3479             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3480
3481   // MOVSDrm zeros the high parts of the register; represent this
3482   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
3483   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
3484             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3485   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
3486             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3487   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
3488             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3489   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
3490             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3491   def : Pat<(v2f64 (X86vzload addr:$src)),
3492             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3493
3494   // Represent the same patterns above but in the form they appear for
3495   // 256-bit types
3496   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
3497                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
3498             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3499   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
3500                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
3501             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3502   def : Pat<(v8f32 (X86vzload addr:$src)),
3503             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3504   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
3505                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
3506             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3507   def : Pat<(v4f64 (X86vzload addr:$src)),
3508             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3509
3510   // Represent the same patterns above but in the form they appear for
3511   // 512-bit types
3512   def : Pat<(v16i32 (X86vzmovl (insert_subvector undef,
3513                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
3514             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3515   def : Pat<(v16f32 (X86vzmovl (insert_subvector undef,
3516                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
3517             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3518   def : Pat<(v16f32 (X86vzload addr:$src)),
3519             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3520   def : Pat<(v8f64 (X86vzmovl (insert_subvector undef,
3521                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
3522             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3523   def : Pat<(v8f64 (X86vzload addr:$src)),
3524             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3525   }
3526   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
3527                    (v4f32 (scalar_to_vector FR32X:$src)), (iPTR 0)))),
3528             (SUBREG_TO_REG (i32 0), (v4f32 (VMOVSSZrr (v4f32 (V_SET0)),
3529                                             FR32X:$src)), sub_xmm)>;
3530   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
3531                    (v2f64 (scalar_to_vector FR64X:$src)), (iPTR 0)))),
3532             (SUBREG_TO_REG (i64 0), (v2f64 (VMOVSDZrr (v2f64 (V_SET0)),
3533                                      FR64X:$src)), sub_xmm)>;
3534   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
3535                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
3536             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
3537
3538   // Move low f64 and clear high bits.
3539   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256X:$src))),
3540             (SUBREG_TO_REG (i32 0),
3541              (VMOVSDZrr (v2f64 (V_SET0)),
3542                        (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm)), sub_xmm)>;
3543   def : Pat<(v8f64 (X86vzmovl (v8f64 VR512:$src))),
3544             (SUBREG_TO_REG (i32 0),
3545              (VMOVSDZrr (v2f64 (V_SET0)),
3546                        (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm)), sub_xmm)>;
3547
3548   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256X:$src))),
3549             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (V_SET0)),
3550                        (EXTRACT_SUBREG (v4i64 VR256X:$src), sub_xmm)), sub_xmm)>;
3551   def : Pat<(v8i64 (X86vzmovl (v8i64 VR512:$src))),
3552             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (V_SET0)),
3553                        (EXTRACT_SUBREG (v8i64 VR512:$src), sub_xmm)), sub_xmm)>;
3554
3555   // Extract and store.
3556   def : Pat<(store (f32 (extractelt (v4f32 VR128X:$src), (iPTR 0))),
3557                    addr:$dst),
3558             (VMOVSSZmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128X:$src), FR32X))>;
3559
3560   // Shuffle with VMOVSS
3561   def : Pat<(v4i32 (X86Movss VR128X:$src1, VR128X:$src2)),
3562             (VMOVSSZrr (v4i32 VR128X:$src1),
3563                       (COPY_TO_REGCLASS (v4i32 VR128X:$src2), FR32X))>;
3564   def : Pat<(v4f32 (X86Movss VR128X:$src1, VR128X:$src2)),
3565             (VMOVSSZrr (v4f32 VR128X:$src1),
3566                       (COPY_TO_REGCLASS (v4f32 VR128X:$src2), FR32X))>;
3567
3568   // 256-bit variants
3569   def : Pat<(v8i32 (X86Movss VR256X:$src1, VR256X:$src2)),
3570             (SUBREG_TO_REG (i32 0),
3571               (VMOVSSZrr (EXTRACT_SUBREG (v8i32 VR256X:$src1), sub_xmm),
3572                         (EXTRACT_SUBREG (v8i32 VR256X:$src2), sub_xmm)),
3573               sub_xmm)>;
3574   def : Pat<(v8f32 (X86Movss VR256X:$src1, VR256X:$src2)),
3575             (SUBREG_TO_REG (i32 0),
3576               (VMOVSSZrr (EXTRACT_SUBREG (v8f32 VR256X:$src1), sub_xmm),
3577                         (EXTRACT_SUBREG (v8f32 VR256X:$src2), sub_xmm)),
3578               sub_xmm)>;
3579
3580   // Shuffle with VMOVSD
3581   def : Pat<(v2i64 (X86Movsd VR128X:$src1, VR128X:$src2)),
3582             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3583   def : Pat<(v2f64 (X86Movsd VR128X:$src1, VR128X:$src2)),
3584             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3585   def : Pat<(v4f32 (X86Movsd VR128X:$src1, VR128X:$src2)),
3586             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3587   def : Pat<(v4i32 (X86Movsd VR128X:$src1, VR128X:$src2)),
3588             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3589
3590   // 256-bit variants
3591   def : Pat<(v4i64 (X86Movsd VR256X:$src1, VR256X:$src2)),
3592             (SUBREG_TO_REG (i32 0),
3593               (VMOVSDZrr (EXTRACT_SUBREG (v4i64 VR256X:$src1), sub_xmm),
3594                         (EXTRACT_SUBREG (v4i64 VR256X:$src2), sub_xmm)),
3595               sub_xmm)>;
3596   def : Pat<(v4f64 (X86Movsd VR256X:$src1, VR256X:$src2)),
3597             (SUBREG_TO_REG (i32 0),
3598               (VMOVSDZrr (EXTRACT_SUBREG (v4f64 VR256X:$src1), sub_xmm),
3599                         (EXTRACT_SUBREG (v4f64 VR256X:$src2), sub_xmm)),
3600               sub_xmm)>;
3601
3602   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
3603             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3604   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
3605             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3606   def : Pat<(v4f32 (X86Movlps VR128X:$src1, VR128X:$src2)),
3607             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3608   def : Pat<(v4i32 (X86Movlps VR128X:$src1, VR128X:$src2)),
3609             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3610 }
3611
3612 let AddedComplexity = 15 in
3613 def VMOVZPQILo2PQIZrr : AVX512XSI<0x7E, MRMSrcReg, (outs VR128X:$dst),
3614                                 (ins VR128X:$src),
3615                                 "vmovq\t{$src, $dst|$dst, $src}",
3616                                 [(set VR128X:$dst, (v2i64 (X86vzmovl
3617                                                    (v2i64 VR128X:$src))))],
3618                                 IIC_SSE_MOVQ_RR>, EVEX, VEX_W;
3619
3620 let Predicates = [HasAVX512] in {
3621   let AddedComplexity = 15 in {
3622     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
3623               (VMOVDI2PDIZrr GR32:$src)>;
3624
3625     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
3626               (VMOV64toPQIZrr GR64:$src)>;
3627
3628     def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
3629                                  (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
3630               (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
3631
3632     def : Pat<(v8i64 (X86vzmovl (insert_subvector undef,
3633                                  (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
3634               (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
3635   }
3636   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
3637   let AddedComplexity = 20 in {
3638     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
3639               (VMOVDI2PDIZrm addr:$src)>;
3640     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
3641               (VMOVDI2PDIZrm addr:$src)>;
3642     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
3643               (VMOVDI2PDIZrm addr:$src)>;
3644     def : Pat<(v4i32 (X86vzload addr:$src)),
3645               (VMOVDI2PDIZrm addr:$src)>;
3646     def : Pat<(v8i32 (X86vzload addr:$src)),
3647               (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3648     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
3649               (VMOVQI2PQIZrm addr:$src)>;
3650     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128X:$src))),
3651               (VMOVZPQILo2PQIZrr VR128X:$src)>;
3652     def : Pat<(v2i64 (X86vzload addr:$src)),
3653               (VMOVQI2PQIZrm addr:$src)>;
3654     def : Pat<(v4i64 (X86vzload addr:$src)),
3655               (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
3656   }
3657
3658   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
3659   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
3660                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
3661             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
3662   def : Pat<(v16i32 (X86vzmovl (insert_subvector undef,
3663                                 (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
3664             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
3665
3666   // Use regular 128-bit instructions to match 512-bit scalar_to_vec+zext.
3667   def : Pat<(v16i32 (X86vzload addr:$src)),
3668             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3669   def : Pat<(v8i64 (X86vzload addr:$src)),
3670             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
3671 }
3672
3673 def : Pat<(v16i32 (X86Vinsert (v16i32 immAllZerosV), GR32:$src2, (iPTR 0))),
3674         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
3675
3676 def : Pat<(v8i64 (X86Vinsert (bc_v8i64 (v16i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
3677         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
3678
3679 def : Pat<(v16i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
3680         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src2), sub_xmm)>;
3681
3682 def : Pat<(v8i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
3683         (SUBREG_TO_REG (i32 0), (VMOV64toPQIZrr GR64:$src2), sub_xmm)>;
3684
3685 //===----------------------------------------------------------------------===//
3686 // AVX-512 - Non-temporals
3687 //===----------------------------------------------------------------------===//
3688 let SchedRW = [WriteLoad] in {
3689   def VMOVNTDQAZrm : AVX512PI<0x2A, MRMSrcMem, (outs VR512:$dst),
3690                         (ins i512mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}",
3691                         [(set VR512:$dst, (int_x86_avx512_movntdqa addr:$src))],
3692                         SSEPackedInt>, EVEX, T8PD, EVEX_V512,
3693                         EVEX_CD8<64, CD8VF>;
3694
3695   let Predicates = [HasVLX] in {
3696     def VMOVNTDQAZ256rm : AVX512PI<0x2A, MRMSrcMem, (outs VR256X:$dst),
3697                          (ins i256mem:$src),
3698                          "vmovntdqa\t{$src, $dst|$dst, $src}",
3699                          [(set VR256X:$dst, (int_x86_avx2_movntdqa addr:$src))],
3700                          SSEPackedInt>, EVEX, T8PD, EVEX_V256,
3701                          EVEX_CD8<64, CD8VF>;
3702
3703     def VMOVNTDQAZ128rm : AVX512PI<0x2A, MRMSrcMem, (outs VR128X:$dst),
3704                         (ins i128mem:$src),
3705                         "vmovntdqa\t{$src, $dst|$dst, $src}",
3706                         [(set VR128X:$dst, (int_x86_sse41_movntdqa addr:$src))],
3707                         SSEPackedInt>, EVEX, T8PD, EVEX_V128,
3708                         EVEX_CD8<64, CD8VF>;
3709   }
3710 }
3711
3712 multiclass avx512_movnt<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
3713                         PatFrag st_frag = alignednontemporalstore,
3714                         InstrItinClass itin = IIC_SSE_MOVNT> {
3715   let SchedRW = [WriteStore], AddedComplexity = 400 in
3716   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins _.MemOp:$dst, _.RC:$src),
3717                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3718                     [(st_frag (_.VT _.RC:$src), addr:$dst)],
3719                     _.ExeDomain, itin>, EVEX, EVEX_CD8<_.EltSize, CD8VF>;
3720 }
3721
3722 multiclass avx512_movnt_vl<bits<8> opc, string OpcodeStr,
3723                                                   AVX512VLVectorVTInfo VTInfo> {
3724   let Predicates = [HasAVX512] in
3725     defm Z : avx512_movnt<opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
3726
3727   let Predicates = [HasAVX512, HasVLX] in {
3728     defm Z256 : avx512_movnt<opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
3729     defm Z128 : avx512_movnt<opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
3730   }
3731 }
3732
3733 defm VMOVNTDQ : avx512_movnt_vl<0xE7, "vmovntdq", avx512vl_i64_info>, PD;
3734 defm VMOVNTPD : avx512_movnt_vl<0x2B, "vmovntpd", avx512vl_f64_info>, PD, VEX_W;
3735 defm VMOVNTPS : avx512_movnt_vl<0x2B, "vmovntps", avx512vl_f32_info>, PS;
3736
3737 let Predicates = [HasAVX512], AddedComplexity = 400 in {
3738   def : Pat<(alignednontemporalstore (v16i32 VR512:$src), addr:$dst),
3739             (VMOVNTDQZmr addr:$dst, VR512:$src)>;
3740   def : Pat<(alignednontemporalstore (v32i16 VR512:$src), addr:$dst),
3741             (VMOVNTDQZmr addr:$dst, VR512:$src)>;
3742   def : Pat<(alignednontemporalstore (v64i8 VR512:$src), addr:$dst),
3743             (VMOVNTDQZmr addr:$dst, VR512:$src)>;
3744
3745   def : Pat<(v8f64 (alignednontemporalload addr:$src)),
3746             (VMOVNTDQAZrm addr:$src)>;
3747   def : Pat<(v16f32 (alignednontemporalload addr:$src)),
3748             (VMOVNTDQAZrm addr:$src)>;
3749   def : Pat<(v8i64 (alignednontemporalload addr:$src)),
3750             (VMOVNTDQAZrm addr:$src)>;
3751   def : Pat<(v16i32 (bitconvert (v8i64 (alignednontemporalload addr:$src)))),
3752             (VMOVNTDQAZrm addr:$src)>;
3753   def : Pat<(v32i16 (bitconvert (v8i64 (alignednontemporalload addr:$src)))),
3754             (VMOVNTDQAZrm addr:$src)>;
3755   def : Pat<(v64i8 (bitconvert (v8i64 (alignednontemporalload addr:$src)))),
3756             (VMOVNTDQAZrm addr:$src)>;
3757 }
3758
3759 let Predicates = [HasVLX], AddedComplexity = 400 in {
3760   def : Pat<(alignednontemporalstore (v8i32 VR256X:$src), addr:$dst),
3761             (VMOVNTDQZ256mr addr:$dst, VR256X:$src)>;
3762   def : Pat<(alignednontemporalstore (v16i16 VR256X:$src), addr:$dst),
3763             (VMOVNTDQZ256mr addr:$dst, VR256X:$src)>;
3764   def : Pat<(alignednontemporalstore (v32i8 VR256X:$src), addr:$dst),
3765             (VMOVNTDQZ256mr addr:$dst, VR256X:$src)>;
3766
3767   def : Pat<(v4f64 (alignednontemporalload addr:$src)),
3768             (VMOVNTDQAZ256rm addr:$src)>;
3769   def : Pat<(v8f32 (alignednontemporalload addr:$src)),
3770             (VMOVNTDQAZ256rm addr:$src)>;
3771   def : Pat<(v4i64 (alignednontemporalload addr:$src)),
3772             (VMOVNTDQAZ256rm addr:$src)>;
3773   def : Pat<(v8i32 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3774             (VMOVNTDQAZ256rm addr:$src)>;
3775   def : Pat<(v16i16 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3776             (VMOVNTDQAZ256rm addr:$src)>;
3777   def : Pat<(v32i8 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3778             (VMOVNTDQAZ256rm addr:$src)>;
3779
3780   def : Pat<(alignednontemporalstore (v4i32 VR128X:$src), addr:$dst),
3781             (VMOVNTDQZ128mr addr:$dst, VR128X:$src)>;
3782   def : Pat<(alignednontemporalstore (v8i16 VR128X:$src), addr:$dst),
3783             (VMOVNTDQZ128mr addr:$dst, VR128X:$src)>;
3784   def : Pat<(alignednontemporalstore (v16i8 VR128X:$src), addr:$dst),
3785             (VMOVNTDQZ128mr addr:$dst, VR128X:$src)>;
3786
3787   def : Pat<(v2f64 (alignednontemporalload addr:$src)),
3788             (VMOVNTDQAZ128rm addr:$src)>;
3789   def : Pat<(v4f32 (alignednontemporalload addr:$src)),
3790             (VMOVNTDQAZ128rm addr:$src)>;
3791   def : Pat<(v2i64 (alignednontemporalload addr:$src)),
3792             (VMOVNTDQAZ128rm addr:$src)>;
3793   def : Pat<(v4i32 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3794             (VMOVNTDQAZ128rm addr:$src)>;
3795   def : Pat<(v8i16 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3796             (VMOVNTDQAZ128rm addr:$src)>;
3797   def : Pat<(v16i8 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3798             (VMOVNTDQAZ128rm addr:$src)>;
3799 }
3800
3801 //===----------------------------------------------------------------------===//
3802 // AVX-512 - Integer arithmetic
3803 //
3804 multiclass avx512_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3805                            X86VectorVTInfo _, OpndItins itins,
3806                            bit IsCommutable = 0> {
3807   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3808                     (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3809                     "$src2, $src1", "$src1, $src2",
3810                     (_.VT (OpNode _.RC:$src1, _.RC:$src2)),
3811                     itins.rr, IsCommutable>,
3812             AVX512BIBase, EVEX_4V;
3813
3814   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3815                   (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
3816                   "$src2, $src1", "$src1, $src2",
3817                   (_.VT (OpNode _.RC:$src1,
3818                                 (bitconvert (_.LdFrag addr:$src2)))),
3819                   itins.rm>,
3820             AVX512BIBase, EVEX_4V;
3821 }
3822
3823 multiclass avx512_binop_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3824                             X86VectorVTInfo _, OpndItins itins,
3825                             bit IsCommutable = 0> :
3826            avx512_binop_rm<opc, OpcodeStr, OpNode, _, itins, IsCommutable> {
3827   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3828                   (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
3829                   "${src2}"##_.BroadcastStr##", $src1",
3830                   "$src1, ${src2}"##_.BroadcastStr,
3831                   (_.VT (OpNode _.RC:$src1,
3832                                 (X86VBroadcast
3833                                     (_.ScalarLdFrag addr:$src2)))),
3834                   itins.rm>,
3835              AVX512BIBase, EVEX_4V, EVEX_B;
3836 }
3837
3838 multiclass avx512_binop_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
3839                               AVX512VLVectorVTInfo VTInfo, OpndItins itins,
3840                               Predicate prd, bit IsCommutable = 0> {
3841   let Predicates = [prd] in
3842     defm Z : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
3843                              IsCommutable>, EVEX_V512;
3844
3845   let Predicates = [prd, HasVLX] in {
3846     defm Z256 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
3847                              IsCommutable>, EVEX_V256;
3848     defm Z128 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
3849                              IsCommutable>, EVEX_V128;
3850   }
3851 }
3852
3853 multiclass avx512_binop_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
3854                                AVX512VLVectorVTInfo VTInfo, OpndItins itins,
3855                                Predicate prd, bit IsCommutable = 0> {
3856   let Predicates = [prd] in
3857     defm Z : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
3858                              IsCommutable>, EVEX_V512;
3859
3860   let Predicates = [prd, HasVLX] in {
3861     defm Z256 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
3862                              IsCommutable>, EVEX_V256;
3863     defm Z128 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
3864                              IsCommutable>, EVEX_V128;
3865   }
3866 }
3867
3868 multiclass avx512_binop_rm_vl_q<bits<8> opc, string OpcodeStr, SDNode OpNode,
3869                                 OpndItins itins, Predicate prd,
3870                                 bit IsCommutable = 0> {
3871   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i64_info,
3872                                itins, prd, IsCommutable>,
3873                                VEX_W, EVEX_CD8<64, CD8VF>;
3874 }
3875
3876 multiclass avx512_binop_rm_vl_d<bits<8> opc, string OpcodeStr, SDNode OpNode,
3877                                 OpndItins itins, Predicate prd,
3878                                 bit IsCommutable = 0> {
3879   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i32_info,
3880                                itins, prd, IsCommutable>, EVEX_CD8<32, CD8VF>;
3881 }
3882
3883 multiclass avx512_binop_rm_vl_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
3884                                 OpndItins itins, Predicate prd,
3885                                 bit IsCommutable = 0> {
3886   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i16_info,
3887                               itins, prd, IsCommutable>, EVEX_CD8<16, CD8VF>;
3888 }
3889
3890 multiclass avx512_binop_rm_vl_b<bits<8> opc, string OpcodeStr, SDNode OpNode,
3891                                 OpndItins itins, Predicate prd,
3892                                 bit IsCommutable = 0> {
3893   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i8_info,
3894                               itins, prd, IsCommutable>, EVEX_CD8<8, CD8VF>;
3895 }
3896
3897 multiclass avx512_binop_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
3898                                  SDNode OpNode, OpndItins itins, Predicate prd,
3899                                  bit IsCommutable = 0> {
3900   defm Q : avx512_binop_rm_vl_q<opc_q, OpcodeStr#"q", OpNode, itins, prd,
3901                                    IsCommutable>;
3902
3903   defm D : avx512_binop_rm_vl_d<opc_d, OpcodeStr#"d", OpNode, itins, prd,
3904                                    IsCommutable>;
3905 }
3906
3907 multiclass avx512_binop_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
3908                                  SDNode OpNode, OpndItins itins, Predicate prd,
3909                                  bit IsCommutable = 0> {
3910   defm W : avx512_binop_rm_vl_w<opc_w, OpcodeStr#"w", OpNode, itins, prd,
3911                                    IsCommutable>;
3912
3913   defm B : avx512_binop_rm_vl_b<opc_b, OpcodeStr#"b", OpNode, itins, prd,
3914                                    IsCommutable>;
3915 }
3916
3917 multiclass avx512_binop_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
3918                                   bits<8> opc_d, bits<8> opc_q,
3919                                   string OpcodeStr, SDNode OpNode,
3920                                   OpndItins itins, bit IsCommutable = 0> {
3921   defm NAME : avx512_binop_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
3922                                     itins, HasAVX512, IsCommutable>,
3923               avx512_binop_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
3924                                     itins, HasBWI, IsCommutable>;
3925 }
3926
3927 multiclass avx512_binop_rm2<bits<8> opc, string OpcodeStr, OpndItins itins,
3928                             SDNode OpNode,X86VectorVTInfo _Src,
3929                             X86VectorVTInfo _Dst, X86VectorVTInfo _Brdct,
3930                             bit IsCommutable = 0> {
3931   defm rr : AVX512_maskable<opc, MRMSrcReg, _Dst, (outs _Dst.RC:$dst),
3932                             (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
3933                             "$src2, $src1","$src1, $src2",
3934                             (_Dst.VT (OpNode
3935                                          (_Src.VT _Src.RC:$src1),
3936                                          (_Src.VT _Src.RC:$src2))),
3937                             itins.rr, IsCommutable>,
3938                             AVX512BIBase, EVEX_4V;
3939   defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3940                         (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr,
3941                         "$src2, $src1", "$src1, $src2",
3942                         (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1),
3943                                       (bitconvert (_Src.LdFrag addr:$src2)))),
3944                         itins.rm>,
3945                         AVX512BIBase, EVEX_4V;
3946
3947   defm rmb : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3948                     (ins _Src.RC:$src1, _Brdct.ScalarMemOp:$src2),
3949                     OpcodeStr,
3950                     "${src2}"##_Brdct.BroadcastStr##", $src1",
3951                      "$src1, ${src2}"##_Brdct.BroadcastStr,
3952                     (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1), (bitconvert
3953                                  (_Brdct.VT (X86VBroadcast
3954                                           (_Brdct.ScalarLdFrag addr:$src2)))))),
3955                     itins.rm>,
3956                     AVX512BIBase, EVEX_4V, EVEX_B;
3957 }
3958
3959 defm VPADD : avx512_binop_rm_vl_all<0xFC, 0xFD, 0xFE, 0xD4, "vpadd", add,
3960                                     SSE_INTALU_ITINS_P, 1>;
3961 defm VPSUB : avx512_binop_rm_vl_all<0xF8, 0xF9, 0xFA, 0xFB, "vpsub", sub,
3962                                     SSE_INTALU_ITINS_P, 0>;
3963 defm VPADDS : avx512_binop_rm_vl_bw<0xEC, 0xED, "vpadds", X86adds,
3964                                     SSE_INTALU_ITINS_P, HasBWI, 1>;
3965 defm VPSUBS : avx512_binop_rm_vl_bw<0xE8, 0xE9, "vpsubs", X86subs,
3966                                     SSE_INTALU_ITINS_P, HasBWI, 0>;
3967 defm VPADDUS : avx512_binop_rm_vl_bw<0xDC, 0xDD, "vpaddus", X86addus,
3968                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3969 defm VPSUBUS : avx512_binop_rm_vl_bw<0xD8, 0xD9, "vpsubus", X86subus,
3970                                      SSE_INTALU_ITINS_P, HasBWI, 0>;
3971 defm VPMULLD : avx512_binop_rm_vl_d<0x40, "vpmulld", mul,
3972                                     SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3973 defm VPMULLW : avx512_binop_rm_vl_w<0xD5, "vpmullw", mul,
3974                                     SSE_INTALU_ITINS_P, HasBWI, 1>;
3975 defm VPMULLQ : avx512_binop_rm_vl_q<0x40, "vpmullq", mul,
3976                                     SSE_INTALU_ITINS_P, HasDQI, 1>, T8PD;
3977 defm VPMULHW : avx512_binop_rm_vl_w<0xE5, "vpmulhw", mulhs, SSE_INTALU_ITINS_P,
3978                                     HasBWI, 1>;
3979 defm VPMULHUW : avx512_binop_rm_vl_w<0xE4, "vpmulhuw", mulhu, SSE_INTMUL_ITINS_P,
3980                                      HasBWI, 1>;
3981 defm VPMULHRSW : avx512_binop_rm_vl_w<0x0B, "vpmulhrsw", X86mulhrs, SSE_INTMUL_ITINS_P,
3982                                       HasBWI, 1>, T8PD;
3983 defm VPAVG : avx512_binop_rm_vl_bw<0xE0, 0xE3, "vpavg", X86avg,
3984                                    SSE_INTALU_ITINS_P, HasBWI, 1>;
3985
3986 multiclass avx512_binop_all<bits<8> opc, string OpcodeStr, OpndItins itins,
3987                             AVX512VLVectorVTInfo _SrcVTInfo, AVX512VLVectorVTInfo _DstVTInfo,
3988                             SDNode OpNode, Predicate prd,  bit IsCommutable = 0> {
3989   let Predicates = [prd] in
3990     defm NAME#Z : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3991                                  _SrcVTInfo.info512, _DstVTInfo.info512,
3992                                  v8i64_info, IsCommutable>,
3993                                   EVEX_V512, EVEX_CD8<64, CD8VF>, VEX_W;
3994   let Predicates = [HasVLX, prd] in {
3995     defm NAME#Z256 : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3996                                       _SrcVTInfo.info256, _DstVTInfo.info256,
3997                                       v4i64x_info, IsCommutable>,
3998                                       EVEX_V256, EVEX_CD8<64, CD8VF>, VEX_W;
3999     defm NAME#Z128 : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
4000                                       _SrcVTInfo.info128, _DstVTInfo.info128,
4001                                       v2i64x_info, IsCommutable>,
4002                                      EVEX_V128, EVEX_CD8<64, CD8VF>, VEX_W;
4003   }
4004 }
4005
4006 defm VPMULDQ : avx512_binop_all<0x28, "vpmuldq", SSE_INTALU_ITINS_P,
4007                                 avx512vl_i32_info, avx512vl_i64_info,
4008                                 X86pmuldq, HasAVX512, 1>,T8PD;
4009 defm VPMULUDQ : avx512_binop_all<0xF4, "vpmuludq", SSE_INTMUL_ITINS_P,
4010                                 avx512vl_i32_info, avx512vl_i64_info,
4011                                 X86pmuludq, HasAVX512, 1>;
4012 defm VPMULTISHIFTQB : avx512_binop_all<0x83, "vpmultishiftqb", SSE_INTALU_ITINS_P,
4013                                 avx512vl_i8_info, avx512vl_i8_info,
4014                                 X86multishift, HasVBMI, 0>, T8PD;
4015
4016 multiclass avx512_packs_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4017                             X86VectorVTInfo _Src, X86VectorVTInfo _Dst> {
4018   defm rmb : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
4019                     (ins _Src.RC:$src1, _Src.ScalarMemOp:$src2),
4020                     OpcodeStr,
4021                     "${src2}"##_Src.BroadcastStr##", $src1",
4022                      "$src1, ${src2}"##_Src.BroadcastStr,
4023                     (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1), (bitconvert
4024                                  (_Src.VT (X86VBroadcast
4025                                           (_Src.ScalarLdFrag addr:$src2))))))>,
4026                     EVEX_4V, EVEX_B, EVEX_CD8<_Src.EltSize, CD8VF>;
4027 }
4028
4029 multiclass avx512_packs_rm<bits<8> opc, string OpcodeStr,
4030                             SDNode OpNode,X86VectorVTInfo _Src,
4031                             X86VectorVTInfo _Dst, bit IsCommutable = 0> {
4032   defm rr : AVX512_maskable<opc, MRMSrcReg, _Dst, (outs _Dst.RC:$dst),
4033                             (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
4034                             "$src2, $src1","$src1, $src2",
4035                             (_Dst.VT (OpNode
4036                                          (_Src.VT _Src.RC:$src1),
4037                                          (_Src.VT _Src.RC:$src2))),
4038                             NoItinerary, IsCommutable>,
4039                             EVEX_CD8<_Src.EltSize, CD8VF>, EVEX_4V;
4040   defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
4041                         (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr,
4042                         "$src2, $src1", "$src1, $src2",
4043                         (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1),
4044                                       (bitconvert (_Src.LdFrag addr:$src2))))>,
4045                          EVEX_4V, EVEX_CD8<_Src.EltSize, CD8VF>;
4046 }
4047
4048 multiclass avx512_packs_all_i32_i16<bits<8> opc, string OpcodeStr,
4049                                     SDNode OpNode> {
4050   let Predicates = [HasBWI] in
4051   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, v16i32_info,
4052                                  v32i16_info>,
4053                 avx512_packs_rmb<opc, OpcodeStr, OpNode, v16i32_info,
4054                                  v32i16_info>, EVEX_V512;
4055   let Predicates = [HasBWI, HasVLX] in {
4056     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, v8i32x_info,
4057                                      v16i16x_info>,
4058                      avx512_packs_rmb<opc, OpcodeStr, OpNode, v8i32x_info,
4059                                      v16i16x_info>, EVEX_V256;
4060     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, v4i32x_info,
4061                                      v8i16x_info>,
4062                      avx512_packs_rmb<opc, OpcodeStr, OpNode, v4i32x_info,
4063                                      v8i16x_info>, EVEX_V128;
4064   }
4065 }
4066 multiclass avx512_packs_all_i16_i8<bits<8> opc, string OpcodeStr,
4067                             SDNode OpNode> {
4068   let Predicates = [HasBWI] in
4069   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, v32i16_info,
4070                                 v64i8_info>, EVEX_V512;
4071   let Predicates = [HasBWI, HasVLX] in {
4072     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, v16i16x_info,
4073                                     v32i8x_info>, EVEX_V256;
4074     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, v8i16x_info,
4075                                     v16i8x_info>, EVEX_V128;
4076   }
4077 }
4078
4079 multiclass avx512_vpmadd<bits<8> opc, string OpcodeStr,
4080                             SDNode OpNode, AVX512VLVectorVTInfo _Src,
4081                             AVX512VLVectorVTInfo _Dst, bit IsCommutable = 0> {
4082   let Predicates = [HasBWI] in
4083   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info512,
4084                                 _Dst.info512, IsCommutable>, EVEX_V512;
4085   let Predicates = [HasBWI, HasVLX] in {
4086     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info256,
4087                                      _Dst.info256, IsCommutable>, EVEX_V256;
4088     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info128,
4089                                      _Dst.info128, IsCommutable>, EVEX_V128;
4090   }
4091 }
4092
4093 defm VPACKSSDW : avx512_packs_all_i32_i16<0x6B, "vpackssdw", X86Packss>, AVX512BIBase;
4094 defm VPACKUSDW : avx512_packs_all_i32_i16<0x2b, "vpackusdw", X86Packus>, AVX5128IBase;
4095 defm VPACKSSWB : avx512_packs_all_i16_i8 <0x63, "vpacksswb", X86Packss>, AVX512BIBase;
4096 defm VPACKUSWB : avx512_packs_all_i16_i8 <0x67, "vpackuswb", X86Packus>, AVX512BIBase;
4097
4098 defm VPMADDUBSW : avx512_vpmadd<0x04, "vpmaddubsw", X86vpmaddubsw,
4099                      avx512vl_i8_info, avx512vl_i16_info>, AVX512BIBase, T8PD;
4100 defm VPMADDWD   : avx512_vpmadd<0xF5, "vpmaddwd", X86vpmaddwd,
4101                      avx512vl_i16_info, avx512vl_i32_info, 1>, AVX512BIBase;
4102
4103 defm VPMAXSB : avx512_binop_rm_vl_b<0x3C, "vpmaxsb", smax,
4104                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4105 defm VPMAXSW : avx512_binop_rm_vl_w<0xEE, "vpmaxsw", smax,
4106                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4107 defm VPMAXS : avx512_binop_rm_vl_dq<0x3D, 0x3D, "vpmaxs", smax,
4108                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4109
4110 defm VPMAXUB : avx512_binop_rm_vl_b<0xDE, "vpmaxub", umax,
4111                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4112 defm VPMAXUW : avx512_binop_rm_vl_w<0x3E, "vpmaxuw", umax,
4113                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4114 defm VPMAXU : avx512_binop_rm_vl_dq<0x3F, 0x3F, "vpmaxu", umax,
4115                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4116
4117 defm VPMINSB : avx512_binop_rm_vl_b<0x38, "vpminsb", smin,
4118                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4119 defm VPMINSW : avx512_binop_rm_vl_w<0xEA, "vpminsw", smin,
4120                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4121 defm VPMINS : avx512_binop_rm_vl_dq<0x39, 0x39, "vpmins", smin,
4122                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4123
4124 defm VPMINUB : avx512_binop_rm_vl_b<0xDA, "vpminub", umin,
4125                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4126 defm VPMINUW : avx512_binop_rm_vl_w<0x3A, "vpminuw", umin,
4127                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4128 defm VPMINU : avx512_binop_rm_vl_dq<0x3B, 0x3B, "vpminu", umin,
4129                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4130
4131 // PMULLQ: Use 512bit version to implement 128/256 bit in case NoVLX.
4132 let Predicates = [HasDQI, NoVLX] in {
4133   def : Pat<(v4i64 (mul (v4i64 VR256X:$src1), (v4i64 VR256X:$src2))),
4134             (EXTRACT_SUBREG
4135                 (VPMULLQZrr
4136                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src1, sub_ymm),
4137                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src2, sub_ymm)),
4138              sub_ymm)>;
4139
4140   def : Pat<(v2i64 (mul (v2i64 VR128X:$src1), (v2i64 VR128X:$src2))),
4141             (EXTRACT_SUBREG
4142                 (VPMULLQZrr
4143                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src1, sub_xmm),
4144                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src2, sub_xmm)),
4145              sub_xmm)>;
4146 }
4147
4148 //===----------------------------------------------------------------------===//
4149 // AVX-512  Logical Instructions
4150 //===----------------------------------------------------------------------===//
4151
4152 multiclass avx512_logic_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4153                            X86VectorVTInfo _, OpndItins itins,
4154                            bit IsCommutable = 0> {
4155   defm rr : AVX512_maskable_logic<opc, MRMSrcReg, _, (outs _.RC:$dst),
4156                     (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4157                     "$src2, $src1", "$src1, $src2",
4158                     (_.i64VT (OpNode (bitconvert (_.VT _.RC:$src1)),
4159                                      (bitconvert (_.VT _.RC:$src2)))),
4160                     (_.VT (bitconvert (_.i64VT (OpNode _.RC:$src1,
4161                                                        _.RC:$src2)))),
4162                     itins.rr, IsCommutable>,
4163             AVX512BIBase, EVEX_4V;
4164
4165   defm rm : AVX512_maskable_logic<opc, MRMSrcMem, _, (outs _.RC:$dst),
4166                   (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
4167                   "$src2, $src1", "$src1, $src2",
4168                   (_.i64VT (OpNode (bitconvert (_.VT _.RC:$src1)),
4169                                    (bitconvert (_.LdFrag addr:$src2)))),
4170                   (_.VT (bitconvert (_.i64VT (OpNode _.RC:$src1,
4171                                      (bitconvert (_.LdFrag addr:$src2)))))),
4172                   itins.rm>,
4173             AVX512BIBase, EVEX_4V;
4174 }
4175
4176 multiclass avx512_logic_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4177                             X86VectorVTInfo _, OpndItins itins,
4178                             bit IsCommutable = 0> :
4179            avx512_logic_rm<opc, OpcodeStr, OpNode, _, itins, IsCommutable> {
4180   defm rmb : AVX512_maskable_logic<opc, MRMSrcMem, _, (outs _.RC:$dst),
4181                   (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4182                   "${src2}"##_.BroadcastStr##", $src1",
4183                   "$src1, ${src2}"##_.BroadcastStr,
4184                   (_.i64VT (OpNode _.RC:$src1,
4185                                    (bitconvert
4186                                     (_.VT (X86VBroadcast
4187                                             (_.ScalarLdFrag addr:$src2)))))),
4188                   (_.VT (bitconvert (_.i64VT (OpNode _.RC:$src1,
4189                                      (bitconvert
4190                                       (_.VT (X86VBroadcast
4191                                              (_.ScalarLdFrag addr:$src2)))))))),
4192                   itins.rm>,
4193              AVX512BIBase, EVEX_4V, EVEX_B;
4194 }
4195
4196 multiclass avx512_logic_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
4197                                AVX512VLVectorVTInfo VTInfo, OpndItins itins,
4198                                Predicate prd, bit IsCommutable = 0> {
4199   let Predicates = [prd] in
4200     defm Z : avx512_logic_rmb<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
4201                              IsCommutable>, EVEX_V512;
4202
4203   let Predicates = [prd, HasVLX] in {
4204     defm Z256 : avx512_logic_rmb<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
4205                              IsCommutable>, EVEX_V256;
4206     defm Z128 : avx512_logic_rmb<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
4207                              IsCommutable>, EVEX_V128;
4208   }
4209 }
4210
4211 multiclass avx512_logic_rm_vl_d<bits<8> opc, string OpcodeStr, SDNode OpNode,
4212                                 OpndItins itins, Predicate prd,
4213                                 bit IsCommutable = 0> {
4214   defm NAME : avx512_logic_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i32_info,
4215                                itins, prd, IsCommutable>, EVEX_CD8<32, CD8VF>;
4216 }
4217
4218 multiclass avx512_logic_rm_vl_q<bits<8> opc, string OpcodeStr, SDNode OpNode,
4219                                 OpndItins itins, Predicate prd,
4220                                 bit IsCommutable = 0> {
4221   defm NAME : avx512_logic_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i64_info,
4222                                itins, prd, IsCommutable>,
4223                                VEX_W, EVEX_CD8<64, CD8VF>;
4224 }
4225
4226 multiclass avx512_logic_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
4227                                  SDNode OpNode, OpndItins itins, Predicate prd,
4228                                  bit IsCommutable = 0> {
4229   defm Q : avx512_logic_rm_vl_q<opc_q, OpcodeStr#"q", OpNode, itins, prd,
4230                                 IsCommutable>;
4231
4232   defm D : avx512_logic_rm_vl_d<opc_d, OpcodeStr#"d", OpNode, itins, prd,
4233                                 IsCommutable>;
4234 }
4235
4236 defm VPAND : avx512_logic_rm_vl_dq<0xDB, 0xDB, "vpand", and,
4237                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
4238 defm VPOR : avx512_logic_rm_vl_dq<0xEB, 0xEB, "vpor", or,
4239                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
4240 defm VPXOR : avx512_logic_rm_vl_dq<0xEF, 0xEF, "vpxor", xor,
4241                                   SSE_INTALU_ITINS_P, HasAVX512, 1>;
4242 defm VPANDN : avx512_logic_rm_vl_dq<0xDF, 0xDF, "vpandn", X86andnp,
4243                                   SSE_INTALU_ITINS_P, HasAVX512, 0>;
4244
4245 //===----------------------------------------------------------------------===//
4246 // AVX-512  FP arithmetic
4247 //===----------------------------------------------------------------------===//
4248 multiclass avx512_fp_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
4249                          SDNode OpNode, SDNode VecNode, OpndItins itins,
4250                          bit IsCommutable> {
4251   let ExeDomain = _.ExeDomain in {
4252   defm rr_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4253                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4254                            "$src2, $src1", "$src1, $src2",
4255                            (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
4256                            (i32 FROUND_CURRENT)),
4257                            itins.rr>;
4258
4259   defm rm_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4260                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4261                          "$src2, $src1", "$src1, $src2",
4262                          (VecNode (_.VT _.RC:$src1),
4263                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
4264                            (i32 FROUND_CURRENT)),
4265                          itins.rm>;
4266   let isCodeGenOnly = 1, Predicates = [HasAVX512] in {
4267   def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
4268                          (ins _.FRC:$src1, _.FRC:$src2),
4269                           OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4270                           [(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
4271                           itins.rr> {
4272     let isCommutable = IsCommutable;
4273   }
4274   def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
4275                          (ins _.FRC:$src1, _.ScalarMemOp:$src2),
4276                          OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4277                          [(set _.FRC:$dst, (OpNode _.FRC:$src1,
4278                          (_.ScalarLdFrag addr:$src2)))], itins.rm>;
4279   }
4280   }
4281 }
4282
4283 multiclass avx512_fp_scalar_round<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
4284                          SDNode VecNode, OpndItins itins, bit IsCommutable = 0> {
4285   let ExeDomain = _.ExeDomain in
4286   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4287                           (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
4288                           "$rc, $src2, $src1", "$src1, $src2, $rc",
4289                           (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
4290                           (i32 imm:$rc)), itins.rr, IsCommutable>,
4291                           EVEX_B, EVEX_RC;
4292 }
4293 multiclass avx512_fp_scalar_sae<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
4294                          SDNode VecNode, OpndItins itins, bit IsCommutable> {
4295   let ExeDomain = _.ExeDomain in
4296   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4297                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4298                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
4299                             (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
4300                             (i32 FROUND_NO_EXC))>, EVEX_B;
4301 }
4302
4303 multiclass avx512_binop_s_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
4304                                   SDNode VecNode,
4305                                   SizeItins itins, bit IsCommutable> {
4306   defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
4307                               itins.s, IsCommutable>,
4308              avx512_fp_scalar_round<opc, OpcodeStr#"ss", f32x_info, VecNode,
4309                               itins.s, IsCommutable>,
4310                               XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
4311   defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
4312                               itins.d,                  IsCommutable>,
4313              avx512_fp_scalar_round<opc, OpcodeStr#"sd", f64x_info, VecNode,
4314                               itins.d, IsCommutable>,
4315                               XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
4316 }
4317
4318 multiclass avx512_binop_s_sae<bits<8> opc, string OpcodeStr, SDNode OpNode,
4319                                   SDNode VecNode,
4320                                   SizeItins itins, bit IsCommutable> {
4321   defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
4322                               itins.s, IsCommutable>,
4323              avx512_fp_scalar_sae<opc, OpcodeStr#"ss", f32x_info, VecNode,
4324                               itins.s, IsCommutable>,
4325                               XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
4326   defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
4327                               itins.d,                  IsCommutable>,
4328              avx512_fp_scalar_sae<opc, OpcodeStr#"sd", f64x_info, VecNode,
4329                               itins.d, IsCommutable>,
4330                               XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
4331 }
4332 defm VADD : avx512_binop_s_round<0x58, "vadd", fadd, X86faddRnd, SSE_ALU_ITINS_S, 1>;
4333 defm VMUL : avx512_binop_s_round<0x59, "vmul", fmul, X86fmulRnd, SSE_MUL_ITINS_S, 1>;
4334 defm VSUB : avx512_binop_s_round<0x5C, "vsub", fsub, X86fsubRnd, SSE_ALU_ITINS_S, 0>;
4335 defm VDIV : avx512_binop_s_round<0x5E, "vdiv", fdiv, X86fdivRnd, SSE_DIV_ITINS_S, 0>;
4336 defm VMIN : avx512_binop_s_sae  <0x5D, "vmin", X86fmin, X86fminRnd, SSE_ALU_ITINS_S, 0>;
4337 defm VMAX : avx512_binop_s_sae  <0x5F, "vmax", X86fmax, X86fmaxRnd, SSE_ALU_ITINS_S, 0>;
4338
4339 // MIN/MAX nodes are commutable under "unsafe-fp-math". In this case we use
4340 // X86fminc and X86fmaxc instead of X86fmin and X86fmax
4341 multiclass avx512_comutable_binop_s<bits<8> opc, string OpcodeStr,
4342                           X86VectorVTInfo _, SDNode OpNode, OpndItins itins> {
4343   let isCodeGenOnly = 1, Predicates = [HasAVX512] in {
4344   def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
4345                          (ins _.FRC:$src1, _.FRC:$src2),
4346                           OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4347                           [(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
4348                           itins.rr> {
4349     let isCommutable = 1;
4350   }
4351   def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
4352                          (ins _.FRC:$src1, _.ScalarMemOp:$src2),
4353                          OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4354                          [(set _.FRC:$dst, (OpNode _.FRC:$src1,
4355                          (_.ScalarLdFrag addr:$src2)))], itins.rm>;
4356   }
4357 }
4358 defm VMINCSSZ : avx512_comutable_binop_s<0x5D, "vminss", f32x_info, X86fminc,
4359                                 SSE_ALU_ITINS_S.s>, XS, EVEX_4V, VEX_LIG,
4360                                 EVEX_CD8<32, CD8VT1>;
4361
4362 defm VMINCSDZ : avx512_comutable_binop_s<0x5D, "vminsd", f64x_info, X86fminc,
4363                                 SSE_ALU_ITINS_S.d>, XD, VEX_W, EVEX_4V, VEX_LIG,
4364                                 EVEX_CD8<64, CD8VT1>;
4365
4366 defm VMAXCSSZ : avx512_comutable_binop_s<0x5F, "vmaxss", f32x_info, X86fmaxc,
4367                                 SSE_ALU_ITINS_S.s>, XS, EVEX_4V, VEX_LIG,
4368                                 EVEX_CD8<32, CD8VT1>;
4369
4370 defm VMAXCSDZ : avx512_comutable_binop_s<0x5F, "vmaxsd", f64x_info, X86fmaxc,
4371                                 SSE_ALU_ITINS_S.d>, XD, VEX_W, EVEX_4V, VEX_LIG,
4372                                 EVEX_CD8<64, CD8VT1>;
4373
4374 multiclass avx512_fp_packed<bits<8> opc, string OpcodeStr, SDPatternOperator OpNode,
4375                             X86VectorVTInfo _, OpndItins itins,
4376                             bit IsCommutable> {
4377   let ExeDomain = _.ExeDomain, hasSideEffects = 0 in {
4378   defm rr: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4379                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4380                   "$src2, $src1", "$src1, $src2",
4381                   (_.VT (OpNode _.RC:$src1, _.RC:$src2)), itins.rr,
4382                   IsCommutable>, EVEX_4V;
4383   let mayLoad = 1 in {
4384     defm rm: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4385                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
4386                     "$src2, $src1", "$src1, $src2",
4387                     (OpNode _.RC:$src1, (_.LdFrag addr:$src2)), itins.rm>,
4388                     EVEX_4V;
4389     defm rmb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4390                      (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
4391                      "${src2}"##_.BroadcastStr##", $src1",
4392                      "$src1, ${src2}"##_.BroadcastStr,
4393                      (OpNode  _.RC:$src1, (_.VT (X86VBroadcast
4394                                                 (_.ScalarLdFrag addr:$src2)))),
4395                      itins.rm>, EVEX_4V, EVEX_B;
4396     }
4397   }
4398 }
4399
4400 multiclass avx512_fp_round_packed<bits<8> opc, string OpcodeStr, SDPatternOperator OpNodeRnd,
4401                                   X86VectorVTInfo _> {
4402   let ExeDomain = _.ExeDomain in
4403   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4404                   (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr##_.Suffix,
4405                   "$rc, $src2, $src1", "$src1, $src2, $rc",
4406                   (_.VT (OpNodeRnd _.RC:$src1, _.RC:$src2, (i32 imm:$rc)))>,
4407                   EVEX_4V, EVEX_B, EVEX_RC;
4408 }
4409
4410
4411 multiclass avx512_fp_sae_packed<bits<8> opc, string OpcodeStr, SDPatternOperator OpNodeRnd,
4412                                 X86VectorVTInfo _> {
4413   let ExeDomain = _.ExeDomain in
4414   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4415                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4416                   "{sae}, $src2, $src1", "$src1, $src2, {sae}",
4417                   (_.VT (OpNodeRnd _.RC:$src1, _.RC:$src2, (i32 FROUND_NO_EXC)))>,
4418                   EVEX_4V, EVEX_B;
4419 }
4420
4421 multiclass avx512_fp_binop_p<bits<8> opc, string OpcodeStr, SDPatternOperator OpNode,
4422                              Predicate prd, SizeItins itins,
4423                              bit IsCommutable = 0> {
4424   let Predicates = [prd] in {
4425   defm PSZ : avx512_fp_packed<opc, OpcodeStr, OpNode, v16f32_info,
4426                               itins.s, IsCommutable>, EVEX_V512, PS,
4427                               EVEX_CD8<32, CD8VF>;
4428   defm PDZ : avx512_fp_packed<opc, OpcodeStr, OpNode, v8f64_info,
4429                               itins.d, IsCommutable>, EVEX_V512, PD, VEX_W,
4430                               EVEX_CD8<64, CD8VF>;
4431   }
4432
4433     // Define only if AVX512VL feature is present.
4434   let Predicates = [prd, HasVLX] in {
4435     defm PSZ128 : avx512_fp_packed<opc, OpcodeStr, OpNode, v4f32x_info,
4436                                    itins.s, IsCommutable>, EVEX_V128, PS,
4437                                    EVEX_CD8<32, CD8VF>;
4438     defm PSZ256 : avx512_fp_packed<opc, OpcodeStr, OpNode, v8f32x_info,
4439                                    itins.s, IsCommutable>, EVEX_V256, PS,
4440                                    EVEX_CD8<32, CD8VF>;
4441     defm PDZ128 : avx512_fp_packed<opc, OpcodeStr, OpNode, v2f64x_info,
4442                                    itins.d, IsCommutable>, EVEX_V128, PD, VEX_W,
4443                                    EVEX_CD8<64, CD8VF>;
4444     defm PDZ256 : avx512_fp_packed<opc, OpcodeStr, OpNode, v4f64x_info,
4445                                    itins.d, IsCommutable>, EVEX_V256, PD, VEX_W,
4446                                    EVEX_CD8<64, CD8VF>;
4447   }
4448 }
4449
4450 multiclass avx512_fp_binop_p_round<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd> {
4451   defm PSZ : avx512_fp_round_packed<opc, OpcodeStr, OpNodeRnd, v16f32_info>,
4452                               EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
4453   defm PDZ : avx512_fp_round_packed<opc, OpcodeStr, OpNodeRnd, v8f64_info>,
4454                               EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>;
4455 }
4456
4457 multiclass avx512_fp_binop_p_sae<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd> {
4458   defm PSZ : avx512_fp_sae_packed<opc, OpcodeStr, OpNodeRnd, v16f32_info>,
4459                               EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
4460   defm PDZ : avx512_fp_sae_packed<opc, OpcodeStr, OpNodeRnd, v8f64_info>,
4461                               EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>;
4462 }
4463
4464 defm VADD : avx512_fp_binop_p<0x58, "vadd", fadd, HasAVX512,
4465                               SSE_ALU_ITINS_P, 1>,
4466             avx512_fp_binop_p_round<0x58, "vadd", X86faddRnd>;
4467 defm VMUL : avx512_fp_binop_p<0x59, "vmul", fmul, HasAVX512,
4468                               SSE_MUL_ITINS_P, 1>,
4469             avx512_fp_binop_p_round<0x59, "vmul", X86fmulRnd>;
4470 defm VSUB : avx512_fp_binop_p<0x5C, "vsub", fsub, HasAVX512, SSE_ALU_ITINS_P>,
4471             avx512_fp_binop_p_round<0x5C, "vsub", X86fsubRnd>;
4472 defm VDIV : avx512_fp_binop_p<0x5E, "vdiv", fdiv, HasAVX512, SSE_DIV_ITINS_P>,
4473             avx512_fp_binop_p_round<0x5E, "vdiv", X86fdivRnd>;
4474 defm VMIN : avx512_fp_binop_p<0x5D, "vmin", X86fmin, HasAVX512,
4475                               SSE_ALU_ITINS_P, 0>,
4476             avx512_fp_binop_p_sae<0x5D, "vmin", X86fminRnd>;
4477 defm VMAX : avx512_fp_binop_p<0x5F, "vmax", X86fmax, HasAVX512,
4478                               SSE_ALU_ITINS_P, 0>,
4479             avx512_fp_binop_p_sae<0x5F, "vmax", X86fmaxRnd>;
4480 let isCodeGenOnly = 1 in {
4481   defm VMINC : avx512_fp_binop_p<0x5D, "vmin", X86fminc, HasAVX512,
4482                                  SSE_ALU_ITINS_P, 1>;
4483   defm VMAXC : avx512_fp_binop_p<0x5F, "vmax", X86fmaxc, HasAVX512,
4484                                  SSE_ALU_ITINS_P, 1>;
4485 }
4486 defm VAND  : avx512_fp_binop_p<0x54, "vand", null_frag, HasDQI,
4487                                SSE_ALU_ITINS_P, 1>;
4488 defm VANDN : avx512_fp_binop_p<0x55, "vandn", null_frag, HasDQI,
4489                                SSE_ALU_ITINS_P, 0>;
4490 defm VOR   : avx512_fp_binop_p<0x56, "vor", null_frag, HasDQI,
4491                                SSE_ALU_ITINS_P, 1>;
4492 defm VXOR  : avx512_fp_binop_p<0x57, "vxor", null_frag, HasDQI,
4493                                SSE_ALU_ITINS_P, 1>;
4494
4495 // Patterns catch floating point selects with bitcasted integer logic ops.
4496 multiclass avx512_fp_logical_lowering<string InstrStr, SDNode OpNode,
4497                                       X86VectorVTInfo _, Predicate prd> {
4498 let Predicates = [prd] in {
4499   // Masked register-register logical operations.
4500   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4501                    (bitconvert (_.i64VT (OpNode _.RC:$src1, _.RC:$src2))),
4502                    _.RC:$src0)),
4503             (!cast<Instruction>(InstrStr#rrk) _.RC:$src0, _.KRCWM:$mask,
4504              _.RC:$src1, _.RC:$src2)>;
4505   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4506                    (bitconvert (_.i64VT (OpNode _.RC:$src1, _.RC:$src2))),
4507                    _.ImmAllZerosV)),
4508             (!cast<Instruction>(InstrStr#rrkz) _.KRCWM:$mask, _.RC:$src1,
4509              _.RC:$src2)>;
4510   // Masked register-memory logical operations.
4511   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4512                    (bitconvert (_.i64VT (OpNode _.RC:$src1,
4513                                          (load addr:$src2)))),
4514                    _.RC:$src0)),
4515             (!cast<Instruction>(InstrStr#rmk) _.RC:$src0, _.KRCWM:$mask,
4516              _.RC:$src1, addr:$src2)>;
4517   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4518                    (bitconvert (_.i64VT (OpNode _.RC:$src1, (load addr:$src2)))),
4519                    _.ImmAllZerosV)),
4520             (!cast<Instruction>(InstrStr#rmkz) _.KRCWM:$mask, _.RC:$src1,
4521              addr:$src2)>;
4522   // Register-broadcast logical operations.
4523   def : Pat<(_.i64VT (OpNode _.RC:$src1,
4524                       (bitconvert (_.VT (X86VBroadcast
4525                                          (_.ScalarLdFrag addr:$src2)))))),
4526             (!cast<Instruction>(InstrStr#rmb) _.RC:$src1, addr:$src2)>;
4527   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4528                    (bitconvert
4529                     (_.i64VT (OpNode _.RC:$src1,
4530                               (bitconvert (_.VT
4531                                            (X86VBroadcast
4532                                             (_.ScalarLdFrag addr:$src2))))))),
4533                    _.RC:$src0)),
4534             (!cast<Instruction>(InstrStr#rmbk) _.RC:$src0, _.KRCWM:$mask,
4535              _.RC:$src1, addr:$src2)>;
4536   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4537                    (bitconvert
4538                     (_.i64VT (OpNode _.RC:$src1,
4539                               (bitconvert (_.VT
4540                                            (X86VBroadcast
4541                                             (_.ScalarLdFrag addr:$src2))))))),
4542                    _.ImmAllZerosV)),
4543             (!cast<Instruction>(InstrStr#rmbkz)  _.KRCWM:$mask,
4544              _.RC:$src1, addr:$src2)>;
4545 }
4546 }
4547
4548 multiclass avx512_fp_logical_lowering_sizes<string InstrStr, SDNode OpNode> {
4549   defm : avx512_fp_logical_lowering<InstrStr#DZ128, OpNode, v4f32x_info, HasVLX>;
4550   defm : avx512_fp_logical_lowering<InstrStr#QZ128, OpNode, v2f64x_info, HasVLX>;
4551   defm : avx512_fp_logical_lowering<InstrStr#DZ256, OpNode, v8f32x_info, HasVLX>;
4552   defm : avx512_fp_logical_lowering<InstrStr#QZ256, OpNode, v4f64x_info, HasVLX>;
4553   defm : avx512_fp_logical_lowering<InstrStr#DZ, OpNode, v16f32_info, HasAVX512>;
4554   defm : avx512_fp_logical_lowering<InstrStr#QZ, OpNode, v8f64_info, HasAVX512>;
4555 }
4556
4557 defm : avx512_fp_logical_lowering_sizes<"VPAND", and>;
4558 defm : avx512_fp_logical_lowering_sizes<"VPOR", or>;
4559 defm : avx512_fp_logical_lowering_sizes<"VPXOR", xor>;
4560 defm : avx512_fp_logical_lowering_sizes<"VPANDN", X86andnp>;
4561
4562 let Predicates = [HasVLX,HasDQI] in {
4563   // Use packed logical operations for scalar ops.
4564   def : Pat<(f64 (X86fand FR64X:$src1, FR64X:$src2)),
4565             (COPY_TO_REGCLASS (VANDPDZ128rr
4566                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4567                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4568   def : Pat<(f64 (X86for FR64X:$src1, FR64X:$src2)),
4569             (COPY_TO_REGCLASS (VORPDZ128rr
4570                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4571                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4572   def : Pat<(f64 (X86fxor FR64X:$src1, FR64X:$src2)),
4573             (COPY_TO_REGCLASS (VXORPDZ128rr
4574                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4575                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4576   def : Pat<(f64 (X86fandn FR64X:$src1, FR64X:$src2)),
4577             (COPY_TO_REGCLASS (VANDNPDZ128rr
4578                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4579                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4580
4581   def : Pat<(f32 (X86fand FR32X:$src1, FR32X:$src2)),
4582             (COPY_TO_REGCLASS (VANDPSZ128rr
4583                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4584                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4585   def : Pat<(f32 (X86for FR32X:$src1, FR32X:$src2)),
4586             (COPY_TO_REGCLASS (VORPSZ128rr
4587                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4588                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4589   def : Pat<(f32 (X86fxor FR32X:$src1, FR32X:$src2)),
4590             (COPY_TO_REGCLASS (VXORPSZ128rr
4591                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4592                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4593   def : Pat<(f32 (X86fandn FR32X:$src1, FR32X:$src2)),
4594             (COPY_TO_REGCLASS (VANDNPSZ128rr
4595                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4596                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4597 }
4598
4599 multiclass avx512_fp_scalef_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
4600                             X86VectorVTInfo _> {
4601   defm rr: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4602                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4603                   "$src2, $src1", "$src1, $src2",
4604                   (_.VT (OpNode _.RC:$src1, _.RC:$src2, (i32 FROUND_CURRENT)))>, EVEX_4V;
4605   defm rm: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4606                   (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
4607                   "$src2, $src1", "$src1, $src2",
4608                   (OpNode _.RC:$src1, (_.LdFrag addr:$src2), (i32 FROUND_CURRENT))>, EVEX_4V;
4609   defm rmb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4610                    (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
4611                    "${src2}"##_.BroadcastStr##", $src1",
4612                    "$src1, ${src2}"##_.BroadcastStr,
4613                    (OpNode  _.RC:$src1, (_.VT (X86VBroadcast
4614                                               (_.ScalarLdFrag addr:$src2))), (i32 FROUND_CURRENT))>,
4615                    EVEX_4V, EVEX_B;
4616 }
4617
4618 multiclass avx512_fp_scalef_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
4619                             X86VectorVTInfo _> {
4620   defm rr: AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4621                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4622                   "$src2, $src1", "$src1, $src2",
4623                   (_.VT (OpNode _.RC:$src1, _.RC:$src2, (i32 FROUND_CURRENT)))>;
4624   defm rm: AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4625                   (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
4626                   "$src2, $src1", "$src1, $src2",
4627                   (OpNode _.RC:$src1,
4628                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
4629                           (i32 FROUND_CURRENT))>;
4630 }
4631
4632 multiclass avx512_fp_scalef_all<bits<8> opc, bits<8> opcScaler, string OpcodeStr, SDNode OpNode, SDNode OpNodeScal> {
4633   defm PSZ : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v16f32_info>,
4634              avx512_fp_round_packed<opc, OpcodeStr, OpNode, v16f32_info>,
4635                               EVEX_V512, EVEX_CD8<32, CD8VF>;
4636   defm PDZ : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v8f64_info>,
4637              avx512_fp_round_packed<opc, OpcodeStr, OpNode, v8f64_info>,
4638                               EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
4639   defm SSZ128 : avx512_fp_scalef_scalar<opcScaler, OpcodeStr, OpNodeScal, f32x_info>,
4640                 avx512_fp_scalar_round<opcScaler, OpcodeStr##"ss", f32x_info, OpNodeScal, SSE_ALU_ITINS_S.s>,
4641                               EVEX_4V,EVEX_CD8<32, CD8VT1>;
4642   defm SDZ128 : avx512_fp_scalef_scalar<opcScaler, OpcodeStr, OpNodeScal, f64x_info>,
4643                 avx512_fp_scalar_round<opcScaler, OpcodeStr##"sd", f64x_info, OpNodeScal, SSE_ALU_ITINS_S.d>,
4644                               EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
4645
4646   // Define only if AVX512VL feature is present.
4647   let Predicates = [HasVLX] in {
4648     defm PSZ128 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v4f32x_info>,
4649                                    EVEX_V128, EVEX_CD8<32, CD8VF>;
4650     defm PSZ256 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v8f32x_info>,
4651                                    EVEX_V256, EVEX_CD8<32, CD8VF>;
4652     defm PDZ128 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v2f64x_info>,
4653                                    EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
4654     defm PDZ256 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v4f64x_info>,
4655                                    EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
4656   }
4657 }
4658 defm VSCALEF : avx512_fp_scalef_all<0x2C, 0x2D, "vscalef", X86scalef, X86scalefs>, T8PD;
4659
4660 //===----------------------------------------------------------------------===//
4661 // AVX-512  VPTESTM instructions
4662 //===----------------------------------------------------------------------===//
4663
4664 multiclass avx512_vptest<bits<8> opc, string OpcodeStr, SDNode OpNode,
4665                             X86VectorVTInfo _> {
4666   let isCommutable = 1 in
4667   defm rr : AVX512_maskable_cmp<opc, MRMSrcReg, _, (outs _.KRC:$dst),
4668                    (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4669                       "$src2, $src1", "$src1, $src2",
4670                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>,
4671                     EVEX_4V;
4672   defm rm : AVX512_maskable_cmp<opc, MRMSrcMem, _, (outs _.KRC:$dst),
4673                    (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
4674                        "$src2, $src1", "$src1, $src2",
4675                    (OpNode (_.VT _.RC:$src1),
4676                     (_.VT (bitconvert (_.LdFrag addr:$src2))))>,
4677                     EVEX_4V,
4678                    EVEX_CD8<_.EltSize, CD8VF>;
4679 }
4680
4681 multiclass avx512_vptest_mb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4682                             X86VectorVTInfo _> {
4683   defm rmb : AVX512_maskable_cmp<opc, MRMSrcMem, _, (outs _.KRC:$dst),
4684                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4685                     "${src2}"##_.BroadcastStr##", $src1",
4686                     "$src1, ${src2}"##_.BroadcastStr,
4687                     (OpNode (_.VT _.RC:$src1), (_.VT (X86VBroadcast
4688                                                 (_.ScalarLdFrag addr:$src2))))>,
4689                     EVEX_B, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
4690 }
4691
4692 // Use 512bit version to implement 128/256 bit in case NoVLX.
4693 multiclass avx512_vptest_lowering<SDNode OpNode, X86VectorVTInfo ExtendInfo,
4694                                   X86VectorVTInfo _, string Suffix> {
4695     def : Pat<(_.KVT (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))),
4696               (_.KVT (COPY_TO_REGCLASS
4697                        (!cast<Instruction>(NAME # Suffix # "Zrr")
4698                          (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
4699                                         _.RC:$src1, _.SubRegIdx),
4700                          (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
4701                                         _.RC:$src2, _.SubRegIdx)),
4702                      _.KRC))>;
4703 }
4704
4705 multiclass avx512_vptest_dq_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4706                                   AVX512VLVectorVTInfo _, string Suffix> {
4707   let Predicates  = [HasAVX512] in
4708   defm Z : avx512_vptest<opc, OpcodeStr, OpNode, _.info512>,
4709            avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
4710
4711   let Predicates = [HasAVX512, HasVLX] in {
4712   defm Z256 : avx512_vptest<opc, OpcodeStr, OpNode, _.info256>,
4713               avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
4714   defm Z128 : avx512_vptest<opc, OpcodeStr, OpNode, _.info128>,
4715               avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
4716   }
4717   let Predicates = [HasAVX512, NoVLX] in {
4718   defm Z256_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info256, Suffix>;
4719   defm Z128_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info128, Suffix>;
4720   }
4721 }
4722
4723 multiclass avx512_vptest_dq<bits<8> opc, string OpcodeStr, SDNode OpNode> {
4724   defm D : avx512_vptest_dq_sizes<opc, OpcodeStr#"d", OpNode,
4725                                  avx512vl_i32_info, "D">;
4726   defm Q : avx512_vptest_dq_sizes<opc, OpcodeStr#"q", OpNode,
4727                                  avx512vl_i64_info, "Q">, VEX_W;
4728 }
4729
4730 multiclass avx512_vptest_wb<bits<8> opc, string OpcodeStr,
4731                                  SDNode OpNode> {
4732   let Predicates = [HasBWI] in {
4733   defm WZ:    avx512_vptest<opc, OpcodeStr#"w", OpNode, v32i16_info>,
4734               EVEX_V512, VEX_W;
4735   defm BZ:    avx512_vptest<opc, OpcodeStr#"b", OpNode, v64i8_info>,
4736               EVEX_V512;
4737   }
4738   let Predicates = [HasVLX, HasBWI] in {
4739
4740   defm WZ256: avx512_vptest<opc, OpcodeStr#"w", OpNode, v16i16x_info>,
4741               EVEX_V256, VEX_W;
4742   defm WZ128: avx512_vptest<opc, OpcodeStr#"w", OpNode, v8i16x_info>,
4743               EVEX_V128, VEX_W;
4744   defm BZ256: avx512_vptest<opc, OpcodeStr#"b", OpNode, v32i8x_info>,
4745               EVEX_V256;
4746   defm BZ128: avx512_vptest<opc, OpcodeStr#"b", OpNode, v16i8x_info>,
4747               EVEX_V128;
4748   }
4749
4750   let Predicates = [HasAVX512, NoVLX] in {
4751   defm BZ256_Alt : avx512_vptest_lowering< OpNode, v64i8_info, v32i8x_info, "B">;
4752   defm BZ128_Alt : avx512_vptest_lowering< OpNode, v64i8_info, v16i8x_info, "B">;
4753   defm WZ256_Alt : avx512_vptest_lowering< OpNode, v32i16_info, v16i16x_info, "W">;
4754   defm WZ128_Alt : avx512_vptest_lowering< OpNode, v32i16_info, v8i16x_info, "W">;
4755   }
4756
4757 }
4758
4759 multiclass avx512_vptest_all_forms<bits<8> opc_wb, bits<8> opc_dq, string OpcodeStr,
4760                                    SDNode OpNode> :
4761   avx512_vptest_wb <opc_wb, OpcodeStr, OpNode>,
4762   avx512_vptest_dq<opc_dq, OpcodeStr, OpNode>;
4763
4764 defm VPTESTM   : avx512_vptest_all_forms<0x26, 0x27, "vptestm", X86testm>, T8PD;
4765 defm VPTESTNM  : avx512_vptest_all_forms<0x26, 0x27, "vptestnm", X86testnm>, T8XS;
4766
4767
4768 //===----------------------------------------------------------------------===//
4769 // AVX-512  Shift instructions
4770 //===----------------------------------------------------------------------===//
4771 multiclass avx512_shift_rmi<bits<8> opc, Format ImmFormR, Format ImmFormM,
4772                          string OpcodeStr, SDNode OpNode, X86VectorVTInfo _> {
4773   let ExeDomain = _.ExeDomain in {
4774   defm ri : AVX512_maskable<opc, ImmFormR, _, (outs _.RC:$dst),
4775                    (ins _.RC:$src1, u8imm:$src2), OpcodeStr,
4776                       "$src2, $src1", "$src1, $src2",
4777                    (_.VT (OpNode _.RC:$src1, (i8 imm:$src2))),
4778                    SSE_INTSHIFT_ITINS_P.rr>;
4779   defm mi : AVX512_maskable<opc, ImmFormM, _, (outs _.RC:$dst),
4780                    (ins _.MemOp:$src1, u8imm:$src2), OpcodeStr,
4781                        "$src2, $src1", "$src1, $src2",
4782                    (_.VT (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
4783                           (i8 imm:$src2))),
4784                    SSE_INTSHIFT_ITINS_P.rm>;
4785   }
4786 }
4787
4788 multiclass avx512_shift_rmbi<bits<8> opc, Format ImmFormM,
4789                          string OpcodeStr, SDNode OpNode, X86VectorVTInfo _> {
4790   let ExeDomain = _.ExeDomain in
4791   defm mbi : AVX512_maskable<opc, ImmFormM, _, (outs _.RC:$dst),
4792                    (ins _.ScalarMemOp:$src1, u8imm:$src2), OpcodeStr,
4793       "$src2, ${src1}"##_.BroadcastStr, "${src1}"##_.BroadcastStr##", $src2",
4794      (_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src1)), (i8 imm:$src2))),
4795      SSE_INTSHIFT_ITINS_P.rm>, EVEX_B;
4796 }
4797
4798 multiclass avx512_shift_rrm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4799                          ValueType SrcVT, PatFrag bc_frag, X86VectorVTInfo _> {
4800    // src2 is always 128-bit
4801   let ExeDomain = _.ExeDomain in {
4802   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4803                    (ins _.RC:$src1, VR128X:$src2), OpcodeStr,
4804                       "$src2, $src1", "$src1, $src2",
4805                    (_.VT (OpNode _.RC:$src1, (SrcVT VR128X:$src2))),
4806                    SSE_INTSHIFT_ITINS_P.rr>, AVX512BIBase, EVEX_4V;
4807   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4808                    (ins _.RC:$src1, i128mem:$src2), OpcodeStr,
4809                        "$src2, $src1", "$src1, $src2",
4810                    (_.VT (OpNode _.RC:$src1, (bc_frag (loadv2i64 addr:$src2)))),
4811                    SSE_INTSHIFT_ITINS_P.rm>, AVX512BIBase,
4812                    EVEX_4V;
4813   }
4814 }
4815
4816 multiclass avx512_shift_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4817                                   ValueType SrcVT, PatFrag bc_frag,
4818                                   AVX512VLVectorVTInfo VTInfo, Predicate prd> {
4819   let Predicates = [prd] in
4820   defm Z    : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
4821                             VTInfo.info512>, EVEX_V512,
4822                             EVEX_CD8<VTInfo.info512.EltSize, CD8VQ> ;
4823   let Predicates = [prd, HasVLX] in {
4824   defm Z256 : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
4825                             VTInfo.info256>, EVEX_V256,
4826                             EVEX_CD8<VTInfo.info256.EltSize, CD8VH>;
4827   defm Z128 : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
4828                             VTInfo.info128>, EVEX_V128,
4829                             EVEX_CD8<VTInfo.info128.EltSize, CD8VF>;
4830   }
4831 }
4832
4833 multiclass avx512_shift_types<bits<8> opcd, bits<8> opcq, bits<8> opcw,
4834                               string OpcodeStr, SDNode OpNode> {
4835   defm D : avx512_shift_sizes<opcd, OpcodeStr#"d", OpNode, v4i32, bc_v4i32,
4836                                  avx512vl_i32_info, HasAVX512>;
4837   defm Q : avx512_shift_sizes<opcq, OpcodeStr#"q", OpNode, v2i64, bc_v2i64,
4838                                  avx512vl_i64_info, HasAVX512>, VEX_W;
4839   defm W : avx512_shift_sizes<opcw, OpcodeStr#"w", OpNode, v8i16, bc_v8i16,
4840                                  avx512vl_i16_info, HasBWI>;
4841 }
4842
4843 multiclass avx512_shift_rmi_sizes<bits<8> opc, Format ImmFormR, Format ImmFormM,
4844                                  string OpcodeStr, SDNode OpNode,
4845                                  AVX512VLVectorVTInfo VTInfo> {
4846   let Predicates = [HasAVX512] in
4847   defm Z:    avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4848                               VTInfo.info512>,
4849              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4850                               VTInfo.info512>, EVEX_V512;
4851   let Predicates = [HasAVX512, HasVLX] in {
4852   defm Z256: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4853                               VTInfo.info256>,
4854              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4855                               VTInfo.info256>, EVEX_V256;
4856   defm Z128: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4857                               VTInfo.info128>,
4858              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4859                               VTInfo.info128>, EVEX_V128;
4860   }
4861 }
4862
4863 multiclass avx512_shift_rmi_w<bits<8> opcw,
4864                                  Format ImmFormR, Format ImmFormM,
4865                                  string OpcodeStr, SDNode OpNode> {
4866   let Predicates = [HasBWI] in
4867   defm WZ:    avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4868                                v32i16_info>, EVEX_V512;
4869   let Predicates = [HasVLX, HasBWI] in {
4870   defm WZ256: avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4871                                v16i16x_info>, EVEX_V256;
4872   defm WZ128: avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4873                                v8i16x_info>, EVEX_V128;
4874   }
4875 }
4876
4877 multiclass avx512_shift_rmi_dq<bits<8> opcd, bits<8> opcq,
4878                                  Format ImmFormR, Format ImmFormM,
4879                                  string OpcodeStr, SDNode OpNode> {
4880   defm D: avx512_shift_rmi_sizes<opcd, ImmFormR, ImmFormM, OpcodeStr#"d", OpNode,
4881                                  avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
4882   defm Q: avx512_shift_rmi_sizes<opcq, ImmFormR, ImmFormM, OpcodeStr#"q", OpNode,
4883                                  avx512vl_i64_info>, EVEX_CD8<64, CD8VF>, VEX_W;
4884 }
4885
4886 defm VPSRL : avx512_shift_rmi_dq<0x72, 0x73, MRM2r, MRM2m, "vpsrl", X86vsrli>,
4887              avx512_shift_rmi_w<0x71, MRM2r, MRM2m, "vpsrlw", X86vsrli>, AVX512BIi8Base, EVEX_4V;
4888
4889 defm VPSLL : avx512_shift_rmi_dq<0x72, 0x73, MRM6r, MRM6m, "vpsll", X86vshli>,
4890              avx512_shift_rmi_w<0x71, MRM6r, MRM6m, "vpsllw", X86vshli>, AVX512BIi8Base, EVEX_4V;
4891
4892 defm VPSRA : avx512_shift_rmi_dq<0x72, 0x72, MRM4r, MRM4m, "vpsra", X86vsrai>,
4893              avx512_shift_rmi_w<0x71, MRM4r, MRM4m, "vpsraw", X86vsrai>, AVX512BIi8Base, EVEX_4V;
4894
4895 defm VPROR : avx512_shift_rmi_dq<0x72, 0x72, MRM0r, MRM0m, "vpror", X86vrotri>, AVX512BIi8Base, EVEX_4V;
4896 defm VPROL : avx512_shift_rmi_dq<0x72, 0x72, MRM1r, MRM1m, "vprol", X86vrotli>, AVX512BIi8Base, EVEX_4V;
4897
4898 defm VPSLL : avx512_shift_types<0xF2, 0xF3, 0xF1, "vpsll", X86vshl>;
4899 defm VPSRA : avx512_shift_types<0xE2, 0xE2, 0xE1, "vpsra", X86vsra>;
4900 defm VPSRL : avx512_shift_types<0xD2, 0xD3, 0xD1, "vpsrl", X86vsrl>;
4901
4902 //===-------------------------------------------------------------------===//
4903 // Variable Bit Shifts
4904 //===-------------------------------------------------------------------===//
4905 multiclass avx512_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
4906                             X86VectorVTInfo _> {
4907   let ExeDomain = _.ExeDomain in {
4908   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4909                    (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4910                       "$src2, $src1", "$src1, $src2",
4911                    (_.VT (OpNode _.RC:$src1, (_.VT _.RC:$src2))),
4912                    SSE_INTSHIFT_ITINS_P.rr>, AVX5128IBase, EVEX_4V;
4913   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4914                    (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
4915                        "$src2, $src1", "$src1, $src2",
4916                    (_.VT (OpNode _.RC:$src1,
4917                    (_.VT (bitconvert (_.LdFrag addr:$src2))))),
4918                    SSE_INTSHIFT_ITINS_P.rm>, AVX5128IBase, EVEX_4V,
4919                    EVEX_CD8<_.EltSize, CD8VF>;
4920   }
4921 }
4922
4923 multiclass avx512_var_shift_mb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4924                             X86VectorVTInfo _> {
4925   let ExeDomain = _.ExeDomain in
4926   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4927                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4928                     "${src2}"##_.BroadcastStr##", $src1",
4929                     "$src1, ${src2}"##_.BroadcastStr,
4930                     (_.VT (OpNode _.RC:$src1, (_.VT (X86VBroadcast
4931                                                 (_.ScalarLdFrag addr:$src2))))),
4932                     SSE_INTSHIFT_ITINS_P.rm>, AVX5128IBase, EVEX_B,
4933                     EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
4934 }
4935 multiclass avx512_var_shift_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4936                                   AVX512VLVectorVTInfo _> {
4937   let Predicates  = [HasAVX512] in
4938   defm Z : avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
4939            avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
4940
4941   let Predicates = [HasAVX512, HasVLX] in {
4942   defm Z256 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
4943               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
4944   defm Z128 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info128>,
4945               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
4946   }
4947 }
4948
4949 multiclass avx512_var_shift_types<bits<8> opc, string OpcodeStr,
4950                                  SDNode OpNode> {
4951   defm D : avx512_var_shift_sizes<opc, OpcodeStr#"d", OpNode,
4952                                  avx512vl_i32_info>;
4953   defm Q : avx512_var_shift_sizes<opc, OpcodeStr#"q", OpNode,
4954                                  avx512vl_i64_info>, VEX_W;
4955 }
4956
4957 // Use 512bit version to implement 128/256 bit in case NoVLX.
4958 multiclass avx512_var_shift_w_lowering<AVX512VLVectorVTInfo _, SDNode OpNode> {
4959   let Predicates = [HasBWI, NoVLX] in {
4960   def : Pat<(_.info256.VT (OpNode (_.info256.VT _.info256.RC:$src1),
4961                                   (_.info256.VT _.info256.RC:$src2))),
4962             (EXTRACT_SUBREG
4963                 (!cast<Instruction>(NAME#"WZrr")
4964                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR256X:$src1, sub_ymm),
4965                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR256X:$src2, sub_ymm)),
4966              sub_ymm)>;
4967
4968   def : Pat<(_.info128.VT (OpNode (_.info128.VT _.info128.RC:$src1),
4969                                   (_.info128.VT _.info128.RC:$src2))),
4970             (EXTRACT_SUBREG
4971                 (!cast<Instruction>(NAME#"WZrr")
4972                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR128X:$src1, sub_xmm),
4973                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR128X:$src2, sub_xmm)),
4974              sub_xmm)>;
4975   }
4976 }
4977
4978 multiclass avx512_var_shift_w<bits<8> opc, string OpcodeStr,
4979                                  SDNode OpNode> {
4980   let Predicates = [HasBWI] in
4981   defm WZ:    avx512_var_shift<opc, OpcodeStr, OpNode, v32i16_info>,
4982               EVEX_V512, VEX_W;
4983   let Predicates = [HasVLX, HasBWI] in {
4984
4985   defm WZ256: avx512_var_shift<opc, OpcodeStr, OpNode, v16i16x_info>,
4986               EVEX_V256, VEX_W;
4987   defm WZ128: avx512_var_shift<opc, OpcodeStr, OpNode, v8i16x_info>,
4988               EVEX_V128, VEX_W;
4989   }
4990 }
4991
4992 defm VPSLLV : avx512_var_shift_types<0x47, "vpsllv", shl>,
4993               avx512_var_shift_w<0x12, "vpsllvw", shl>,
4994               avx512_var_shift_w_lowering<avx512vl_i16_info, shl>;
4995
4996 defm VPSRAV : avx512_var_shift_types<0x46, "vpsrav", sra>,
4997               avx512_var_shift_w<0x11, "vpsravw", sra>,
4998               avx512_var_shift_w_lowering<avx512vl_i16_info, sra>;
4999
5000 defm VPSRLV : avx512_var_shift_types<0x45, "vpsrlv", srl>,
5001               avx512_var_shift_w<0x10, "vpsrlvw", srl>,
5002               avx512_var_shift_w_lowering<avx512vl_i16_info, srl>;
5003 defm VPRORV : avx512_var_shift_types<0x14, "vprorv", rotr>;
5004 defm VPROLV : avx512_var_shift_types<0x15, "vprolv", rotl>;
5005
5006 // Special handing for handling VPSRAV intrinsics.
5007 multiclass avx512_var_shift_int_lowering<string InstrStr, X86VectorVTInfo _,
5008                                          list<Predicate> p> {
5009   let Predicates = p in {
5010     def : Pat<(_.VT (X86vsrav _.RC:$src1, _.RC:$src2)),
5011               (!cast<Instruction>(InstrStr#_.ZSuffix#rr) _.RC:$src1,
5012                _.RC:$src2)>;
5013     def : Pat<(_.VT (X86vsrav _.RC:$src1, (bitconvert (_.LdFrag addr:$src2)))),
5014               (!cast<Instruction>(InstrStr#_.ZSuffix##rm)
5015                _.RC:$src1, addr:$src2)>;
5016     let AddedComplexity = 20 in {
5017     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5018                      (X86vsrav _.RC:$src1, _.RC:$src2), _.RC:$src0)),
5019               (!cast<Instruction>(InstrStr#_.ZSuffix#rrk) _.RC:$src0,
5020                _.KRC:$mask, _.RC:$src1, _.RC:$src2)>;
5021     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5022                      (X86vsrav _.RC:$src1, (bitconvert (_.LdFrag addr:$src2))),
5023                      _.RC:$src0)),
5024               (!cast<Instruction>(InstrStr#_.ZSuffix##rmk) _.RC:$src0,
5025                _.KRC:$mask, _.RC:$src1, addr:$src2)>;
5026     }
5027     let AddedComplexity = 30 in {
5028     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5029                      (X86vsrav _.RC:$src1, _.RC:$src2), _.ImmAllZerosV)),
5030               (!cast<Instruction>(InstrStr#_.ZSuffix#rrkz) _.KRC:$mask,
5031                _.RC:$src1, _.RC:$src2)>;
5032     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5033                      (X86vsrav _.RC:$src1, (bitconvert (_.LdFrag addr:$src2))),
5034                      _.ImmAllZerosV)),
5035               (!cast<Instruction>(InstrStr#_.ZSuffix##rmkz) _.KRC:$mask,
5036                _.RC:$src1, addr:$src2)>;
5037     }
5038   }
5039 }
5040
5041 multiclass avx512_var_shift_int_lowering_mb<string InstrStr, X86VectorVTInfo _,
5042                                          list<Predicate> p> :
5043            avx512_var_shift_int_lowering<InstrStr, _, p> {
5044   let Predicates = p in {
5045     def : Pat<(_.VT (X86vsrav _.RC:$src1,
5046                      (X86VBroadcast (_.ScalarLdFrag addr:$src2)))),
5047               (!cast<Instruction>(InstrStr#_.ZSuffix##rmb)
5048                _.RC:$src1, addr:$src2)>;
5049     let AddedComplexity = 20 in
5050     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5051                      (X86vsrav _.RC:$src1,
5052                       (X86VBroadcast (_.ScalarLdFrag addr:$src2))),
5053                      _.RC:$src0)),
5054               (!cast<Instruction>(InstrStr#_.ZSuffix##rmbk) _.RC:$src0,
5055                _.KRC:$mask, _.RC:$src1, addr:$src2)>;
5056     let AddedComplexity = 30 in
5057     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5058                      (X86vsrav _.RC:$src1,
5059                       (X86VBroadcast (_.ScalarLdFrag addr:$src2))),
5060                      _.ImmAllZerosV)),
5061               (!cast<Instruction>(InstrStr#_.ZSuffix##rmbkz) _.KRC:$mask,
5062                _.RC:$src1, addr:$src2)>;
5063   }
5064 }
5065
5066 defm : avx512_var_shift_int_lowering<"VPSRAVW", v8i16x_info, [HasVLX, HasBWI]>;
5067 defm : avx512_var_shift_int_lowering<"VPSRAVW", v16i16x_info, [HasVLX, HasBWI]>;
5068 defm : avx512_var_shift_int_lowering<"VPSRAVW", v32i16_info, [HasBWI]>;
5069 defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v4i32x_info, [HasVLX]>;
5070 defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v8i32x_info, [HasVLX]>;
5071 defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v16i32_info, [HasAVX512]>;
5072 defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v2i64x_info, [HasVLX]>;
5073 defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v4i64x_info, [HasVLX]>;
5074 defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v8i64_info, [HasAVX512]>;
5075
5076 //===-------------------------------------------------------------------===//
5077 // 1-src variable permutation VPERMW/D/Q
5078 //===-------------------------------------------------------------------===//
5079 multiclass avx512_vperm_dq_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
5080                                   AVX512VLVectorVTInfo _> {
5081   let Predicates  = [HasAVX512] in
5082   defm Z : avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
5083            avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
5084
5085   let Predicates = [HasAVX512, HasVLX] in
5086   defm Z256 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
5087               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
5088 }
5089
5090 multiclass avx512_vpermi_dq_sizes<bits<8> opc, Format ImmFormR, Format ImmFormM,
5091                                  string OpcodeStr, SDNode OpNode,
5092                                  AVX512VLVectorVTInfo VTInfo> {
5093   let Predicates = [HasAVX512] in
5094   defm Z:    avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
5095                               VTInfo.info512>,
5096              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
5097                               VTInfo.info512>, EVEX_V512;
5098   let Predicates = [HasAVX512, HasVLX] in
5099   defm Z256: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
5100                               VTInfo.info256>,
5101              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
5102                               VTInfo.info256>, EVEX_V256;
5103 }
5104
5105 multiclass avx512_vperm_bw<bits<8> opc, string OpcodeStr,
5106                               Predicate prd, SDNode OpNode,
5107                               AVX512VLVectorVTInfo _> {
5108   let Predicates = [prd] in
5109   defm Z:    avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
5110               EVEX_V512 ;
5111   let Predicates = [HasVLX, prd] in {
5112   defm Z256: avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
5113               EVEX_V256 ;
5114   defm Z128: avx512_var_shift<opc, OpcodeStr, OpNode, _.info128>,
5115               EVEX_V128 ;
5116   }
5117 }
5118
5119 defm VPERMW  : avx512_vperm_bw<0x8D, "vpermw", HasBWI, X86VPermv,
5120                                   avx512vl_i16_info>, VEX_W;
5121 defm VPERMB  : avx512_vperm_bw<0x8D, "vpermb", HasVBMI, X86VPermv,
5122                                   avx512vl_i8_info>;
5123
5124 defm VPERMD : avx512_vperm_dq_sizes<0x36, "vpermd", X86VPermv,
5125                                     avx512vl_i32_info>;
5126 defm VPERMQ : avx512_vperm_dq_sizes<0x36, "vpermq", X86VPermv,
5127                                     avx512vl_i64_info>, VEX_W;
5128 defm VPERMPS : avx512_vperm_dq_sizes<0x16, "vpermps", X86VPermv,
5129                                     avx512vl_f32_info>;
5130 defm VPERMPD : avx512_vperm_dq_sizes<0x16, "vpermpd", X86VPermv,
5131                                     avx512vl_f64_info>, VEX_W;
5132
5133 defm VPERMQ : avx512_vpermi_dq_sizes<0x00, MRMSrcReg, MRMSrcMem, "vpermq",
5134                              X86VPermi, avx512vl_i64_info>,
5135                              EVEX, AVX512AIi8Base, EVEX_CD8<64, CD8VF>, VEX_W;
5136 defm VPERMPD : avx512_vpermi_dq_sizes<0x01, MRMSrcReg, MRMSrcMem, "vpermpd",
5137                              X86VPermi, avx512vl_f64_info>,
5138                              EVEX, AVX512AIi8Base, EVEX_CD8<64, CD8VF>, VEX_W;
5139 //===----------------------------------------------------------------------===//
5140 // AVX-512 - VPERMIL
5141 //===----------------------------------------------------------------------===//
5142
5143 multiclass avx512_permil_vec<bits<8> OpcVar, string OpcodeStr,  SDNode OpNode,
5144                              X86VectorVTInfo _, X86VectorVTInfo Ctrl> {
5145   defm rr: AVX512_maskable<OpcVar, MRMSrcReg, _, (outs _.RC:$dst),
5146                   (ins _.RC:$src1, Ctrl.RC:$src2), OpcodeStr,
5147                   "$src2, $src1", "$src1, $src2",
5148                   (_.VT (OpNode _.RC:$src1,
5149                                (Ctrl.VT Ctrl.RC:$src2)))>,
5150                   T8PD, EVEX_4V;
5151   defm rm: AVX512_maskable<OpcVar, MRMSrcMem, _, (outs _.RC:$dst),
5152                   (ins _.RC:$src1, Ctrl.MemOp:$src2), OpcodeStr,
5153                   "$src2, $src1", "$src1, $src2",
5154                   (_.VT (OpNode
5155                            _.RC:$src1,
5156                            (Ctrl.VT (bitconvert(Ctrl.LdFrag addr:$src2)))))>,
5157                   T8PD, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
5158   defm rmb: AVX512_maskable<OpcVar, MRMSrcMem, _, (outs _.RC:$dst),
5159                    (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
5160                    "${src2}"##_.BroadcastStr##", $src1",
5161                    "$src1, ${src2}"##_.BroadcastStr,
5162                    (_.VT (OpNode
5163                             _.RC:$src1,
5164                             (Ctrl.VT (X86VBroadcast
5165                                        (Ctrl.ScalarLdFrag addr:$src2)))))>,
5166                    T8PD, EVEX_4V, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
5167 }
5168
5169 multiclass avx512_permil_vec_common<string OpcodeStr, bits<8> OpcVar,
5170                              AVX512VLVectorVTInfo _, AVX512VLVectorVTInfo Ctrl>{
5171   let Predicates = [HasAVX512] in {
5172     defm Z    : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info512,
5173                                   Ctrl.info512>, EVEX_V512;
5174   }
5175   let Predicates = [HasAVX512, HasVLX] in {
5176     defm Z128 : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info128,
5177                                   Ctrl.info128>, EVEX_V128;
5178     defm Z256 : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info256,
5179                                   Ctrl.info256>, EVEX_V256;
5180   }
5181 }
5182
5183 multiclass avx512_permil<string OpcodeStr, bits<8> OpcImm, bits<8> OpcVar,
5184                          AVX512VLVectorVTInfo _, AVX512VLVectorVTInfo Ctrl>{
5185
5186   defm NAME: avx512_permil_vec_common<OpcodeStr, OpcVar, _, Ctrl>;
5187   defm NAME: avx512_shift_rmi_sizes<OpcImm, MRMSrcReg, MRMSrcMem, OpcodeStr,
5188                                     X86VPermilpi, _>,
5189                     EVEX, AVX512AIi8Base, EVEX_CD8<_.info128.EltSize, CD8VF>;
5190 }
5191
5192 let ExeDomain = SSEPackedSingle in
5193 defm VPERMILPS : avx512_permil<"vpermilps", 0x04, 0x0C, avx512vl_f32_info,
5194                                avx512vl_i32_info>;
5195 let ExeDomain = SSEPackedDouble in
5196 defm VPERMILPD : avx512_permil<"vpermilpd", 0x05, 0x0D, avx512vl_f64_info,
5197                                avx512vl_i64_info>, VEX_W;
5198 //===----------------------------------------------------------------------===//
5199 // AVX-512 - VPSHUFD, VPSHUFLW, VPSHUFHW
5200 //===----------------------------------------------------------------------===//
5201
5202 defm VPSHUFD : avx512_shift_rmi_sizes<0x70, MRMSrcReg, MRMSrcMem, "vpshufd",
5203                              X86PShufd, avx512vl_i32_info>,
5204                              EVEX, AVX512BIi8Base, EVEX_CD8<32, CD8VF>;
5205 defm VPSHUFH : avx512_shift_rmi_w<0x70, MRMSrcReg, MRMSrcMem, "vpshufhw",
5206                                   X86PShufhw>, EVEX, AVX512XSIi8Base;
5207 defm VPSHUFL : avx512_shift_rmi_w<0x70, MRMSrcReg, MRMSrcMem, "vpshuflw",
5208                                   X86PShuflw>, EVEX, AVX512XDIi8Base;
5209
5210 multiclass avx512_pshufb_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5211   let Predicates = [HasBWI] in
5212   defm Z:    avx512_var_shift<opc, OpcodeStr, OpNode, v64i8_info>, EVEX_V512;
5213
5214   let Predicates = [HasVLX, HasBWI] in {
5215   defm Z256: avx512_var_shift<opc, OpcodeStr, OpNode, v32i8x_info>, EVEX_V256;
5216   defm Z128: avx512_var_shift<opc, OpcodeStr, OpNode, v16i8x_info>, EVEX_V128;
5217   }
5218 }
5219
5220 defm VPSHUFB: avx512_pshufb_sizes<0x00, "vpshufb", X86pshufb>;
5221
5222 //===----------------------------------------------------------------------===//
5223 // Move Low to High and High to Low packed FP Instructions
5224 //===----------------------------------------------------------------------===//
5225 def VMOVLHPSZrr : AVX512PSI<0x16, MRMSrcReg, (outs VR128X:$dst),
5226           (ins VR128X:$src1, VR128X:$src2),
5227           "vmovlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
5228           [(set VR128X:$dst, (v4f32 (X86Movlhps VR128X:$src1, VR128X:$src2)))],
5229            IIC_SSE_MOV_LH>, EVEX_4V;
5230 def VMOVHLPSZrr : AVX512PSI<0x12, MRMSrcReg, (outs VR128X:$dst),
5231           (ins VR128X:$src1, VR128X:$src2),
5232           "vmovhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
5233           [(set VR128X:$dst, (v4f32 (X86Movhlps VR128X:$src1, VR128X:$src2)))],
5234           IIC_SSE_MOV_LH>, EVEX_4V;
5235
5236 let Predicates = [HasAVX512] in {
5237   // MOVLHPS patterns
5238   def : Pat<(v4i32 (X86Movlhps VR128X:$src1, VR128X:$src2)),
5239             (VMOVLHPSZrr VR128X:$src1, VR128X:$src2)>;
5240   def : Pat<(v2i64 (X86Movlhps VR128X:$src1, VR128X:$src2)),
5241             (VMOVLHPSZrr (v2i64 VR128X:$src1), VR128X:$src2)>;
5242
5243   // MOVHLPS patterns
5244   def : Pat<(v4i32 (X86Movhlps VR128X:$src1, VR128X:$src2)),
5245             (VMOVHLPSZrr VR128X:$src1, VR128X:$src2)>;
5246 }
5247
5248 //===----------------------------------------------------------------------===//
5249 // VMOVHPS/PD VMOVLPS Instructions
5250 // All patterns was taken from SSS implementation.
5251 //===----------------------------------------------------------------------===//
5252 multiclass avx512_mov_hilo_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
5253                                   X86VectorVTInfo _> {
5254   def rm : AVX512<opc, MRMSrcMem, (outs _.RC:$dst),
5255                   (ins _.RC:$src1, f64mem:$src2),
5256                   !strconcat(OpcodeStr,
5257                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5258                   [(set _.RC:$dst,
5259                      (OpNode _.RC:$src1,
5260                        (_.VT (bitconvert
5261                          (v2f64 (scalar_to_vector (loadf64 addr:$src2)))))))],
5262                   IIC_SSE_MOV_LH>, EVEX_4V;
5263 }
5264
5265 defm VMOVHPSZ128 : avx512_mov_hilo_packed<0x16, "vmovhps", X86Movlhps,
5266                                   v4f32x_info>, EVEX_CD8<32, CD8VT2>, PS;
5267 defm VMOVHPDZ128 : avx512_mov_hilo_packed<0x16, "vmovhpd", X86Movlhpd,
5268                                   v2f64x_info>, EVEX_CD8<64, CD8VT1>, PD, VEX_W;
5269 defm VMOVLPSZ128 : avx512_mov_hilo_packed<0x12, "vmovlps", X86Movlps,
5270                                   v4f32x_info>, EVEX_CD8<32, CD8VT2>, PS;
5271 defm VMOVLPDZ128 : avx512_mov_hilo_packed<0x12, "vmovlpd", X86Movlpd,
5272                                   v2f64x_info>, EVEX_CD8<64, CD8VT1>, PD, VEX_W;
5273
5274 let Predicates = [HasAVX512] in {
5275   // VMOVHPS patterns
5276   def : Pat<(X86Movlhps VR128X:$src1,
5277                (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
5278           (VMOVHPSZ128rm VR128X:$src1, addr:$src2)>;
5279   def : Pat<(X86Movlhps VR128X:$src1,
5280                (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
5281           (VMOVHPSZ128rm VR128X:$src1, addr:$src2)>;
5282   // VMOVHPD patterns
5283   def : Pat<(v2f64 (X86Unpckl VR128X:$src1,
5284                     (scalar_to_vector (loadf64 addr:$src2)))),
5285            (VMOVHPDZ128rm VR128X:$src1, addr:$src2)>;
5286   def : Pat<(v2f64 (X86Unpckl VR128X:$src1,
5287                     (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
5288            (VMOVHPDZ128rm VR128X:$src1, addr:$src2)>;
5289   // VMOVLPS patterns
5290   def : Pat<(v4f32 (X86Movlps VR128X:$src1, (load addr:$src2))),
5291           (VMOVLPSZ128rm VR128X:$src1, addr:$src2)>;
5292   def : Pat<(v4i32 (X86Movlps VR128X:$src1, (load addr:$src2))),
5293           (VMOVLPSZ128rm VR128X:$src1, addr:$src2)>;
5294   // VMOVLPD patterns
5295   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, (load addr:$src2))),
5296           (VMOVLPDZ128rm VR128X:$src1, addr:$src2)>;
5297   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, (load addr:$src2))),
5298           (VMOVLPDZ128rm VR128X:$src1, addr:$src2)>;
5299   def : Pat<(v2f64 (X86Movsd VR128X:$src1,
5300                            (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
5301           (VMOVLPDZ128rm VR128X:$src1, addr:$src2)>;
5302 }
5303
5304 def VMOVHPSZ128mr : AVX512PSI<0x17, MRMDestMem, (outs),
5305                        (ins f64mem:$dst, VR128X:$src),
5306                        "vmovhps\t{$src, $dst|$dst, $src}",
5307                        [(store (f64 (extractelt
5308                                      (X86Unpckh (bc_v2f64 (v4f32 VR128X:$src)),
5309                                                 (bc_v2f64 (v4f32 VR128X:$src))),
5310                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>,
5311                        EVEX, EVEX_CD8<32, CD8VT2>;
5312 def VMOVHPDZ128mr : AVX512PDI<0x17, MRMDestMem, (outs),
5313                        (ins f64mem:$dst, VR128X:$src),
5314                        "vmovhpd\t{$src, $dst|$dst, $src}",
5315                        [(store (f64 (extractelt
5316                                      (v2f64 (X86Unpckh VR128X:$src, VR128X:$src)),
5317                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>,
5318                        EVEX, EVEX_CD8<64, CD8VT1>, VEX_W;
5319 def VMOVLPSZ128mr : AVX512PSI<0x13, MRMDestMem, (outs),
5320                        (ins f64mem:$dst, VR128X:$src),
5321                        "vmovlps\t{$src, $dst|$dst, $src}",
5322                        [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128X:$src)),
5323                                      (iPTR 0))), addr:$dst)],
5324                                      IIC_SSE_MOV_LH>,
5325                        EVEX, EVEX_CD8<32, CD8VT2>;
5326 def VMOVLPDZ128mr : AVX512PDI<0x13, MRMDestMem, (outs),
5327                        (ins f64mem:$dst, VR128X:$src),
5328                        "vmovlpd\t{$src, $dst|$dst, $src}",
5329                        [(store (f64 (extractelt (v2f64 VR128X:$src),
5330                                      (iPTR 0))), addr:$dst)],
5331                                      IIC_SSE_MOV_LH>,
5332                        EVEX, EVEX_CD8<64, CD8VT1>, VEX_W;
5333
5334 let Predicates = [HasAVX512] in {
5335   // VMOVHPD patterns
5336   def : Pat<(store (f64 (extractelt
5337                            (v2f64 (X86VPermilpi VR128X:$src, (i8 1))),
5338                            (iPTR 0))), addr:$dst),
5339            (VMOVHPDZ128mr addr:$dst, VR128X:$src)>;
5340   // VMOVLPS patterns
5341   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128X:$src2)),
5342                    addr:$src1),
5343             (VMOVLPSZ128mr addr:$src1, VR128X:$src2)>;
5344   def : Pat<(store (v4i32 (X86Movlps
5345                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128X:$src2)), addr:$src1),
5346             (VMOVLPSZ128mr addr:$src1, VR128X:$src2)>;
5347   // VMOVLPD patterns
5348   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128X:$src2)),
5349                    addr:$src1),
5350             (VMOVLPDZ128mr addr:$src1, VR128X:$src2)>;
5351   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128X:$src2)),
5352                    addr:$src1),
5353             (VMOVLPDZ128mr addr:$src1, VR128X:$src2)>;
5354 }
5355 //===----------------------------------------------------------------------===//
5356 // FMA - Fused Multiply Operations
5357 //
5358
5359 multiclass avx512_fma3p_213_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5360                                X86VectorVTInfo _, string Suff> {
5361   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
5362   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5363           (ins _.RC:$src2, _.RC:$src3),
5364           OpcodeStr, "$src3, $src2", "$src2, $src3",
5365           (_.VT (OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3)), 1, 1>,
5366          AVX512FMA3Base;
5367
5368   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5369           (ins _.RC:$src2, _.MemOp:$src3),
5370           OpcodeStr, "$src3, $src2", "$src2, $src3",
5371           (_.VT (OpNode _.RC:$src2, _.RC:$src1, (_.LdFrag addr:$src3))), 1, 0>,
5372           AVX512FMA3Base;
5373
5374   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5375             (ins _.RC:$src2, _.ScalarMemOp:$src3),
5376             OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
5377             !strconcat("$src2, ${src3}", _.BroadcastStr ),
5378             (OpNode _.RC:$src2,
5379              _.RC:$src1,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3)))), 1, 0>,
5380             AVX512FMA3Base, EVEX_B;
5381   }
5382
5383   // Additional pattern for folding broadcast nodes in other orders.
5384   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5385                    (OpNode _.RC:$src1, _.RC:$src2,
5386                     (X86VBroadcast (_.ScalarLdFrag addr:$src3))),
5387                    _.RC:$src1)),
5388             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbk) _.RC:$src1,
5389              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5390 }
5391
5392 multiclass avx512_fma3_213_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
5393                                  X86VectorVTInfo _, string Suff> {
5394   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
5395   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5396           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5397           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
5398           (_.VT ( OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3, (i32 imm:$rc))), 1, 1>,
5399           AVX512FMA3Base, EVEX_B, EVEX_RC;
5400 }
5401
5402 multiclass avx512_fma3p_213_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5403                                    SDNode OpNodeRnd, AVX512VLVectorVTInfo _,
5404                                    string Suff> {
5405   let Predicates = [HasAVX512] in {
5406     defm Z      : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info512, Suff>,
5407                   avx512_fma3_213_round<opc, OpcodeStr, OpNodeRnd, _.info512,
5408                       Suff>, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5409   }
5410   let Predicates = [HasVLX, HasAVX512] in {
5411     defm Z256 : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info256, Suff>,
5412                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5413     defm Z128 : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info128, Suff>,
5414                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5415   }
5416 }
5417
5418 multiclass avx512_fma3p_213_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
5419                               SDNode OpNodeRnd > {
5420     defm PS : avx512_fma3p_213_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
5421                                       avx512vl_f32_info, "PS">;
5422     defm PD : avx512_fma3p_213_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
5423                                       avx512vl_f64_info, "PD">, VEX_W;
5424 }
5425
5426 defm VFMADD213    : avx512_fma3p_213_f<0xA8, "vfmadd213", X86Fmadd, X86FmaddRnd>;
5427 defm VFMSUB213    : avx512_fma3p_213_f<0xAA, "vfmsub213", X86Fmsub, X86FmsubRnd>;
5428 defm VFMADDSUB213 : avx512_fma3p_213_f<0xA6, "vfmaddsub213", X86Fmaddsub, X86FmaddsubRnd>;
5429 defm VFMSUBADD213 : avx512_fma3p_213_f<0xA7, "vfmsubadd213", X86Fmsubadd, X86FmsubaddRnd>;
5430 defm VFNMADD213   : avx512_fma3p_213_f<0xAC, "vfnmadd213", X86Fnmadd, X86FnmaddRnd>;
5431 defm VFNMSUB213   : avx512_fma3p_213_f<0xAE, "vfnmsub213", X86Fnmsub, X86FnmsubRnd>;
5432
5433
5434 multiclass avx512_fma3p_231_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5435                                X86VectorVTInfo _, string Suff> {
5436   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
5437   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5438           (ins _.RC:$src2, _.RC:$src3),
5439           OpcodeStr, "$src3, $src2", "$src2, $src3",
5440           (_.VT (OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1)), 1, 1>,
5441          AVX512FMA3Base;
5442
5443   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5444           (ins _.RC:$src2, _.MemOp:$src3),
5445           OpcodeStr, "$src3, $src2", "$src2, $src3",
5446           (_.VT (OpNode _.RC:$src2, (_.LdFrag addr:$src3), _.RC:$src1)), 1, 0>,
5447          AVX512FMA3Base;
5448
5449   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5450          (ins _.RC:$src2, _.ScalarMemOp:$src3),
5451          OpcodeStr, "${src3}"##_.BroadcastStr##", $src2",
5452          "$src2, ${src3}"##_.BroadcastStr,
5453          (_.VT (OpNode _.RC:$src2,
5454                       (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
5455                       _.RC:$src1)), 1, 0>, AVX512FMA3Base, EVEX_B;
5456   }
5457
5458   // Additional patterns for folding broadcast nodes in other orders.
5459   def : Pat<(_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5460                    _.RC:$src2, _.RC:$src1)),
5461             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mb) _.RC:$src1,
5462              _.RC:$src2, addr:$src3)>;
5463   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5464                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5465                     _.RC:$src2, _.RC:$src1),
5466                    _.RC:$src1)),
5467             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbk) _.RC:$src1,
5468              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5469   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5470                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5471                     _.RC:$src2, _.RC:$src1),
5472                    _.ImmAllZerosV)),
5473             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbkz) _.RC:$src1,
5474              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5475 }
5476
5477 multiclass avx512_fma3_231_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
5478                                  X86VectorVTInfo _, string Suff> {
5479   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
5480   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5481           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5482           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
5483           (_.VT ( OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1, (i32 imm:$rc))), 1, 1>,
5484           AVX512FMA3Base, EVEX_B, EVEX_RC;
5485 }
5486
5487 multiclass avx512_fma3p_231_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5488                                    SDNode OpNodeRnd, AVX512VLVectorVTInfo _,
5489                                    string Suff> {
5490   let Predicates = [HasAVX512] in {
5491     defm Z      : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info512, Suff>,
5492                   avx512_fma3_231_round<opc, OpcodeStr, OpNodeRnd, _.info512,
5493                       Suff>, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5494   }
5495   let Predicates = [HasVLX, HasAVX512] in {
5496     defm Z256 : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info256, Suff>,
5497                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5498     defm Z128 : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info128, Suff>,
5499                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5500   }
5501 }
5502
5503 multiclass avx512_fma3p_231_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
5504                               SDNode OpNodeRnd > {
5505     defm PS : avx512_fma3p_231_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
5506                                       avx512vl_f32_info, "PS">;
5507     defm PD : avx512_fma3p_231_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
5508                                       avx512vl_f64_info, "PD">, VEX_W;
5509 }
5510
5511 defm VFMADD231    : avx512_fma3p_231_f<0xB8, "vfmadd231", X86Fmadd, X86FmaddRnd>;
5512 defm VFMSUB231    : avx512_fma3p_231_f<0xBA, "vfmsub231", X86Fmsub, X86FmsubRnd>;
5513 defm VFMADDSUB231 : avx512_fma3p_231_f<0xB6, "vfmaddsub231", X86Fmaddsub, X86FmaddsubRnd>;
5514 defm VFMSUBADD231 : avx512_fma3p_231_f<0xB7, "vfmsubadd231", X86Fmsubadd, X86FmsubaddRnd>;
5515 defm VFNMADD231   : avx512_fma3p_231_f<0xBC, "vfnmadd231", X86Fnmadd, X86FnmaddRnd>;
5516 defm VFNMSUB231   : avx512_fma3p_231_f<0xBE, "vfnmsub231", X86Fnmsub, X86FnmsubRnd>;
5517
5518 multiclass avx512_fma3p_132_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5519                                X86VectorVTInfo _, string Suff> {
5520   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
5521   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5522           (ins _.RC:$src2, _.RC:$src3),
5523           OpcodeStr, "$src3, $src2", "$src2, $src3",
5524           (_.VT (OpNode _.RC:$src1, _.RC:$src3, _.RC:$src2)), 1, 1>,
5525          AVX512FMA3Base;
5526
5527   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5528           (ins _.RC:$src2, _.MemOp:$src3),
5529           OpcodeStr, "$src3, $src2", "$src2, $src3",
5530           (_.VT (OpNode _.RC:$src1, (_.LdFrag addr:$src3), _.RC:$src2)), 1, 0>,
5531          AVX512FMA3Base;
5532
5533   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5534          (ins _.RC:$src2, _.ScalarMemOp:$src3),
5535          OpcodeStr, "${src3}"##_.BroadcastStr##", $src2",
5536          "$src2, ${src3}"##_.BroadcastStr,
5537          (_.VT (OpNode _.RC:$src1,
5538                       (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
5539                       _.RC:$src2)), 1, 0>, AVX512FMA3Base, EVEX_B;
5540   }
5541
5542   // Additional patterns for folding broadcast nodes in other orders.
5543   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5544                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5545                     _.RC:$src1, _.RC:$src2),
5546                    _.RC:$src1)),
5547             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbk) _.RC:$src1,
5548              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5549 }
5550
5551 multiclass avx512_fma3_132_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
5552                                  X86VectorVTInfo _, string Suff> {
5553   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
5554   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5555           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5556           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
5557           (_.VT ( OpNode _.RC:$src1, _.RC:$src3, _.RC:$src2, (i32 imm:$rc))), 1, 1>,
5558           AVX512FMA3Base, EVEX_B, EVEX_RC;
5559 }
5560
5561 multiclass avx512_fma3p_132_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5562                                    SDNode OpNodeRnd, AVX512VLVectorVTInfo _,
5563                                    string Suff> {
5564   let Predicates = [HasAVX512] in {
5565     defm Z      : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info512, Suff>,
5566                   avx512_fma3_132_round<opc, OpcodeStr, OpNodeRnd, _.info512,
5567                       Suff>, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5568   }
5569   let Predicates = [HasVLX, HasAVX512] in {
5570     defm Z256 : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info256, Suff>,
5571                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5572     defm Z128 : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info128, Suff>,
5573                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5574   }
5575 }
5576
5577 multiclass avx512_fma3p_132_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
5578                               SDNode OpNodeRnd > {
5579     defm PS : avx512_fma3p_132_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
5580                                       avx512vl_f32_info, "PS">;
5581     defm PD : avx512_fma3p_132_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
5582                                       avx512vl_f64_info, "PD">, VEX_W;
5583 }
5584
5585 defm VFMADD132    : avx512_fma3p_132_f<0x98, "vfmadd132", X86Fmadd, X86FmaddRnd>;
5586 defm VFMSUB132    : avx512_fma3p_132_f<0x9A, "vfmsub132", X86Fmsub, X86FmsubRnd>;
5587 defm VFMADDSUB132 : avx512_fma3p_132_f<0x96, "vfmaddsub132", X86Fmaddsub, X86FmaddsubRnd>;
5588 defm VFMSUBADD132 : avx512_fma3p_132_f<0x97, "vfmsubadd132", X86Fmsubadd, X86FmsubaddRnd>;
5589 defm VFNMADD132   : avx512_fma3p_132_f<0x9C, "vfnmadd132", X86Fnmadd, X86FnmaddRnd>;
5590 defm VFNMSUB132   : avx512_fma3p_132_f<0x9E, "vfnmsub132", X86Fnmsub, X86FnmsubRnd>;
5591
5592 // Scalar FMA
5593 let Constraints = "$src1 = $dst" in {
5594 multiclass avx512_fma3s_common<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
5595                                dag RHS_VEC_r, dag RHS_VEC_m, dag RHS_VEC_rb,
5596                                                         dag RHS_r, dag RHS_m > {
5597   defm r_Int: AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5598           (ins _.RC:$src2, _.RC:$src3), OpcodeStr,
5599           "$src3, $src2", "$src2, $src3", RHS_VEC_r, 1, 1>, AVX512FMA3Base;
5600
5601   defm m_Int: AVX512_maskable_3src_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5602           (ins _.RC:$src2, _.ScalarMemOp:$src3), OpcodeStr,
5603           "$src3, $src2", "$src2, $src3", RHS_VEC_m, 1, 1>, AVX512FMA3Base;
5604
5605   defm rb_Int: AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5606          (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5607          OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc", RHS_VEC_rb, 1, 1>,
5608                                        AVX512FMA3Base, EVEX_B, EVEX_RC;
5609
5610   let isCodeGenOnly = 1, isCommutable = 1 in {
5611     def r     : AVX512FMA3<opc, MRMSrcReg, (outs _.FRC:$dst),
5612                      (ins _.FRC:$src1, _.FRC:$src2, _.FRC:$src3),
5613                      !strconcat(OpcodeStr,
5614                               "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5615                      [RHS_r]>;
5616     def m     : AVX512FMA3<opc, MRMSrcMem, (outs _.FRC:$dst),
5617                     (ins _.FRC:$src1, _.FRC:$src2, _.ScalarMemOp:$src3),
5618                     !strconcat(OpcodeStr,
5619                                "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5620                     [RHS_m]>;
5621   }// isCodeGenOnly = 1
5622 }
5623 }// Constraints = "$src1 = $dst"
5624
5625 multiclass avx512_fma3s_all<bits<8> opc213, bits<8> opc231, bits<8> opc132,
5626                             string OpcodeStr, SDNode OpNode, SDNode OpNodeRnds1,
5627                             SDNode OpNodeRnds3, X86VectorVTInfo _ , string SUFF> {
5628
5629   defm NAME#213#SUFF#Z: avx512_fma3s_common<opc213, OpcodeStr#"213"#_.Suffix , _ ,
5630                 // Operands for intrinsic are in 123 order to preserve passthu
5631                 // semantics.
5632                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src2, _.RC:$src3, (i32 FROUND_CURRENT))),
5633                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src2,
5634                          (_.VT (scalar_to_vector(_.ScalarLdFrag addr:$src3))), (i32 FROUND_CURRENT))),
5635                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src2, _.RC:$src3,
5636                          (i32 imm:$rc))),
5637                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src1,
5638                          _.FRC:$src3))),
5639                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src1,
5640                          (_.ScalarLdFrag addr:$src3))))>;
5641
5642   defm NAME#231#SUFF#Z: avx512_fma3s_common<opc231, OpcodeStr#"231"#_.Suffix , _ ,
5643                 (_.VT (OpNodeRnds3 _.RC:$src2, _.RC:$src3, _.RC:$src1, (i32 FROUND_CURRENT))),
5644                 (_.VT (OpNodeRnds3 _.RC:$src2,
5645                        (_.VT (scalar_to_vector(_.ScalarLdFrag addr:$src3))),
5646                               _.RC:$src1, (i32 FROUND_CURRENT))),
5647                 (_.VT ( OpNodeRnds3 _.RC:$src2, _.RC:$src3, _.RC:$src1,
5648                                   (i32 imm:$rc))),
5649                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src3,
5650                                           _.FRC:$src1))),
5651                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2,
5652                             (_.ScalarLdFrag addr:$src3), _.FRC:$src1)))>;
5653
5654   defm NAME#132#SUFF#Z: avx512_fma3s_common<opc132, OpcodeStr#"132"#_.Suffix , _ ,
5655                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src3, _.RC:$src2, (i32 FROUND_CURRENT))),
5656                 (_.VT (OpNodeRnds1 _.RC:$src1,
5657                        (_.VT (scalar_to_vector(_.ScalarLdFrag addr:$src3))),
5658                               _.RC:$src2, (i32 FROUND_CURRENT))),
5659                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src3, _.RC:$src2,
5660                          (i32 imm:$rc))),
5661                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src1, _.FRC:$src3,
5662                          _.FRC:$src2))),
5663                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src1,
5664                           (_.ScalarLdFrag addr:$src3), _.FRC:$src2)))>;
5665 }
5666
5667 multiclass avx512_fma3s<bits<8> opc213, bits<8> opc231, bits<8> opc132,
5668                         string OpcodeStr, SDNode OpNode, SDNode OpNodeRnds1,
5669                         SDNode OpNodeRnds3> {
5670   let Predicates = [HasAVX512] in {
5671     defm NAME : avx512_fma3s_all<opc213, opc231, opc132, OpcodeStr, OpNode,
5672                                  OpNodeRnds1, OpNodeRnds3, f32x_info, "SS">,
5673                                  EVEX_CD8<32, CD8VT1>, VEX_LIG;
5674     defm NAME : avx512_fma3s_all<opc213, opc231, opc132, OpcodeStr, OpNode,
5675                                  OpNodeRnds1, OpNodeRnds3, f64x_info, "SD">,
5676                                  EVEX_CD8<64, CD8VT1>, VEX_LIG, VEX_W;
5677   }
5678 }
5679
5680 defm VFMADD  : avx512_fma3s<0xA9, 0xB9, 0x99, "vfmadd", X86Fmadd, X86FmaddRnds1,
5681                             X86FmaddRnds3>;
5682 defm VFMSUB  : avx512_fma3s<0xAB, 0xBB, 0x9B, "vfmsub", X86Fmsub, X86FmsubRnds1,
5683                             X86FmsubRnds3>;
5684 defm VFNMADD : avx512_fma3s<0xAD, 0xBD, 0x9D, "vfnmadd", X86Fnmadd,
5685                             X86FnmaddRnds1, X86FnmaddRnds3>;
5686 defm VFNMSUB : avx512_fma3s<0xAF, 0xBF, 0x9F, "vfnmsub", X86Fnmsub,
5687                             X86FnmsubRnds1, X86FnmsubRnds3>;
5688
5689 //===----------------------------------------------------------------------===//
5690 // AVX-512  Packed Multiply of Unsigned 52-bit Integers and Add the Low 52-bit IFMA
5691 //===----------------------------------------------------------------------===//
5692 let Constraints = "$src1 = $dst" in {
5693 multiclass avx512_pmadd52_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5694                                                             X86VectorVTInfo _> {
5695   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5696           (ins _.RC:$src2, _.RC:$src3),
5697           OpcodeStr, "$src3, $src2", "$src2, $src3",
5698           (_.VT (OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3))>,
5699          AVX512FMA3Base;
5700
5701   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5702           (ins _.RC:$src2, _.MemOp:$src3),
5703           OpcodeStr, "$src3, $src2", "$src2, $src3",
5704           (_.VT (OpNode _.RC:$src1, _.RC:$src2, (_.LdFrag addr:$src3)))>,
5705           AVX512FMA3Base;
5706
5707   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5708             (ins _.RC:$src2, _.ScalarMemOp:$src3),
5709             OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
5710             !strconcat("$src2, ${src3}", _.BroadcastStr ),
5711             (OpNode _.RC:$src1,
5712              _.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))>,
5713             AVX512FMA3Base, EVEX_B;
5714 }
5715 } // Constraints = "$src1 = $dst"
5716
5717 multiclass avx512_pmadd52_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5718                                      AVX512VLVectorVTInfo _> {
5719   let Predicates = [HasIFMA] in {
5720     defm Z      : avx512_pmadd52_rm<opc, OpcodeStr, OpNode, _.info512>,
5721                       EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5722   }
5723   let Predicates = [HasVLX, HasIFMA] in {
5724     defm Z256 : avx512_pmadd52_rm<opc, OpcodeStr, OpNode, _.info256>,
5725                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5726     defm Z128 : avx512_pmadd52_rm<opc, OpcodeStr, OpNode, _.info128>,
5727                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5728   }
5729 }
5730
5731 defm VPMADD52LUQ : avx512_pmadd52_common<0xb4, "vpmadd52luq", x86vpmadd52l,
5732                                   avx512vl_i64_info>, VEX_W;
5733 defm VPMADD52HUQ : avx512_pmadd52_common<0xb5, "vpmadd52huq", x86vpmadd52h,
5734                                   avx512vl_i64_info>, VEX_W;
5735
5736 //===----------------------------------------------------------------------===//
5737 // AVX-512  Scalar convert from sign integer to float/double
5738 //===----------------------------------------------------------------------===//
5739
5740 multiclass avx512_vcvtsi<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
5741                     X86VectorVTInfo DstVT, X86MemOperand x86memop,
5742                     PatFrag ld_frag, string asm> {
5743   let hasSideEffects = 0 in {
5744     def rr : SI<opc, MRMSrcReg, (outs DstVT.FRC:$dst),
5745               (ins DstVT.FRC:$src1, SrcRC:$src),
5746               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
5747               EVEX_4V;
5748     let mayLoad = 1 in
5749       def rm : SI<opc, MRMSrcMem, (outs DstVT.FRC:$dst),
5750               (ins DstVT.FRC:$src1, x86memop:$src),
5751               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
5752               EVEX_4V;
5753   } // hasSideEffects = 0
5754   let isCodeGenOnly = 1 in {
5755     def rr_Int : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst),
5756                   (ins DstVT.RC:$src1, SrcRC:$src2),
5757                   !strconcat(asm,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5758                   [(set DstVT.RC:$dst,
5759                         (OpNode (DstVT.VT DstVT.RC:$src1),
5760                                  SrcRC:$src2,
5761                                  (i32 FROUND_CURRENT)))]>, EVEX_4V;
5762
5763     def rm_Int : SI<opc, MRMSrcMem, (outs DstVT.RC:$dst),
5764                   (ins DstVT.RC:$src1, x86memop:$src2),
5765                   !strconcat(asm,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5766                   [(set DstVT.RC:$dst,
5767                         (OpNode (DstVT.VT DstVT.RC:$src1),
5768                                  (ld_frag addr:$src2),
5769                                  (i32 FROUND_CURRENT)))]>, EVEX_4V;
5770   }//isCodeGenOnly = 1
5771 }
5772
5773 multiclass avx512_vcvtsi_round<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
5774                     X86VectorVTInfo DstVT, string asm> {
5775   def rrb_Int : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst),
5776               (ins DstVT.RC:$src1, SrcRC:$src2, AVX512RC:$rc),
5777               !strconcat(asm,
5778                   "\t{$src2, $rc, $src1, $dst|$dst, $src1, $rc, $src2}"),
5779               [(set DstVT.RC:$dst,
5780                     (OpNode (DstVT.VT DstVT.RC:$src1),
5781                              SrcRC:$src2,
5782                              (i32 imm:$rc)))]>, EVEX_4V, EVEX_B, EVEX_RC;
5783 }
5784
5785 multiclass avx512_vcvtsi_common<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
5786                     X86VectorVTInfo DstVT, X86MemOperand x86memop,
5787                     PatFrag ld_frag, string asm> {
5788   defm NAME : avx512_vcvtsi_round<opc, OpNode, SrcRC, DstVT, asm>,
5789               avx512_vcvtsi<opc, OpNode, SrcRC, DstVT, x86memop, ld_frag, asm>,
5790                         VEX_LIG;
5791 }
5792
5793 let Predicates = [HasAVX512] in {
5794 defm VCVTSI2SSZ  : avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR32,
5795                                  v4f32x_info, i32mem, loadi32, "cvtsi2ss{l}">,
5796                                  XS, EVEX_CD8<32, CD8VT1>;
5797 defm VCVTSI642SSZ: avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR64,
5798                                  v4f32x_info, i64mem, loadi64, "cvtsi2ss{q}">,
5799                                  XS, VEX_W, EVEX_CD8<64, CD8VT1>;
5800 defm VCVTSI2SDZ  : avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR32,
5801                                  v2f64x_info, i32mem, loadi32, "cvtsi2sd{l}">,
5802                                  XD, EVEX_CD8<32, CD8VT1>;
5803 defm VCVTSI642SDZ: avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR64,
5804                                  v2f64x_info, i64mem, loadi64, "cvtsi2sd{q}">,
5805                                  XD, VEX_W, EVEX_CD8<64, CD8VT1>;
5806
5807 def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
5808               (VCVTSI2SSZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5809 def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
5810               (VCVTSI2SDZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5811
5812 def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
5813           (VCVTSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5814 def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
5815           (VCVTSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5816 def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
5817           (VCVTSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5818 def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
5819           (VCVTSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5820
5821 def : Pat<(f32 (sint_to_fp GR32:$src)),
5822           (VCVTSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
5823 def : Pat<(f32 (sint_to_fp GR64:$src)),
5824           (VCVTSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
5825 def : Pat<(f64 (sint_to_fp GR32:$src)),
5826           (VCVTSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
5827 def : Pat<(f64 (sint_to_fp GR64:$src)),
5828           (VCVTSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
5829
5830 defm VCVTUSI2SSZ   : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR32,
5831                                   v4f32x_info, i32mem, loadi32,
5832                                   "cvtusi2ss{l}">, XS, EVEX_CD8<32, CD8VT1>;
5833 defm VCVTUSI642SSZ : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR64,
5834                                   v4f32x_info, i64mem, loadi64, "cvtusi2ss{q}">,
5835                                   XS, VEX_W, EVEX_CD8<64, CD8VT1>;
5836 defm VCVTUSI2SDZ   : avx512_vcvtsi<0x7B, X86UintToFpRnd, GR32, v2f64x_info,
5837                                   i32mem, loadi32, "cvtusi2sd{l}">,
5838                                   XD, VEX_LIG, EVEX_CD8<32, CD8VT1>;
5839 defm VCVTUSI642SDZ : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR64,
5840                                   v2f64x_info, i64mem, loadi64, "cvtusi2sd{q}">,
5841                                   XD, VEX_W, EVEX_CD8<64, CD8VT1>;
5842
5843 def : InstAlias<"vcvtusi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
5844               (VCVTUSI2SSZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5845 def : InstAlias<"vcvtusi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
5846               (VCVTUSI2SDZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5847
5848 def : Pat<(f32 (uint_to_fp (loadi32 addr:$src))),
5849           (VCVTUSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5850 def : Pat<(f32 (uint_to_fp (loadi64 addr:$src))),
5851           (VCVTUSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5852 def : Pat<(f64 (uint_to_fp (loadi32 addr:$src))),
5853           (VCVTUSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5854 def : Pat<(f64 (uint_to_fp (loadi64 addr:$src))),
5855           (VCVTUSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5856
5857 def : Pat<(f32 (uint_to_fp GR32:$src)),
5858           (VCVTUSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
5859 def : Pat<(f32 (uint_to_fp GR64:$src)),
5860           (VCVTUSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
5861 def : Pat<(f64 (uint_to_fp GR32:$src)),
5862           (VCVTUSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
5863 def : Pat<(f64 (uint_to_fp GR64:$src)),
5864           (VCVTUSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
5865 }
5866
5867 //===----------------------------------------------------------------------===//
5868 // AVX-512  Scalar convert from float/double to integer
5869 //===----------------------------------------------------------------------===//
5870 multiclass avx512_cvt_s_int_round<bits<8> opc, X86VectorVTInfo SrcVT ,
5871                                   X86VectorVTInfo DstVT, SDNode OpNode, string asm> {
5872   let Predicates = [HasAVX512] in {
5873     def rr : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst), (ins SrcVT.RC:$src),
5874                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5875                 [(set DstVT.RC:$dst, (OpNode (SrcVT.VT SrcVT.RC:$src),(i32 FROUND_CURRENT)))]>,
5876                 EVEX, VEX_LIG;
5877     def rb : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst), (ins SrcVT.RC:$src, AVX512RC:$rc),
5878                 !strconcat(asm,"\t{$rc, $src, $dst|$dst, $src, $rc}"),
5879                 [(set DstVT.RC:$dst, (OpNode (SrcVT.VT SrcVT.RC:$src),(i32 imm:$rc)))]>,
5880                 EVEX, VEX_LIG, EVEX_B, EVEX_RC;
5881     def rm : SI<opc, MRMSrcMem, (outs DstVT.RC:$dst), (ins SrcVT.ScalarMemOp:$src),
5882                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5883                 [(set DstVT.RC:$dst, (OpNode
5884                       (SrcVT.VT (scalar_to_vector (SrcVT.ScalarLdFrag addr:$src))),
5885                       (i32 FROUND_CURRENT)))]>,
5886                 EVEX, VEX_LIG;
5887   } // Predicates = [HasAVX512]
5888 }
5889
5890 // Convert float/double to signed/unsigned int 32/64
5891 defm VCVTSS2SIZ: avx512_cvt_s_int_round<0x2D, f32x_info, i32x_info,
5892                                    X86cvts2si, "cvtss2si">,
5893                                    XS, EVEX_CD8<32, CD8VT1>;
5894 defm VCVTSS2SI64Z: avx512_cvt_s_int_round<0x2D, f32x_info, i64x_info,
5895                                    X86cvts2si, "cvtss2si">,
5896                                    XS, VEX_W, EVEX_CD8<32, CD8VT1>;
5897 defm VCVTSS2USIZ: avx512_cvt_s_int_round<0x79, f32x_info, i32x_info,
5898                                    X86cvts2usi, "cvtss2usi">,
5899                                    XS, EVEX_CD8<32, CD8VT1>;
5900 defm VCVTSS2USI64Z: avx512_cvt_s_int_round<0x79, f32x_info, i64x_info,
5901                                    X86cvts2usi, "cvtss2usi">, XS, VEX_W,
5902                                    EVEX_CD8<32, CD8VT1>;
5903 defm VCVTSD2SIZ: avx512_cvt_s_int_round<0x2D, f64x_info, i32x_info,
5904                                    X86cvts2si, "cvtsd2si">,
5905                                    XD, EVEX_CD8<64, CD8VT1>;
5906 defm VCVTSD2SI64Z: avx512_cvt_s_int_round<0x2D, f64x_info, i64x_info,
5907                                    X86cvts2si, "cvtsd2si">,
5908                                    XD, VEX_W, EVEX_CD8<64, CD8VT1>;
5909 defm VCVTSD2USIZ:   avx512_cvt_s_int_round<0x79, f64x_info, i32x_info,
5910                                    X86cvts2usi, "cvtsd2usi">,
5911                                    XD, EVEX_CD8<64, CD8VT1>;
5912 defm VCVTSD2USI64Z: avx512_cvt_s_int_round<0x79, f64x_info, i64x_info,
5913                                    X86cvts2usi, "cvtsd2usi">, XD, VEX_W,
5914                                    EVEX_CD8<64, CD8VT1>;
5915
5916 // The SSE version of these instructions are disabled for AVX512.
5917 // Therefore, the SSE intrinsics are mapped to the AVX512 instructions.
5918 let Predicates = [HasAVX512] in {
5919   def : Pat<(i32 (int_x86_sse_cvtss2si (v4f32 VR128X:$src))),
5920             (VCVTSS2SIZrr VR128X:$src)>;
5921   def : Pat<(i32 (int_x86_sse_cvtss2si (sse_load_f32 addr:$src))),
5922             (VCVTSS2SIZrm addr:$src)>;
5923   def : Pat<(i64 (int_x86_sse_cvtss2si64 (v4f32 VR128X:$src))),
5924             (VCVTSS2SI64Zrr VR128X:$src)>;
5925   def : Pat<(i64 (int_x86_sse_cvtss2si64 (sse_load_f32 addr:$src))),
5926             (VCVTSS2SI64Zrm addr:$src)>;
5927   def : Pat<(i32 (int_x86_sse2_cvtsd2si (v2f64 VR128X:$src))),
5928             (VCVTSD2SIZrr VR128X:$src)>;
5929   def : Pat<(i32 (int_x86_sse2_cvtsd2si (sse_load_f64 addr:$src))),
5930             (VCVTSD2SIZrm addr:$src)>;
5931   def : Pat<(i64 (int_x86_sse2_cvtsd2si64 (v2f64 VR128X:$src))),
5932             (VCVTSD2SI64Zrr VR128X:$src)>;
5933   def : Pat<(i64 (int_x86_sse2_cvtsd2si64 (sse_load_f64 addr:$src))),
5934             (VCVTSD2SI64Zrm addr:$src)>;
5935 } // HasAVX512
5936
5937 let Predicates = [HasAVX512] in {
5938   def : Pat<(int_x86_sse_cvtsi2ss VR128X:$src1, GR32:$src2),
5939             (VCVTSI2SSZrr_Int VR128X:$src1, GR32:$src2)>;
5940   def : Pat<(int_x86_sse_cvtsi2ss VR128X:$src1, (loadi32 addr:$src2)),
5941             (VCVTSI2SSZrm_Int VR128X:$src1, addr:$src2)>;
5942   def : Pat<(int_x86_sse_cvtsi642ss VR128X:$src1, GR64:$src2),
5943             (VCVTSI642SSZrr_Int VR128X:$src1, GR64:$src2)>;
5944   def : Pat<(int_x86_sse_cvtsi642ss VR128X:$src1, (loadi64 addr:$src2)),
5945             (VCVTSI642SSZrm_Int VR128X:$src1, addr:$src2)>;
5946   def : Pat<(int_x86_sse2_cvtsi2sd VR128X:$src1, GR32:$src2),
5947             (VCVTSI2SDZrr_Int VR128X:$src1, GR32:$src2)>;
5948   def : Pat<(int_x86_sse2_cvtsi2sd VR128X:$src1, (loadi32 addr:$src2)),
5949             (VCVTSI2SDZrm_Int VR128X:$src1, addr:$src2)>;
5950   def : Pat<(int_x86_sse2_cvtsi642sd VR128X:$src1, GR64:$src2),
5951             (VCVTSI642SDZrr_Int VR128X:$src1, GR64:$src2)>;
5952   def : Pat<(int_x86_sse2_cvtsi642sd VR128X:$src1, (loadi64 addr:$src2)),
5953             (VCVTSI642SDZrm_Int VR128X:$src1, addr:$src2)>;
5954   def : Pat<(int_x86_avx512_cvtusi2sd VR128X:$src1, GR32:$src2),
5955             (VCVTUSI2SDZrr_Int VR128X:$src1, GR32:$src2)>;
5956   def : Pat<(int_x86_avx512_cvtusi2sd VR128X:$src1, (loadi32 addr:$src2)),
5957             (VCVTUSI2SDZrm_Int VR128X:$src1, addr:$src2)>;
5958 } // Predicates = [HasAVX512]
5959
5960 // Patterns used for matching vcvtsi2s{s,d} intrinsic sequences from clang
5961 // which produce unnecessary vmovs{s,d} instructions
5962 let Predicates = [HasAVX512] in {
5963 def : Pat<(v4f32 (X86Movss
5964                    (v4f32 VR128X:$dst),
5965                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR64:$src)))))),
5966           (VCVTSI642SSZrr_Int VR128X:$dst, GR64:$src)>;
5967
5968 def : Pat<(v4f32 (X86Movss
5969                    (v4f32 VR128X:$dst),
5970                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR32:$src)))))),
5971           (VCVTSI2SSZrr_Int VR128X:$dst, GR32:$src)>;
5972
5973 def : Pat<(v2f64 (X86Movsd
5974                    (v2f64 VR128X:$dst),
5975                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR64:$src)))))),
5976           (VCVTSI642SDZrr_Int VR128X:$dst, GR64:$src)>;
5977
5978 def : Pat<(v2f64 (X86Movsd
5979                    (v2f64 VR128X:$dst),
5980                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR32:$src)))))),
5981           (VCVTSI2SDZrr_Int VR128X:$dst, GR32:$src)>;
5982 } // Predicates = [HasAVX512]
5983
5984 // Convert float/double to signed/unsigned int 32/64 with truncation
5985 multiclass avx512_cvt_s_all<bits<8> opc, string asm, X86VectorVTInfo _SrcRC,
5986                             X86VectorVTInfo _DstRC, SDNode OpNode,
5987                             SDNode OpNodeRnd, string aliasStr>{
5988 let Predicates = [HasAVX512] in {
5989   def rr : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
5990               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5991               [(set _DstRC.RC:$dst, (OpNode _SrcRC.FRC:$src))]>, EVEX;
5992   let hasSideEffects = 0 in
5993   def rb : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
5994                 !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
5995                 []>, EVEX, EVEX_B;
5996   def rm : AVX512<opc, MRMSrcMem, (outs _DstRC.RC:$dst), (ins _SrcRC.ScalarMemOp:$src),
5997               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5998               [(set _DstRC.RC:$dst, (OpNode (_SrcRC.ScalarLdFrag addr:$src)))]>,
5999               EVEX;
6000
6001   def : InstAlias<asm # aliasStr # "\t{$src, $dst|$dst, $src}",
6002           (!cast<Instruction>(NAME # "rr") _DstRC.RC:$dst, _SrcRC.FRC:$src), 0>;
6003   def : InstAlias<asm # aliasStr # "\t\t{{sae}, $src, $dst|$dst, $src, {sae}}",
6004           (!cast<Instruction>(NAME # "rb") _DstRC.RC:$dst, _SrcRC.FRC:$src), 0>;
6005   def : InstAlias<asm # aliasStr # "\t{$src, $dst|$dst, $src}",
6006           (!cast<Instruction>(NAME # "rm") _DstRC.RC:$dst,
6007                                           _SrcRC.ScalarMemOp:$src), 0>;
6008
6009   let isCodeGenOnly = 1 in {
6010     def rr_Int : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
6011               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
6012              [(set _DstRC.RC:$dst, (OpNodeRnd (_SrcRC.VT _SrcRC.RC:$src),
6013                                    (i32 FROUND_CURRENT)))]>, EVEX, VEX_LIG;
6014     def rb_Int : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
6015               !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
6016               [(set _DstRC.RC:$dst, (OpNodeRnd (_SrcRC.VT _SrcRC.RC:$src),
6017                                     (i32 FROUND_NO_EXC)))]>,
6018                                     EVEX,VEX_LIG , EVEX_B;
6019     let mayLoad = 1, hasSideEffects = 0 in
6020       def rm_Int : AVX512<opc, MRMSrcMem, (outs _DstRC.RC:$dst),
6021                   (ins _SrcRC.MemOp:$src),
6022                   !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
6023                   []>, EVEX, VEX_LIG;
6024
6025   } // isCodeGenOnly = 1
6026 } //HasAVX512
6027 }
6028
6029
6030 defm VCVTTSS2SIZ: avx512_cvt_s_all<0x2C, "vcvttss2si", f32x_info, i32x_info,
6031                         fp_to_sint, X86cvtts2IntRnd, "{l}">,
6032                         XS, EVEX_CD8<32, CD8VT1>;
6033 defm VCVTTSS2SI64Z: avx512_cvt_s_all<0x2C, "vcvttss2si", f32x_info, i64x_info,
6034                         fp_to_sint, X86cvtts2IntRnd, "{q}">,
6035                         VEX_W, XS, EVEX_CD8<32, CD8VT1>;
6036 defm VCVTTSD2SIZ: avx512_cvt_s_all<0x2C, "vcvttsd2si", f64x_info, i32x_info,
6037                         fp_to_sint, X86cvtts2IntRnd, "{l}">,
6038                         XD, EVEX_CD8<64, CD8VT1>;
6039 defm VCVTTSD2SI64Z: avx512_cvt_s_all<0x2C, "vcvttsd2si", f64x_info, i64x_info,
6040                         fp_to_sint, X86cvtts2IntRnd, "{q}">,
6041                         VEX_W, XD, EVEX_CD8<64, CD8VT1>;
6042
6043 defm VCVTTSS2USIZ: avx512_cvt_s_all<0x78, "vcvttss2usi", f32x_info, i32x_info,
6044                         fp_to_uint, X86cvtts2UIntRnd, "{l}">,
6045                         XS, EVEX_CD8<32, CD8VT1>;
6046 defm VCVTTSS2USI64Z: avx512_cvt_s_all<0x78, "vcvttss2usi", f32x_info, i64x_info,
6047                         fp_to_uint, X86cvtts2UIntRnd, "{q}">,
6048                         XS,VEX_W, EVEX_CD8<32, CD8VT1>;
6049 defm VCVTTSD2USIZ: avx512_cvt_s_all<0x78, "vcvttsd2usi", f64x_info, i32x_info,
6050                         fp_to_uint, X86cvtts2UIntRnd, "{l}">,
6051                         XD, EVEX_CD8<64, CD8VT1>;
6052 defm VCVTTSD2USI64Z: avx512_cvt_s_all<0x78, "vcvttsd2usi", f64x_info, i64x_info,
6053                         fp_to_uint, X86cvtts2UIntRnd, "{q}">,
6054                         XD, VEX_W, EVEX_CD8<64, CD8VT1>;
6055 let Predicates = [HasAVX512] in {
6056   def : Pat<(i32 (int_x86_sse_cvttss2si (v4f32 VR128X:$src))),
6057             (VCVTTSS2SIZrr_Int VR128X:$src)>;
6058   def : Pat<(i32 (int_x86_sse_cvttss2si (sse_load_f32 addr:$src))),
6059             (VCVTTSS2SIZrm_Int addr:$src)>;
6060   def : Pat<(i64 (int_x86_sse_cvttss2si64 (v4f32 VR128X:$src))),
6061             (VCVTTSS2SI64Zrr_Int VR128X:$src)>;
6062   def : Pat<(i64 (int_x86_sse_cvttss2si64 (sse_load_f32 addr:$src))),
6063             (VCVTTSS2SI64Zrm_Int addr:$src)>;
6064   def : Pat<(i32 (int_x86_sse2_cvttsd2si (v2f64 VR128X:$src))),
6065             (VCVTTSD2SIZrr_Int VR128X:$src)>;
6066   def : Pat<(i32 (int_x86_sse2_cvttsd2si (sse_load_f64 addr:$src))),
6067             (VCVTTSD2SIZrm_Int addr:$src)>;
6068   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 (v2f64 VR128X:$src))),
6069             (VCVTTSD2SI64Zrr_Int VR128X:$src)>;
6070   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 (sse_load_f64 addr:$src))),
6071             (VCVTTSD2SI64Zrm_Int addr:$src)>;
6072 } // HasAVX512
6073 //===----------------------------------------------------------------------===//
6074 // AVX-512  Convert form float to double and back
6075 //===----------------------------------------------------------------------===//
6076 multiclass avx512_cvt_fp_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6077                          X86VectorVTInfo _Src, SDNode OpNode> {
6078   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6079                          (ins _.RC:$src1, _Src.RC:$src2), OpcodeStr,
6080                          "$src2, $src1", "$src1, $src2",
6081                          (_.VT (OpNode (_.VT _.RC:$src1),
6082                                        (_Src.VT _Src.RC:$src2),
6083                                        (i32 FROUND_CURRENT)))>,
6084                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2F]>;
6085   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6086                          (ins _Src.RC:$src1, _Src.ScalarMemOp:$src2), OpcodeStr,
6087                          "$src2, $src1", "$src1, $src2",
6088                          (_.VT (OpNode (_.VT _.RC:$src1),
6089                                   (_Src.VT (scalar_to_vector
6090                                             (_Src.ScalarLdFrag addr:$src2))),
6091                                   (i32 FROUND_CURRENT)))>,
6092                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
6093 }
6094
6095 // Scalar Coversion with SAE - suppress all exceptions
6096 multiclass avx512_cvt_fp_sae_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6097                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6098   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6099                         (ins _.RC:$src1, _Src.RC:$src2), OpcodeStr,
6100                         "{sae}, $src2, $src1", "$src1, $src2, {sae}",
6101                         (_.VT (OpNodeRnd (_.VT _.RC:$src1),
6102                                          (_Src.VT _Src.RC:$src2),
6103                                          (i32 FROUND_NO_EXC)))>,
6104                         EVEX_4V, VEX_LIG, EVEX_B;
6105 }
6106
6107 // Scalar Conversion with rounding control (RC)
6108 multiclass avx512_cvt_fp_rc_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6109                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6110   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6111                         (ins _.RC:$src1, _Src.RC:$src2, AVX512RC:$rc), OpcodeStr,
6112                         "$rc, $src2, $src1", "$src1, $src2, $rc",
6113                         (_.VT (OpNodeRnd (_.VT _.RC:$src1),
6114                                          (_Src.VT _Src.RC:$src2), (i32 imm:$rc)))>,
6115                         EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>,
6116                         EVEX_B, EVEX_RC;
6117 }
6118 multiclass avx512_cvt_fp_scalar_sd2ss<bits<8> opc, string OpcodeStr,
6119                                   SDNode OpNodeRnd, X86VectorVTInfo _src,
6120                                                         X86VectorVTInfo _dst> {
6121   let Predicates = [HasAVX512] in {
6122     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6123              avx512_cvt_fp_rc_scalar<opc, OpcodeStr, _dst, _src,
6124                                OpNodeRnd>, VEX_W, EVEX_CD8<64, CD8VT1>, XD;
6125   }
6126 }
6127
6128 multiclass avx512_cvt_fp_scalar_ss2sd<bits<8> opc, string OpcodeStr,
6129                                     SDNode OpNodeRnd, X86VectorVTInfo _src,
6130                                                           X86VectorVTInfo _dst> {
6131   let Predicates = [HasAVX512] in {
6132     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6133              avx512_cvt_fp_sae_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6134              EVEX_CD8<32, CD8VT1>, XS;
6135   }
6136 }
6137 defm VCVTSD2SS : avx512_cvt_fp_scalar_sd2ss<0x5A, "vcvtsd2ss",
6138                                          X86froundRnd, f64x_info, f32x_info>;
6139 defm VCVTSS2SD : avx512_cvt_fp_scalar_ss2sd<0x5A, "vcvtss2sd",
6140                                           X86fpextRnd,f32x_info, f64x_info >;
6141
6142 def : Pat<(f64 (fpextend FR32X:$src)),
6143           (COPY_TO_REGCLASS (VCVTSS2SDZrr (COPY_TO_REGCLASS FR32X:$src, VR128X),
6144                                (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>,
6145           Requires<[HasAVX512]>;
6146 def : Pat<(f64 (fpextend (loadf32 addr:$src))),
6147           (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
6148           Requires<[HasAVX512]>;
6149
6150 def : Pat<(f64 (extloadf32 addr:$src)),
6151       (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
6152       Requires<[HasAVX512, OptForSize]>;
6153
6154 def : Pat<(f64 (extloadf32 addr:$src)),
6155           (COPY_TO_REGCLASS (VCVTSS2SDZrr (v4f32 (IMPLICIT_DEF)),
6156                     (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)), VR128X)>,
6157           Requires<[HasAVX512, OptForSpeed]>;
6158
6159 def : Pat<(f32 (fpround FR64X:$src)),
6160           (COPY_TO_REGCLASS (VCVTSD2SSZrr (COPY_TO_REGCLASS FR64X:$src, VR128X),
6161                     (COPY_TO_REGCLASS FR64X:$src, VR128X)), VR128X)>,
6162            Requires<[HasAVX512]>;
6163
6164 def : Pat<(v4f32 (X86Movss
6165                    (v4f32 VR128X:$dst),
6166                    (v4f32 (scalar_to_vector
6167                      (f32 (fpround (f64 (extractelt VR128X:$src, (iPTR 0))))))))),
6168           (VCVTSD2SSZrr VR128X:$dst, VR128X:$src)>,
6169           Requires<[HasAVX512]>;
6170
6171 def : Pat<(v2f64 (X86Movsd
6172                    (v2f64 VR128X:$dst),
6173                    (v2f64 (scalar_to_vector
6174                      (f64 (fpextend (f32 (extractelt VR128X:$src, (iPTR 0))))))))),
6175           (VCVTSS2SDZrr VR128X:$dst, VR128X:$src)>,
6176           Requires<[HasAVX512]>;
6177
6178 //===----------------------------------------------------------------------===//
6179 // AVX-512  Vector convert from signed/unsigned integer to float/double
6180 //          and from float/double to signed/unsigned integer
6181 //===----------------------------------------------------------------------===//
6182
6183 multiclass avx512_vcvt_fp<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6184                          X86VectorVTInfo _Src, SDNode OpNode,
6185                          string Broadcast = _.BroadcastStr,
6186                          string Alias = "", X86MemOperand MemOp = _Src.MemOp> {
6187
6188   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6189                          (ins _Src.RC:$src), OpcodeStr, "$src", "$src",
6190                          (_.VT (OpNode (_Src.VT _Src.RC:$src)))>, EVEX;
6191
6192   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6193                          (ins MemOp:$src), OpcodeStr#Alias, "$src", "$src",
6194                          (_.VT (OpNode (_Src.VT
6195                              (bitconvert (_Src.LdFrag addr:$src)))))>, EVEX;
6196
6197   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6198                          (ins _Src.ScalarMemOp:$src), OpcodeStr,
6199                          "${src}"##Broadcast, "${src}"##Broadcast,
6200                          (_.VT (OpNode (_Src.VT
6201                                   (X86VBroadcast (_Src.ScalarLdFrag addr:$src)))
6202                             ))>, EVEX, EVEX_B;
6203 }
6204 // Coversion with SAE - suppress all exceptions
6205 multiclass avx512_vcvt_fp_sae<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6206                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6207   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6208                         (ins _Src.RC:$src), OpcodeStr,
6209                         "{sae}, $src", "$src, {sae}",
6210                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src),
6211                                (i32 FROUND_NO_EXC)))>,
6212                         EVEX, EVEX_B;
6213 }
6214
6215 // Conversion with rounding control (RC)
6216 multiclass avx512_vcvt_fp_rc<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6217                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6218   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6219                         (ins _Src.RC:$src, AVX512RC:$rc), OpcodeStr,
6220                         "$rc, $src", "$src, $rc",
6221                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src), (i32 imm:$rc)))>,
6222                         EVEX, EVEX_B, EVEX_RC;
6223 }
6224
6225 // Extend Float to Double
6226 multiclass avx512_cvtps2pd<bits<8> opc, string OpcodeStr> {
6227   let Predicates = [HasAVX512] in {
6228     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8f32x_info, fpextend>,
6229              avx512_vcvt_fp_sae<opc, OpcodeStr, v8f64_info, v8f32x_info,
6230                                 X86vfpextRnd>, EVEX_V512;
6231   }
6232   let Predicates = [HasVLX] in {
6233     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4f32x_info,
6234                                X86vfpext, "{1to2}", "", f64mem>, EVEX_V128;
6235     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4f32x_info, fpextend>,
6236                                      EVEX_V256;
6237   }
6238 }
6239
6240 // Truncate Double to Float
6241 multiclass avx512_cvtpd2ps<bits<8> opc, string OpcodeStr> {
6242   let Predicates = [HasAVX512] in {
6243     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8f64_info, fpround>,
6244              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8f64_info,
6245                                X86vfproundRnd>, EVEX_V512;
6246   }
6247   let Predicates = [HasVLX] in {
6248     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2f64x_info,
6249                                X86vfpround, "{1to2}", "{x}">, EVEX_V128;
6250     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4f64x_info, fpround,
6251                                "{1to4}", "{y}">, EVEX_V256;
6252
6253     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6254                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6255     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6256                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, f128mem:$src), 0>;
6257     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6258                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6259     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6260                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, f256mem:$src), 0>;
6261   }
6262 }
6263
6264 defm VCVTPD2PS : avx512_cvtpd2ps<0x5A, "vcvtpd2ps">,
6265                                   VEX_W, PD, EVEX_CD8<64, CD8VF>;
6266 defm VCVTPS2PD : avx512_cvtps2pd<0x5A, "vcvtps2pd">,
6267                                   PS, EVEX_CD8<32, CD8VH>;
6268
6269 def : Pat<(v8f64 (extloadv8f32 addr:$src)),
6270             (VCVTPS2PDZrm addr:$src)>;
6271
6272 let Predicates = [HasVLX] in {
6273   let AddedComplexity = 15 in
6274   def : Pat<(X86vzmovl (v2f64 (bitconvert
6275                                (v4f32 (X86vfpround (v2f64 VR128X:$src)))))),
6276             (VCVTPD2PSZ128rr VR128X:$src)>;
6277   def : Pat<(v2f64 (extloadv2f32 addr:$src)),
6278               (VCVTPS2PDZ128rm addr:$src)>;
6279   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
6280               (VCVTPS2PDZ256rm addr:$src)>;
6281 }
6282
6283 // Convert Signed/Unsigned Doubleword to Double
6284 multiclass avx512_cvtdq2pd<bits<8> opc, string OpcodeStr, SDNode OpNode,
6285                            SDNode OpNode128> {
6286   // No rounding in this op
6287   let Predicates = [HasAVX512] in
6288     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i32x_info, OpNode>,
6289                                      EVEX_V512;
6290
6291   let Predicates = [HasVLX] in {
6292     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4i32x_info,
6293                                      OpNode128, "{1to2}", "", i64mem>, EVEX_V128;
6294     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i32x_info, OpNode>,
6295                                      EVEX_V256;
6296   }
6297 }
6298
6299 // Convert Signed/Unsigned Doubleword to Float
6300 multiclass avx512_cvtdq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
6301                            SDNode OpNodeRnd> {
6302   let Predicates = [HasAVX512] in
6303     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16f32_info, v16i32_info, OpNode>,
6304              avx512_vcvt_fp_rc<opc, OpcodeStr, v16f32_info, v16i32_info,
6305                                OpNodeRnd>, EVEX_V512;
6306
6307   let Predicates = [HasVLX] in {
6308     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i32x_info, OpNode>,
6309                                      EVEX_V128;
6310     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i32x_info, OpNode>,
6311                                      EVEX_V256;
6312   }
6313 }
6314
6315 // Convert Float to Signed/Unsigned Doubleword with truncation
6316 multiclass avx512_cvttps2dq<bits<8> opc, string OpcodeStr,
6317                                   SDNode OpNode, SDNode OpNodeRnd> {
6318   let Predicates = [HasAVX512] in {
6319     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
6320              avx512_vcvt_fp_sae<opc, OpcodeStr, v16i32_info, v16f32_info,
6321                                 OpNodeRnd>, EVEX_V512;
6322   }
6323   let Predicates = [HasVLX] in {
6324     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
6325                                      EVEX_V128;
6326     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
6327                                      EVEX_V256;
6328   }
6329 }
6330
6331 // Convert Float to Signed/Unsigned Doubleword
6332 multiclass avx512_cvtps2dq<bits<8> opc, string OpcodeStr,
6333                                   SDNode OpNode, SDNode OpNodeRnd> {
6334   let Predicates = [HasAVX512] in {
6335     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
6336              avx512_vcvt_fp_rc<opc, OpcodeStr, v16i32_info, v16f32_info,
6337                                 OpNodeRnd>, EVEX_V512;
6338   }
6339   let Predicates = [HasVLX] in {
6340     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
6341                                      EVEX_V128;
6342     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
6343                                      EVEX_V256;
6344   }
6345 }
6346
6347 // Convert Double to Signed/Unsigned Doubleword with truncation
6348 multiclass avx512_cvttpd2dq<bits<8> opc, string OpcodeStr, SDNode OpNode,
6349                             SDNode OpNode128, SDNode OpNodeRnd> {
6350   let Predicates = [HasAVX512] in {
6351     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
6352              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i32x_info, v8f64_info,
6353                                 OpNodeRnd>, EVEX_V512;
6354   }
6355   let Predicates = [HasVLX] in {
6356     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6357     // memory forms of these instructions in Asm Parser. They have the same
6358     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6359     // due to the same reason.
6360     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info,
6361                                OpNode128, "{1to2}", "{x}">, EVEX_V128;
6362     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
6363                                "{1to4}", "{y}">, EVEX_V256;
6364
6365     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6366                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6367     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6368                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, i128mem:$src), 0>;
6369     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6370                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6371     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6372                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, i256mem:$src), 0>;
6373   }
6374 }
6375
6376 // Convert Double to Signed/Unsigned Doubleword
6377 multiclass avx512_cvtpd2dq<bits<8> opc, string OpcodeStr,
6378                                   SDNode OpNode, SDNode OpNodeRnd> {
6379   let Predicates = [HasAVX512] in {
6380     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
6381              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i32x_info, v8f64_info,
6382                                OpNodeRnd>, EVEX_V512;
6383   }
6384   let Predicates = [HasVLX] in {
6385     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6386     // memory forms of these instructions in Asm Parcer. They have the same
6387     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6388     // due to the same reason.
6389     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info, OpNode,
6390                                "{1to2}", "{x}">, EVEX_V128;
6391     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
6392                                "{1to4}", "{y}">, EVEX_V256;
6393
6394     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6395                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6396     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6397                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, f128mem:$src), 0>;
6398     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6399                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6400     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6401                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, f256mem:$src), 0>;
6402   }
6403 }
6404
6405 // Convert Double to Signed/Unsigned Quardword
6406 multiclass avx512_cvtpd2qq<bits<8> opc, string OpcodeStr,
6407                                   SDNode OpNode, SDNode OpNodeRnd> {
6408   let Predicates = [HasDQI] in {
6409     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
6410              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f64_info,
6411                                OpNodeRnd>, EVEX_V512;
6412   }
6413   let Predicates = [HasDQI, HasVLX] in {
6414     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
6415                                EVEX_V128;
6416     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
6417                                EVEX_V256;
6418   }
6419 }
6420
6421 // Convert Double to Signed/Unsigned Quardword with truncation
6422 multiclass avx512_cvttpd2qq<bits<8> opc, string OpcodeStr,
6423                                   SDNode OpNode, SDNode OpNodeRnd> {
6424   let Predicates = [HasDQI] in {
6425     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
6426              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f64_info,
6427                                OpNodeRnd>, EVEX_V512;
6428   }
6429   let Predicates = [HasDQI, HasVLX] in {
6430     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
6431                                EVEX_V128;
6432     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
6433                                EVEX_V256;
6434   }
6435 }
6436
6437 // Convert Signed/Unsigned Quardword to Double
6438 multiclass avx512_cvtqq2pd<bits<8> opc, string OpcodeStr,
6439                                   SDNode OpNode, SDNode OpNodeRnd> {
6440   let Predicates = [HasDQI] in {
6441     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i64_info, OpNode>,
6442              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f64_info, v8i64_info,
6443                                OpNodeRnd>, EVEX_V512;
6444   }
6445   let Predicates = [HasDQI, HasVLX] in {
6446     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v2i64x_info, OpNode>,
6447                                EVEX_V128;
6448     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i64x_info, OpNode>,
6449                                EVEX_V256;
6450   }
6451 }
6452
6453 // Convert Float to Signed/Unsigned Quardword
6454 multiclass avx512_cvtps2qq<bits<8> opc, string OpcodeStr,
6455                                   SDNode OpNode, SDNode OpNodeRnd> {
6456   let Predicates = [HasDQI] in {
6457     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
6458              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f32x_info,
6459                                OpNodeRnd>, EVEX_V512;
6460   }
6461   let Predicates = [HasDQI, HasVLX] in {
6462     // Explicitly specified broadcast string, since we take only 2 elements
6463     // from v4f32x_info source
6464     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode,
6465                                "{1to2}", "", f64mem>, EVEX_V128;
6466     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
6467                                EVEX_V256;
6468   }
6469 }
6470
6471 // Convert Float to Signed/Unsigned Quardword with truncation
6472 multiclass avx512_cvttps2qq<bits<8> opc, string OpcodeStr, SDNode OpNode,
6473                             SDNode OpNode128, SDNode OpNodeRnd> {
6474   let Predicates = [HasDQI] in {
6475     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
6476              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f32x_info,
6477                                OpNodeRnd>, EVEX_V512;
6478   }
6479   let Predicates = [HasDQI, HasVLX] in {
6480     // Explicitly specified broadcast string, since we take only 2 elements
6481     // from v4f32x_info source
6482     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode128,
6483                                "{1to2}", "", f64mem>, EVEX_V128;
6484     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
6485                                EVEX_V256;
6486   }
6487 }
6488
6489 // Convert Signed/Unsigned Quardword to Float
6490 multiclass avx512_cvtqq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
6491                                   SDNode OpNode128, SDNode OpNodeRnd> {
6492   let Predicates = [HasDQI] in {
6493     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i64_info, OpNode>,
6494              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8i64_info,
6495                                OpNodeRnd>, EVEX_V512;
6496   }
6497   let Predicates = [HasDQI, HasVLX] in {
6498     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6499     // memory forms of these instructions in Asm Parcer. They have the same
6500     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6501     // due to the same reason.
6502     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2i64x_info, OpNode128,
6503                                "{1to2}", "{x}">, EVEX_V128;
6504     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i64x_info, OpNode,
6505                                "{1to4}", "{y}">, EVEX_V256;
6506
6507     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6508                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6509     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6510                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, i128mem:$src), 0>;
6511     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6512                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6513     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6514                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, i256mem:$src), 0>;
6515   }
6516 }
6517
6518 defm VCVTDQ2PD : avx512_cvtdq2pd<0xE6, "vcvtdq2pd", sint_to_fp, X86VSintToFP>,
6519                                 XS, EVEX_CD8<32, CD8VH>;
6520
6521 defm VCVTDQ2PS : avx512_cvtdq2ps<0x5B, "vcvtdq2ps", sint_to_fp,
6522                                 X86VSintToFpRnd>,
6523                                 PS, EVEX_CD8<32, CD8VF>;
6524
6525 defm VCVTTPS2DQ : avx512_cvttps2dq<0x5B, "vcvttps2dq", fp_to_sint,
6526                                 X86cvttp2siRnd>,
6527                                 XS, EVEX_CD8<32, CD8VF>;
6528
6529 defm VCVTTPD2DQ : avx512_cvttpd2dq<0xE6, "vcvttpd2dq", fp_to_sint, X86cvttp2si,
6530                                  X86cvttp2siRnd>,
6531                                  PD, VEX_W, EVEX_CD8<64, CD8VF>;
6532
6533 defm VCVTTPS2UDQ : avx512_cvttps2dq<0x78, "vcvttps2udq", fp_to_uint,
6534                                  X86cvttp2uiRnd>, PS,
6535                                  EVEX_CD8<32, CD8VF>;
6536
6537 defm VCVTTPD2UDQ : avx512_cvttpd2dq<0x78, "vcvttpd2udq", fp_to_uint,
6538                                  X86cvttp2ui, X86cvttp2uiRnd>, PS, VEX_W,
6539                                  EVEX_CD8<64, CD8VF>;
6540
6541 defm VCVTUDQ2PD : avx512_cvtdq2pd<0x7A, "vcvtudq2pd", uint_to_fp, X86VUintToFP>,
6542                                  XS, EVEX_CD8<32, CD8VH>;
6543
6544 defm VCVTUDQ2PS : avx512_cvtdq2ps<0x7A, "vcvtudq2ps", uint_to_fp,
6545                                  X86VUintToFpRnd>, XD,
6546                                  EVEX_CD8<32, CD8VF>;
6547
6548 defm VCVTPS2DQ : avx512_cvtps2dq<0x5B, "vcvtps2dq", X86cvtp2Int,
6549                                  X86cvtp2IntRnd>, PD, EVEX_CD8<32, CD8VF>;
6550
6551 defm VCVTPD2DQ : avx512_cvtpd2dq<0xE6, "vcvtpd2dq", X86cvtp2Int,
6552                                  X86cvtp2IntRnd>, XD, VEX_W,
6553                                  EVEX_CD8<64, CD8VF>;
6554
6555 defm VCVTPS2UDQ : avx512_cvtps2dq<0x79, "vcvtps2udq", X86cvtp2UInt,
6556                                  X86cvtp2UIntRnd>,
6557                                  PS, EVEX_CD8<32, CD8VF>;
6558 defm VCVTPD2UDQ : avx512_cvtpd2dq<0x79, "vcvtpd2udq", X86cvtp2UInt,
6559                                  X86cvtp2UIntRnd>, VEX_W,
6560                                  PS, EVEX_CD8<64, CD8VF>;
6561
6562 defm VCVTPD2QQ : avx512_cvtpd2qq<0x7B, "vcvtpd2qq", X86cvtp2Int,
6563                                  X86cvtp2IntRnd>, VEX_W,
6564                                  PD, EVEX_CD8<64, CD8VF>;
6565
6566 defm VCVTPS2QQ : avx512_cvtps2qq<0x7B, "vcvtps2qq", X86cvtp2Int,
6567                                  X86cvtp2IntRnd>, PD, EVEX_CD8<32, CD8VH>;
6568
6569 defm VCVTPD2UQQ : avx512_cvtpd2qq<0x79, "vcvtpd2uqq", X86cvtp2UInt,
6570                                  X86cvtp2UIntRnd>, VEX_W,
6571                                  PD, EVEX_CD8<64, CD8VF>;
6572
6573 defm VCVTPS2UQQ : avx512_cvtps2qq<0x79, "vcvtps2uqq", X86cvtp2UInt,
6574                                  X86cvtp2UIntRnd>, PD, EVEX_CD8<32, CD8VH>;
6575
6576 defm VCVTTPD2QQ : avx512_cvttpd2qq<0x7A, "vcvttpd2qq", fp_to_sint,
6577                                  X86cvttp2siRnd>, VEX_W,
6578                                  PD, EVEX_CD8<64, CD8VF>;
6579
6580 defm VCVTTPS2QQ : avx512_cvttps2qq<0x7A, "vcvttps2qq", fp_to_sint, X86cvttp2si,
6581                                  X86cvttp2siRnd>, PD, EVEX_CD8<32, CD8VH>;
6582
6583 defm VCVTTPD2UQQ : avx512_cvttpd2qq<0x78, "vcvttpd2uqq", fp_to_uint,
6584                                  X86cvttp2uiRnd>, VEX_W,
6585                                  PD, EVEX_CD8<64, CD8VF>;
6586
6587 defm VCVTTPS2UQQ : avx512_cvttps2qq<0x78, "vcvttps2uqq", fp_to_uint, X86cvttp2ui,
6588                                  X86cvttp2uiRnd>, PD, EVEX_CD8<32, CD8VH>;
6589
6590 defm VCVTQQ2PD : avx512_cvtqq2pd<0xE6, "vcvtqq2pd", sint_to_fp,
6591                             X86VSintToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
6592
6593 defm VCVTUQQ2PD : avx512_cvtqq2pd<0x7A, "vcvtuqq2pd", uint_to_fp,
6594                             X86VUintToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
6595
6596 defm VCVTQQ2PS : avx512_cvtqq2ps<0x5B, "vcvtqq2ps", sint_to_fp, X86VSintToFP,
6597                             X86VSintToFpRnd>, VEX_W, PS, EVEX_CD8<64, CD8VF>;
6598
6599 defm VCVTUQQ2PS : avx512_cvtqq2ps<0x7A, "vcvtuqq2ps", uint_to_fp, X86VUintToFP,
6600                             X86VUintToFpRnd>, VEX_W, XD, EVEX_CD8<64, CD8VF>;
6601
6602 let Predicates = [HasAVX512, NoVLX] in {
6603 def : Pat<(v8i32 (fp_to_uint (v8f32 VR256X:$src1))),
6604           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
6605            (v16f32 (INSERT_SUBREG (IMPLICIT_DEF),
6606                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6607
6608 def : Pat<(v4i32 (fp_to_uint (v4f32 VR128X:$src1))),
6609           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
6610            (v16f32 (INSERT_SUBREG (IMPLICIT_DEF),
6611                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6612
6613 def : Pat<(v4i32 (fp_to_uint (v4f64 VR256X:$src1))),
6614           (EXTRACT_SUBREG (v8i32 (VCVTTPD2UDQZrr
6615            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6616                                  VR256X:$src1, sub_ymm)))), sub_xmm)>;
6617
6618 def : Pat<(v4i32 (X86cvttp2ui (v2f64 VR128X:$src))),
6619           (EXTRACT_SUBREG (v8i32 (VCVTTPD2UDQZrr
6620            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6621                                  VR128X:$src, sub_xmm)))), sub_xmm)>;
6622
6623 def : Pat<(v8f32 (uint_to_fp (v8i32 VR256X:$src1))),
6624           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
6625            (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
6626                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6627
6628 def : Pat<(v4f32 (uint_to_fp (v4i32 VR128X:$src1))),
6629           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
6630            (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
6631                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6632
6633 def : Pat<(v4f64 (uint_to_fp (v4i32 VR128X:$src1))),
6634           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
6635            (v8i32 (INSERT_SUBREG (IMPLICIT_DEF),
6636                                  VR128X:$src1, sub_xmm)))), sub_ymm)>;
6637
6638 def : Pat<(v2f64 (X86VUintToFP (v4i32 VR128X:$src1))),
6639           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
6640            (v8i32 (INSERT_SUBREG (IMPLICIT_DEF),
6641                                  VR128X:$src1, sub_xmm)))), sub_xmm)>;
6642 }
6643
6644 let Predicates = [HasAVX512, HasVLX] in {
6645   let AddedComplexity = 15 in {
6646     def : Pat<(X86vzmovl (v2i64 (bitconvert
6647                                 (v4i32 (X86cvtp2Int (v2f64 VR128X:$src)))))),
6648               (VCVTPD2DQZ128rr VR128X:$src)>;
6649     def : Pat<(v4i32 (bitconvert (X86vzmovl (v2i64 (bitconvert
6650                                  (v4i32 (X86cvtp2UInt (v2f64 VR128X:$src)))))))),
6651               (VCVTPD2UDQZ128rr VR128X:$src)>;
6652     def : Pat<(X86vzmovl (v2i64 (bitconvert
6653                                 (v4i32 (X86cvttp2si (v2f64 VR128X:$src)))))),
6654               (VCVTTPD2DQZ128rr VR128X:$src)>;
6655     def : Pat<(v4i32 (bitconvert (X86vzmovl (v2i64 (bitconvert
6656                                  (v4i32 (X86cvttp2ui (v2f64 VR128X:$src)))))))),
6657               (VCVTTPD2UDQZ128rr VR128X:$src)>;
6658   }
6659 }
6660
6661 let Predicates = [HasAVX512] in {
6662   def : Pat<(v8f32 (fpround (loadv8f64 addr:$src))),
6663             (VCVTPD2PSZrm addr:$src)>;
6664   def : Pat<(v8f64 (extloadv8f32 addr:$src)),
6665             (VCVTPS2PDZrm addr:$src)>;
6666 }
6667
6668 let Predicates = [HasDQI, HasVLX] in {
6669   let AddedComplexity = 15 in {
6670     def : Pat<(X86vzmovl (v2f64 (bitconvert
6671                                 (v4f32 (X86VSintToFP (v2i64 VR128X:$src)))))),
6672               (VCVTQQ2PSZ128rr VR128X:$src)>;
6673     def : Pat<(X86vzmovl (v2f64 (bitconvert
6674                                 (v4f32 (X86VUintToFP (v2i64 VR128X:$src)))))),
6675               (VCVTUQQ2PSZ128rr VR128X:$src)>;
6676   }
6677 }
6678
6679 let Predicates = [HasDQI, NoVLX] in {
6680 def : Pat<(v2i64 (fp_to_sint (v2f64 VR128X:$src1))),
6681           (EXTRACT_SUBREG (v8i64 (VCVTTPD2QQZrr
6682            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6683                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6684
6685 def : Pat<(v4i64 (fp_to_sint (v4f32 VR128X:$src1))),
6686           (EXTRACT_SUBREG (v8i64 (VCVTTPS2QQZrr
6687            (v8f32 (INSERT_SUBREG (IMPLICIT_DEF),
6688                                   VR128X:$src1, sub_xmm)))), sub_ymm)>;
6689
6690 def : Pat<(v4i64 (fp_to_sint (v4f64 VR256X:$src1))),
6691           (EXTRACT_SUBREG (v8i64 (VCVTTPD2QQZrr
6692            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6693                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6694
6695 def : Pat<(v2i64 (fp_to_uint (v2f64 VR128X:$src1))),
6696           (EXTRACT_SUBREG (v8i64 (VCVTTPD2UQQZrr
6697            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6698                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6699
6700 def : Pat<(v4i64 (fp_to_uint (v4f32 VR128X:$src1))),
6701           (EXTRACT_SUBREG (v8i64 (VCVTTPS2UQQZrr
6702            (v8f32 (INSERT_SUBREG (IMPLICIT_DEF),
6703                                   VR128X:$src1, sub_xmm)))), sub_ymm)>;
6704
6705 def : Pat<(v4i64 (fp_to_uint (v4f64 VR256X:$src1))),
6706           (EXTRACT_SUBREG (v8i64 (VCVTTPD2UQQZrr
6707            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6708                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6709
6710 def : Pat<(v4f32 (sint_to_fp (v4i64 VR256X:$src1))),
6711           (EXTRACT_SUBREG (v8f32 (VCVTQQ2PSZrr
6712            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6713                                   VR256X:$src1, sub_ymm)))), sub_xmm)>;
6714
6715 def : Pat<(v2f64 (sint_to_fp (v2i64 VR128X:$src1))),
6716           (EXTRACT_SUBREG (v8f64 (VCVTQQ2PDZrr
6717            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6718                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6719
6720 def : Pat<(v4f64 (sint_to_fp (v4i64 VR256X:$src1))),
6721           (EXTRACT_SUBREG (v8f64 (VCVTQQ2PDZrr
6722            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6723                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6724
6725 def : Pat<(v4f32 (uint_to_fp (v4i64 VR256X:$src1))),
6726           (EXTRACT_SUBREG (v8f32 (VCVTUQQ2PSZrr
6727            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6728                                   VR256X:$src1, sub_ymm)))), sub_xmm)>;
6729
6730 def : Pat<(v2f64 (uint_to_fp (v2i64 VR128X:$src1))),
6731           (EXTRACT_SUBREG (v8f64 (VCVTUQQ2PDZrr
6732            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6733                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6734
6735 def : Pat<(v4f64 (uint_to_fp (v4i64 VR256X:$src1))),
6736           (EXTRACT_SUBREG (v8f64 (VCVTUQQ2PDZrr
6737            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6738                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6739 }
6740
6741 //===----------------------------------------------------------------------===//
6742 // Half precision conversion instructions
6743 //===----------------------------------------------------------------------===//
6744 multiclass avx512_cvtph2ps<X86VectorVTInfo _dest, X86VectorVTInfo _src,
6745                            X86MemOperand x86memop, PatFrag ld_frag> {
6746   defm rr : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src),
6747                     "vcvtph2ps", "$src", "$src",
6748                    (X86cvtph2ps (_src.VT _src.RC:$src),
6749                                                 (i32 FROUND_CURRENT))>, T8PD;
6750   defm rm : AVX512_maskable<0x13, MRMSrcMem, _dest, (outs _dest.RC:$dst), (ins x86memop:$src),
6751                     "vcvtph2ps", "$src", "$src",
6752                     (X86cvtph2ps (_src.VT (bitconvert (ld_frag addr:$src))),
6753                                      (i32 FROUND_CURRENT))>, T8PD;
6754 }
6755
6756 multiclass avx512_cvtph2ps_sae<X86VectorVTInfo _dest, X86VectorVTInfo _src> {
6757   defm rb : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src),
6758                     "vcvtph2ps", "{sae}, $src", "$src, {sae}",
6759                    (X86cvtph2ps (_src.VT _src.RC:$src),
6760                                                 (i32 FROUND_NO_EXC))>, T8PD, EVEX_B;
6761
6762 }
6763
6764 let Predicates = [HasAVX512] in {
6765   defm VCVTPH2PSZ : avx512_cvtph2ps<v16f32_info, v16i16x_info, f256mem, loadv4i64>,
6766                     avx512_cvtph2ps_sae<v16f32_info, v16i16x_info>,
6767                     EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>;
6768   let Predicates = [HasVLX] in {
6769     defm VCVTPH2PSZ256 : avx512_cvtph2ps<v8f32x_info, v8i16x_info, f128mem,
6770                          loadv2i64>,EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>;
6771     defm VCVTPH2PSZ128 : avx512_cvtph2ps<v4f32x_info, v8i16x_info, f64mem,
6772                          loadv2i64>, EVEX, EVEX_V128, EVEX_CD8<32, CD8VH>;
6773   }
6774 }
6775
6776 multiclass avx512_cvtps2ph<X86VectorVTInfo _dest, X86VectorVTInfo _src,
6777                            X86MemOperand x86memop> {
6778   defm rr : AVX512_maskable<0x1D, MRMDestReg, _dest ,(outs _dest.RC:$dst),
6779                    (ins _src.RC:$src1, i32u8imm:$src2),
6780                    "vcvtps2ph", "$src2, $src1", "$src1, $src2",
6781                    (X86cvtps2ph (_src.VT _src.RC:$src1),
6782                                 (i32 imm:$src2)),
6783                    NoItinerary, 0, 0, X86select>, AVX512AIi8Base;
6784   def mr : AVX512AIi8<0x1D, MRMDestMem, (outs),
6785              (ins x86memop:$dst, _src.RC:$src1, i32u8imm:$src2),
6786              "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6787              [(store (_dest.VT (X86cvtps2ph (_src.VT _src.RC:$src1),
6788                                      (i32 imm:$src2))),
6789                                      addr:$dst)]>;
6790   let hasSideEffects = 0, mayStore = 1 in
6791   def mrk : AVX512AIi8<0x1D, MRMDestMem, (outs),
6792              (ins x86memop:$dst, _dest.KRCWM:$mask, _src.RC:$src1, i32u8imm:$src2),
6793              "vcvtps2ph\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
6794               []>, EVEX_K;
6795 }
6796 multiclass avx512_cvtps2ph_sae<X86VectorVTInfo _dest, X86VectorVTInfo _src> {
6797   let hasSideEffects = 0 in
6798   defm rb : AVX512_maskable_in_asm<0x1D, MRMDestReg, _dest,
6799                    (outs _dest.RC:$dst),
6800                    (ins _src.RC:$src1, i32u8imm:$src2),
6801                    "vcvtps2ph", "$src2, {sae}, $src1", "$src1, {sae}, $src2",
6802                    []>, EVEX_B, AVX512AIi8Base;
6803 }
6804 let Predicates = [HasAVX512] in {
6805   defm VCVTPS2PHZ : avx512_cvtps2ph<v16i16x_info, v16f32_info, f256mem>,
6806                     avx512_cvtps2ph_sae<v16i16x_info, v16f32_info>,
6807                       EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>;
6808   let Predicates = [HasVLX] in {
6809     defm VCVTPS2PHZ256 : avx512_cvtps2ph<v8i16x_info, v8f32x_info, f128mem>,
6810                         EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>;
6811     defm VCVTPS2PHZ128 : avx512_cvtps2ph<v8i16x_info, v4f32x_info, f128mem>,
6812                         EVEX, EVEX_V128, EVEX_CD8<32, CD8VH>;
6813   }
6814 }
6815
6816 // Patterns for matching conversions from float to half-float and vice versa.
6817 let Predicates = [HasVLX] in {
6818   // Use MXCSR.RC for rounding instead of explicitly specifying the default
6819   // rounding mode (Nearest-Even, encoded as 0). Both are equivalent in the
6820   // configurations we support (the default). However, falling back to MXCSR is
6821   // more consistent with other instructions, which are always controlled by it.
6822   // It's encoded as 0b100.
6823   def : Pat<(fp_to_f16 FR32X:$src),
6824             (i16 (EXTRACT_SUBREG (VMOVPDI2DIZrr (VCVTPS2PHZ128rr
6825               (COPY_TO_REGCLASS FR32X:$src, VR128X), 4)), sub_16bit))>;
6826
6827   def : Pat<(f16_to_fp GR16:$src),
6828             (f32 (COPY_TO_REGCLASS (VCVTPH2PSZ128rr
6829               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128X)), FR32X)) >;
6830
6831   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32X:$src))),
6832             (f32 (COPY_TO_REGCLASS (VCVTPH2PSZ128rr
6833               (VCVTPS2PHZ128rr (COPY_TO_REGCLASS FR32X:$src, VR128X), 4)), FR32X)) >;
6834 }
6835
6836 // Patterns for matching float to half-float conversion when AVX512 is supported
6837 // but F16C isn't. In that case we have to use 512-bit vectors.
6838 let Predicates = [HasAVX512, NoVLX, NoF16C] in {
6839   def : Pat<(fp_to_f16 FR32X:$src),
6840             (i16 (EXTRACT_SUBREG
6841                   (VMOVPDI2DIZrr
6842                    (v8i16 (EXTRACT_SUBREG
6843                     (VCVTPS2PHZrr
6844                      (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
6845                       (v4f32 (COPY_TO_REGCLASS FR32X:$src, VR128X)),
6846                       sub_xmm), 4), sub_xmm))), sub_16bit))>;
6847
6848   def : Pat<(f16_to_fp GR16:$src),
6849             (f32 (COPY_TO_REGCLASS
6850                   (v4f32 (EXTRACT_SUBREG
6851                    (VCVTPH2PSZrr
6852                     (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)),
6853                      (v8i16 (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128X)),
6854                      sub_xmm)), sub_xmm)), FR32X))>;
6855
6856   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32X:$src))),
6857             (f32 (COPY_TO_REGCLASS
6858                   (v4f32 (EXTRACT_SUBREG
6859                           (VCVTPH2PSZrr
6860                            (VCVTPS2PHZrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
6861                             (v4f32 (COPY_TO_REGCLASS FR32X:$src, VR128X)),
6862                             sub_xmm), 4)), sub_xmm)), FR32X))>;
6863 }
6864
6865 //  Unordered/Ordered scalar fp compare with Sea and set EFLAGS
6866 multiclass avx512_ord_cmp_sae<bits<8> opc, X86VectorVTInfo _,
6867                             string OpcodeStr> {
6868   def rb: AVX512<opc, MRMSrcReg, (outs), (ins _.RC:$src1, _.RC:$src2),
6869                  !strconcat(OpcodeStr, "\t{{sae}, $src2, $src1|$src1, $src2, {sae}}"),
6870                  [], IIC_SSE_COMIS_RR>, EVEX, EVEX_B, VEX_LIG, EVEX_V128,
6871                  Sched<[WriteFAdd]>;
6872 }
6873
6874 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
6875   defm VUCOMISSZ : avx512_ord_cmp_sae<0x2E, v4f32x_info, "vucomiss">,
6876                                    AVX512PSIi8Base, EVEX_CD8<32, CD8VT1>;
6877   defm VUCOMISDZ : avx512_ord_cmp_sae<0x2E, v2f64x_info, "vucomisd">,
6878                                    AVX512PDIi8Base, VEX_W, EVEX_CD8<64, CD8VT1>;
6879   defm VCOMISSZ : avx512_ord_cmp_sae<0x2F, v4f32x_info, "vcomiss">,
6880                                    AVX512PSIi8Base, EVEX_CD8<32, CD8VT1>;
6881   defm VCOMISDZ : avx512_ord_cmp_sae<0x2F, v2f64x_info, "vcomisd">,
6882                                    AVX512PDIi8Base, VEX_W, EVEX_CD8<64, CD8VT1>;
6883 }
6884
6885 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
6886   defm VUCOMISSZ : sse12_ord_cmp<0x2E, FR32X, X86cmp, f32, f32mem, loadf32,
6887                                  "ucomiss">, PS, EVEX, VEX_LIG,
6888                                  EVEX_CD8<32, CD8VT1>;
6889   defm VUCOMISDZ : sse12_ord_cmp<0x2E, FR64X, X86cmp, f64, f64mem, loadf64,
6890                                   "ucomisd">, PD, EVEX,
6891                                   VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6892   let Pattern = []<dag> in {
6893     defm VCOMISSZ  : sse12_ord_cmp<0x2F, FR32X, undef, f32, f32mem, loadf32,
6894                                    "comiss">, PS, EVEX, VEX_LIG,
6895                                    EVEX_CD8<32, CD8VT1>;
6896     defm VCOMISDZ  : sse12_ord_cmp<0x2F, FR64X, undef, f64, f64mem, loadf64,
6897                                    "comisd">, PD, EVEX,
6898                                     VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6899   }
6900   let isCodeGenOnly = 1 in {
6901     defm Int_VUCOMISSZ  : sse12_ord_cmp_int<0x2E, VR128X, X86ucomi, v4f32, ssmem,
6902                               sse_load_f32, "ucomiss">, PS, EVEX, VEX_LIG,
6903                               EVEX_CD8<32, CD8VT1>;
6904     defm Int_VUCOMISDZ  : sse12_ord_cmp_int<0x2E, VR128X, X86ucomi, v2f64, sdmem,
6905                               sse_load_f64, "ucomisd">, PD, EVEX,
6906                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6907
6908     defm Int_VCOMISSZ  : sse12_ord_cmp_int<0x2F, VR128X, X86comi, v4f32, ssmem,
6909                               sse_load_f32, "comiss">, PS, EVEX, VEX_LIG,
6910                               EVEX_CD8<32, CD8VT1>;
6911     defm Int_VCOMISDZ  : sse12_ord_cmp_int<0x2F, VR128X, X86comi, v2f64, sdmem,
6912                               sse_load_f64, "comisd">, PD, EVEX,
6913                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6914   }
6915 }
6916
6917 /// avx512_fp14_s rcp14ss, rcp14sd, rsqrt14ss, rsqrt14sd
6918 multiclass avx512_fp14_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
6919                             X86VectorVTInfo _> {
6920   let AddedComplexity = 20 , Predicates = [HasAVX512] in {
6921   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6922                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6923                            "$src2, $src1", "$src1, $src2",
6924                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>, EVEX_4V;
6925   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6926                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
6927                          "$src2, $src1", "$src1, $src2",
6928                          (OpNode (_.VT _.RC:$src1),
6929                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))))>, EVEX_4V;
6930 }
6931 }
6932
6933 defm VRCP14SS   : avx512_fp14_s<0x4D, "vrcp14ss", X86frcp14s, f32x_info>,
6934                   EVEX_CD8<32, CD8VT1>, T8PD;
6935 defm VRCP14SD   : avx512_fp14_s<0x4D, "vrcp14sd", X86frcp14s, f64x_info>,
6936                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
6937 defm VRSQRT14SS   : avx512_fp14_s<0x4F, "vrsqrt14ss", X86frsqrt14s, f32x_info>,
6938                   EVEX_CD8<32, CD8VT1>, T8PD;
6939 defm VRSQRT14SD   : avx512_fp14_s<0x4F, "vrsqrt14sd", X86frsqrt14s, f64x_info>,
6940                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
6941
6942 /// avx512_fp14_p rcp14ps, rcp14pd, rsqrt14ps, rsqrt14pd
6943 multiclass avx512_fp14_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
6944                          X86VectorVTInfo _> {
6945   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6946                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
6947                          (_.FloatVT (OpNode _.RC:$src))>, EVEX, T8PD;
6948   defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6949                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
6950                          (OpNode (_.FloatVT
6951                            (bitconvert (_.LdFrag addr:$src))))>, EVEX, T8PD;
6952   defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6953                           (ins _.ScalarMemOp:$src), OpcodeStr,
6954                           "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
6955                           (OpNode (_.FloatVT
6956                             (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
6957                           EVEX, T8PD, EVEX_B;
6958 }
6959
6960 multiclass avx512_fp14_p_vl_all<bits<8> opc, string OpcodeStr, SDNode OpNode> {
6961   defm PSZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"), OpNode, v16f32_info>,
6962                           EVEX_V512, EVEX_CD8<32, CD8VF>;
6963   defm PDZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"), OpNode, v8f64_info>,
6964                           EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
6965
6966   // Define only if AVX512VL feature is present.
6967   let Predicates = [HasVLX] in {
6968     defm PSZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
6969                                 OpNode, v4f32x_info>,
6970                                EVEX_V128, EVEX_CD8<32, CD8VF>;
6971     defm PSZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
6972                                 OpNode, v8f32x_info>,
6973                                EVEX_V256, EVEX_CD8<32, CD8VF>;
6974     defm PDZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
6975                                 OpNode, v2f64x_info>,
6976                                EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
6977     defm PDZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
6978                                 OpNode, v4f64x_info>,
6979                                EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
6980   }
6981 }
6982
6983 defm VRSQRT14 : avx512_fp14_p_vl_all<0x4E, "vrsqrt14", X86frsqrt>;
6984 defm VRCP14 : avx512_fp14_p_vl_all<0x4C, "vrcp14", X86frcp>;
6985
6986 /// avx512_fp28_s rcp28ss, rcp28sd, rsqrt28ss, rsqrt28sd
6987 multiclass avx512_fp28_s<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
6988                          SDNode OpNode> {
6989
6990   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6991                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6992                            "$src2, $src1", "$src1, $src2",
6993                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
6994                            (i32 FROUND_CURRENT))>;
6995
6996   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6997                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6998                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
6999                             (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7000                             (i32 FROUND_NO_EXC))>, EVEX_B;
7001
7002   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7003                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
7004                          "$src2, $src1", "$src1, $src2",
7005                          (OpNode (_.VT _.RC:$src1),
7006                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
7007                          (i32 FROUND_CURRENT))>;
7008 }
7009
7010 multiclass avx512_eri_s<bits<8> opc, string OpcodeStr, SDNode OpNode> {
7011   defm SS : avx512_fp28_s<opc, OpcodeStr#"ss", f32x_info, OpNode>,
7012               EVEX_CD8<32, CD8VT1>;
7013   defm SD : avx512_fp28_s<opc, OpcodeStr#"sd", f64x_info, OpNode>,
7014               EVEX_CD8<64, CD8VT1>, VEX_W;
7015 }
7016
7017 let Predicates = [HasERI] in {
7018   defm VRCP28   : avx512_eri_s<0xCB, "vrcp28",   X86rcp28s>,   T8PD, EVEX_4V;
7019   defm VRSQRT28 : avx512_eri_s<0xCD, "vrsqrt28", X86rsqrt28s>, T8PD, EVEX_4V;
7020 }
7021
7022 defm VGETEXP   : avx512_eri_s<0x43, "vgetexp", X86fgetexpRnds>, T8PD, EVEX_4V;
7023 /// avx512_fp28_p rcp28ps, rcp28pd, rsqrt28ps, rsqrt28pd
7024
7025 multiclass avx512_fp28_p<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7026                          SDNode OpNode> {
7027
7028   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7029                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
7030                          (OpNode (_.VT _.RC:$src), (i32 FROUND_CURRENT))>;
7031
7032   defm m : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7033                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
7034                          (OpNode (_.FloatVT
7035                              (bitconvert (_.LdFrag addr:$src))),
7036                           (i32 FROUND_CURRENT))>;
7037
7038   defm mb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7039                          (ins _.ScalarMemOp:$src), OpcodeStr,
7040                          "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
7041                          (OpNode (_.FloatVT
7042                                   (X86VBroadcast (_.ScalarLdFrag addr:$src))),
7043                                  (i32 FROUND_CURRENT))>, EVEX_B;
7044 }
7045 multiclass avx512_fp28_p_round<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7046                          SDNode OpNode> {
7047   defm rb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7048                         (ins _.RC:$src), OpcodeStr,
7049                         "{sae}, $src", "$src, {sae}",
7050                         (OpNode (_.VT _.RC:$src), (i32 FROUND_NO_EXC))>, EVEX_B;
7051 }
7052
7053 multiclass  avx512_eri<bits<8> opc, string OpcodeStr, SDNode OpNode> {
7054    defm PS : avx512_fp28_p<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
7055              avx512_fp28_p_round<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
7056              T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
7057    defm PD : avx512_fp28_p<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
7058              avx512_fp28_p_round<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
7059              T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
7060 }
7061
7062 multiclass avx512_fp_unaryop_packed<bits<8> opc, string OpcodeStr,
7063                                   SDNode OpNode> {
7064   // Define only if AVX512VL feature is present.
7065   let Predicates = [HasVLX] in {
7066     defm PSZ128 : avx512_fp28_p<opc, OpcodeStr#"ps", v4f32x_info, OpNode>,
7067                                      EVEX_V128, T8PD, EVEX_CD8<32, CD8VF>;
7068     defm PSZ256 : avx512_fp28_p<opc, OpcodeStr#"ps", v8f32x_info, OpNode>,
7069                                      EVEX_V256, T8PD, EVEX_CD8<32, CD8VF>;
7070     defm PDZ128 : avx512_fp28_p<opc, OpcodeStr#"pd", v2f64x_info, OpNode>,
7071                                      EVEX_V128, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
7072     defm PDZ256 : avx512_fp28_p<opc, OpcodeStr#"pd", v4f64x_info, OpNode>,
7073                                      EVEX_V256, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
7074   }
7075 }
7076 let Predicates = [HasERI] in {
7077
7078  defm VRSQRT28 : avx512_eri<0xCC, "vrsqrt28", X86rsqrt28>, EVEX;
7079  defm VRCP28   : avx512_eri<0xCA, "vrcp28",   X86rcp28>,   EVEX;
7080  defm VEXP2    : avx512_eri<0xC8, "vexp2",    X86exp2>,    EVEX;
7081 }
7082 defm VGETEXP   : avx512_eri<0x42, "vgetexp", X86fgetexpRnd>,
7083                  avx512_fp_unaryop_packed<0x42, "vgetexp", X86fgetexpRnd> , EVEX;
7084
7085 multiclass avx512_sqrt_packed_round<bits<8> opc, string OpcodeStr,
7086                               SDNode OpNodeRnd, X86VectorVTInfo _>{
7087   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7088                          (ins _.RC:$src, AVX512RC:$rc), OpcodeStr, "$rc, $src", "$src, $rc",
7089                          (_.VT (OpNodeRnd _.RC:$src, (i32 imm:$rc)))>,
7090                          EVEX, EVEX_B, EVEX_RC;
7091 }
7092
7093 multiclass avx512_sqrt_packed<bits<8> opc, string OpcodeStr,
7094                               SDNode OpNode, X86VectorVTInfo _>{
7095   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7096                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
7097                          (_.FloatVT (OpNode _.RC:$src))>, EVEX;
7098   defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7099                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
7100                          (OpNode (_.FloatVT
7101                            (bitconvert (_.LdFrag addr:$src))))>, EVEX;
7102
7103   defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7104                           (ins _.ScalarMemOp:$src), OpcodeStr,
7105                           "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
7106                           (OpNode (_.FloatVT
7107                             (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
7108                           EVEX, EVEX_B;
7109 }
7110
7111 multiclass avx512_sqrt_packed_all<bits<8> opc, string OpcodeStr,
7112                                   SDNode OpNode> {
7113   defm PSZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
7114                                 v16f32_info>,
7115                                 EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
7116   defm PDZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
7117                                 v8f64_info>,
7118                                 EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7119   // Define only if AVX512VL feature is present.
7120   let Predicates = [HasVLX] in {
7121     defm PSZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
7122                                      OpNode, v4f32x_info>,
7123                                      EVEX_V128, PS, EVEX_CD8<32, CD8VF>;
7124     defm PSZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
7125                                      OpNode, v8f32x_info>,
7126                                      EVEX_V256, PS, EVEX_CD8<32, CD8VF>;
7127     defm PDZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
7128                                      OpNode, v2f64x_info>,
7129                                      EVEX_V128, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7130     defm PDZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
7131                                      OpNode, v4f64x_info>,
7132                                      EVEX_V256, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7133   }
7134 }
7135
7136 multiclass avx512_sqrt_packed_all_round<bits<8> opc, string OpcodeStr,
7137                                           SDNode OpNodeRnd> {
7138   defm PSZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "ps"), OpNodeRnd,
7139                                 v16f32_info>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
7140   defm PDZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "pd"), OpNodeRnd,
7141                                 v8f64_info>, EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7142 }
7143
7144 multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
7145                               string SUFF, SDNode OpNode, SDNode OpNodeRnd> {
7146
7147   defm r_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7148                          (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
7149                          "$src2, $src1", "$src1, $src2",
7150                          (OpNodeRnd (_.VT _.RC:$src1),
7151                                     (_.VT _.RC:$src2),
7152                                     (i32 FROUND_CURRENT))>;
7153   defm m_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7154                        (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
7155                        "$src2, $src1", "$src1, $src2",
7156                        (OpNodeRnd (_.VT _.RC:$src1),
7157                                   (_.VT (scalar_to_vector
7158                                             (_.ScalarLdFrag addr:$src2))),
7159                                   (i32 FROUND_CURRENT))>;
7160
7161   defm rb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7162                          (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
7163                          "$rc, $src2, $src1", "$src1, $src2, $rc",
7164                          (OpNodeRnd (_.VT _.RC:$src1),
7165                                      (_.VT _.RC:$src2),
7166                                      (i32 imm:$rc))>,
7167                          EVEX_B, EVEX_RC;
7168
7169   let isCodeGenOnly = 1, hasSideEffects = 0 in {
7170     def r : I<opc, MRMSrcReg, (outs _.FRC:$dst),
7171                (ins _.FRC:$src1, _.FRC:$src2),
7172                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
7173
7174     let mayLoad = 1 in
7175       def m : I<opc, MRMSrcMem, (outs _.FRC:$dst),
7176                  (ins _.FRC:$src1, _.ScalarMemOp:$src2),
7177                  OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
7178   }
7179
7180   def : Pat<(_.EltVT (OpNode _.FRC:$src)),
7181             (!cast<Instruction>(NAME#SUFF#Zr)
7182                 (_.EltVT (IMPLICIT_DEF)), _.FRC:$src)>;
7183
7184   def : Pat<(_.EltVT (OpNode (load addr:$src))),
7185             (!cast<Instruction>(NAME#SUFF#Zm)
7186                 (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[HasAVX512, OptForSize]>;
7187 }
7188
7189 multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> {
7190   defm SSZ : avx512_sqrt_scalar<opc, OpcodeStr#"ss", f32x_info, "SS", fsqrt,
7191                         X86fsqrtRnds>, EVEX_CD8<32, CD8VT1>, EVEX_4V, XS;
7192   defm SDZ : avx512_sqrt_scalar<opc, OpcodeStr#"sd", f64x_info, "SD", fsqrt,
7193                         X86fsqrtRnds>, EVEX_CD8<64, CD8VT1>, EVEX_4V, XD, VEX_W;
7194 }
7195
7196 defm VSQRT   : avx512_sqrt_packed_all<0x51, "vsqrt", fsqrt>,
7197                avx512_sqrt_packed_all_round<0x51, "vsqrt", X86fsqrtRnd>;
7198
7199 defm VSQRT   : avx512_sqrt_scalar_all<0x51, "vsqrt">, VEX_LIG;
7200
7201 let Predicates = [HasAVX512] in {
7202   def : Pat<(f32 (X86frsqrt FR32X:$src)),
7203             (COPY_TO_REGCLASS (VRSQRT14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>;
7204   def : Pat<(f32 (X86frsqrt (load addr:$src))),
7205             (COPY_TO_REGCLASS (VRSQRT14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
7206             Requires<[OptForSize]>;
7207   def : Pat<(f32 (X86frcp FR32X:$src)),
7208             (COPY_TO_REGCLASS (VRCP14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X )>;
7209   def : Pat<(f32 (X86frcp (load addr:$src))),
7210             (COPY_TO_REGCLASS (VRCP14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
7211             Requires<[OptForSize]>;
7212 }
7213
7214 multiclass
7215 avx512_rndscale_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
7216
7217   let ExeDomain = _.ExeDomain in {
7218   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7219                            (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
7220                            "$src3, $src2, $src1", "$src1, $src2, $src3",
7221                            (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7222                             (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
7223
7224   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7225                          (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
7226                          "$src3, {sae}, $src2, $src1", "$src1, $src2, {sae}, $src3",
7227                          (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7228                          (i32 imm:$src3), (i32 FROUND_NO_EXC)))>, EVEX_B;
7229
7230   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7231                          (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
7232                          OpcodeStr,
7233                          "$src3, $src2, $src1", "$src1, $src2, $src3",
7234                          (_.VT (X86RndScales (_.VT _.RC:$src1),
7235                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
7236                           (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
7237   }
7238   let Predicates = [HasAVX512] in {
7239   def : Pat<(ffloor _.FRC:$src), (COPY_TO_REGCLASS
7240              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7241              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x1))), _.FRC)>;
7242   def : Pat<(fceil _.FRC:$src), (COPY_TO_REGCLASS
7243              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7244              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x2))), _.FRC)>;
7245   def : Pat<(ftrunc _.FRC:$src), (COPY_TO_REGCLASS
7246              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7247              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x3))), _.FRC)>;
7248   def : Pat<(frint _.FRC:$src), (COPY_TO_REGCLASS
7249              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7250              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x4))), _.FRC)>;
7251   def : Pat<(fnearbyint _.FRC:$src), (COPY_TO_REGCLASS
7252              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7253              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0xc))), _.FRC)>;
7254
7255   def : Pat<(ffloor (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7256              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7257              addr:$src, (i32 0x1))), _.FRC)>;
7258   def : Pat<(fceil (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7259              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7260              addr:$src, (i32 0x2))), _.FRC)>;
7261   def : Pat<(ftrunc (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7262              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7263              addr:$src, (i32 0x3))), _.FRC)>;
7264   def : Pat<(frint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7265              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7266              addr:$src, (i32 0x4))), _.FRC)>;
7267   def : Pat<(fnearbyint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7268              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7269              addr:$src, (i32 0xc))), _.FRC)>;
7270   }
7271 }
7272
7273 defm VRNDSCALESS : avx512_rndscale_scalar<0x0A, "vrndscaless", f32x_info>,
7274                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VT1>;
7275
7276 defm VRNDSCALESD : avx512_rndscale_scalar<0x0B, "vrndscalesd", f64x_info>, VEX_W,
7277                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VT1>;
7278
7279 //-------------------------------------------------
7280 // Integer truncate and extend operations
7281 //-------------------------------------------------
7282
7283 multiclass avx512_trunc_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
7284                               X86VectorVTInfo SrcInfo, X86VectorVTInfo DestInfo,
7285                               X86MemOperand x86memop> {
7286   let ExeDomain = DestInfo.ExeDomain in
7287   defm rr  : AVX512_maskable<opc, MRMDestReg, DestInfo, (outs DestInfo.RC:$dst),
7288                       (ins SrcInfo.RC:$src1), OpcodeStr ,"$src1", "$src1",
7289                       (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1)))>,
7290                        EVEX, T8XS;
7291
7292   // for intrinsic patter match
7293   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7294                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7295                            undef)),
7296             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
7297                                       SrcInfo.RC:$src1)>;
7298
7299   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7300                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7301                            DestInfo.ImmAllZerosV)),
7302             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
7303                                       SrcInfo.RC:$src1)>;
7304
7305   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7306                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7307                            DestInfo.RC:$src0)),
7308             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrk) DestInfo.RC:$src0,
7309                                       DestInfo.KRCWM:$mask ,
7310                                       SrcInfo.RC:$src1)>;
7311
7312   let mayStore = 1, mayLoad = 1, hasSideEffects = 0,
7313       ExeDomain = DestInfo.ExeDomain in {
7314     def mr : AVX512XS8I<opc, MRMDestMem, (outs),
7315                (ins x86memop:$dst, SrcInfo.RC:$src),
7316                OpcodeStr # "\t{$src, $dst|$dst, $src}",
7317                []>, EVEX;
7318
7319     def mrk : AVX512XS8I<opc, MRMDestMem, (outs),
7320                (ins x86memop:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src),
7321                OpcodeStr # "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}",
7322                []>, EVEX, EVEX_K;
7323   }//mayStore = 1, mayLoad = 1, hasSideEffects = 0
7324 }
7325
7326 multiclass avx512_trunc_mr_lowering<X86VectorVTInfo SrcInfo,
7327                                     X86VectorVTInfo DestInfo,
7328                                     PatFrag truncFrag, PatFrag mtruncFrag > {
7329
7330   def : Pat<(truncFrag (SrcInfo.VT SrcInfo.RC:$src), addr:$dst),
7331             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr)
7332                                     addr:$dst, SrcInfo.RC:$src)>;
7333
7334   def : Pat<(mtruncFrag addr:$dst, SrcInfo.KRCWM:$mask,
7335                                                (SrcInfo.VT SrcInfo.RC:$src)),
7336             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk)
7337                             addr:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src)>;
7338 }
7339
7340 multiclass avx512_trunc<bits<8> opc, string OpcodeStr, SDNode OpNode,
7341          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
7342          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
7343          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
7344          X86MemOperand x86memopZ, PatFrag truncFrag, PatFrag mtruncFrag,
7345                                                      Predicate prd = HasAVX512>{
7346
7347   let Predicates = [HasVLX, prd] in {
7348     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
7349                              DestInfoZ128, x86memopZ128>,
7350                 avx512_trunc_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
7351                              truncFrag, mtruncFrag>, EVEX_V128;
7352
7353     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
7354                              DestInfoZ256, x86memopZ256>,
7355                 avx512_trunc_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
7356                              truncFrag, mtruncFrag>, EVEX_V256;
7357   }
7358   let Predicates = [prd] in
7359     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
7360                              DestInfoZ, x86memopZ>,
7361                 avx512_trunc_mr_lowering<VTSrcInfo.info512, DestInfoZ,
7362                              truncFrag, mtruncFrag>, EVEX_V512;
7363 }
7364
7365 multiclass avx512_trunc_qb<bits<8> opc, string OpcodeStr, SDNode OpNode,
7366                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7367   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7368                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
7369                StoreNode, MaskedStoreNode>, EVEX_CD8<8, CD8VO>;
7370 }
7371
7372 multiclass avx512_trunc_qw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7373                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7374   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7375                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
7376                StoreNode, MaskedStoreNode>, EVEX_CD8<16, CD8VQ>;
7377 }
7378
7379 multiclass avx512_trunc_qd<bits<8> opc, string OpcodeStr, SDNode OpNode,
7380                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7381   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7382                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
7383                StoreNode, MaskedStoreNode>, EVEX_CD8<32, CD8VH>;
7384 }
7385
7386 multiclass avx512_trunc_db<bits<8> opc, string OpcodeStr, SDNode OpNode,
7387                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7388   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
7389                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
7390                StoreNode, MaskedStoreNode>, EVEX_CD8<8, CD8VQ>;
7391 }
7392
7393 multiclass avx512_trunc_dw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7394                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7395   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
7396               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
7397               StoreNode, MaskedStoreNode>, EVEX_CD8<16, CD8VH>;
7398 }
7399
7400 multiclass avx512_trunc_wb<bits<8> opc, string OpcodeStr, SDNode OpNode,
7401                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7402   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i16_info,
7403               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
7404               StoreNode, MaskedStoreNode, HasBWI>, EVEX_CD8<16, CD8VH>;
7405 }
7406
7407 defm VPMOVQB    : avx512_trunc_qb<0x32, "vpmovqb",   X86vtrunc,
7408                                   truncstorevi8, masked_truncstorevi8>;
7409 defm VPMOVSQB   : avx512_trunc_qb<0x22, "vpmovsqb",  X86vtruncs,
7410                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7411 defm VPMOVUSQB  : avx512_trunc_qb<0x12, "vpmovusqb", X86vtruncus,
7412                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7413
7414 defm VPMOVQW    : avx512_trunc_qw<0x34, "vpmovqw",   X86vtrunc,
7415                                   truncstorevi16, masked_truncstorevi16>;
7416 defm VPMOVSQW   : avx512_trunc_qw<0x24, "vpmovsqw",  X86vtruncs,
7417                                   truncstore_s_vi16, masked_truncstore_s_vi16>;
7418 defm VPMOVUSQW  : avx512_trunc_qw<0x14, "vpmovusqw", X86vtruncus,
7419                                   truncstore_us_vi16, masked_truncstore_us_vi16>;
7420
7421 defm VPMOVQD    : avx512_trunc_qd<0x35, "vpmovqd",   X86vtrunc,
7422                                   truncstorevi32, masked_truncstorevi32>;
7423 defm VPMOVSQD   : avx512_trunc_qd<0x25, "vpmovsqd",  X86vtruncs,
7424                                   truncstore_s_vi32, masked_truncstore_s_vi32>;
7425 defm VPMOVUSQD  : avx512_trunc_qd<0x15, "vpmovusqd", X86vtruncus,
7426                                   truncstore_us_vi32, masked_truncstore_us_vi32>;
7427
7428 defm VPMOVDB    : avx512_trunc_db<0x31, "vpmovdb", X86vtrunc,
7429                                   truncstorevi8, masked_truncstorevi8>;
7430 defm VPMOVSDB   : avx512_trunc_db<0x21, "vpmovsdb",   X86vtruncs,
7431                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7432 defm VPMOVUSDB  : avx512_trunc_db<0x11, "vpmovusdb",  X86vtruncus,
7433                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7434
7435 defm VPMOVDW    : avx512_trunc_dw<0x33, "vpmovdw", X86vtrunc,
7436                                   truncstorevi16, masked_truncstorevi16>;
7437 defm VPMOVSDW   : avx512_trunc_dw<0x23, "vpmovsdw",   X86vtruncs,
7438                                   truncstore_s_vi16, masked_truncstore_s_vi16>;
7439 defm VPMOVUSDW  : avx512_trunc_dw<0x13, "vpmovusdw",  X86vtruncus,
7440                                   truncstore_us_vi16, masked_truncstore_us_vi16>;
7441
7442 defm VPMOVWB    : avx512_trunc_wb<0x30, "vpmovwb", X86vtrunc,
7443                                   truncstorevi8, masked_truncstorevi8>;
7444 defm VPMOVSWB   : avx512_trunc_wb<0x20, "vpmovswb",   X86vtruncs,
7445                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7446 defm VPMOVUSWB  : avx512_trunc_wb<0x10, "vpmovuswb",  X86vtruncus,
7447                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7448
7449 let Predicates = [HasAVX512, NoVLX] in {
7450 def: Pat<(v8i16 (X86vtrunc (v8i32 VR256X:$src))),
7451          (v8i16 (EXTRACT_SUBREG
7452                  (v16i16 (VPMOVDWZrr (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
7453                                           VR256X:$src, sub_ymm)))), sub_xmm))>;
7454 def: Pat<(v4i32 (X86vtrunc (v4i64 VR256X:$src))),
7455          (v4i32 (EXTRACT_SUBREG
7456                  (v8i32 (VPMOVQDZrr (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
7457                                            VR256X:$src, sub_ymm)))), sub_xmm))>;
7458 }
7459
7460 let Predicates = [HasBWI, NoVLX] in {
7461 def: Pat<(v16i8 (X86vtrunc (v16i16 VR256X:$src))),
7462          (v16i8 (EXTRACT_SUBREG (VPMOVWBZrr (v32i16 (INSERT_SUBREG (IMPLICIT_DEF),
7463                                             VR256X:$src, sub_ymm))), sub_xmm))>;
7464 }
7465
7466 multiclass avx512_extend_common<bits<8> opc, string OpcodeStr,
7467               X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo,
7468               X86MemOperand x86memop, PatFrag LdFrag, SDPatternOperator OpNode>{
7469   let ExeDomain = DestInfo.ExeDomain in {
7470   defm rr   : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
7471                     (ins SrcInfo.RC:$src), OpcodeStr ,"$src", "$src",
7472                     (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src)))>,
7473                   EVEX;
7474
7475   defm rm : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
7476                   (ins x86memop:$src), OpcodeStr ,"$src", "$src",
7477                   (DestInfo.VT (LdFrag addr:$src))>,
7478                 EVEX;
7479   }
7480 }
7481
7482 multiclass avx512_extend_BW<bits<8> opc, string OpcodeStr,
7483           SDPatternOperator OpNode,
7484           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7485   let Predicates = [HasVLX, HasBWI] in {
7486     defm Z128:  avx512_extend_common<opc, OpcodeStr, v8i16x_info,
7487                     v16i8x_info, i64mem, LdFrag, OpNode>,
7488                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V128;
7489
7490     defm Z256:  avx512_extend_common<opc, OpcodeStr, v16i16x_info,
7491                     v16i8x_info, i128mem, LdFrag, OpNode>,
7492                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V256;
7493   }
7494   let Predicates = [HasBWI] in {
7495     defm Z   :  avx512_extend_common<opc, OpcodeStr, v32i16_info,
7496                     v32i8x_info, i256mem, LdFrag, OpNode>,
7497                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V512;
7498   }
7499 }
7500
7501 multiclass avx512_extend_BD<bits<8> opc, string OpcodeStr,
7502           SDPatternOperator OpNode,
7503           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7504   let Predicates = [HasVLX, HasAVX512] in {
7505     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
7506                    v16i8x_info, i32mem, LdFrag, OpNode>,
7507                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V128;
7508
7509     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
7510                    v16i8x_info, i64mem, LdFrag, OpNode>,
7511                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V256;
7512   }
7513   let Predicates = [HasAVX512] in {
7514     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
7515                    v16i8x_info, i128mem, LdFrag, OpNode>,
7516                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V512;
7517   }
7518 }
7519
7520 multiclass avx512_extend_BQ<bits<8> opc, string OpcodeStr,
7521           SDPatternOperator OpNode,
7522           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7523   let Predicates = [HasVLX, HasAVX512] in {
7524     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7525                    v16i8x_info, i16mem, LdFrag, OpNode>,
7526                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V128;
7527
7528     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7529                    v16i8x_info, i32mem, LdFrag, OpNode>,
7530                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V256;
7531   }
7532   let Predicates = [HasAVX512] in {
7533     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7534                    v16i8x_info, i64mem, LdFrag, OpNode>,
7535                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V512;
7536   }
7537 }
7538
7539 multiclass avx512_extend_WD<bits<8> opc, string OpcodeStr,
7540          SDPatternOperator OpNode,
7541          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
7542   let Predicates = [HasVLX, HasAVX512] in {
7543     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
7544                    v8i16x_info, i64mem, LdFrag, OpNode>,
7545                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V128;
7546
7547     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
7548                    v8i16x_info, i128mem, LdFrag, OpNode>,
7549                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V256;
7550   }
7551   let Predicates = [HasAVX512] in {
7552     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
7553                    v16i16x_info, i256mem, LdFrag, OpNode>,
7554                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V512;
7555   }
7556 }
7557
7558 multiclass avx512_extend_WQ<bits<8> opc, string OpcodeStr,
7559          SDPatternOperator OpNode,
7560          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
7561   let Predicates = [HasVLX, HasAVX512] in {
7562     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7563                    v8i16x_info, i32mem, LdFrag, OpNode>,
7564                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V128;
7565
7566     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7567                    v8i16x_info, i64mem, LdFrag, OpNode>,
7568                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V256;
7569   }
7570   let Predicates = [HasAVX512] in {
7571     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7572                    v8i16x_info, i128mem, LdFrag, OpNode>,
7573                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V512;
7574   }
7575 }
7576
7577 multiclass avx512_extend_DQ<bits<8> opc, string OpcodeStr,
7578          SDPatternOperator OpNode,
7579          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi32")> {
7580
7581   let Predicates = [HasVLX, HasAVX512] in {
7582     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7583                    v4i32x_info, i64mem, LdFrag, OpNode>,
7584                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V128;
7585
7586     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7587                    v4i32x_info, i128mem, LdFrag, OpNode>,
7588                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V256;
7589   }
7590   let Predicates = [HasAVX512] in {
7591     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7592                    v8i32x_info, i256mem, LdFrag, OpNode>,
7593                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V512;
7594   }
7595 }
7596
7597 defm VPMOVZXBW : avx512_extend_BW<0x30, "vpmovzxbw", X86vzext, "z">;
7598 defm VPMOVZXBD : avx512_extend_BD<0x31, "vpmovzxbd", X86vzext, "z">;
7599 defm VPMOVZXBQ : avx512_extend_BQ<0x32, "vpmovzxbq", X86vzext, "z">;
7600 defm VPMOVZXWD : avx512_extend_WD<0x33, "vpmovzxwd", X86vzext, "z">;
7601 defm VPMOVZXWQ : avx512_extend_WQ<0x34, "vpmovzxwq", X86vzext, "z">;
7602 defm VPMOVZXDQ : avx512_extend_DQ<0x35, "vpmovzxdq", X86vzext, "z">;
7603
7604 defm VPMOVSXBW: avx512_extend_BW<0x20, "vpmovsxbw", X86vsext, "s">;
7605 defm VPMOVSXBD: avx512_extend_BD<0x21, "vpmovsxbd", X86vsext, "s">;
7606 defm VPMOVSXBQ: avx512_extend_BQ<0x22, "vpmovsxbq", X86vsext, "s">;
7607 defm VPMOVSXWD: avx512_extend_WD<0x23, "vpmovsxwd", X86vsext, "s">;
7608 defm VPMOVSXWQ: avx512_extend_WQ<0x24, "vpmovsxwq", X86vsext, "s">;
7609 defm VPMOVSXDQ: avx512_extend_DQ<0x25, "vpmovsxdq", X86vsext, "s">;
7610
7611 // EXTLOAD patterns, implemented using vpmovz
7612 multiclass avx512_ext_lowering<string InstrStr, X86VectorVTInfo To,
7613                                X86VectorVTInfo From, PatFrag LdFrag> {
7614   def : Pat<(To.VT (LdFrag addr:$src)),
7615             (!cast<Instruction>("VPMOVZX"#InstrStr#"rm") addr:$src)>;
7616   def : Pat<(To.VT (vselect To.KRCWM:$mask, (LdFrag addr:$src), To.RC:$src0)),
7617             (!cast<Instruction>("VPMOVZX"#InstrStr#"rmk") To.RC:$src0,
7618              To.KRC:$mask, addr:$src)>;
7619   def : Pat<(To.VT (vselect To.KRCWM:$mask, (LdFrag addr:$src),
7620                     To.ImmAllZerosV)),
7621             (!cast<Instruction>("VPMOVZX"#InstrStr#"rmkz") To.KRC:$mask,
7622              addr:$src)>;
7623 }
7624
7625 let Predicates = [HasVLX, HasBWI] in {
7626   defm : avx512_ext_lowering<"BWZ128", v8i16x_info,  v16i8x_info,  extloadvi8>;
7627   defm : avx512_ext_lowering<"BWZ256", v16i16x_info, v16i8x_info,  extloadvi8>;
7628 }
7629 let Predicates = [HasBWI] in {
7630   defm : avx512_ext_lowering<"BWZ",    v32i16_info,  v32i8x_info,  extloadvi8>;
7631 }
7632 let Predicates = [HasVLX, HasAVX512] in {
7633   defm : avx512_ext_lowering<"BDZ128", v4i32x_info,  v16i8x_info,  extloadvi8>;
7634   defm : avx512_ext_lowering<"BDZ256", v8i32x_info,  v16i8x_info,  extloadvi8>;
7635   defm : avx512_ext_lowering<"BQZ128", v2i64x_info,  v16i8x_info,  extloadvi8>;
7636   defm : avx512_ext_lowering<"BQZ256", v4i64x_info,  v16i8x_info,  extloadvi8>;
7637   defm : avx512_ext_lowering<"WDZ128", v4i32x_info,  v8i16x_info,  extloadvi16>;
7638   defm : avx512_ext_lowering<"WDZ256", v8i32x_info,  v8i16x_info,  extloadvi16>;
7639   defm : avx512_ext_lowering<"WQZ128", v2i64x_info,  v8i16x_info,  extloadvi16>;
7640   defm : avx512_ext_lowering<"WQZ256", v4i64x_info,  v8i16x_info,  extloadvi16>;
7641   defm : avx512_ext_lowering<"DQZ128", v2i64x_info,  v4i32x_info,  extloadvi32>;
7642   defm : avx512_ext_lowering<"DQZ256", v4i64x_info,  v4i32x_info,  extloadvi32>;
7643 }
7644 let Predicates = [HasAVX512] in {
7645   defm : avx512_ext_lowering<"BDZ",    v16i32_info,  v16i8x_info,  extloadvi8>;
7646   defm : avx512_ext_lowering<"BQZ",    v8i64_info,   v16i8x_info,  extloadvi8>;
7647   defm : avx512_ext_lowering<"WDZ",    v16i32_info,  v16i16x_info, extloadvi16>;
7648   defm : avx512_ext_lowering<"WQZ",    v8i64_info,   v8i16x_info,  extloadvi16>;
7649   defm : avx512_ext_lowering<"DQZ",    v8i64_info,   v8i32x_info,  extloadvi32>;
7650 }
7651
7652 multiclass AVX512_pmovx_patterns<string OpcPrefix, string ExtTy,
7653                                  SDNode ExtOp, PatFrag ExtLoad16> {
7654   // 128-bit patterns
7655   let Predicates = [HasVLX, HasBWI] in {
7656   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7657             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7658   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7659             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7660   def : Pat<(v8i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7661             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7662   def : Pat<(v8i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7663             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7664   def : Pat<(v8i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7665             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7666   }
7667   let Predicates = [HasVLX] in {
7668   def : Pat<(v4i32 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7669             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7670   def : Pat<(v4i32 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7671             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7672   def : Pat<(v4i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7673             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7674   def : Pat<(v4i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7675             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7676
7677   def : Pat<(v2i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (ExtLoad16 addr:$src)))))),
7678             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7679   def : Pat<(v2i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7680             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7681   def : Pat<(v2i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7682             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7683   def : Pat<(v2i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7684             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7685
7686   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7687             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7688   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7689             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7690   def : Pat<(v4i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7691             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7692   def : Pat<(v4i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7693             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7694   def : Pat<(v4i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7695             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7696
7697   def : Pat<(v2i64 (ExtOp (bc_v8i16 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7698             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7699   def : Pat<(v2i64 (ExtOp (v8i16 (vzmovl_v4i32 addr:$src)))),
7700             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7701   def : Pat<(v2i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7702             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7703   def : Pat<(v2i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7704             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7705
7706   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7707             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7708   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7709             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7710   def : Pat<(v2i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
7711             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7712   def : Pat<(v2i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
7713             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7714   def : Pat<(v2i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
7715             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7716   }
7717   // 256-bit patterns
7718   let Predicates = [HasVLX, HasBWI] in {
7719   def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7720             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7721   def : Pat<(v16i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7722             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7723   def : Pat<(v16i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7724             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7725   }
7726   let Predicates = [HasVLX] in {
7727   def : Pat<(v8i32 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7728             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7729   def : Pat<(v8i32 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7730             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7731   def : Pat<(v8i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7732             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7733   def : Pat<(v8i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7734             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7735
7736   def : Pat<(v4i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7737             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7738   def : Pat<(v4i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7739             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7740   def : Pat<(v4i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7741             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7742   def : Pat<(v4i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7743             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7744
7745   def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7746             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7747   def : Pat<(v8i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7748             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7749   def : Pat<(v8i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7750             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7751
7752   def : Pat<(v4i64 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7753             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7754   def : Pat<(v4i64 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7755             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7756   def : Pat<(v4i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7757             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7758   def : Pat<(v4i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7759             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7760
7761   def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
7762             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7763   def : Pat<(v4i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
7764             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7765   def : Pat<(v4i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
7766             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7767   }
7768   // 512-bit patterns
7769   let Predicates = [HasBWI] in {
7770   def : Pat<(v32i16 (ExtOp (bc_v32i8 (loadv4i64 addr:$src)))),
7771             (!cast<I>(OpcPrefix#BWZrm) addr:$src)>;
7772   }
7773   let Predicates = [HasAVX512] in {
7774   def : Pat<(v16i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7775             (!cast<I>(OpcPrefix#BDZrm) addr:$src)>;
7776
7777   def : Pat<(v8i64 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7778             (!cast<I>(OpcPrefix#BQZrm) addr:$src)>;
7779   def : Pat<(v8i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7780             (!cast<I>(OpcPrefix#BQZrm) addr:$src)>;
7781
7782   def : Pat<(v16i32 (ExtOp (bc_v16i16 (loadv4i64 addr:$src)))),
7783             (!cast<I>(OpcPrefix#WDZrm) addr:$src)>;
7784
7785   def : Pat<(v8i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7786             (!cast<I>(OpcPrefix#WQZrm) addr:$src)>;
7787
7788   def : Pat<(v8i64 (ExtOp (bc_v8i32 (loadv4i64 addr:$src)))),
7789             (!cast<I>(OpcPrefix#DQZrm) addr:$src)>;
7790   }
7791 }
7792
7793 defm : AVX512_pmovx_patterns<"VPMOVSX", "s", X86vsext, extloadi32i16>;
7794 defm : AVX512_pmovx_patterns<"VPMOVZX", "z", X86vzext, loadi16_anyext>;
7795
7796 //===----------------------------------------------------------------------===//
7797 // GATHER - SCATTER Operations
7798
7799 multiclass avx512_gather<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7800                          X86MemOperand memop, PatFrag GatherNode> {
7801   let Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb",
7802       ExeDomain = _.ExeDomain in
7803   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst, _.KRCWM:$mask_wb),
7804             (ins _.RC:$src1, _.KRCWM:$mask, memop:$src2),
7805             !strconcat(OpcodeStr#_.Suffix,
7806             "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
7807             [(set _.RC:$dst, _.KRCWM:$mask_wb,
7808               (GatherNode  (_.VT _.RC:$src1), _.KRCWM:$mask,
7809                      vectoraddr:$src2))]>, EVEX, EVEX_K,
7810              EVEX_CD8<_.EltSize, CD8VT1>;
7811 }
7812
7813 multiclass avx512_gather_q_pd<bits<8> dopc, bits<8> qopc,
7814                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7815   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512,
7816                                       vy512mem, mgatherv8i32>, EVEX_V512, VEX_W;
7817   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info512,
7818                                       vz512mem,  mgatherv8i64>, EVEX_V512, VEX_W;
7819 let Predicates = [HasVLX] in {
7820   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
7821                               vx256xmem, mgatherv4i32>, EVEX_V256, VEX_W;
7822   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info256,
7823                               vy256xmem, mgatherv4i64>, EVEX_V256, VEX_W;
7824   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
7825                               vx128xmem, mgatherv4i32>, EVEX_V128, VEX_W;
7826   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7827                               vx128xmem, mgatherv2i64>, EVEX_V128, VEX_W;
7828 }
7829 }
7830
7831 multiclass avx512_gather_d_ps<bits<8> dopc, bits<8> qopc,
7832                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7833   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512, vz512mem,
7834                                        mgatherv16i32>, EVEX_V512;
7835   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info256, vz512mem,
7836                                        mgatherv8i64>, EVEX_V512;
7837 let Predicates = [HasVLX] in {
7838   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
7839                                           vy256xmem, mgatherv8i32>, EVEX_V256;
7840   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7841                                           vy128xmem, mgatherv4i64>, EVEX_V256;
7842   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
7843                                           vx128xmem, mgatherv4i32>, EVEX_V128;
7844   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7845                                           vx64xmem, mgatherv2i64>, EVEX_V128;
7846 }
7847 }
7848
7849
7850 defm VGATHER : avx512_gather_q_pd<0x92, 0x93, avx512vl_f64_info, "vgather", "PD">,
7851                avx512_gather_d_ps<0x92, 0x93, avx512vl_f32_info, "vgather", "PS">;
7852
7853 defm VPGATHER : avx512_gather_q_pd<0x90, 0x91, avx512vl_i64_info, "vpgather", "Q">,
7854                 avx512_gather_d_ps<0x90, 0x91, avx512vl_i32_info, "vpgather", "D">;
7855
7856 multiclass avx512_scatter<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7857                           X86MemOperand memop, PatFrag ScatterNode> {
7858
7859 let mayStore = 1, Constraints = "$mask = $mask_wb", ExeDomain = _.ExeDomain in
7860
7861   def mr  : AVX5128I<opc, MRMDestMem, (outs _.KRCWM:$mask_wb),
7862             (ins memop:$dst, _.KRCWM:$mask, _.RC:$src),
7863             !strconcat(OpcodeStr#_.Suffix,
7864             "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
7865             [(set _.KRCWM:$mask_wb, (ScatterNode (_.VT _.RC:$src),
7866                                      _.KRCWM:$mask,  vectoraddr:$dst))]>,
7867             EVEX, EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
7868 }
7869
7870 multiclass avx512_scatter_q_pd<bits<8> dopc, bits<8> qopc,
7871                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7872   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512,
7873                                       vy512mem, mscatterv8i32>, EVEX_V512, VEX_W;
7874   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info512,
7875                                       vz512mem,  mscatterv8i64>, EVEX_V512, VEX_W;
7876 let Predicates = [HasVLX] in {
7877   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
7878                               vx256xmem, mscatterv4i32>, EVEX_V256, VEX_W;
7879   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info256,
7880                               vy256xmem, mscatterv4i64>, EVEX_V256, VEX_W;
7881   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
7882                               vx128xmem, mscatterv4i32>, EVEX_V128, VEX_W;
7883   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7884                               vx128xmem, mscatterv2i64>, EVEX_V128, VEX_W;
7885 }
7886 }
7887
7888 multiclass avx512_scatter_d_ps<bits<8> dopc, bits<8> qopc,
7889                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7890   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512, vz512mem,
7891                                        mscatterv16i32>, EVEX_V512;
7892   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info256, vz512mem,
7893                                        mscatterv8i64>, EVEX_V512;
7894 let Predicates = [HasVLX] in {
7895   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
7896                                           vy256xmem, mscatterv8i32>, EVEX_V256;
7897   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7898                                           vy128xmem, mscatterv4i64>, EVEX_V256;
7899   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
7900                                           vx128xmem, mscatterv4i32>, EVEX_V128;
7901   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7902                                           vx64xmem, mscatterv2i64>, EVEX_V128;
7903 }
7904 }
7905
7906 defm VSCATTER : avx512_scatter_q_pd<0xA2, 0xA3, avx512vl_f64_info, "vscatter", "PD">,
7907                avx512_scatter_d_ps<0xA2, 0xA3, avx512vl_f32_info, "vscatter", "PS">;
7908
7909 defm VPSCATTER : avx512_scatter_q_pd<0xA0, 0xA1, avx512vl_i64_info, "vpscatter", "Q">,
7910                 avx512_scatter_d_ps<0xA0, 0xA1, avx512vl_i32_info, "vpscatter", "D">;
7911
7912 // prefetch
7913 multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,
7914                        RegisterClass KRC, X86MemOperand memop> {
7915   let Predicates = [HasPFI], hasSideEffects = 1 in
7916   def m  : AVX5128I<opc, F, (outs), (ins KRC:$mask, memop:$src),
7917             !strconcat(OpcodeStr, "\t{$src {${mask}}|{${mask}}, $src}"),
7918             []>, EVEX, EVEX_K;
7919 }
7920
7921 defm VGATHERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dps",
7922                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7923
7924 defm VGATHERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qps",
7925                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7926
7927 defm VGATHERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dpd",
7928                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7929
7930 defm VGATHERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qpd",
7931                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7932
7933 defm VGATHERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dps",
7934                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7935
7936 defm VGATHERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qps",
7937                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7938
7939 defm VGATHERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dpd",
7940                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7941
7942 defm VGATHERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qpd",
7943                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7944
7945 defm VSCATTERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dps",
7946                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7947
7948 defm VSCATTERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qps",
7949                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7950
7951 defm VSCATTERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dpd",
7952                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7953
7954 defm VSCATTERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qpd",
7955                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7956
7957 defm VSCATTERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dps",
7958                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7959
7960 defm VSCATTERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qps",
7961                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7962
7963 defm VSCATTERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dpd",
7964                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7965
7966 defm VSCATTERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qpd",
7967                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7968
7969 // Helper fragments to match sext vXi1 to vXiY.
7970 def v64i1sextv64i8 : PatLeaf<(v64i8
7971                               (X86vsext
7972                                (v64i1 (X86pcmpgtm
7973                                 (bc_v64i8 (v16i32 immAllZerosV)),
7974                                 VR512:$src))))>;
7975 def v32i1sextv32i16 : PatLeaf<(v32i16 (X86vsrai VR512:$src, (i8 15)))>;
7976 def v16i1sextv16i32 : PatLeaf<(v16i32 (X86vsrai VR512:$src, (i8 31)))>;
7977 def v8i1sextv8i64   : PatLeaf<(v8i64 (X86vsrai VR512:$src, (i8 63)))>;
7978
7979 multiclass cvt_by_vec_width<bits<8> opc, X86VectorVTInfo Vec, string OpcodeStr > {
7980 def rr : AVX512XS8I<opc, MRMSrcReg, (outs Vec.RC:$dst), (ins Vec.KRC:$src),
7981                   !strconcat(OpcodeStr##Vec.Suffix, "\t{$src, $dst|$dst, $src}"),
7982                   [(set Vec.RC:$dst, (Vec.VT (X86vsext Vec.KRC:$src)))]>, EVEX;
7983 }
7984
7985 multiclass cvt_mask_by_elt_width<bits<8> opc, AVX512VLVectorVTInfo VTInfo,
7986                                  string OpcodeStr, Predicate prd> {
7987 let Predicates = [prd] in
7988   defm Z : cvt_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
7989
7990   let Predicates = [prd, HasVLX] in {
7991     defm Z256 : cvt_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
7992     defm Z128 : cvt_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
7993   }
7994 }
7995
7996 multiclass avx512_convert_mask_to_vector<string OpcodeStr> {
7997   defm NAME##B : cvt_mask_by_elt_width<0x28, avx512vl_i8_info,  OpcodeStr,
7998                                        HasBWI>;
7999   defm NAME##W : cvt_mask_by_elt_width<0x28, avx512vl_i16_info, OpcodeStr,
8000                                        HasBWI>, VEX_W;
8001   defm NAME##D : cvt_mask_by_elt_width<0x38, avx512vl_i32_info, OpcodeStr,
8002                                        HasDQI>;
8003   defm NAME##Q : cvt_mask_by_elt_width<0x38, avx512vl_i64_info, OpcodeStr,
8004                                        HasDQI>, VEX_W;
8005 }
8006
8007 defm VPMOVM2 : avx512_convert_mask_to_vector<"vpmovm2">;
8008
8009 multiclass convert_vector_to_mask_common<bits<8> opc, X86VectorVTInfo _, string OpcodeStr > {
8010     def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.KRC:$dst), (ins _.RC:$src),
8011                         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8012                         [(set _.KRC:$dst, (X86cvt2mask (_.VT _.RC:$src)))]>, EVEX;
8013 }
8014
8015 // Use 512bit version to implement 128/256 bit in case NoVLX.
8016 multiclass convert_vector_to_mask_lowering<X86VectorVTInfo ExtendInfo,
8017                                                             X86VectorVTInfo _> {
8018
8019   def : Pat<(_.KVT (X86cvt2mask (_.VT _.RC:$src))),
8020             (_.KVT (COPY_TO_REGCLASS
8021                      (!cast<Instruction>(NAME#"Zrr")
8022                        (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
8023                                       _.RC:$src, _.SubRegIdx)),
8024                    _.KRC))>;
8025 }
8026
8027 multiclass avx512_convert_vector_to_mask<bits<8> opc, string OpcodeStr,
8028                                    AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8029   let Predicates = [prd] in
8030     defm Z : convert_vector_to_mask_common <opc, VTInfo.info512, OpcodeStr>,
8031                                             EVEX_V512;
8032
8033   let Predicates = [prd, HasVLX] in {
8034     defm Z256 : convert_vector_to_mask_common<opc, VTInfo.info256, OpcodeStr>,
8035                                               EVEX_V256;
8036     defm Z128 : convert_vector_to_mask_common<opc, VTInfo.info128, OpcodeStr>,
8037                                                EVEX_V128;
8038   }
8039   let Predicates = [prd, NoVLX] in {
8040     defm Z256_Alt : convert_vector_to_mask_lowering<VTInfo.info512, VTInfo.info256>;
8041     defm Z128_Alt : convert_vector_to_mask_lowering<VTInfo.info512, VTInfo.info128>;
8042   }
8043 }
8044
8045 defm VPMOVB2M : avx512_convert_vector_to_mask<0x29, "vpmovb2m",
8046                                               avx512vl_i8_info, HasBWI>;
8047 defm VPMOVW2M : avx512_convert_vector_to_mask<0x29, "vpmovw2m",
8048                                               avx512vl_i16_info, HasBWI>, VEX_W;
8049 defm VPMOVD2M : avx512_convert_vector_to_mask<0x39, "vpmovd2m",
8050                                               avx512vl_i32_info, HasDQI>;
8051 defm VPMOVQ2M : avx512_convert_vector_to_mask<0x39, "vpmovq2m",
8052                                               avx512vl_i64_info, HasDQI>, VEX_W;
8053
8054 //===----------------------------------------------------------------------===//
8055 // AVX-512 - COMPRESS and EXPAND
8056 //
8057
8058 multiclass compress_by_vec_width_common<bits<8> opc, X86VectorVTInfo _,
8059                                  string OpcodeStr> {
8060   defm rr : AVX512_maskable<opc, MRMDestReg, _, (outs _.RC:$dst),
8061               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
8062               (_.VT (X86compress _.RC:$src1))>, AVX5128IBase;
8063
8064   let mayStore = 1, hasSideEffects = 0 in
8065   def mr : AVX5128I<opc, MRMDestMem, (outs),
8066               (ins _.MemOp:$dst, _.RC:$src),
8067               OpcodeStr # "\t{$src, $dst|$dst, $src}",
8068               []>, EVEX_CD8<_.EltSize, CD8VT1>;
8069
8070   def mrk : AVX5128I<opc, MRMDestMem, (outs),
8071               (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
8072               OpcodeStr # "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}",
8073               []>,
8074               EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
8075 }
8076
8077 multiclass compress_by_vec_width_lowering<X86VectorVTInfo _ > {
8078
8079   def : Pat<(X86mCompressingStore addr:$dst, _.KRCWM:$mask,
8080                                                (_.VT _.RC:$src)),
8081             (!cast<Instruction>(NAME#_.ZSuffix##mrk)
8082                             addr:$dst, _.KRCWM:$mask, _.RC:$src)>;
8083 }
8084
8085 multiclass compress_by_elt_width<bits<8> opc, string OpcodeStr,
8086                                  AVX512VLVectorVTInfo VTInfo> {
8087   defm Z : compress_by_vec_width_common<opc, VTInfo.info512, OpcodeStr>,
8088            compress_by_vec_width_lowering<VTInfo.info512>, EVEX_V512;
8089
8090   let Predicates = [HasVLX] in {
8091     defm Z256 : compress_by_vec_width_common<opc, VTInfo.info256, OpcodeStr>,
8092                 compress_by_vec_width_lowering<VTInfo.info256>, EVEX_V256;
8093     defm Z128 : compress_by_vec_width_common<opc, VTInfo.info128, OpcodeStr>,
8094                 compress_by_vec_width_lowering<VTInfo.info128>, EVEX_V128;
8095   }
8096 }
8097
8098 defm VPCOMPRESSD : compress_by_elt_width <0x8B, "vpcompressd", avx512vl_i32_info>,
8099                                          EVEX;
8100 defm VPCOMPRESSQ : compress_by_elt_width <0x8B, "vpcompressq", avx512vl_i64_info>,
8101                                          EVEX, VEX_W;
8102 defm VCOMPRESSPS : compress_by_elt_width <0x8A, "vcompressps", avx512vl_f32_info>,
8103                                          EVEX;
8104 defm VCOMPRESSPD : compress_by_elt_width <0x8A, "vcompresspd", avx512vl_f64_info>,
8105                                          EVEX, VEX_W;
8106
8107 // expand
8108 multiclass expand_by_vec_width<bits<8> opc, X86VectorVTInfo _,
8109                                  string OpcodeStr> {
8110   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8111               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
8112               (_.VT (X86expand _.RC:$src1))>, AVX5128IBase;
8113
8114   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8115               (ins _.MemOp:$src1), OpcodeStr, "$src1", "$src1",
8116               (_.VT (X86expand (_.VT (bitconvert
8117                                       (_.LdFrag addr:$src1)))))>,
8118             AVX5128IBase, EVEX_CD8<_.EltSize, CD8VT1>;
8119 }
8120
8121 multiclass expand_by_vec_width_lowering<X86VectorVTInfo _ > {
8122
8123   def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask, undef)),
8124             (!cast<Instruction>(NAME#_.ZSuffix##rmkz)
8125                                         _.KRCWM:$mask, addr:$src)>;
8126
8127   def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask,
8128                                                (_.VT _.RC:$src0))),
8129             (!cast<Instruction>(NAME#_.ZSuffix##rmk)
8130                             _.RC:$src0, _.KRCWM:$mask, addr:$src)>;
8131 }
8132
8133 multiclass expand_by_elt_width<bits<8> opc, string OpcodeStr,
8134                                  AVX512VLVectorVTInfo VTInfo> {
8135   defm Z : expand_by_vec_width<opc, VTInfo.info512, OpcodeStr>,
8136            expand_by_vec_width_lowering<VTInfo.info512>, EVEX_V512;
8137
8138   let Predicates = [HasVLX] in {
8139     defm Z256 : expand_by_vec_width<opc, VTInfo.info256, OpcodeStr>,
8140                 expand_by_vec_width_lowering<VTInfo.info256>, EVEX_V256;
8141     defm Z128 : expand_by_vec_width<opc, VTInfo.info128, OpcodeStr>,
8142                 expand_by_vec_width_lowering<VTInfo.info128>, EVEX_V128;
8143   }
8144 }
8145
8146 defm VPEXPANDD : expand_by_elt_width <0x89, "vpexpandd", avx512vl_i32_info>,
8147                                          EVEX;
8148 defm VPEXPANDQ : expand_by_elt_width <0x89, "vpexpandq", avx512vl_i64_info>,
8149                                          EVEX, VEX_W;
8150 defm VEXPANDPS : expand_by_elt_width <0x88, "vexpandps", avx512vl_f32_info>,
8151                                          EVEX;
8152 defm VEXPANDPD : expand_by_elt_width <0x88, "vexpandpd", avx512vl_f64_info>,
8153                                          EVEX, VEX_W;
8154
8155 //handle instruction  reg_vec1 = op(reg_vec,imm)
8156 //                               op(mem_vec,imm)
8157 //                               op(broadcast(eltVt),imm)
8158 //all instruction created with FROUND_CURRENT
8159 multiclass avx512_unary_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8160                                       X86VectorVTInfo _>{
8161   let ExeDomain = _.ExeDomain in {
8162   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8163                       (ins _.RC:$src1, i32u8imm:$src2),
8164                       OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
8165                       (OpNode (_.VT _.RC:$src1),
8166                               (i32 imm:$src2),
8167                               (i32 FROUND_CURRENT))>;
8168   defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8169                     (ins _.MemOp:$src1, i32u8imm:$src2),
8170                     OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
8171                     (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
8172                             (i32 imm:$src2),
8173                             (i32 FROUND_CURRENT))>;
8174   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8175                     (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
8176                     OpcodeStr##_.Suffix, "$src2, ${src1}"##_.BroadcastStr,
8177                     "${src1}"##_.BroadcastStr##", $src2",
8178                     (OpNode (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src1))),
8179                             (i32 imm:$src2),
8180                             (i32 FROUND_CURRENT))>, EVEX_B;
8181   }
8182 }
8183
8184 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8185 multiclass avx512_unary_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
8186                                              SDNode OpNode, X86VectorVTInfo _>{
8187   let ExeDomain = _.ExeDomain in
8188   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8189                       (ins _.RC:$src1, i32u8imm:$src2),
8190                       OpcodeStr##_.Suffix, "$src2, {sae}, $src1",
8191                       "$src1, {sae}, $src2",
8192                       (OpNode (_.VT _.RC:$src1),
8193                               (i32 imm:$src2),
8194                               (i32 FROUND_NO_EXC))>, EVEX_B;
8195 }
8196
8197 multiclass avx512_common_unary_fp_sae_packed_imm<string OpcodeStr,
8198             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8199   let Predicates = [prd] in {
8200     defm Z    : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8201                 avx512_unary_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8202                                   EVEX_V512;
8203   }
8204   let Predicates = [prd, HasVLX] in {
8205     defm Z128 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
8206                                   EVEX_V128;
8207     defm Z256 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
8208                                   EVEX_V256;
8209   }
8210 }
8211
8212 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8213 //                               op(reg_vec2,mem_vec,imm)
8214 //                               op(reg_vec2,broadcast(eltVt),imm)
8215 //all instruction created with FROUND_CURRENT
8216 multiclass avx512_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8217                                 X86VectorVTInfo _>{
8218   let ExeDomain = _.ExeDomain in {
8219   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8220                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8221                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8222                       (OpNode (_.VT _.RC:$src1),
8223                               (_.VT _.RC:$src2),
8224                               (i32 imm:$src3),
8225                               (i32 FROUND_CURRENT))>;
8226   defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8227                     (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
8228                     OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8229                     (OpNode (_.VT _.RC:$src1),
8230                             (_.VT (bitconvert (_.LdFrag addr:$src2))),
8231                             (i32 imm:$src3),
8232                             (i32 FROUND_CURRENT))>;
8233   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8234                     (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
8235                     OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
8236                     "$src1, ${src2}"##_.BroadcastStr##", $src3",
8237                     (OpNode (_.VT _.RC:$src1),
8238                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
8239                             (i32 imm:$src3),
8240                             (i32 FROUND_CURRENT))>, EVEX_B;
8241   }
8242 }
8243
8244 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8245 //                               op(reg_vec2,mem_vec,imm)
8246 multiclass avx512_3Op_rm_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
8247                              X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo>{
8248   let ExeDomain = DestInfo.ExeDomain in {
8249   defm rri : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
8250                   (ins SrcInfo.RC:$src1, SrcInfo.RC:$src2, u8imm:$src3),
8251                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8252                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
8253                                (SrcInfo.VT SrcInfo.RC:$src2),
8254                                (i8 imm:$src3)))>;
8255   defm rmi : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
8256                 (ins SrcInfo.RC:$src1, SrcInfo.MemOp:$src2, u8imm:$src3),
8257                 OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8258                 (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
8259                              (SrcInfo.VT (bitconvert
8260                                                 (SrcInfo.LdFrag addr:$src2))),
8261                              (i8 imm:$src3)))>;
8262   }
8263 }
8264
8265 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8266 //                               op(reg_vec2,mem_vec,imm)
8267 //                               op(reg_vec2,broadcast(eltVt),imm)
8268 multiclass avx512_3Op_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
8269                            X86VectorVTInfo _>:
8270   avx512_3Op_rm_imm8<opc, OpcodeStr, OpNode, _, _>{
8271
8272   let ExeDomain = _.ExeDomain in
8273   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8274                     (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
8275                     OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
8276                     "$src1, ${src2}"##_.BroadcastStr##", $src3",
8277                     (OpNode (_.VT _.RC:$src1),
8278                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
8279                             (i8 imm:$src3))>, EVEX_B;
8280 }
8281
8282 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8283 //                                      op(reg_vec2,mem_scalar,imm)
8284 //all instruction created with FROUND_CURRENT
8285 multiclass avx512_fp_scalar_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8286                                 X86VectorVTInfo _> {
8287   let ExeDomain = _.ExeDomain in {
8288   defm rri : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
8289                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8290                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8291                       (OpNode (_.VT _.RC:$src1),
8292                               (_.VT _.RC:$src2),
8293                               (i32 imm:$src3),
8294                               (i32 FROUND_CURRENT))>;
8295   defm rmi : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
8296                     (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
8297                     OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8298                     (OpNode (_.VT _.RC:$src1),
8299                             (_.VT (scalar_to_vector
8300                                       (_.ScalarLdFrag addr:$src2))),
8301                             (i32 imm:$src3),
8302                             (i32 FROUND_CURRENT))>;
8303   }
8304 }
8305
8306 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8307 multiclass avx512_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
8308                                              SDNode OpNode, X86VectorVTInfo _>{
8309   let ExeDomain = _.ExeDomain in
8310   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8311                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8312                       OpcodeStr, "$src3, {sae}, $src2, $src1",
8313                       "$src1, $src2, {sae}, $src3",
8314                       (OpNode (_.VT _.RC:$src1),
8315                               (_.VT _.RC:$src2),
8316                               (i32 imm:$src3),
8317                               (i32 FROUND_NO_EXC))>, EVEX_B;
8318 }
8319 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8320 multiclass avx512_fp_sae_scalar_imm<bits<8> opc, string OpcodeStr,
8321                                              SDNode OpNode, X86VectorVTInfo _> {
8322   defm NAME#rrib : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
8323                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8324                       OpcodeStr, "$src3, {sae}, $src2, $src1",
8325                       "$src1, $src2, {sae}, $src3",
8326                       (OpNode (_.VT _.RC:$src1),
8327                               (_.VT _.RC:$src2),
8328                               (i32 imm:$src3),
8329                               (i32 FROUND_NO_EXC))>, EVEX_B;
8330 }
8331
8332 multiclass avx512_common_fp_sae_packed_imm<string OpcodeStr,
8333             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8334   let Predicates = [prd] in {
8335     defm Z    : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8336                 avx512_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8337                                   EVEX_V512;
8338
8339   }
8340   let Predicates = [prd, HasVLX] in {
8341     defm Z128 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
8342                                   EVEX_V128;
8343     defm Z256 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
8344                                   EVEX_V256;
8345   }
8346 }
8347
8348 multiclass avx512_common_3Op_rm_imm8<bits<8> opc, SDNode OpNode, string OpStr,
8349                    AVX512VLVectorVTInfo DestInfo, AVX512VLVectorVTInfo SrcInfo>{
8350   let Predicates = [HasBWI] in {
8351     defm Z    : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info512,
8352                            SrcInfo.info512>, EVEX_V512, AVX512AIi8Base, EVEX_4V;
8353   }
8354   let Predicates = [HasBWI, HasVLX] in {
8355     defm Z128 : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info128,
8356                            SrcInfo.info128>, EVEX_V128, AVX512AIi8Base, EVEX_4V;
8357     defm Z256 : avx512_3Op_rm_imm8<opc, OpStr, OpNode,  DestInfo.info256,
8358                            SrcInfo.info256>, EVEX_V256, AVX512AIi8Base, EVEX_4V;
8359   }
8360 }
8361
8362 multiclass avx512_common_3Op_imm8<string OpcodeStr, AVX512VLVectorVTInfo _,
8363                                 bits<8> opc, SDNode OpNode>{
8364   let Predicates = [HasAVX512] in {
8365     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
8366   }
8367   let Predicates = [HasAVX512, HasVLX] in {
8368     defm Z128 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
8369     defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
8370   }
8371 }
8372
8373 multiclass avx512_common_fp_sae_scalar_imm<string OpcodeStr,
8374                   X86VectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8375   let Predicates = [prd] in {
8376      defm Z128 : avx512_fp_scalar_imm<opc, OpcodeStr, OpNode, _>,
8377                  avx512_fp_sae_scalar_imm<opc, OpcodeStr, OpNode, _>;
8378   }
8379 }
8380
8381 multiclass avx512_common_unary_fp_sae_packed_imm_all<string OpcodeStr,
8382                     bits<8> opcPs, bits<8> opcPd, SDNode OpNode, Predicate prd>{
8383   defm PS : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f32_info,
8384                             opcPs, OpNode, prd>, EVEX_CD8<32, CD8VF>;
8385   defm PD : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f64_info,
8386                             opcPd, OpNode, prd>, EVEX_CD8<64, CD8VF>, VEX_W;
8387 }
8388
8389
8390 defm VREDUCE   : avx512_common_unary_fp_sae_packed_imm_all<"vreduce", 0x56, 0x56,
8391                               X86VReduce, HasDQI>, AVX512AIi8Base, EVEX;
8392 defm VRNDSCALE : avx512_common_unary_fp_sae_packed_imm_all<"vrndscale", 0x08, 0x09,
8393                               X86VRndScale, HasAVX512>, AVX512AIi8Base, EVEX;
8394 defm VGETMANT : avx512_common_unary_fp_sae_packed_imm_all<"vgetmant", 0x26, 0x26,
8395                               X86VGetMant, HasAVX512>, AVX512AIi8Base, EVEX;
8396
8397
8398 defm VRANGEPD : avx512_common_fp_sae_packed_imm<"vrangepd", avx512vl_f64_info,
8399                                                        0x50, X86VRange, HasDQI>,
8400       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8401 defm VRANGEPS : avx512_common_fp_sae_packed_imm<"vrangeps", avx512vl_f32_info,
8402                                                        0x50, X86VRange, HasDQI>,
8403       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8404
8405 defm VRANGESD: avx512_common_fp_sae_scalar_imm<"vrangesd", f64x_info,
8406                                                  0x51, X86VRange, HasDQI>,
8407       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8408 defm VRANGESS: avx512_common_fp_sae_scalar_imm<"vrangess", f32x_info,
8409                                                  0x51, X86VRange, HasDQI>,
8410       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8411
8412 defm VREDUCESD: avx512_common_fp_sae_scalar_imm<"vreducesd", f64x_info,
8413                                                  0x57, X86Reduces, HasDQI>,
8414       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8415 defm VREDUCESS: avx512_common_fp_sae_scalar_imm<"vreducess", f32x_info,
8416                                                  0x57, X86Reduces, HasDQI>,
8417       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8418
8419 defm VGETMANTSD: avx512_common_fp_sae_scalar_imm<"vgetmantsd", f64x_info,
8420                                                  0x27, X86GetMants, HasAVX512>,
8421       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8422 defm VGETMANTSS: avx512_common_fp_sae_scalar_imm<"vgetmantss", f32x_info,
8423                                                  0x27, X86GetMants, HasAVX512>,
8424       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8425
8426 multiclass avx512_shuff_packed_128<string OpcodeStr, AVX512VLVectorVTInfo _,
8427                                        bits<8> opc, SDNode OpNode = X86Shuf128>{
8428   let Predicates = [HasAVX512] in {
8429     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
8430
8431   }
8432   let Predicates = [HasAVX512, HasVLX] in {
8433      defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
8434   }
8435 }
8436 let Predicates = [HasAVX512] in {
8437 def : Pat<(v16f32 (ffloor VR512:$src)),
8438           (VRNDSCALEPSZrri VR512:$src, (i32 0x1))>;
8439 def : Pat<(v16f32 (fnearbyint VR512:$src)),
8440           (VRNDSCALEPSZrri VR512:$src, (i32 0xC))>;
8441 def : Pat<(v16f32 (fceil VR512:$src)),
8442           (VRNDSCALEPSZrri VR512:$src, (i32 0x2))>;
8443 def : Pat<(v16f32 (frint VR512:$src)),
8444           (VRNDSCALEPSZrri VR512:$src, (i32 0x4))>;
8445 def : Pat<(v16f32 (ftrunc VR512:$src)),
8446           (VRNDSCALEPSZrri VR512:$src, (i32 0x3))>;
8447
8448 def : Pat<(v8f64 (ffloor VR512:$src)),
8449           (VRNDSCALEPDZrri VR512:$src, (i32 0x1))>;
8450 def : Pat<(v8f64 (fnearbyint VR512:$src)),
8451           (VRNDSCALEPDZrri VR512:$src, (i32 0xC))>;
8452 def : Pat<(v8f64 (fceil VR512:$src)),
8453           (VRNDSCALEPDZrri VR512:$src, (i32 0x2))>;
8454 def : Pat<(v8f64 (frint VR512:$src)),
8455           (VRNDSCALEPDZrri VR512:$src, (i32 0x4))>;
8456 def : Pat<(v8f64 (ftrunc VR512:$src)),
8457           (VRNDSCALEPDZrri VR512:$src, (i32 0x3))>;
8458 }
8459
8460 defm VSHUFF32X4 : avx512_shuff_packed_128<"vshuff32x4",avx512vl_f32_info, 0x23>,
8461       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8462 defm VSHUFF64X2 : avx512_shuff_packed_128<"vshuff64x2",avx512vl_f64_info, 0x23>,
8463       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8464 defm VSHUFI32X4 : avx512_shuff_packed_128<"vshufi32x4",avx512vl_i32_info, 0x43>,
8465       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8466 defm VSHUFI64X2 : avx512_shuff_packed_128<"vshufi64x2",avx512vl_i64_info, 0x43>,
8467       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8468
8469 multiclass avx512_valign<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I> {
8470   defm NAME:       avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0x03, X86VAlign>,
8471                            AVX512AIi8Base, EVEX_4V;
8472 }
8473
8474 defm VALIGND: avx512_valign<"valignd", avx512vl_i32_info>,
8475                                                   EVEX_CD8<32, CD8VF>;
8476 defm VALIGNQ: avx512_valign<"valignq", avx512vl_i64_info>,
8477                                                   EVEX_CD8<64, CD8VF>, VEX_W;
8478
8479 multiclass avx512_vpalignr_lowering<X86VectorVTInfo _ , list<Predicate> p>{
8480   let Predicates = p in
8481     def NAME#_.VTName#rri:
8482           Pat<(_.VT (X86PAlignr _.RC:$src1, _.RC:$src2, (i8 imm:$imm))),
8483               (!cast<Instruction>(NAME#_.ZSuffix#rri)
8484                     _.RC:$src1, _.RC:$src2, imm:$imm)>;
8485 }
8486
8487 multiclass avx512_vpalignr_lowering_common<AVX512VLVectorVTInfo _>:
8488       avx512_vpalignr_lowering<_.info512, [HasBWI]>,
8489       avx512_vpalignr_lowering<_.info128, [HasBWI, HasVLX]>,
8490       avx512_vpalignr_lowering<_.info256, [HasBWI, HasVLX]>;
8491
8492 defm VPALIGNR:   avx512_common_3Op_rm_imm8<0x0F, X86PAlignr, "vpalignr" ,
8493                                           avx512vl_i8_info, avx512vl_i8_info>,
8494                 avx512_vpalignr_lowering_common<avx512vl_i16_info>,
8495                 avx512_vpalignr_lowering_common<avx512vl_i32_info>,
8496                 avx512_vpalignr_lowering_common<avx512vl_f32_info>,
8497                 avx512_vpalignr_lowering_common<avx512vl_i64_info>,
8498                 avx512_vpalignr_lowering_common<avx512vl_f64_info>,
8499                 EVEX_CD8<8, CD8VF>;
8500
8501 defm VDBPSADBW: avx512_common_3Op_rm_imm8<0x42, X86dbpsadbw, "vdbpsadbw" ,
8502                     avx512vl_i16_info, avx512vl_i8_info>, EVEX_CD8<8, CD8VF>;
8503
8504 multiclass avx512_unary_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8505                            X86VectorVTInfo _> {
8506   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8507                     (ins _.RC:$src1), OpcodeStr,
8508                     "$src1", "$src1",
8509                     (_.VT (OpNode _.RC:$src1))>, EVEX, AVX5128IBase;
8510
8511   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8512                   (ins _.MemOp:$src1), OpcodeStr,
8513                   "$src1", "$src1",
8514                   (_.VT (OpNode (bitconvert (_.LdFrag addr:$src1))))>,
8515             EVEX, AVX5128IBase, EVEX_CD8<_.EltSize, CD8VF>;
8516 }
8517
8518 multiclass avx512_unary_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
8519                             X86VectorVTInfo _> :
8520            avx512_unary_rm<opc, OpcodeStr, OpNode, _> {
8521   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8522                   (ins _.ScalarMemOp:$src1), OpcodeStr,
8523                   "${src1}"##_.BroadcastStr,
8524                   "${src1}"##_.BroadcastStr,
8525                   (_.VT (OpNode (X86VBroadcast
8526                                     (_.ScalarLdFrag addr:$src1))))>,
8527              EVEX, AVX5128IBase, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
8528 }
8529
8530 multiclass avx512_unary_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
8531                               AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8532   let Predicates = [prd] in
8533     defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
8534
8535   let Predicates = [prd, HasVLX] in {
8536     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
8537                               EVEX_V256;
8538     defm Z128 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info128>,
8539                               EVEX_V128;
8540   }
8541 }
8542
8543 multiclass avx512_unary_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
8544                                AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8545   let Predicates = [prd] in
8546     defm Z : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
8547                               EVEX_V512;
8548
8549   let Predicates = [prd, HasVLX] in {
8550     defm Z256 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
8551                                  EVEX_V256;
8552     defm Z128 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
8553                                  EVEX_V128;
8554   }
8555 }
8556
8557 multiclass avx512_unary_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
8558                                  SDNode OpNode, Predicate prd> {
8559   defm Q : avx512_unary_rmb_vl<opc_q, OpcodeStr#"q", OpNode, avx512vl_i64_info,
8560                                prd>, VEX_W;
8561   defm D : avx512_unary_rmb_vl<opc_d, OpcodeStr#"d", OpNode, avx512vl_i32_info,
8562                                prd>;
8563 }
8564
8565 multiclass avx512_unary_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
8566                                  SDNode OpNode, Predicate prd> {
8567   defm W : avx512_unary_rm_vl<opc_w, OpcodeStr#"w", OpNode, avx512vl_i16_info, prd>;
8568   defm B : avx512_unary_rm_vl<opc_b, OpcodeStr#"b", OpNode, avx512vl_i8_info, prd>;
8569 }
8570
8571 multiclass avx512_unary_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
8572                                   bits<8> opc_d, bits<8> opc_q,
8573                                   string OpcodeStr, SDNode OpNode> {
8574   defm NAME : avx512_unary_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
8575                                     HasAVX512>,
8576               avx512_unary_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
8577                                     HasBWI>;
8578 }
8579
8580 defm VPABS : avx512_unary_rm_vl_all<0x1C, 0x1D, 0x1E, 0x1F, "vpabs", X86Abs>;
8581
8582 def avx512_v16i1sextv16i8 : PatLeaf<(v16i8 (X86pcmpgt (bc_v16i8 (v4i32 immAllZerosV)),
8583                                                       VR128X:$src))>;
8584 def avx512_v8i1sextv8i16 : PatLeaf<(v8i16 (X86vsrai VR128X:$src, (i8 15)))>;
8585 def avx512_v4i1sextv4i32  : PatLeaf<(v4i32 (X86vsrai VR128X:$src, (i8 31)))>;
8586 def avx512_v32i1sextv32i8 : PatLeaf<(v32i8 (X86pcmpgt (bc_v32i8 (v8i32 immAllZerosV)),
8587                                                       VR256X:$src))>;
8588 def avx512_v16i1sextv16i16: PatLeaf<(v16i16 (X86vsrai VR256X:$src, (i8 15)))>;
8589 def avx512_v8i1sextv8i32  : PatLeaf<(v8i32 (X86vsrai VR256X:$src, (i8 31)))>;
8590
8591 let Predicates = [HasBWI, HasVLX] in {
8592   def : Pat<(xor
8593             (bc_v2i64 (avx512_v16i1sextv16i8)),
8594             (bc_v2i64 (add (v16i8 VR128X:$src), (avx512_v16i1sextv16i8)))),
8595             (VPABSBZ128rr VR128X:$src)>;
8596   def : Pat<(xor
8597             (bc_v2i64 (avx512_v8i1sextv8i16)),
8598             (bc_v2i64 (add (v8i16 VR128X:$src), (avx512_v8i1sextv8i16)))),
8599             (VPABSWZ128rr VR128X:$src)>;
8600   def : Pat<(xor
8601             (bc_v4i64 (avx512_v32i1sextv32i8)),
8602             (bc_v4i64 (add (v32i8 VR256X:$src), (avx512_v32i1sextv32i8)))),
8603             (VPABSBZ256rr VR256X:$src)>;
8604   def : Pat<(xor
8605             (bc_v4i64 (avx512_v16i1sextv16i16)),
8606             (bc_v4i64 (add (v16i16 VR256X:$src), (avx512_v16i1sextv16i16)))),
8607             (VPABSWZ256rr VR256X:$src)>;
8608 }
8609 let Predicates = [HasAVX512, HasVLX] in {
8610   def : Pat<(xor
8611             (bc_v2i64 (avx512_v4i1sextv4i32)),
8612             (bc_v2i64 (add (v4i32 VR128X:$src), (avx512_v4i1sextv4i32)))),
8613             (VPABSDZ128rr VR128X:$src)>;
8614   def : Pat<(xor
8615             (bc_v4i64 (avx512_v8i1sextv8i32)),
8616             (bc_v4i64 (add (v8i32 VR256X:$src), (avx512_v8i1sextv8i32)))),
8617             (VPABSDZ256rr VR256X:$src)>;
8618 }
8619
8620 let Predicates = [HasAVX512] in {
8621 def : Pat<(xor
8622           (bc_v8i64 (v16i1sextv16i32)),
8623           (bc_v8i64 (add (v16i32 VR512:$src), (v16i1sextv16i32)))),
8624           (VPABSDZrr VR512:$src)>;
8625 def : Pat<(xor
8626           (bc_v8i64 (v8i1sextv8i64)),
8627           (bc_v8i64 (add (v8i64 VR512:$src), (v8i1sextv8i64)))),
8628           (VPABSQZrr VR512:$src)>;
8629 }
8630 let Predicates = [HasBWI] in {
8631 def : Pat<(xor
8632           (bc_v8i64 (v64i1sextv64i8)),
8633           (bc_v8i64 (add (v64i8 VR512:$src), (v64i1sextv64i8)))),
8634           (VPABSBZrr VR512:$src)>;
8635 def : Pat<(xor
8636           (bc_v8i64 (v32i1sextv32i16)),
8637           (bc_v8i64 (add (v32i16 VR512:$src), (v32i1sextv32i16)))),
8638           (VPABSWZrr VR512:$src)>;
8639 }
8640
8641 multiclass avx512_ctlz<bits<8> opc, string OpcodeStr, Predicate prd>{
8642
8643   defm NAME :          avx512_unary_rm_vl_dq<opc, opc, OpcodeStr, ctlz, prd>;
8644 }
8645
8646 defm VPLZCNT    : avx512_ctlz<0x44, "vplzcnt", HasCDI>;
8647 defm VPCONFLICT : avx512_unary_rm_vl_dq<0xC4, 0xC4, "vpconflict", X86Conflict, HasCDI>;
8648
8649 //===---------------------------------------------------------------------===//
8650 // Replicate Single FP - MOVSHDUP and MOVSLDUP
8651 //===---------------------------------------------------------------------===//
8652 multiclass avx512_replicate<bits<8> opc, string OpcodeStr, SDNode OpNode>{
8653   defm NAME:       avx512_unary_rm_vl<opc, OpcodeStr, OpNode, avx512vl_f32_info,
8654                                       HasAVX512>, XS;
8655 }
8656
8657 defm VMOVSHDUP : avx512_replicate<0x16, "vmovshdup", X86Movshdup>;
8658 defm VMOVSLDUP : avx512_replicate<0x12, "vmovsldup", X86Movsldup>;
8659
8660 //===----------------------------------------------------------------------===//
8661 // AVX-512 - MOVDDUP
8662 //===----------------------------------------------------------------------===//
8663
8664 multiclass avx512_movddup_128<bits<8> opc, string OpcodeStr, SDNode OpNode,
8665                                                             X86VectorVTInfo _> {
8666   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8667                    (ins _.RC:$src), OpcodeStr, "$src", "$src",
8668                    (_.VT (OpNode (_.VT _.RC:$src)))>, EVEX;
8669   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8670                  (ins _.ScalarMemOp:$src), OpcodeStr, "$src", "$src",
8671                  (_.VT (OpNode (_.VT (scalar_to_vector
8672                                        (_.ScalarLdFrag addr:$src)))))>,
8673                  EVEX, EVEX_CD8<_.EltSize, CD8VH>;
8674 }
8675
8676 multiclass avx512_movddup_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
8677                                                   AVX512VLVectorVTInfo VTInfo> {
8678
8679   defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
8680
8681   let Predicates = [HasAVX512, HasVLX] in {
8682     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
8683                                EVEX_V256;
8684     defm Z128 : avx512_movddup_128<opc, OpcodeStr, OpNode, VTInfo.info128>,
8685                                EVEX_V128;
8686   }
8687 }
8688
8689 multiclass avx512_movddup<bits<8> opc, string OpcodeStr, SDNode OpNode>{
8690   defm NAME:      avx512_movddup_common<opc, OpcodeStr, OpNode,
8691                                         avx512vl_f64_info>, XD, VEX_W;
8692 }
8693
8694 defm VMOVDDUP : avx512_movddup<0x12, "vmovddup", X86Movddup>;
8695
8696 let Predicates = [HasVLX] in {
8697 def : Pat<(X86Movddup (loadv2f64 addr:$src)),
8698           (VMOVDDUPZ128rm addr:$src)>;
8699 def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
8700           (VMOVDDUPZ128rm addr:$src)>;
8701 def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8702           (VMOVDDUPZ128rr (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8703
8704 def : Pat<(vselect (v2i1 VK2WM:$mask), (X86Movddup (loadv2f64 addr:$src)),
8705                    (v2f64 VR128X:$src0)),
8706           (VMOVDDUPZ128rmk VR128X:$src0, VK2WM:$mask, addr:$src)>;
8707 def : Pat<(vselect (v2i1 VK2WM:$mask), (X86Movddup (loadv2f64 addr:$src)),
8708                    (bitconvert (v4i32 immAllZerosV))),
8709           (VMOVDDUPZ128rmkz VK2WM:$mask, addr:$src)>;
8710
8711 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast f64:$src)),
8712                    (v2f64 VR128X:$src0)),
8713           (VMOVDDUPZ128rrk VR128X:$src0, VK2WM:$mask,
8714                            (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8715 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast f64:$src)),
8716                    (bitconvert (v4i32 immAllZerosV))),
8717           (VMOVDDUPZ128rrkz VK2WM:$mask, (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8718
8719 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast (loadf64 addr:$src))),
8720                    (v2f64 VR128X:$src0)),
8721           (VMOVDDUPZ128rmk VR128X:$src0, VK2WM:$mask, addr:$src)>;
8722 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast (loadf64 addr:$src))),
8723                    (bitconvert (v4i32 immAllZerosV))),
8724           (VMOVDDUPZ128rmkz VK2WM:$mask, addr:$src)>;
8725 }
8726
8727 //===----------------------------------------------------------------------===//
8728 // AVX-512 - Unpack Instructions
8729 //===----------------------------------------------------------------------===//
8730 defm VUNPCKH : avx512_fp_binop_p<0x15, "vunpckh", X86Unpckh, HasAVX512,
8731                                  SSE_ALU_ITINS_S>;
8732 defm VUNPCKL : avx512_fp_binop_p<0x14, "vunpckl", X86Unpckl, HasAVX512,
8733                                  SSE_ALU_ITINS_S>;
8734
8735 defm VPUNPCKLBW : avx512_binop_rm_vl_b<0x60, "vpunpcklbw", X86Unpckl,
8736                                        SSE_INTALU_ITINS_P, HasBWI>;
8737 defm VPUNPCKHBW : avx512_binop_rm_vl_b<0x68, "vpunpckhbw", X86Unpckh,
8738                                        SSE_INTALU_ITINS_P, HasBWI>;
8739 defm VPUNPCKLWD : avx512_binop_rm_vl_w<0x61, "vpunpcklwd", X86Unpckl,
8740                                        SSE_INTALU_ITINS_P, HasBWI>;
8741 defm VPUNPCKHWD : avx512_binop_rm_vl_w<0x69, "vpunpckhwd", X86Unpckh,
8742                                        SSE_INTALU_ITINS_P, HasBWI>;
8743
8744 defm VPUNPCKLDQ : avx512_binop_rm_vl_d<0x62, "vpunpckldq", X86Unpckl,
8745                                        SSE_INTALU_ITINS_P, HasAVX512>;
8746 defm VPUNPCKHDQ : avx512_binop_rm_vl_d<0x6A, "vpunpckhdq", X86Unpckh,
8747                                        SSE_INTALU_ITINS_P, HasAVX512>;
8748 defm VPUNPCKLQDQ : avx512_binop_rm_vl_q<0x6C, "vpunpcklqdq", X86Unpckl,
8749                                        SSE_INTALU_ITINS_P, HasAVX512>;
8750 defm VPUNPCKHQDQ : avx512_binop_rm_vl_q<0x6D, "vpunpckhqdq", X86Unpckh,
8751                                        SSE_INTALU_ITINS_P, HasAVX512>;
8752
8753 //===----------------------------------------------------------------------===//
8754 // AVX-512 - Extract & Insert Integer Instructions
8755 //===----------------------------------------------------------------------===//
8756
8757 multiclass avx512_extract_elt_bw_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
8758                                                             X86VectorVTInfo _> {
8759   def mr : AVX512Ii8<opc, MRMDestMem, (outs),
8760               (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
8761               OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8762               [(store (_.EltVT (trunc (assertzext (OpNode (_.VT _.RC:$src1),
8763                                                           imm:$src2)))),
8764                       addr:$dst)]>,
8765               EVEX, EVEX_CD8<_.EltSize, CD8VT1>;
8766 }
8767
8768 multiclass avx512_extract_elt_b<string OpcodeStr, X86VectorVTInfo _> {
8769   let Predicates = [HasBWI] in {
8770     def rr : AVX512Ii8<0x14, MRMDestReg, (outs GR32orGR64:$dst),
8771                   (ins _.RC:$src1, u8imm:$src2),
8772                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8773                   [(set GR32orGR64:$dst,
8774                         (X86pextrb (_.VT _.RC:$src1), imm:$src2))]>,
8775                   EVEX, TAPD;
8776
8777     defm NAME : avx512_extract_elt_bw_m<0x14, OpcodeStr, X86pextrb, _>, TAPD;
8778   }
8779 }
8780
8781 multiclass avx512_extract_elt_w<string OpcodeStr, X86VectorVTInfo _> {
8782   let Predicates = [HasBWI] in {
8783     def rr : AVX512Ii8<0xC5, MRMSrcReg, (outs GR32orGR64:$dst),
8784                   (ins _.RC:$src1, u8imm:$src2),
8785                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8786                   [(set GR32orGR64:$dst,
8787                         (X86pextrw (_.VT _.RC:$src1), imm:$src2))]>,
8788                   EVEX, PD;
8789
8790     let hasSideEffects = 0 in
8791     def rr_REV : AVX512Ii8<0x15, MRMDestReg, (outs GR32orGR64:$dst),
8792                    (ins _.RC:$src1, u8imm:$src2),
8793                    OpcodeStr#".s\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8794                    EVEX, TAPD;
8795
8796     defm NAME : avx512_extract_elt_bw_m<0x15, OpcodeStr, X86pextrw, _>, TAPD;
8797   }
8798 }
8799
8800 multiclass avx512_extract_elt_dq<string OpcodeStr, X86VectorVTInfo _,
8801                                                             RegisterClass GRC> {
8802   let Predicates = [HasDQI] in {
8803     def rr : AVX512Ii8<0x16, MRMDestReg, (outs GRC:$dst),
8804                   (ins _.RC:$src1, u8imm:$src2),
8805                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8806                   [(set GRC:$dst,
8807                       (extractelt (_.VT _.RC:$src1), imm:$src2))]>,
8808                   EVEX, TAPD;
8809
8810     def mr : AVX512Ii8<0x16, MRMDestMem, (outs),
8811                 (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
8812                 OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8813                 [(store (extractelt (_.VT _.RC:$src1),
8814                                     imm:$src2),addr:$dst)]>,
8815                 EVEX, EVEX_CD8<_.EltSize, CD8VT1>, TAPD;
8816   }
8817 }
8818
8819 defm VPEXTRBZ : avx512_extract_elt_b<"vpextrb", v16i8x_info>;
8820 defm VPEXTRWZ : avx512_extract_elt_w<"vpextrw", v8i16x_info>;
8821 defm VPEXTRDZ : avx512_extract_elt_dq<"vpextrd", v4i32x_info, GR32>;
8822 defm VPEXTRQZ : avx512_extract_elt_dq<"vpextrq", v2i64x_info, GR64>, VEX_W;
8823
8824 multiclass avx512_insert_elt_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
8825                                             X86VectorVTInfo _, PatFrag LdFrag> {
8826   def rm : AVX512Ii8<opc, MRMSrcMem, (outs _.RC:$dst),
8827       (ins _.RC:$src1,  _.ScalarMemOp:$src2, u8imm:$src3),
8828       OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8829       [(set _.RC:$dst,
8830           (_.VT (OpNode _.RC:$src1, (LdFrag addr:$src2), imm:$src3)))]>,
8831       EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
8832 }
8833
8834 multiclass avx512_insert_elt_bw<bits<8> opc, string OpcodeStr, SDNode OpNode,
8835                                             X86VectorVTInfo _, PatFrag LdFrag> {
8836   let Predicates = [HasBWI] in {
8837     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
8838         (ins _.RC:$src1, GR32orGR64:$src2, u8imm:$src3),
8839         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8840         [(set _.RC:$dst,
8841             (OpNode _.RC:$src1, GR32orGR64:$src2, imm:$src3))]>, EVEX_4V;
8842
8843     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, OpNode, _, LdFrag>;
8844   }
8845 }
8846
8847 multiclass avx512_insert_elt_dq<bits<8> opc, string OpcodeStr,
8848                                          X86VectorVTInfo _, RegisterClass GRC> {
8849   let Predicates = [HasDQI] in {
8850     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
8851         (ins _.RC:$src1, GRC:$src2, u8imm:$src3),
8852         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8853         [(set _.RC:$dst,
8854             (_.VT (insertelt _.RC:$src1, GRC:$src2, imm:$src3)))]>,
8855         EVEX_4V, TAPD;
8856
8857     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, insertelt, _,
8858                                     _.ScalarLdFrag>, TAPD;
8859   }
8860 }
8861
8862 defm VPINSRBZ : avx512_insert_elt_bw<0x20, "vpinsrb", X86pinsrb, v16i8x_info,
8863                                      extloadi8>, TAPD;
8864 defm VPINSRWZ : avx512_insert_elt_bw<0xC4, "vpinsrw", X86pinsrw, v8i16x_info,
8865                                      extloadi16>, PD;
8866 defm VPINSRDZ : avx512_insert_elt_dq<0x22, "vpinsrd", v4i32x_info, GR32>;
8867 defm VPINSRQZ : avx512_insert_elt_dq<0x22, "vpinsrq", v2i64x_info, GR64>, VEX_W;
8868 //===----------------------------------------------------------------------===//
8869 // VSHUFPS - VSHUFPD Operations
8870 //===----------------------------------------------------------------------===//
8871 multiclass avx512_shufp<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
8872                                                 AVX512VLVectorVTInfo VTInfo_FP>{
8873   defm NAME:     avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0xC6, X86Shufp>,
8874                                    EVEX_CD8<VTInfo_FP.info512.EltSize, CD8VF>,
8875                                    AVX512AIi8Base, EVEX_4V;
8876 }
8877
8878 defm VSHUFPS: avx512_shufp<"vshufps", avx512vl_i32_info, avx512vl_f32_info>, PS;
8879 defm VSHUFPD: avx512_shufp<"vshufpd", avx512vl_i64_info, avx512vl_f64_info>, PD, VEX_W;
8880 //===----------------------------------------------------------------------===//
8881 // AVX-512 - Byte shift Left/Right
8882 //===----------------------------------------------------------------------===//
8883
8884 multiclass avx512_shift_packed<bits<8> opc, SDNode OpNode, Format MRMr,
8885                              Format MRMm, string OpcodeStr, X86VectorVTInfo _>{
8886   def rr : AVX512<opc, MRMr,
8887              (outs _.RC:$dst), (ins _.RC:$src1, u8imm:$src2),
8888              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8889              [(set _.RC:$dst,(_.VT (OpNode _.RC:$src1, (i8 imm:$src2))))]>;
8890   def rm : AVX512<opc, MRMm,
8891            (outs _.RC:$dst), (ins _.MemOp:$src1, u8imm:$src2),
8892            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8893            [(set _.RC:$dst,(_.VT (OpNode
8894                                  (_.VT (bitconvert (_.LdFrag addr:$src1))),
8895                                  (i8 imm:$src2))))]>;
8896 }
8897
8898 multiclass avx512_shift_packed_all<bits<8> opc, SDNode OpNode, Format MRMr,
8899                                  Format MRMm, string OpcodeStr, Predicate prd>{
8900   let Predicates = [prd] in
8901     defm Z512 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8902                                     OpcodeStr, v64i8_info>, EVEX_V512;
8903   let Predicates = [prd, HasVLX] in {
8904     defm Z256 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8905                                     OpcodeStr, v32i8x_info>, EVEX_V256;
8906     defm Z128 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8907                                     OpcodeStr, v16i8x_info>, EVEX_V128;
8908   }
8909 }
8910 defm VPSLLDQ : avx512_shift_packed_all<0x73, X86vshldq, MRM7r, MRM7m, "vpslldq",
8911                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
8912 defm VPSRLDQ : avx512_shift_packed_all<0x73, X86vshrdq, MRM3r, MRM3m, "vpsrldq",
8913                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
8914
8915
8916 multiclass avx512_psadbw_packed<bits<8> opc, SDNode OpNode,
8917                                 string OpcodeStr, X86VectorVTInfo _dst,
8918                                 X86VectorVTInfo _src>{
8919   def rr : AVX512BI<opc, MRMSrcReg,
8920              (outs _dst.RC:$dst), (ins _src.RC:$src1, _src.RC:$src2),
8921              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8922              [(set _dst.RC:$dst,(_dst.VT
8923                                 (OpNode (_src.VT _src.RC:$src1),
8924                                         (_src.VT _src.RC:$src2))))]>;
8925   def rm : AVX512BI<opc, MRMSrcMem,
8926            (outs _dst.RC:$dst), (ins _src.RC:$src1, _src.MemOp:$src2),
8927            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8928            [(set _dst.RC:$dst,(_dst.VT
8929                               (OpNode (_src.VT _src.RC:$src1),
8930                               (_src.VT (bitconvert
8931                                         (_src.LdFrag addr:$src2))))))]>;
8932 }
8933
8934 multiclass avx512_psadbw_packed_all<bits<8> opc, SDNode OpNode,
8935                                     string OpcodeStr, Predicate prd> {
8936   let Predicates = [prd] in
8937     defm Z512 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v8i64_info,
8938                                     v64i8_info>, EVEX_V512;
8939   let Predicates = [prd, HasVLX] in {
8940     defm Z256 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v4i64x_info,
8941                                     v32i8x_info>, EVEX_V256;
8942     defm Z128 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v2i64x_info,
8943                                     v16i8x_info>, EVEX_V128;
8944   }
8945 }
8946
8947 defm VPSADBW : avx512_psadbw_packed_all<0xf6, X86psadbw, "vpsadbw",
8948                                        HasBWI>, EVEX_4V;
8949
8950 multiclass avx512_ternlog<bits<8> opc, string OpcodeStr, SDNode OpNode,
8951                           X86VectorVTInfo _>{
8952   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
8953   defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
8954                       (ins _.RC:$src2, _.RC:$src3, u8imm:$src4),
8955                       OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src4",
8956                       (OpNode (_.VT _.RC:$src1),
8957                               (_.VT _.RC:$src2),
8958                               (_.VT _.RC:$src3),
8959                               (i8 imm:$src4)), 1, 1>, AVX512AIi8Base, EVEX_4V;
8960   defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
8961                     (ins _.RC:$src2, _.MemOp:$src3, u8imm:$src4),
8962                     OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src4",
8963                     (OpNode (_.VT _.RC:$src1),
8964                             (_.VT _.RC:$src2),
8965                             (_.VT (bitconvert (_.LdFrag addr:$src3))),
8966                             (i8 imm:$src4)), 1, 0>,
8967                     AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
8968   defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
8969                     (ins _.RC:$src2, _.ScalarMemOp:$src3, u8imm:$src4),
8970                     OpcodeStr, "$src4, ${src3}"##_.BroadcastStr##", $src2",
8971                     "$src2, ${src3}"##_.BroadcastStr##", $src4",
8972                     (OpNode (_.VT _.RC:$src1),
8973                             (_.VT _.RC:$src2),
8974                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
8975                             (i8 imm:$src4)), 1, 0>, EVEX_B,
8976                     AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
8977   }// Constraints = "$src1 = $dst"
8978 }
8979
8980 multiclass avx512_common_ternlog<string OpcodeStr, AVX512VLVectorVTInfo _>{
8981   let Predicates = [HasAVX512] in
8982     defm Z    : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info512>, EVEX_V512;
8983   let Predicates = [HasAVX512, HasVLX] in {
8984     defm Z128 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info128>, EVEX_V128;
8985     defm Z256 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info256>, EVEX_V256;
8986   }
8987 }
8988
8989 defm VPTERNLOGD : avx512_common_ternlog<"vpternlogd", avx512vl_i32_info>;
8990 defm VPTERNLOGQ : avx512_common_ternlog<"vpternlogq", avx512vl_i64_info>, VEX_W;
8991
8992 //===----------------------------------------------------------------------===//
8993 // AVX-512 - FixupImm
8994 //===----------------------------------------------------------------------===//
8995
8996 multiclass avx512_fixupimm_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
8997                                   X86VectorVTInfo _>{
8998   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
8999     defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
9000                         (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9001                          OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9002                         (OpNode (_.VT _.RC:$src1),
9003                                 (_.VT _.RC:$src2),
9004                                 (_.IntVT _.RC:$src3),
9005                                 (i32 imm:$src4),
9006                                 (i32 FROUND_CURRENT))>;
9007     defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
9008                       (ins _.RC:$src2, _.MemOp:$src3, i32u8imm:$src4),
9009                       OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9010                       (OpNode (_.VT _.RC:$src1),
9011                               (_.VT _.RC:$src2),
9012                               (_.IntVT (bitconvert (_.LdFrag addr:$src3))),
9013                               (i32 imm:$src4),
9014                               (i32 FROUND_CURRENT))>;
9015     defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
9016                       (ins _.RC:$src2, _.ScalarMemOp:$src3, i32u8imm:$src4),
9017                     OpcodeStr##_.Suffix, "$src4, ${src3}"##_.BroadcastStr##", $src2",
9018                     "$src2, ${src3}"##_.BroadcastStr##", $src4",
9019                       (OpNode (_.VT _.RC:$src1),
9020                               (_.VT _.RC:$src2),
9021                               (_.IntVT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
9022                               (i32 imm:$src4),
9023                               (i32 FROUND_CURRENT))>, EVEX_B;
9024   } // Constraints = "$src1 = $dst"
9025 }
9026
9027 multiclass avx512_fixupimm_packed_sae<bits<8> opc, string OpcodeStr,
9028                                       SDNode OpNode, X86VectorVTInfo _>{
9029 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
9030   defm rrib : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
9031                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9032                       OpcodeStr##_.Suffix, "$src4, {sae}, $src3, $src2",
9033                       "$src2, $src3, {sae}, $src4",
9034                       (OpNode (_.VT _.RC:$src1),
9035                                 (_.VT _.RC:$src2),
9036                                 (_.IntVT _.RC:$src3),
9037                                 (i32 imm:$src4),
9038                                 (i32 FROUND_NO_EXC))>, EVEX_B;
9039   }
9040 }
9041
9042 multiclass avx512_fixupimm_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
9043                                   X86VectorVTInfo _, X86VectorVTInfo _src3VT> {
9044   let Constraints = "$src1 = $dst" , Predicates = [HasAVX512],
9045       ExeDomain = _.ExeDomain in {
9046     defm rri : AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
9047                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9048                       OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9049                       (OpNode (_.VT _.RC:$src1),
9050                               (_.VT _.RC:$src2),
9051                               (_src3VT.VT _src3VT.RC:$src3),
9052                               (i32 imm:$src4),
9053                               (i32 FROUND_CURRENT))>;
9054
9055     defm rrib : AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
9056                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9057                       OpcodeStr##_.Suffix, "$src4, {sae}, $src3, $src2",
9058                       "$src2, $src3, {sae}, $src4",
9059                       (OpNode (_.VT _.RC:$src1),
9060                               (_.VT _.RC:$src2),
9061                               (_src3VT.VT _src3VT.RC:$src3),
9062                               (i32 imm:$src4),
9063                               (i32 FROUND_NO_EXC))>, EVEX_B;
9064     defm rmi : AVX512_maskable_3src_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
9065                      (ins _.RC:$src2, _.ScalarMemOp:$src3, i32u8imm:$src4),
9066                      OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9067                      (OpNode (_.VT _.RC:$src1),
9068                              (_.VT _.RC:$src2),
9069                              (_src3VT.VT (scalar_to_vector
9070                                        (_src3VT.ScalarLdFrag addr:$src3))),
9071                              (i32 imm:$src4),
9072                              (i32 FROUND_CURRENT))>;
9073   }
9074 }
9075
9076 multiclass avx512_fixupimm_packed_all<AVX512VLVectorVTInfo _Vec>{
9077   let Predicates = [HasAVX512] in
9078     defm Z    : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>,
9079                 avx512_fixupimm_packed_sae<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>,
9080                                   AVX512AIi8Base, EVEX_4V, EVEX_V512;
9081   let Predicates = [HasAVX512, HasVLX] in {
9082     defm Z128 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info128>,
9083                                   AVX512AIi8Base, EVEX_4V, EVEX_V128;
9084     defm Z256 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info256>,
9085                                   AVX512AIi8Base, EVEX_4V, EVEX_V256;
9086   }
9087 }
9088
9089 defm VFIXUPIMMSS : avx512_fixupimm_scalar<0x55, "vfixupimm", X86VFixupimmScalar,
9090                                           f32x_info, v4i32x_info>,
9091                          AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
9092 defm VFIXUPIMMSD : avx512_fixupimm_scalar<0x55, "vfixupimm", X86VFixupimmScalar,
9093                                           f64x_info, v2i64x_info>,
9094                          AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
9095 defm VFIXUPIMMPS : avx512_fixupimm_packed_all<avx512vl_f32_info>,
9096                          EVEX_CD8<32, CD8VF>;
9097 defm VFIXUPIMMPD : avx512_fixupimm_packed_all<avx512vl_f64_info>,
9098                          EVEX_CD8<64, CD8VF>, VEX_W;
9099
9100
9101
9102 // Patterns used to select SSE scalar fp arithmetic instructions from
9103 // either:
9104 //
9105 // (1) a scalar fp operation followed by a blend
9106 //
9107 // The effect is that the backend no longer emits unnecessary vector
9108 // insert instructions immediately after SSE scalar fp instructions
9109 // like addss or mulss.
9110 //
9111 // For example, given the following code:
9112 //   __m128 foo(__m128 A, __m128 B) {
9113 //     A[0] += B[0];
9114 //     return A;
9115 //   }
9116 //
9117 // Previously we generated:
9118 //   addss %xmm0, %xmm1
9119 //   movss %xmm1, %xmm0
9120 //
9121 // We now generate:
9122 //   addss %xmm1, %xmm0
9123 //
9124 // (2) a vector packed single/double fp operation followed by a vector insert
9125 //
9126 // The effect is that the backend converts the packed fp instruction
9127 // followed by a vector insert into a single SSE scalar fp instruction.
9128 //
9129 // For example, given the following code:
9130 //   __m128 foo(__m128 A, __m128 B) {
9131 //     __m128 C = A + B;
9132 //     return (__m128) {c[0], a[1], a[2], a[3]};
9133 //   }
9134 //
9135 // Previously we generated:
9136 //   addps %xmm0, %xmm1
9137 //   movss %xmm1, %xmm0
9138 //
9139 // We now generate:
9140 //   addss %xmm1, %xmm0
9141
9142 // TODO: Some canonicalization in lowering would simplify the number of
9143 // patterns we have to try to match.
9144 multiclass AVX512_scalar_math_f32_patterns<SDNode Op, string OpcPrefix> {
9145   let Predicates = [HasAVX512] in {
9146     // extracted scalar math op with insert via movss
9147     def : Pat<(v4f32 (X86Movss (v4f32 VR128X:$dst), (v4f32 (scalar_to_vector
9148           (Op (f32 (extractelt (v4f32 VR128X:$dst), (iPTR 0))),
9149           FR32X:$src))))),
9150       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst,
9151           (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
9152
9153     // extracted scalar math op with insert via blend
9154     def : Pat<(v4f32 (X86Blendi (v4f32 VR128X:$dst), (v4f32 (scalar_to_vector
9155           (Op (f32 (extractelt (v4f32 VR128X:$dst), (iPTR 0))),
9156           FR32X:$src))), (i8 1))),
9157       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst,
9158           (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
9159
9160     // vector math op with insert via movss
9161     def : Pat<(v4f32 (X86Movss (v4f32 VR128X:$dst),
9162           (Op (v4f32 VR128X:$dst), (v4f32 VR128X:$src)))),
9163       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst, v4f32:$src)>;
9164
9165     // vector math op with insert via blend
9166     def : Pat<(v4f32 (X86Blendi (v4f32 VR128X:$dst),
9167           (Op (v4f32 VR128X:$dst), (v4f32 VR128X:$src)), (i8 1))),
9168       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst, v4f32:$src)>;
9169
9170     // extracted masked scalar math op with insert via movss
9171     def : Pat<(X86Movss (v4f32 VR128X:$src1),
9172                (scalar_to_vector
9173                 (X86selects VK1WM:$mask,
9174                             (Op (f32 (extractelt (v4f32 VR128X:$src1), (iPTR 0))),
9175                                 FR32X:$src2),
9176                             FR32X:$src0))),
9177       (!cast<I>("V"#OpcPrefix#SSZrr_Intk) (COPY_TO_REGCLASS FR32X:$src0, VR128X),
9178           VK1WM:$mask, v4f32:$src1,
9179           (COPY_TO_REGCLASS FR32X:$src2, VR128X))>;
9180   }
9181 }
9182
9183 defm : AVX512_scalar_math_f32_patterns<fadd, "ADD">;
9184 defm : AVX512_scalar_math_f32_patterns<fsub, "SUB">;
9185 defm : AVX512_scalar_math_f32_patterns<fmul, "MUL">;
9186 defm : AVX512_scalar_math_f32_patterns<fdiv, "DIV">;
9187
9188 multiclass AVX512_scalar_math_f64_patterns<SDNode Op, string OpcPrefix> {
9189   let Predicates = [HasAVX512] in {
9190     // extracted scalar math op with insert via movsd
9191     def : Pat<(v2f64 (X86Movsd (v2f64 VR128X:$dst), (v2f64 (scalar_to_vector
9192           (Op (f64 (extractelt (v2f64 VR128X:$dst), (iPTR 0))),
9193           FR64X:$src))))),
9194       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst,
9195           (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
9196
9197     // extracted scalar math op with insert via blend
9198     def : Pat<(v2f64 (X86Blendi (v2f64 VR128X:$dst), (v2f64 (scalar_to_vector
9199           (Op (f64 (extractelt (v2f64 VR128X:$dst), (iPTR 0))),
9200           FR64X:$src))), (i8 1))),
9201       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst,
9202           (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
9203
9204     // vector math op with insert via movsd
9205     def : Pat<(v2f64 (X86Movsd (v2f64 VR128X:$dst),
9206           (Op (v2f64 VR128X:$dst), (v2f64 VR128X:$src)))),
9207       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst, v2f64:$src)>;
9208
9209     // vector math op with insert via blend
9210     def : Pat<(v2f64 (X86Blendi (v2f64 VR128X:$dst),
9211           (Op (v2f64 VR128X:$dst), (v2f64 VR128X:$src)), (i8 1))),
9212       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst, v2f64:$src)>;
9213
9214     // extracted masked scalar math op with insert via movss
9215     def : Pat<(X86Movsd (v2f64 VR128X:$src1),
9216                (scalar_to_vector
9217                 (X86selects VK1WM:$mask,
9218                             (Op (f64 (extractelt (v2f64 VR128X:$src1), (iPTR 0))),
9219                                 FR64X:$src2),
9220                             FR64X:$src0))),
9221       (!cast<I>("V"#OpcPrefix#SDZrr_Intk) (COPY_TO_REGCLASS FR64X:$src0, VR128X),
9222           VK1WM:$mask, v2f64:$src1,
9223           (COPY_TO_REGCLASS FR64X:$src2, VR128X))>;
9224   }
9225 }
9226
9227 defm : AVX512_scalar_math_f64_patterns<fadd, "ADD">;
9228 defm : AVX512_scalar_math_f64_patterns<fsub, "SUB">;
9229 defm : AVX512_scalar_math_f64_patterns<fmul, "MUL">;
9230 defm : AVX512_scalar_math_f64_patterns<fdiv, "DIV">;