]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86InstrAVX512.td
Merge llvm, clang, lld and lldb trunk r291476.
[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 // Convert float/double to signed/unsigned int 32/64 with truncation
5961 multiclass avx512_cvt_s_all<bits<8> opc, string asm, X86VectorVTInfo _SrcRC,
5962                             X86VectorVTInfo _DstRC, SDNode OpNode,
5963                             SDNode OpNodeRnd, string aliasStr>{
5964 let Predicates = [HasAVX512] in {
5965   def rr : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
5966               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5967               [(set _DstRC.RC:$dst, (OpNode _SrcRC.FRC:$src))]>, EVEX;
5968   let hasSideEffects = 0 in
5969   def rb : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
5970                 !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
5971                 []>, EVEX, EVEX_B;
5972   def rm : AVX512<opc, MRMSrcMem, (outs _DstRC.RC:$dst), (ins _SrcRC.ScalarMemOp:$src),
5973               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5974               [(set _DstRC.RC:$dst, (OpNode (_SrcRC.ScalarLdFrag addr:$src)))]>,
5975               EVEX;
5976
5977   def : InstAlias<asm # aliasStr # "\t{$src, $dst|$dst, $src}",
5978           (!cast<Instruction>(NAME # "rr") _DstRC.RC:$dst, _SrcRC.FRC:$src), 0>;
5979   def : InstAlias<asm # aliasStr # "\t\t{{sae}, $src, $dst|$dst, $src, {sae}}",
5980           (!cast<Instruction>(NAME # "rb") _DstRC.RC:$dst, _SrcRC.FRC:$src), 0>;
5981   def : InstAlias<asm # aliasStr # "\t{$src, $dst|$dst, $src}",
5982           (!cast<Instruction>(NAME # "rm") _DstRC.RC:$dst,
5983                                           _SrcRC.ScalarMemOp:$src), 0>;
5984
5985   let isCodeGenOnly = 1 in {
5986     def rr_Int : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
5987               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5988              [(set _DstRC.RC:$dst, (OpNodeRnd (_SrcRC.VT _SrcRC.RC:$src),
5989                                    (i32 FROUND_CURRENT)))]>, EVEX, VEX_LIG;
5990     def rb_Int : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
5991               !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
5992               [(set _DstRC.RC:$dst, (OpNodeRnd (_SrcRC.VT _SrcRC.RC:$src),
5993                                     (i32 FROUND_NO_EXC)))]>,
5994                                     EVEX,VEX_LIG , EVEX_B;
5995     let mayLoad = 1, hasSideEffects = 0 in
5996       def rm_Int : AVX512<opc, MRMSrcMem, (outs _DstRC.RC:$dst),
5997                   (ins _SrcRC.MemOp:$src),
5998                   !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5999                   []>, EVEX, VEX_LIG;
6000
6001   } // isCodeGenOnly = 1
6002 } //HasAVX512
6003 }
6004
6005
6006 defm VCVTTSS2SIZ: avx512_cvt_s_all<0x2C, "vcvttss2si", f32x_info, i32x_info,
6007                         fp_to_sint, X86cvtts2IntRnd, "{l}">,
6008                         XS, EVEX_CD8<32, CD8VT1>;
6009 defm VCVTTSS2SI64Z: avx512_cvt_s_all<0x2C, "vcvttss2si", f32x_info, i64x_info,
6010                         fp_to_sint, X86cvtts2IntRnd, "{q}">,
6011                         VEX_W, XS, EVEX_CD8<32, CD8VT1>;
6012 defm VCVTTSD2SIZ: avx512_cvt_s_all<0x2C, "vcvttsd2si", f64x_info, i32x_info,
6013                         fp_to_sint, X86cvtts2IntRnd, "{l}">,
6014                         XD, EVEX_CD8<64, CD8VT1>;
6015 defm VCVTTSD2SI64Z: avx512_cvt_s_all<0x2C, "vcvttsd2si", f64x_info, i64x_info,
6016                         fp_to_sint, X86cvtts2IntRnd, "{q}">,
6017                         VEX_W, XD, EVEX_CD8<64, CD8VT1>;
6018
6019 defm VCVTTSS2USIZ: avx512_cvt_s_all<0x78, "vcvttss2usi", f32x_info, i32x_info,
6020                         fp_to_uint, X86cvtts2UIntRnd, "{l}">,
6021                         XS, EVEX_CD8<32, CD8VT1>;
6022 defm VCVTTSS2USI64Z: avx512_cvt_s_all<0x78, "vcvttss2usi", f32x_info, i64x_info,
6023                         fp_to_uint, X86cvtts2UIntRnd, "{q}">,
6024                         XS,VEX_W, EVEX_CD8<32, CD8VT1>;
6025 defm VCVTTSD2USIZ: avx512_cvt_s_all<0x78, "vcvttsd2usi", f64x_info, i32x_info,
6026                         fp_to_uint, X86cvtts2UIntRnd, "{l}">,
6027                         XD, EVEX_CD8<64, CD8VT1>;
6028 defm VCVTTSD2USI64Z: avx512_cvt_s_all<0x78, "vcvttsd2usi", f64x_info, i64x_info,
6029                         fp_to_uint, X86cvtts2UIntRnd, "{q}">,
6030                         XD, VEX_W, EVEX_CD8<64, CD8VT1>;
6031 let Predicates = [HasAVX512] in {
6032   def : Pat<(i32 (int_x86_sse_cvttss2si (v4f32 VR128X:$src))),
6033             (VCVTTSS2SIZrr_Int VR128X:$src)>;
6034   def : Pat<(i32 (int_x86_sse_cvttss2si (sse_load_f32 addr:$src))),
6035             (VCVTTSS2SIZrm_Int addr:$src)>;
6036   def : Pat<(i64 (int_x86_sse_cvttss2si64 (v4f32 VR128X:$src))),
6037             (VCVTTSS2SI64Zrr_Int VR128X:$src)>;
6038   def : Pat<(i64 (int_x86_sse_cvttss2si64 (sse_load_f32 addr:$src))),
6039             (VCVTTSS2SI64Zrm_Int addr:$src)>;
6040   def : Pat<(i32 (int_x86_sse2_cvttsd2si (v2f64 VR128X:$src))),
6041             (VCVTTSD2SIZrr_Int VR128X:$src)>;
6042   def : Pat<(i32 (int_x86_sse2_cvttsd2si (sse_load_f64 addr:$src))),
6043             (VCVTTSD2SIZrm_Int addr:$src)>;
6044   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 (v2f64 VR128X:$src))),
6045             (VCVTTSD2SI64Zrr_Int VR128X:$src)>;
6046   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 (sse_load_f64 addr:$src))),
6047             (VCVTTSD2SI64Zrm_Int addr:$src)>;
6048 } // HasAVX512
6049 //===----------------------------------------------------------------------===//
6050 // AVX-512  Convert form float to double and back
6051 //===----------------------------------------------------------------------===//
6052 multiclass avx512_cvt_fp_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6053                          X86VectorVTInfo _Src, SDNode OpNode> {
6054   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6055                          (ins _.RC:$src1, _Src.RC:$src2), OpcodeStr,
6056                          "$src2, $src1", "$src1, $src2",
6057                          (_.VT (OpNode (_.VT _.RC:$src1),
6058                                        (_Src.VT _Src.RC:$src2),
6059                                        (i32 FROUND_CURRENT)))>,
6060                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2F]>;
6061   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6062                          (ins _Src.RC:$src1, _Src.ScalarMemOp:$src2), OpcodeStr,
6063                          "$src2, $src1", "$src1, $src2",
6064                          (_.VT (OpNode (_.VT _.RC:$src1),
6065                                   (_Src.VT (scalar_to_vector
6066                                             (_Src.ScalarLdFrag addr:$src2))),
6067                                   (i32 FROUND_CURRENT)))>,
6068                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
6069 }
6070
6071 // Scalar Coversion with SAE - suppress all exceptions
6072 multiclass avx512_cvt_fp_sae_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6073                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6074   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6075                         (ins _.RC:$src1, _Src.RC:$src2), OpcodeStr,
6076                         "{sae}, $src2, $src1", "$src1, $src2, {sae}",
6077                         (_.VT (OpNodeRnd (_.VT _.RC:$src1),
6078                                          (_Src.VT _Src.RC:$src2),
6079                                          (i32 FROUND_NO_EXC)))>,
6080                         EVEX_4V, VEX_LIG, EVEX_B;
6081 }
6082
6083 // Scalar Conversion with rounding control (RC)
6084 multiclass avx512_cvt_fp_rc_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6085                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6086   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6087                         (ins _.RC:$src1, _Src.RC:$src2, AVX512RC:$rc), OpcodeStr,
6088                         "$rc, $src2, $src1", "$src1, $src2, $rc",
6089                         (_.VT (OpNodeRnd (_.VT _.RC:$src1),
6090                                          (_Src.VT _Src.RC:$src2), (i32 imm:$rc)))>,
6091                         EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>,
6092                         EVEX_B, EVEX_RC;
6093 }
6094 multiclass avx512_cvt_fp_scalar_sd2ss<bits<8> opc, string OpcodeStr,
6095                                   SDNode OpNodeRnd, X86VectorVTInfo _src,
6096                                                         X86VectorVTInfo _dst> {
6097   let Predicates = [HasAVX512] in {
6098     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6099              avx512_cvt_fp_rc_scalar<opc, OpcodeStr, _dst, _src,
6100                                OpNodeRnd>, VEX_W, EVEX_CD8<64, CD8VT1>, XD;
6101   }
6102 }
6103
6104 multiclass avx512_cvt_fp_scalar_ss2sd<bits<8> opc, string OpcodeStr,
6105                                     SDNode OpNodeRnd, X86VectorVTInfo _src,
6106                                                           X86VectorVTInfo _dst> {
6107   let Predicates = [HasAVX512] in {
6108     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6109              avx512_cvt_fp_sae_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6110              EVEX_CD8<32, CD8VT1>, XS;
6111   }
6112 }
6113 defm VCVTSD2SS : avx512_cvt_fp_scalar_sd2ss<0x5A, "vcvtsd2ss",
6114                                          X86froundRnd, f64x_info, f32x_info>;
6115 defm VCVTSS2SD : avx512_cvt_fp_scalar_ss2sd<0x5A, "vcvtss2sd",
6116                                           X86fpextRnd,f32x_info, f64x_info >;
6117
6118 def : Pat<(f64 (fpextend FR32X:$src)),
6119           (COPY_TO_REGCLASS (VCVTSS2SDZrr (COPY_TO_REGCLASS FR32X:$src, VR128X),
6120                                (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>,
6121           Requires<[HasAVX512]>;
6122 def : Pat<(f64 (fpextend (loadf32 addr:$src))),
6123           (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
6124           Requires<[HasAVX512]>;
6125
6126 def : Pat<(f64 (extloadf32 addr:$src)),
6127       (COPY_TO_REGCLASS (VCVTSS2SDZrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
6128       Requires<[HasAVX512, OptForSize]>;
6129
6130 def : Pat<(f64 (extloadf32 addr:$src)),
6131           (COPY_TO_REGCLASS (VCVTSS2SDZrr (v4f32 (IMPLICIT_DEF)),
6132                     (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)), VR128X)>,
6133           Requires<[HasAVX512, OptForSpeed]>;
6134
6135 def : Pat<(f32 (fpround FR64X:$src)),
6136           (COPY_TO_REGCLASS (VCVTSD2SSZrr (COPY_TO_REGCLASS FR64X:$src, VR128X),
6137                     (COPY_TO_REGCLASS FR64X:$src, VR128X)), VR128X)>,
6138            Requires<[HasAVX512]>;
6139 //===----------------------------------------------------------------------===//
6140 // AVX-512  Vector convert from signed/unsigned integer to float/double
6141 //          and from float/double to signed/unsigned integer
6142 //===----------------------------------------------------------------------===//
6143
6144 multiclass avx512_vcvt_fp<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6145                          X86VectorVTInfo _Src, SDNode OpNode,
6146                          string Broadcast = _.BroadcastStr,
6147                          string Alias = "", X86MemOperand MemOp = _Src.MemOp> {
6148
6149   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6150                          (ins _Src.RC:$src), OpcodeStr, "$src", "$src",
6151                          (_.VT (OpNode (_Src.VT _Src.RC:$src)))>, EVEX;
6152
6153   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6154                          (ins MemOp:$src), OpcodeStr#Alias, "$src", "$src",
6155                          (_.VT (OpNode (_Src.VT
6156                              (bitconvert (_Src.LdFrag addr:$src)))))>, EVEX;
6157
6158   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6159                          (ins _Src.ScalarMemOp:$src), OpcodeStr,
6160                          "${src}"##Broadcast, "${src}"##Broadcast,
6161                          (_.VT (OpNode (_Src.VT
6162                                   (X86VBroadcast (_Src.ScalarLdFrag addr:$src)))
6163                             ))>, EVEX, EVEX_B;
6164 }
6165 // Coversion with SAE - suppress all exceptions
6166 multiclass avx512_vcvt_fp_sae<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6167                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6168   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6169                         (ins _Src.RC:$src), OpcodeStr,
6170                         "{sae}, $src", "$src, {sae}",
6171                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src),
6172                                (i32 FROUND_NO_EXC)))>,
6173                         EVEX, EVEX_B;
6174 }
6175
6176 // Conversion with rounding control (RC)
6177 multiclass avx512_vcvt_fp_rc<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6178                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6179   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6180                         (ins _Src.RC:$src, AVX512RC:$rc), OpcodeStr,
6181                         "$rc, $src", "$src, $rc",
6182                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src), (i32 imm:$rc)))>,
6183                         EVEX, EVEX_B, EVEX_RC;
6184 }
6185
6186 // Extend Float to Double
6187 multiclass avx512_cvtps2pd<bits<8> opc, string OpcodeStr> {
6188   let Predicates = [HasAVX512] in {
6189     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8f32x_info, fpextend>,
6190              avx512_vcvt_fp_sae<opc, OpcodeStr, v8f64_info, v8f32x_info,
6191                                 X86vfpextRnd>, EVEX_V512;
6192   }
6193   let Predicates = [HasVLX] in {
6194     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4f32x_info,
6195                                X86vfpext, "{1to2}", "", f64mem>, EVEX_V128;
6196     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4f32x_info, fpextend>,
6197                                      EVEX_V256;
6198   }
6199 }
6200
6201 // Truncate Double to Float
6202 multiclass avx512_cvtpd2ps<bits<8> opc, string OpcodeStr> {
6203   let Predicates = [HasAVX512] in {
6204     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8f64_info, fpround>,
6205              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8f64_info,
6206                                X86vfproundRnd>, EVEX_V512;
6207   }
6208   let Predicates = [HasVLX] in {
6209     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2f64x_info,
6210                                X86vfpround, "{1to2}", "{x}">, EVEX_V128;
6211     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4f64x_info, fpround,
6212                                "{1to4}", "{y}">, EVEX_V256;
6213
6214     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6215                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6216     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6217                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, f128mem:$src), 0>;
6218     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6219                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6220     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6221                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, f256mem:$src), 0>;
6222   }
6223 }
6224
6225 defm VCVTPD2PS : avx512_cvtpd2ps<0x5A, "vcvtpd2ps">,
6226                                   VEX_W, PD, EVEX_CD8<64, CD8VF>;
6227 defm VCVTPS2PD : avx512_cvtps2pd<0x5A, "vcvtps2pd">,
6228                                   PS, EVEX_CD8<32, CD8VH>;
6229
6230 def : Pat<(v8f64 (extloadv8f32 addr:$src)),
6231             (VCVTPS2PDZrm addr:$src)>;
6232
6233 let Predicates = [HasVLX] in {
6234   let AddedComplexity = 15 in
6235   def : Pat<(X86vzmovl (v2f64 (bitconvert
6236                                (v4f32 (X86vfpround (v2f64 VR128X:$src)))))),
6237             (VCVTPD2PSZ128rr VR128X:$src)>;
6238   def : Pat<(v2f64 (extloadv2f32 addr:$src)),
6239               (VCVTPS2PDZ128rm addr:$src)>;
6240   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
6241               (VCVTPS2PDZ256rm addr:$src)>;
6242 }
6243
6244 // Convert Signed/Unsigned Doubleword to Double
6245 multiclass avx512_cvtdq2pd<bits<8> opc, string OpcodeStr, SDNode OpNode,
6246                            SDNode OpNode128> {
6247   // No rounding in this op
6248   let Predicates = [HasAVX512] in
6249     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i32x_info, OpNode>,
6250                                      EVEX_V512;
6251
6252   let Predicates = [HasVLX] in {
6253     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4i32x_info,
6254                                      OpNode128, "{1to2}", "", i64mem>, EVEX_V128;
6255     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i32x_info, OpNode>,
6256                                      EVEX_V256;
6257   }
6258 }
6259
6260 // Convert Signed/Unsigned Doubleword to Float
6261 multiclass avx512_cvtdq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
6262                            SDNode OpNodeRnd> {
6263   let Predicates = [HasAVX512] in
6264     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16f32_info, v16i32_info, OpNode>,
6265              avx512_vcvt_fp_rc<opc, OpcodeStr, v16f32_info, v16i32_info,
6266                                OpNodeRnd>, EVEX_V512;
6267
6268   let Predicates = [HasVLX] in {
6269     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i32x_info, OpNode>,
6270                                      EVEX_V128;
6271     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i32x_info, OpNode>,
6272                                      EVEX_V256;
6273   }
6274 }
6275
6276 // Convert Float to Signed/Unsigned Doubleword with truncation
6277 multiclass avx512_cvttps2dq<bits<8> opc, string OpcodeStr,
6278                                   SDNode OpNode, SDNode OpNodeRnd> {
6279   let Predicates = [HasAVX512] in {
6280     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
6281              avx512_vcvt_fp_sae<opc, OpcodeStr, v16i32_info, v16f32_info,
6282                                 OpNodeRnd>, EVEX_V512;
6283   }
6284   let Predicates = [HasVLX] in {
6285     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
6286                                      EVEX_V128;
6287     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
6288                                      EVEX_V256;
6289   }
6290 }
6291
6292 // Convert Float to Signed/Unsigned Doubleword
6293 multiclass avx512_cvtps2dq<bits<8> opc, string OpcodeStr,
6294                                   SDNode OpNode, SDNode OpNodeRnd> {
6295   let Predicates = [HasAVX512] in {
6296     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
6297              avx512_vcvt_fp_rc<opc, OpcodeStr, v16i32_info, v16f32_info,
6298                                 OpNodeRnd>, EVEX_V512;
6299   }
6300   let Predicates = [HasVLX] in {
6301     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
6302                                      EVEX_V128;
6303     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
6304                                      EVEX_V256;
6305   }
6306 }
6307
6308 // Convert Double to Signed/Unsigned Doubleword with truncation
6309 multiclass avx512_cvttpd2dq<bits<8> opc, string OpcodeStr, SDNode OpNode,
6310                             SDNode OpNode128, SDNode OpNodeRnd> {
6311   let Predicates = [HasAVX512] in {
6312     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
6313              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i32x_info, v8f64_info,
6314                                 OpNodeRnd>, EVEX_V512;
6315   }
6316   let Predicates = [HasVLX] in {
6317     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6318     // memory forms of these instructions in Asm Parser. They have the same
6319     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6320     // due to the same reason.
6321     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info,
6322                                OpNode128, "{1to2}", "{x}">, EVEX_V128;
6323     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
6324                                "{1to4}", "{y}">, EVEX_V256;
6325
6326     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6327                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6328     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6329                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, i128mem:$src), 0>;
6330     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6331                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6332     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6333                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, i256mem:$src), 0>;
6334   }
6335 }
6336
6337 // Convert Double to Signed/Unsigned Doubleword
6338 multiclass avx512_cvtpd2dq<bits<8> opc, string OpcodeStr,
6339                                   SDNode OpNode, SDNode OpNodeRnd> {
6340   let Predicates = [HasAVX512] in {
6341     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
6342              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i32x_info, v8f64_info,
6343                                OpNodeRnd>, EVEX_V512;
6344   }
6345   let Predicates = [HasVLX] in {
6346     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6347     // memory forms of these instructions in Asm Parcer. They have the same
6348     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6349     // due to the same reason.
6350     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info, OpNode,
6351                                "{1to2}", "{x}">, EVEX_V128;
6352     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
6353                                "{1to4}", "{y}">, EVEX_V256;
6354
6355     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6356                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6357     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6358                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, f128mem:$src), 0>;
6359     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6360                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6361     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6362                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, f256mem:$src), 0>;
6363   }
6364 }
6365
6366 // Convert Double to Signed/Unsigned Quardword
6367 multiclass avx512_cvtpd2qq<bits<8> opc, string OpcodeStr,
6368                                   SDNode OpNode, SDNode OpNodeRnd> {
6369   let Predicates = [HasDQI] in {
6370     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
6371              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f64_info,
6372                                OpNodeRnd>, EVEX_V512;
6373   }
6374   let Predicates = [HasDQI, HasVLX] in {
6375     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
6376                                EVEX_V128;
6377     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
6378                                EVEX_V256;
6379   }
6380 }
6381
6382 // Convert Double to Signed/Unsigned Quardword with truncation
6383 multiclass avx512_cvttpd2qq<bits<8> opc, string OpcodeStr,
6384                                   SDNode OpNode, SDNode OpNodeRnd> {
6385   let Predicates = [HasDQI] in {
6386     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
6387              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f64_info,
6388                                OpNodeRnd>, EVEX_V512;
6389   }
6390   let Predicates = [HasDQI, HasVLX] in {
6391     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
6392                                EVEX_V128;
6393     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
6394                                EVEX_V256;
6395   }
6396 }
6397
6398 // Convert Signed/Unsigned Quardword to Double
6399 multiclass avx512_cvtqq2pd<bits<8> opc, string OpcodeStr,
6400                                   SDNode OpNode, SDNode OpNodeRnd> {
6401   let Predicates = [HasDQI] in {
6402     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i64_info, OpNode>,
6403              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f64_info, v8i64_info,
6404                                OpNodeRnd>, EVEX_V512;
6405   }
6406   let Predicates = [HasDQI, HasVLX] in {
6407     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v2i64x_info, OpNode>,
6408                                EVEX_V128;
6409     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i64x_info, OpNode>,
6410                                EVEX_V256;
6411   }
6412 }
6413
6414 // Convert Float to Signed/Unsigned Quardword
6415 multiclass avx512_cvtps2qq<bits<8> opc, string OpcodeStr,
6416                                   SDNode OpNode, SDNode OpNodeRnd> {
6417   let Predicates = [HasDQI] in {
6418     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
6419              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f32x_info,
6420                                OpNodeRnd>, EVEX_V512;
6421   }
6422   let Predicates = [HasDQI, HasVLX] in {
6423     // Explicitly specified broadcast string, since we take only 2 elements
6424     // from v4f32x_info source
6425     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode,
6426                                "{1to2}", "", f64mem>, EVEX_V128;
6427     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
6428                                EVEX_V256;
6429   }
6430 }
6431
6432 // Convert Float to Signed/Unsigned Quardword with truncation
6433 multiclass avx512_cvttps2qq<bits<8> opc, string OpcodeStr, SDNode OpNode,
6434                             SDNode OpNode128, SDNode OpNodeRnd> {
6435   let Predicates = [HasDQI] in {
6436     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
6437              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f32x_info,
6438                                OpNodeRnd>, EVEX_V512;
6439   }
6440   let Predicates = [HasDQI, HasVLX] in {
6441     // Explicitly specified broadcast string, since we take only 2 elements
6442     // from v4f32x_info source
6443     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode128,
6444                                "{1to2}", "", f64mem>, EVEX_V128;
6445     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
6446                                EVEX_V256;
6447   }
6448 }
6449
6450 // Convert Signed/Unsigned Quardword to Float
6451 multiclass avx512_cvtqq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
6452                                   SDNode OpNode128, SDNode OpNodeRnd> {
6453   let Predicates = [HasDQI] in {
6454     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i64_info, OpNode>,
6455              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8i64_info,
6456                                OpNodeRnd>, EVEX_V512;
6457   }
6458   let Predicates = [HasDQI, HasVLX] in {
6459     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6460     // memory forms of these instructions in Asm Parcer. They have the same
6461     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6462     // due to the same reason.
6463     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2i64x_info, OpNode128,
6464                                "{1to2}", "{x}">, EVEX_V128;
6465     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i64x_info, OpNode,
6466                                "{1to4}", "{y}">, EVEX_V256;
6467
6468     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6469                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6470     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6471                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, i128mem:$src), 0>;
6472     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6473                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6474     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6475                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, i256mem:$src), 0>;
6476   }
6477 }
6478
6479 defm VCVTDQ2PD : avx512_cvtdq2pd<0xE6, "vcvtdq2pd", sint_to_fp, X86VSintToFP>,
6480                                 XS, EVEX_CD8<32, CD8VH>;
6481
6482 defm VCVTDQ2PS : avx512_cvtdq2ps<0x5B, "vcvtdq2ps", sint_to_fp,
6483                                 X86VSintToFpRnd>,
6484                                 PS, EVEX_CD8<32, CD8VF>;
6485
6486 defm VCVTTPS2DQ : avx512_cvttps2dq<0x5B, "vcvttps2dq", fp_to_sint,
6487                                 X86cvttp2siRnd>,
6488                                 XS, EVEX_CD8<32, CD8VF>;
6489
6490 defm VCVTTPD2DQ : avx512_cvttpd2dq<0xE6, "vcvttpd2dq", fp_to_sint, X86cvttp2si,
6491                                  X86cvttp2siRnd>,
6492                                  PD, VEX_W, EVEX_CD8<64, CD8VF>;
6493
6494 defm VCVTTPS2UDQ : avx512_cvttps2dq<0x78, "vcvttps2udq", fp_to_uint,
6495                                  X86cvttp2uiRnd>, PS,
6496                                  EVEX_CD8<32, CD8VF>;
6497
6498 defm VCVTTPD2UDQ : avx512_cvttpd2dq<0x78, "vcvttpd2udq", fp_to_uint,
6499                                  X86cvttp2ui, X86cvttp2uiRnd>, PS, VEX_W,
6500                                  EVEX_CD8<64, CD8VF>;
6501
6502 defm VCVTUDQ2PD : avx512_cvtdq2pd<0x7A, "vcvtudq2pd", uint_to_fp, X86VUintToFP>,
6503                                  XS, EVEX_CD8<32, CD8VH>;
6504
6505 defm VCVTUDQ2PS : avx512_cvtdq2ps<0x7A, "vcvtudq2ps", uint_to_fp,
6506                                  X86VUintToFpRnd>, XD,
6507                                  EVEX_CD8<32, CD8VF>;
6508
6509 defm VCVTPS2DQ : avx512_cvtps2dq<0x5B, "vcvtps2dq", X86cvtp2Int,
6510                                  X86cvtp2IntRnd>, PD, EVEX_CD8<32, CD8VF>;
6511
6512 defm VCVTPD2DQ : avx512_cvtpd2dq<0xE6, "vcvtpd2dq", X86cvtp2Int,
6513                                  X86cvtp2IntRnd>, XD, VEX_W,
6514                                  EVEX_CD8<64, CD8VF>;
6515
6516 defm VCVTPS2UDQ : avx512_cvtps2dq<0x79, "vcvtps2udq", X86cvtp2UInt,
6517                                  X86cvtp2UIntRnd>,
6518                                  PS, EVEX_CD8<32, CD8VF>;
6519 defm VCVTPD2UDQ : avx512_cvtpd2dq<0x79, "vcvtpd2udq", X86cvtp2UInt,
6520                                  X86cvtp2UIntRnd>, VEX_W,
6521                                  PS, EVEX_CD8<64, CD8VF>;
6522
6523 defm VCVTPD2QQ : avx512_cvtpd2qq<0x7B, "vcvtpd2qq", X86cvtp2Int,
6524                                  X86cvtp2IntRnd>, VEX_W,
6525                                  PD, EVEX_CD8<64, CD8VF>;
6526
6527 defm VCVTPS2QQ : avx512_cvtps2qq<0x7B, "vcvtps2qq", X86cvtp2Int,
6528                                  X86cvtp2IntRnd>, PD, EVEX_CD8<32, CD8VH>;
6529
6530 defm VCVTPD2UQQ : avx512_cvtpd2qq<0x79, "vcvtpd2uqq", X86cvtp2UInt,
6531                                  X86cvtp2UIntRnd>, VEX_W,
6532                                  PD, EVEX_CD8<64, CD8VF>;
6533
6534 defm VCVTPS2UQQ : avx512_cvtps2qq<0x79, "vcvtps2uqq", X86cvtp2UInt,
6535                                  X86cvtp2UIntRnd>, PD, EVEX_CD8<32, CD8VH>;
6536
6537 defm VCVTTPD2QQ : avx512_cvttpd2qq<0x7A, "vcvttpd2qq", fp_to_sint,
6538                                  X86cvttp2siRnd>, VEX_W,
6539                                  PD, EVEX_CD8<64, CD8VF>;
6540
6541 defm VCVTTPS2QQ : avx512_cvttps2qq<0x7A, "vcvttps2qq", fp_to_sint, X86cvttp2si,
6542                                  X86cvttp2siRnd>, PD, EVEX_CD8<32, CD8VH>;
6543
6544 defm VCVTTPD2UQQ : avx512_cvttpd2qq<0x78, "vcvttpd2uqq", fp_to_uint,
6545                                  X86cvttp2uiRnd>, VEX_W,
6546                                  PD, EVEX_CD8<64, CD8VF>;
6547
6548 defm VCVTTPS2UQQ : avx512_cvttps2qq<0x78, "vcvttps2uqq", fp_to_uint, X86cvttp2ui,
6549                                  X86cvttp2uiRnd>, PD, EVEX_CD8<32, CD8VH>;
6550
6551 defm VCVTQQ2PD : avx512_cvtqq2pd<0xE6, "vcvtqq2pd", sint_to_fp,
6552                             X86VSintToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
6553
6554 defm VCVTUQQ2PD : avx512_cvtqq2pd<0x7A, "vcvtuqq2pd", uint_to_fp,
6555                             X86VUintToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
6556
6557 defm VCVTQQ2PS : avx512_cvtqq2ps<0x5B, "vcvtqq2ps", sint_to_fp, X86VSintToFP,
6558                             X86VSintToFpRnd>, VEX_W, PS, EVEX_CD8<64, CD8VF>;
6559
6560 defm VCVTUQQ2PS : avx512_cvtqq2ps<0x7A, "vcvtuqq2ps", uint_to_fp, X86VUintToFP,
6561                             X86VUintToFpRnd>, VEX_W, XD, EVEX_CD8<64, CD8VF>;
6562
6563 let Predicates = [HasAVX512, NoVLX] in {
6564 def : Pat<(v8i32 (fp_to_uint (v8f32 VR256X:$src1))),
6565           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
6566            (v16f32 (INSERT_SUBREG (IMPLICIT_DEF),
6567                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6568
6569 def : Pat<(v4i32 (fp_to_uint (v4f32 VR128X:$src1))),
6570           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
6571            (v16f32 (INSERT_SUBREG (IMPLICIT_DEF),
6572                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6573
6574 def : Pat<(v4i32 (fp_to_uint (v4f64 VR256X:$src1))),
6575           (EXTRACT_SUBREG (v8i32 (VCVTTPD2UDQZrr
6576            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6577                                  VR256X:$src1, sub_ymm)))), sub_xmm)>;
6578
6579 def : Pat<(v4i32 (X86cvttp2ui (v2f64 VR128X:$src))),
6580           (EXTRACT_SUBREG (v8i32 (VCVTTPD2UDQZrr
6581            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6582                                  VR128X:$src, sub_xmm)))), sub_xmm)>;
6583
6584 def : Pat<(v8f32 (uint_to_fp (v8i32 VR256X:$src1))),
6585           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
6586            (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
6587                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6588
6589 def : Pat<(v4f32 (uint_to_fp (v4i32 VR128X:$src1))),
6590           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
6591            (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
6592                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6593
6594 def : Pat<(v4f64 (uint_to_fp (v4i32 VR128X:$src1))),
6595           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
6596            (v8i32 (INSERT_SUBREG (IMPLICIT_DEF),
6597                                  VR128X:$src1, sub_xmm)))), sub_ymm)>;
6598
6599 def : Pat<(v2f64 (X86VUintToFP (v4i32 VR128X:$src1))),
6600           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
6601            (v8i32 (INSERT_SUBREG (IMPLICIT_DEF),
6602                                  VR128X:$src1, sub_xmm)))), sub_xmm)>;
6603 }
6604
6605 let Predicates = [HasAVX512, HasVLX] in {
6606   let AddedComplexity = 15 in {
6607     def : Pat<(X86vzmovl (v2i64 (bitconvert
6608                                 (v4i32 (X86cvtp2Int (v2f64 VR128X:$src)))))),
6609               (VCVTPD2DQZ128rr VR128X:$src)>;
6610     def : Pat<(v4i32 (bitconvert (X86vzmovl (v2i64 (bitconvert
6611                                  (v4i32 (X86cvtp2UInt (v2f64 VR128X:$src)))))))),
6612               (VCVTPD2UDQZ128rr VR128X:$src)>;
6613     def : Pat<(X86vzmovl (v2i64 (bitconvert
6614                                 (v4i32 (X86cvttp2si (v2f64 VR128X:$src)))))),
6615               (VCVTTPD2DQZ128rr VR128X:$src)>;
6616     def : Pat<(v4i32 (bitconvert (X86vzmovl (v2i64 (bitconvert
6617                                  (v4i32 (X86cvttp2ui (v2f64 VR128X:$src)))))))),
6618               (VCVTTPD2UDQZ128rr VR128X:$src)>;
6619   }
6620 }
6621
6622 let Predicates = [HasAVX512] in {
6623   def : Pat<(v8f32 (fpround (loadv8f64 addr:$src))),
6624             (VCVTPD2PSZrm addr:$src)>;
6625   def : Pat<(v8f64 (extloadv8f32 addr:$src)),
6626             (VCVTPS2PDZrm addr:$src)>;
6627 }
6628
6629 let Predicates = [HasDQI, HasVLX] in {
6630   let AddedComplexity = 15 in {
6631     def : Pat<(X86vzmovl (v2f64 (bitconvert
6632                                 (v4f32 (X86VSintToFP (v2i64 VR128X:$src)))))),
6633               (VCVTQQ2PSZ128rr VR128X:$src)>;
6634     def : Pat<(X86vzmovl (v2f64 (bitconvert
6635                                 (v4f32 (X86VUintToFP (v2i64 VR128X:$src)))))),
6636               (VCVTUQQ2PSZ128rr VR128X:$src)>;
6637   }
6638 }
6639
6640 let Predicates = [HasDQI, NoVLX] in {
6641 def : Pat<(v2i64 (fp_to_sint (v2f64 VR128X:$src1))),
6642           (EXTRACT_SUBREG (v8i64 (VCVTTPD2QQZrr
6643            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6644                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6645
6646 def : Pat<(v4i64 (fp_to_sint (v4f32 VR128X:$src1))),
6647           (EXTRACT_SUBREG (v8i64 (VCVTTPS2QQZrr
6648            (v8f32 (INSERT_SUBREG (IMPLICIT_DEF),
6649                                   VR128X:$src1, sub_xmm)))), sub_ymm)>;
6650
6651 def : Pat<(v4i64 (fp_to_sint (v4f64 VR256X:$src1))),
6652           (EXTRACT_SUBREG (v8i64 (VCVTTPD2QQZrr
6653            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6654                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6655
6656 def : Pat<(v2i64 (fp_to_uint (v2f64 VR128X:$src1))),
6657           (EXTRACT_SUBREG (v8i64 (VCVTTPD2UQQZrr
6658            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6659                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6660
6661 def : Pat<(v4i64 (fp_to_uint (v4f32 VR128X:$src1))),
6662           (EXTRACT_SUBREG (v8i64 (VCVTTPS2UQQZrr
6663            (v8f32 (INSERT_SUBREG (IMPLICIT_DEF),
6664                                   VR128X:$src1, sub_xmm)))), sub_ymm)>;
6665
6666 def : Pat<(v4i64 (fp_to_uint (v4f64 VR256X:$src1))),
6667           (EXTRACT_SUBREG (v8i64 (VCVTTPD2UQQZrr
6668            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6669                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6670
6671 def : Pat<(v4f32 (sint_to_fp (v4i64 VR256X:$src1))),
6672           (EXTRACT_SUBREG (v8f32 (VCVTQQ2PSZrr
6673            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6674                                   VR256X:$src1, sub_ymm)))), sub_xmm)>;
6675
6676 def : Pat<(v2f64 (sint_to_fp (v2i64 VR128X:$src1))),
6677           (EXTRACT_SUBREG (v8f64 (VCVTQQ2PDZrr
6678            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6679                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6680
6681 def : Pat<(v4f64 (sint_to_fp (v4i64 VR256X:$src1))),
6682           (EXTRACT_SUBREG (v8f64 (VCVTQQ2PDZrr
6683            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6684                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6685
6686 def : Pat<(v4f32 (uint_to_fp (v4i64 VR256X:$src1))),
6687           (EXTRACT_SUBREG (v8f32 (VCVTUQQ2PSZrr
6688            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6689                                   VR256X:$src1, sub_ymm)))), sub_xmm)>;
6690
6691 def : Pat<(v2f64 (uint_to_fp (v2i64 VR128X:$src1))),
6692           (EXTRACT_SUBREG (v8f64 (VCVTUQQ2PDZrr
6693            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6694                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6695
6696 def : Pat<(v4f64 (uint_to_fp (v4i64 VR256X:$src1))),
6697           (EXTRACT_SUBREG (v8f64 (VCVTUQQ2PDZrr
6698            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6699                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6700 }
6701
6702 //===----------------------------------------------------------------------===//
6703 // Half precision conversion instructions
6704 //===----------------------------------------------------------------------===//
6705 multiclass avx512_cvtph2ps<X86VectorVTInfo _dest, X86VectorVTInfo _src,
6706                            X86MemOperand x86memop, PatFrag ld_frag> {
6707   defm rr : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src),
6708                     "vcvtph2ps", "$src", "$src",
6709                    (X86cvtph2ps (_src.VT _src.RC:$src),
6710                                                 (i32 FROUND_CURRENT))>, T8PD;
6711   defm rm : AVX512_maskable<0x13, MRMSrcMem, _dest, (outs _dest.RC:$dst), (ins x86memop:$src),
6712                     "vcvtph2ps", "$src", "$src",
6713                     (X86cvtph2ps (_src.VT (bitconvert (ld_frag addr:$src))),
6714                                      (i32 FROUND_CURRENT))>, T8PD;
6715 }
6716
6717 multiclass avx512_cvtph2ps_sae<X86VectorVTInfo _dest, X86VectorVTInfo _src> {
6718   defm rb : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src),
6719                     "vcvtph2ps", "{sae}, $src", "$src, {sae}",
6720                    (X86cvtph2ps (_src.VT _src.RC:$src),
6721                                                 (i32 FROUND_NO_EXC))>, T8PD, EVEX_B;
6722
6723 }
6724
6725 let Predicates = [HasAVX512] in {
6726   defm VCVTPH2PSZ : avx512_cvtph2ps<v16f32_info, v16i16x_info, f256mem, loadv4i64>,
6727                     avx512_cvtph2ps_sae<v16f32_info, v16i16x_info>,
6728                     EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>;
6729   let Predicates = [HasVLX] in {
6730     defm VCVTPH2PSZ256 : avx512_cvtph2ps<v8f32x_info, v8i16x_info, f128mem,
6731                          loadv2i64>,EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>;
6732     defm VCVTPH2PSZ128 : avx512_cvtph2ps<v4f32x_info, v8i16x_info, f64mem,
6733                          loadv2i64>, EVEX, EVEX_V128, EVEX_CD8<32, CD8VH>;
6734   }
6735 }
6736
6737 multiclass avx512_cvtps2ph<X86VectorVTInfo _dest, X86VectorVTInfo _src,
6738                            X86MemOperand x86memop> {
6739   defm rr : AVX512_maskable<0x1D, MRMDestReg, _dest ,(outs _dest.RC:$dst),
6740                    (ins _src.RC:$src1, i32u8imm:$src2),
6741                    "vcvtps2ph", "$src2, $src1", "$src1, $src2",
6742                    (X86cvtps2ph (_src.VT _src.RC:$src1),
6743                                 (i32 imm:$src2)),
6744                    NoItinerary, 0, 0, X86select>, AVX512AIi8Base;
6745   def mr : AVX512AIi8<0x1D, MRMDestMem, (outs),
6746              (ins x86memop:$dst, _src.RC:$src1, i32u8imm:$src2),
6747              "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6748              [(store (_dest.VT (X86cvtps2ph (_src.VT _src.RC:$src1),
6749                                      (i32 imm:$src2))),
6750                                      addr:$dst)]>;
6751   let hasSideEffects = 0, mayStore = 1 in
6752   def mrk : AVX512AIi8<0x1D, MRMDestMem, (outs),
6753              (ins x86memop:$dst, _dest.KRCWM:$mask, _src.RC:$src1, i32u8imm:$src2),
6754              "vcvtps2ph\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
6755               []>, EVEX_K;
6756 }
6757 multiclass avx512_cvtps2ph_sae<X86VectorVTInfo _dest, X86VectorVTInfo _src> {
6758   let hasSideEffects = 0 in
6759   defm rb : AVX512_maskable_in_asm<0x1D, MRMDestReg, _dest,
6760                    (outs _dest.RC:$dst),
6761                    (ins _src.RC:$src1, i32u8imm:$src2),
6762                    "vcvtps2ph", "$src2, {sae}, $src1", "$src1, {sae}, $src2",
6763                    []>, EVEX_B, AVX512AIi8Base;
6764 }
6765 let Predicates = [HasAVX512] in {
6766   defm VCVTPS2PHZ : avx512_cvtps2ph<v16i16x_info, v16f32_info, f256mem>,
6767                     avx512_cvtps2ph_sae<v16i16x_info, v16f32_info>,
6768                       EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>;
6769   let Predicates = [HasVLX] in {
6770     defm VCVTPS2PHZ256 : avx512_cvtps2ph<v8i16x_info, v8f32x_info, f128mem>,
6771                         EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>;
6772     defm VCVTPS2PHZ128 : avx512_cvtps2ph<v8i16x_info, v4f32x_info, f128mem>,
6773                         EVEX, EVEX_V128, EVEX_CD8<32, CD8VH>;
6774   }
6775 }
6776
6777 // Patterns for matching conversions from float to half-float and vice versa.
6778 let Predicates = [HasVLX] in {
6779   // Use MXCSR.RC for rounding instead of explicitly specifying the default
6780   // rounding mode (Nearest-Even, encoded as 0). Both are equivalent in the
6781   // configurations we support (the default). However, falling back to MXCSR is
6782   // more consistent with other instructions, which are always controlled by it.
6783   // It's encoded as 0b100.
6784   def : Pat<(fp_to_f16 FR32X:$src),
6785             (i16 (EXTRACT_SUBREG (VMOVPDI2DIZrr (VCVTPS2PHZ128rr
6786               (COPY_TO_REGCLASS FR32X:$src, VR128X), 4)), sub_16bit))>;
6787
6788   def : Pat<(f16_to_fp GR16:$src),
6789             (f32 (COPY_TO_REGCLASS (VCVTPH2PSZ128rr
6790               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128X)), FR32X)) >;
6791
6792   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32X:$src))),
6793             (f32 (COPY_TO_REGCLASS (VCVTPH2PSZ128rr
6794               (VCVTPS2PHZ128rr (COPY_TO_REGCLASS FR32X:$src, VR128X), 4)), FR32X)) >;
6795 }
6796
6797 // Patterns for matching float to half-float conversion when AVX512 is supported
6798 // but F16C isn't. In that case we have to use 512-bit vectors.
6799 let Predicates = [HasAVX512, NoVLX, NoF16C] in {
6800   def : Pat<(fp_to_f16 FR32X:$src),
6801             (i16 (EXTRACT_SUBREG
6802                   (VMOVPDI2DIZrr
6803                    (v8i16 (EXTRACT_SUBREG
6804                     (VCVTPS2PHZrr
6805                      (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
6806                       (v4f32 (COPY_TO_REGCLASS FR32X:$src, VR128X)),
6807                       sub_xmm), 4), sub_xmm))), sub_16bit))>;
6808
6809   def : Pat<(f16_to_fp GR16:$src),
6810             (f32 (COPY_TO_REGCLASS
6811                   (v4f32 (EXTRACT_SUBREG
6812                    (VCVTPH2PSZrr
6813                     (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)),
6814                      (v8i16 (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128X)),
6815                      sub_xmm)), sub_xmm)), FR32X))>;
6816
6817   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32X:$src))),
6818             (f32 (COPY_TO_REGCLASS
6819                   (v4f32 (EXTRACT_SUBREG
6820                           (VCVTPH2PSZrr
6821                            (VCVTPS2PHZrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
6822                             (v4f32 (COPY_TO_REGCLASS FR32X:$src, VR128X)),
6823                             sub_xmm), 4)), sub_xmm)), FR32X))>;
6824 }
6825
6826 //  Unordered/Ordered scalar fp compare with Sea and set EFLAGS
6827 multiclass avx512_ord_cmp_sae<bits<8> opc, X86VectorVTInfo _,
6828                             string OpcodeStr> {
6829   def rb: AVX512<opc, MRMSrcReg, (outs), (ins _.RC:$src1, _.RC:$src2),
6830                  !strconcat(OpcodeStr, "\t{{sae}, $src2, $src1|$src1, $src2, {sae}}"),
6831                  [], IIC_SSE_COMIS_RR>, EVEX, EVEX_B, VEX_LIG, EVEX_V128,
6832                  Sched<[WriteFAdd]>;
6833 }
6834
6835 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
6836   defm VUCOMISSZ : avx512_ord_cmp_sae<0x2E, v4f32x_info, "vucomiss">,
6837                                    AVX512PSIi8Base, EVEX_CD8<32, CD8VT1>;
6838   defm VUCOMISDZ : avx512_ord_cmp_sae<0x2E, v2f64x_info, "vucomisd">,
6839                                    AVX512PDIi8Base, VEX_W, EVEX_CD8<64, CD8VT1>;
6840   defm VCOMISSZ : avx512_ord_cmp_sae<0x2F, v4f32x_info, "vcomiss">,
6841                                    AVX512PSIi8Base, EVEX_CD8<32, CD8VT1>;
6842   defm VCOMISDZ : avx512_ord_cmp_sae<0x2F, v2f64x_info, "vcomisd">,
6843                                    AVX512PDIi8Base, VEX_W, EVEX_CD8<64, CD8VT1>;
6844 }
6845
6846 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
6847   defm VUCOMISSZ : sse12_ord_cmp<0x2E, FR32X, X86cmp, f32, f32mem, loadf32,
6848                                  "ucomiss">, PS, EVEX, VEX_LIG,
6849                                  EVEX_CD8<32, CD8VT1>;
6850   defm VUCOMISDZ : sse12_ord_cmp<0x2E, FR64X, X86cmp, f64, f64mem, loadf64,
6851                                   "ucomisd">, PD, EVEX,
6852                                   VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6853   let Pattern = []<dag> in {
6854     defm VCOMISSZ  : sse12_ord_cmp<0x2F, FR32X, undef, f32, f32mem, loadf32,
6855                                    "comiss">, PS, EVEX, VEX_LIG,
6856                                    EVEX_CD8<32, CD8VT1>;
6857     defm VCOMISDZ  : sse12_ord_cmp<0x2F, FR64X, undef, f64, f64mem, loadf64,
6858                                    "comisd">, PD, EVEX,
6859                                     VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6860   }
6861   let isCodeGenOnly = 1 in {
6862     defm Int_VUCOMISSZ  : sse12_ord_cmp_int<0x2E, VR128X, X86ucomi, v4f32, ssmem,
6863                               sse_load_f32, "ucomiss">, PS, EVEX, VEX_LIG,
6864                               EVEX_CD8<32, CD8VT1>;
6865     defm Int_VUCOMISDZ  : sse12_ord_cmp_int<0x2E, VR128X, X86ucomi, v2f64, sdmem,
6866                               sse_load_f64, "ucomisd">, PD, EVEX,
6867                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6868
6869     defm Int_VCOMISSZ  : sse12_ord_cmp_int<0x2F, VR128X, X86comi, v4f32, ssmem,
6870                               sse_load_f32, "comiss">, PS, EVEX, VEX_LIG,
6871                               EVEX_CD8<32, CD8VT1>;
6872     defm Int_VCOMISDZ  : sse12_ord_cmp_int<0x2F, VR128X, X86comi, v2f64, sdmem,
6873                               sse_load_f64, "comisd">, PD, EVEX,
6874                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6875   }
6876 }
6877
6878 /// avx512_fp14_s rcp14ss, rcp14sd, rsqrt14ss, rsqrt14sd
6879 multiclass avx512_fp14_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
6880                             X86VectorVTInfo _> {
6881   let AddedComplexity = 20 , Predicates = [HasAVX512] in {
6882   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6883                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6884                            "$src2, $src1", "$src1, $src2",
6885                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>, EVEX_4V;
6886   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6887                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
6888                          "$src2, $src1", "$src1, $src2",
6889                          (OpNode (_.VT _.RC:$src1),
6890                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))))>, EVEX_4V;
6891 }
6892 }
6893
6894 defm VRCP14SS   : avx512_fp14_s<0x4D, "vrcp14ss", X86frcp14s, f32x_info>,
6895                   EVEX_CD8<32, CD8VT1>, T8PD;
6896 defm VRCP14SD   : avx512_fp14_s<0x4D, "vrcp14sd", X86frcp14s, f64x_info>,
6897                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
6898 defm VRSQRT14SS   : avx512_fp14_s<0x4F, "vrsqrt14ss", X86frsqrt14s, f32x_info>,
6899                   EVEX_CD8<32, CD8VT1>, T8PD;
6900 defm VRSQRT14SD   : avx512_fp14_s<0x4F, "vrsqrt14sd", X86frsqrt14s, f64x_info>,
6901                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
6902
6903 /// avx512_fp14_p rcp14ps, rcp14pd, rsqrt14ps, rsqrt14pd
6904 multiclass avx512_fp14_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
6905                          X86VectorVTInfo _> {
6906   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6907                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
6908                          (_.FloatVT (OpNode _.RC:$src))>, EVEX, T8PD;
6909   defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6910                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
6911                          (OpNode (_.FloatVT
6912                            (bitconvert (_.LdFrag addr:$src))))>, EVEX, T8PD;
6913   defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6914                           (ins _.ScalarMemOp:$src), OpcodeStr,
6915                           "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
6916                           (OpNode (_.FloatVT
6917                             (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
6918                           EVEX, T8PD, EVEX_B;
6919 }
6920
6921 multiclass avx512_fp14_p_vl_all<bits<8> opc, string OpcodeStr, SDNode OpNode> {
6922   defm PSZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"), OpNode, v16f32_info>,
6923                           EVEX_V512, EVEX_CD8<32, CD8VF>;
6924   defm PDZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"), OpNode, v8f64_info>,
6925                           EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
6926
6927   // Define only if AVX512VL feature is present.
6928   let Predicates = [HasVLX] in {
6929     defm PSZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
6930                                 OpNode, v4f32x_info>,
6931                                EVEX_V128, EVEX_CD8<32, CD8VF>;
6932     defm PSZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
6933                                 OpNode, v8f32x_info>,
6934                                EVEX_V256, EVEX_CD8<32, CD8VF>;
6935     defm PDZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
6936                                 OpNode, v2f64x_info>,
6937                                EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
6938     defm PDZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
6939                                 OpNode, v4f64x_info>,
6940                                EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
6941   }
6942 }
6943
6944 defm VRSQRT14 : avx512_fp14_p_vl_all<0x4E, "vrsqrt14", X86frsqrt>;
6945 defm VRCP14 : avx512_fp14_p_vl_all<0x4C, "vrcp14", X86frcp>;
6946
6947 /// avx512_fp28_s rcp28ss, rcp28sd, rsqrt28ss, rsqrt28sd
6948 multiclass avx512_fp28_s<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
6949                          SDNode OpNode> {
6950
6951   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6952                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6953                            "$src2, $src1", "$src1, $src2",
6954                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
6955                            (i32 FROUND_CURRENT))>;
6956
6957   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6958                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6959                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
6960                             (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
6961                             (i32 FROUND_NO_EXC))>, EVEX_B;
6962
6963   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6964                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
6965                          "$src2, $src1", "$src1, $src2",
6966                          (OpNode (_.VT _.RC:$src1),
6967                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
6968                          (i32 FROUND_CURRENT))>;
6969 }
6970
6971 multiclass avx512_eri_s<bits<8> opc, string OpcodeStr, SDNode OpNode> {
6972   defm SS : avx512_fp28_s<opc, OpcodeStr#"ss", f32x_info, OpNode>,
6973               EVEX_CD8<32, CD8VT1>;
6974   defm SD : avx512_fp28_s<opc, OpcodeStr#"sd", f64x_info, OpNode>,
6975               EVEX_CD8<64, CD8VT1>, VEX_W;
6976 }
6977
6978 let Predicates = [HasERI] in {
6979   defm VRCP28   : avx512_eri_s<0xCB, "vrcp28",   X86rcp28s>,   T8PD, EVEX_4V;
6980   defm VRSQRT28 : avx512_eri_s<0xCD, "vrsqrt28", X86rsqrt28s>, T8PD, EVEX_4V;
6981 }
6982
6983 defm VGETEXP   : avx512_eri_s<0x43, "vgetexp", X86fgetexpRnds>, T8PD, EVEX_4V;
6984 /// avx512_fp28_p rcp28ps, rcp28pd, rsqrt28ps, rsqrt28pd
6985
6986 multiclass avx512_fp28_p<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6987                          SDNode OpNode> {
6988
6989   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6990                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
6991                          (OpNode (_.VT _.RC:$src), (i32 FROUND_CURRENT))>;
6992
6993   defm m : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6994                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
6995                          (OpNode (_.FloatVT
6996                              (bitconvert (_.LdFrag addr:$src))),
6997                           (i32 FROUND_CURRENT))>;
6998
6999   defm mb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7000                          (ins _.ScalarMemOp:$src), OpcodeStr,
7001                          "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
7002                          (OpNode (_.FloatVT
7003                                   (X86VBroadcast (_.ScalarLdFrag addr:$src))),
7004                                  (i32 FROUND_CURRENT))>, EVEX_B;
7005 }
7006 multiclass avx512_fp28_p_round<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7007                          SDNode OpNode> {
7008   defm rb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7009                         (ins _.RC:$src), OpcodeStr,
7010                         "{sae}, $src", "$src, {sae}",
7011                         (OpNode (_.VT _.RC:$src), (i32 FROUND_NO_EXC))>, EVEX_B;
7012 }
7013
7014 multiclass  avx512_eri<bits<8> opc, string OpcodeStr, SDNode OpNode> {
7015    defm PS : avx512_fp28_p<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
7016              avx512_fp28_p_round<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
7017              T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
7018    defm PD : avx512_fp28_p<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
7019              avx512_fp28_p_round<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
7020              T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
7021 }
7022
7023 multiclass avx512_fp_unaryop_packed<bits<8> opc, string OpcodeStr,
7024                                   SDNode OpNode> {
7025   // Define only if AVX512VL feature is present.
7026   let Predicates = [HasVLX] in {
7027     defm PSZ128 : avx512_fp28_p<opc, OpcodeStr#"ps", v4f32x_info, OpNode>,
7028                                      EVEX_V128, T8PD, EVEX_CD8<32, CD8VF>;
7029     defm PSZ256 : avx512_fp28_p<opc, OpcodeStr#"ps", v8f32x_info, OpNode>,
7030                                      EVEX_V256, T8PD, EVEX_CD8<32, CD8VF>;
7031     defm PDZ128 : avx512_fp28_p<opc, OpcodeStr#"pd", v2f64x_info, OpNode>,
7032                                      EVEX_V128, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
7033     defm PDZ256 : avx512_fp28_p<opc, OpcodeStr#"pd", v4f64x_info, OpNode>,
7034                                      EVEX_V256, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
7035   }
7036 }
7037 let Predicates = [HasERI] in {
7038
7039  defm VRSQRT28 : avx512_eri<0xCC, "vrsqrt28", X86rsqrt28>, EVEX;
7040  defm VRCP28   : avx512_eri<0xCA, "vrcp28",   X86rcp28>,   EVEX;
7041  defm VEXP2    : avx512_eri<0xC8, "vexp2",    X86exp2>,    EVEX;
7042 }
7043 defm VGETEXP   : avx512_eri<0x42, "vgetexp", X86fgetexpRnd>,
7044                  avx512_fp_unaryop_packed<0x42, "vgetexp", X86fgetexpRnd> , EVEX;
7045
7046 multiclass avx512_sqrt_packed_round<bits<8> opc, string OpcodeStr,
7047                               SDNode OpNodeRnd, X86VectorVTInfo _>{
7048   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7049                          (ins _.RC:$src, AVX512RC:$rc), OpcodeStr, "$rc, $src", "$src, $rc",
7050                          (_.VT (OpNodeRnd _.RC:$src, (i32 imm:$rc)))>,
7051                          EVEX, EVEX_B, EVEX_RC;
7052 }
7053
7054 multiclass avx512_sqrt_packed<bits<8> opc, string OpcodeStr,
7055                               SDNode OpNode, X86VectorVTInfo _>{
7056   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7057                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
7058                          (_.FloatVT (OpNode _.RC:$src))>, EVEX;
7059   defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7060                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
7061                          (OpNode (_.FloatVT
7062                            (bitconvert (_.LdFrag addr:$src))))>, EVEX;
7063
7064   defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7065                           (ins _.ScalarMemOp:$src), OpcodeStr,
7066                           "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
7067                           (OpNode (_.FloatVT
7068                             (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
7069                           EVEX, EVEX_B;
7070 }
7071
7072 multiclass avx512_sqrt_packed_all<bits<8> opc, string OpcodeStr,
7073                                   SDNode OpNode> {
7074   defm PSZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
7075                                 v16f32_info>,
7076                                 EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
7077   defm PDZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
7078                                 v8f64_info>,
7079                                 EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7080   // Define only if AVX512VL feature is present.
7081   let Predicates = [HasVLX] in {
7082     defm PSZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
7083                                      OpNode, v4f32x_info>,
7084                                      EVEX_V128, PS, EVEX_CD8<32, CD8VF>;
7085     defm PSZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
7086                                      OpNode, v8f32x_info>,
7087                                      EVEX_V256, PS, EVEX_CD8<32, CD8VF>;
7088     defm PDZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
7089                                      OpNode, v2f64x_info>,
7090                                      EVEX_V128, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7091     defm PDZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
7092                                      OpNode, v4f64x_info>,
7093                                      EVEX_V256, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7094   }
7095 }
7096
7097 multiclass avx512_sqrt_packed_all_round<bits<8> opc, string OpcodeStr,
7098                                           SDNode OpNodeRnd> {
7099   defm PSZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "ps"), OpNodeRnd,
7100                                 v16f32_info>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
7101   defm PDZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "pd"), OpNodeRnd,
7102                                 v8f64_info>, EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7103 }
7104
7105 multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
7106                               string SUFF, SDNode OpNode, SDNode OpNodeRnd> {
7107
7108   defm r_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7109                          (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
7110                          "$src2, $src1", "$src1, $src2",
7111                          (OpNodeRnd (_.VT _.RC:$src1),
7112                                     (_.VT _.RC:$src2),
7113                                     (i32 FROUND_CURRENT))>;
7114   defm m_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7115                        (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
7116                        "$src2, $src1", "$src1, $src2",
7117                        (OpNodeRnd (_.VT _.RC:$src1),
7118                                   (_.VT (scalar_to_vector
7119                                             (_.ScalarLdFrag addr:$src2))),
7120                                   (i32 FROUND_CURRENT))>;
7121
7122   defm rb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7123                          (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
7124                          "$rc, $src2, $src1", "$src1, $src2, $rc",
7125                          (OpNodeRnd (_.VT _.RC:$src1),
7126                                      (_.VT _.RC:$src2),
7127                                      (i32 imm:$rc))>,
7128                          EVEX_B, EVEX_RC;
7129
7130   let isCodeGenOnly = 1, hasSideEffects = 0 in {
7131     def r : I<opc, MRMSrcReg, (outs _.FRC:$dst),
7132                (ins _.FRC:$src1, _.FRC:$src2),
7133                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
7134
7135     let mayLoad = 1 in
7136       def m : I<opc, MRMSrcMem, (outs _.FRC:$dst),
7137                  (ins _.FRC:$src1, _.ScalarMemOp:$src2),
7138                  OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
7139   }
7140
7141   def : Pat<(_.EltVT (OpNode _.FRC:$src)),
7142             (!cast<Instruction>(NAME#SUFF#Zr)
7143                 (_.EltVT (IMPLICIT_DEF)), _.FRC:$src)>;
7144
7145   def : Pat<(_.EltVT (OpNode (load addr:$src))),
7146             (!cast<Instruction>(NAME#SUFF#Zm)
7147                 (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[HasAVX512, OptForSize]>;
7148 }
7149
7150 multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> {
7151   defm SSZ : avx512_sqrt_scalar<opc, OpcodeStr#"ss", f32x_info, "SS", fsqrt,
7152                         X86fsqrtRnds>, EVEX_CD8<32, CD8VT1>, EVEX_4V, XS;
7153   defm SDZ : avx512_sqrt_scalar<opc, OpcodeStr#"sd", f64x_info, "SD", fsqrt,
7154                         X86fsqrtRnds>, EVEX_CD8<64, CD8VT1>, EVEX_4V, XD, VEX_W;
7155 }
7156
7157 defm VSQRT   : avx512_sqrt_packed_all<0x51, "vsqrt", fsqrt>,
7158                avx512_sqrt_packed_all_round<0x51, "vsqrt", X86fsqrtRnd>;
7159
7160 defm VSQRT   : avx512_sqrt_scalar_all<0x51, "vsqrt">, VEX_LIG;
7161
7162 let Predicates = [HasAVX512] in {
7163   def : Pat<(f32 (X86frsqrt FR32X:$src)),
7164             (COPY_TO_REGCLASS (VRSQRT14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>;
7165   def : Pat<(f32 (X86frsqrt (load addr:$src))),
7166             (COPY_TO_REGCLASS (VRSQRT14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
7167             Requires<[OptForSize]>;
7168   def : Pat<(f32 (X86frcp FR32X:$src)),
7169             (COPY_TO_REGCLASS (VRCP14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X )>;
7170   def : Pat<(f32 (X86frcp (load addr:$src))),
7171             (COPY_TO_REGCLASS (VRCP14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
7172             Requires<[OptForSize]>;
7173 }
7174
7175 multiclass
7176 avx512_rndscale_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
7177
7178   let ExeDomain = _.ExeDomain in {
7179   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7180                            (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
7181                            "$src3, $src2, $src1", "$src1, $src2, $src3",
7182                            (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7183                             (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
7184
7185   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7186                          (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
7187                          "$src3, {sae}, $src2, $src1", "$src1, $src2, {sae}, $src3",
7188                          (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7189                          (i32 imm:$src3), (i32 FROUND_NO_EXC)))>, EVEX_B;
7190
7191   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7192                          (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
7193                          OpcodeStr,
7194                          "$src3, $src2, $src1", "$src1, $src2, $src3",
7195                          (_.VT (X86RndScales (_.VT _.RC:$src1),
7196                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
7197                           (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
7198   }
7199   let Predicates = [HasAVX512] in {
7200   def : Pat<(ffloor _.FRC:$src), (COPY_TO_REGCLASS
7201              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7202              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x1))), _.FRC)>;
7203   def : Pat<(fceil _.FRC:$src), (COPY_TO_REGCLASS
7204              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7205              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x2))), _.FRC)>;
7206   def : Pat<(ftrunc _.FRC:$src), (COPY_TO_REGCLASS
7207              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7208              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x3))), _.FRC)>;
7209   def : Pat<(frint _.FRC:$src), (COPY_TO_REGCLASS
7210              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7211              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x4))), _.FRC)>;
7212   def : Pat<(fnearbyint _.FRC:$src), (COPY_TO_REGCLASS
7213              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7214              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0xc))), _.FRC)>;
7215
7216   def : Pat<(ffloor (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7217              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7218              addr:$src, (i32 0x1))), _.FRC)>;
7219   def : Pat<(fceil (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7220              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7221              addr:$src, (i32 0x2))), _.FRC)>;
7222   def : Pat<(ftrunc (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7223              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7224              addr:$src, (i32 0x3))), _.FRC)>;
7225   def : Pat<(frint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7226              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7227              addr:$src, (i32 0x4))), _.FRC)>;
7228   def : Pat<(fnearbyint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7229              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7230              addr:$src, (i32 0xc))), _.FRC)>;
7231   }
7232 }
7233
7234 defm VRNDSCALESS : avx512_rndscale_scalar<0x0A, "vrndscaless", f32x_info>,
7235                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VT1>;
7236
7237 defm VRNDSCALESD : avx512_rndscale_scalar<0x0B, "vrndscalesd", f64x_info>, VEX_W,
7238                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VT1>;
7239
7240 //-------------------------------------------------
7241 // Integer truncate and extend operations
7242 //-------------------------------------------------
7243
7244 multiclass avx512_trunc_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
7245                               X86VectorVTInfo SrcInfo, X86VectorVTInfo DestInfo,
7246                               X86MemOperand x86memop> {
7247   let ExeDomain = DestInfo.ExeDomain in
7248   defm rr  : AVX512_maskable<opc, MRMDestReg, DestInfo, (outs DestInfo.RC:$dst),
7249                       (ins SrcInfo.RC:$src1), OpcodeStr ,"$src1", "$src1",
7250                       (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1)))>,
7251                        EVEX, T8XS;
7252
7253   // for intrinsic patter match
7254   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7255                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7256                            undef)),
7257             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
7258                                       SrcInfo.RC:$src1)>;
7259
7260   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7261                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7262                            DestInfo.ImmAllZerosV)),
7263             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
7264                                       SrcInfo.RC:$src1)>;
7265
7266   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7267                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7268                            DestInfo.RC:$src0)),
7269             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrk) DestInfo.RC:$src0,
7270                                       DestInfo.KRCWM:$mask ,
7271                                       SrcInfo.RC:$src1)>;
7272
7273   let mayStore = 1, mayLoad = 1, hasSideEffects = 0,
7274       ExeDomain = DestInfo.ExeDomain in {
7275     def mr : AVX512XS8I<opc, MRMDestMem, (outs),
7276                (ins x86memop:$dst, SrcInfo.RC:$src),
7277                OpcodeStr # "\t{$src, $dst|$dst, $src}",
7278                []>, EVEX;
7279
7280     def mrk : AVX512XS8I<opc, MRMDestMem, (outs),
7281                (ins x86memop:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src),
7282                OpcodeStr # "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}",
7283                []>, EVEX, EVEX_K;
7284   }//mayStore = 1, mayLoad = 1, hasSideEffects = 0
7285 }
7286
7287 multiclass avx512_trunc_mr_lowering<X86VectorVTInfo SrcInfo,
7288                                     X86VectorVTInfo DestInfo,
7289                                     PatFrag truncFrag, PatFrag mtruncFrag > {
7290
7291   def : Pat<(truncFrag (SrcInfo.VT SrcInfo.RC:$src), addr:$dst),
7292             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr)
7293                                     addr:$dst, SrcInfo.RC:$src)>;
7294
7295   def : Pat<(mtruncFrag addr:$dst, SrcInfo.KRCWM:$mask,
7296                                                (SrcInfo.VT SrcInfo.RC:$src)),
7297             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk)
7298                             addr:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src)>;
7299 }
7300
7301 multiclass avx512_trunc<bits<8> opc, string OpcodeStr, SDNode OpNode,
7302          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
7303          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
7304          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
7305          X86MemOperand x86memopZ, PatFrag truncFrag, PatFrag mtruncFrag,
7306                                                      Predicate prd = HasAVX512>{
7307
7308   let Predicates = [HasVLX, prd] in {
7309     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
7310                              DestInfoZ128, x86memopZ128>,
7311                 avx512_trunc_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
7312                              truncFrag, mtruncFrag>, EVEX_V128;
7313
7314     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
7315                              DestInfoZ256, x86memopZ256>,
7316                 avx512_trunc_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
7317                              truncFrag, mtruncFrag>, EVEX_V256;
7318   }
7319   let Predicates = [prd] in
7320     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
7321                              DestInfoZ, x86memopZ>,
7322                 avx512_trunc_mr_lowering<VTSrcInfo.info512, DestInfoZ,
7323                              truncFrag, mtruncFrag>, EVEX_V512;
7324 }
7325
7326 multiclass avx512_trunc_qb<bits<8> opc, string OpcodeStr, SDNode OpNode,
7327                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7328   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7329                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
7330                StoreNode, MaskedStoreNode>, EVEX_CD8<8, CD8VO>;
7331 }
7332
7333 multiclass avx512_trunc_qw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7334                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7335   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7336                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
7337                StoreNode, MaskedStoreNode>, EVEX_CD8<16, CD8VQ>;
7338 }
7339
7340 multiclass avx512_trunc_qd<bits<8> opc, string OpcodeStr, SDNode OpNode,
7341                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7342   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7343                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
7344                StoreNode, MaskedStoreNode>, EVEX_CD8<32, CD8VH>;
7345 }
7346
7347 multiclass avx512_trunc_db<bits<8> opc, string OpcodeStr, SDNode OpNode,
7348                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7349   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
7350                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
7351                StoreNode, MaskedStoreNode>, EVEX_CD8<8, CD8VQ>;
7352 }
7353
7354 multiclass avx512_trunc_dw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7355                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7356   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
7357               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
7358               StoreNode, MaskedStoreNode>, EVEX_CD8<16, CD8VH>;
7359 }
7360
7361 multiclass avx512_trunc_wb<bits<8> opc, string OpcodeStr, SDNode OpNode,
7362                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7363   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i16_info,
7364               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
7365               StoreNode, MaskedStoreNode, HasBWI>, EVEX_CD8<16, CD8VH>;
7366 }
7367
7368 defm VPMOVQB    : avx512_trunc_qb<0x32, "vpmovqb",   X86vtrunc,
7369                                   truncstorevi8, masked_truncstorevi8>;
7370 defm VPMOVSQB   : avx512_trunc_qb<0x22, "vpmovsqb",  X86vtruncs,
7371                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7372 defm VPMOVUSQB  : avx512_trunc_qb<0x12, "vpmovusqb", X86vtruncus,
7373                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7374
7375 defm VPMOVQW    : avx512_trunc_qw<0x34, "vpmovqw",   X86vtrunc,
7376                                   truncstorevi16, masked_truncstorevi16>;
7377 defm VPMOVSQW   : avx512_trunc_qw<0x24, "vpmovsqw",  X86vtruncs,
7378                                   truncstore_s_vi16, masked_truncstore_s_vi16>;
7379 defm VPMOVUSQW  : avx512_trunc_qw<0x14, "vpmovusqw", X86vtruncus,
7380                                   truncstore_us_vi16, masked_truncstore_us_vi16>;
7381
7382 defm VPMOVQD    : avx512_trunc_qd<0x35, "vpmovqd",   X86vtrunc,
7383                                   truncstorevi32, masked_truncstorevi32>;
7384 defm VPMOVSQD   : avx512_trunc_qd<0x25, "vpmovsqd",  X86vtruncs,
7385                                   truncstore_s_vi32, masked_truncstore_s_vi32>;
7386 defm VPMOVUSQD  : avx512_trunc_qd<0x15, "vpmovusqd", X86vtruncus,
7387                                   truncstore_us_vi32, masked_truncstore_us_vi32>;
7388
7389 defm VPMOVDB    : avx512_trunc_db<0x31, "vpmovdb", X86vtrunc,
7390                                   truncstorevi8, masked_truncstorevi8>;
7391 defm VPMOVSDB   : avx512_trunc_db<0x21, "vpmovsdb",   X86vtruncs,
7392                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7393 defm VPMOVUSDB  : avx512_trunc_db<0x11, "vpmovusdb",  X86vtruncus,
7394                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7395
7396 defm VPMOVDW    : avx512_trunc_dw<0x33, "vpmovdw", X86vtrunc,
7397                                   truncstorevi16, masked_truncstorevi16>;
7398 defm VPMOVSDW   : avx512_trunc_dw<0x23, "vpmovsdw",   X86vtruncs,
7399                                   truncstore_s_vi16, masked_truncstore_s_vi16>;
7400 defm VPMOVUSDW  : avx512_trunc_dw<0x13, "vpmovusdw",  X86vtruncus,
7401                                   truncstore_us_vi16, masked_truncstore_us_vi16>;
7402
7403 defm VPMOVWB    : avx512_trunc_wb<0x30, "vpmovwb", X86vtrunc,
7404                                   truncstorevi8, masked_truncstorevi8>;
7405 defm VPMOVSWB   : avx512_trunc_wb<0x20, "vpmovswb",   X86vtruncs,
7406                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7407 defm VPMOVUSWB  : avx512_trunc_wb<0x10, "vpmovuswb",  X86vtruncus,
7408                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7409
7410 let Predicates = [HasAVX512, NoVLX] in {
7411 def: Pat<(v8i16 (X86vtrunc (v8i32 VR256X:$src))),
7412          (v8i16 (EXTRACT_SUBREG
7413                  (v16i16 (VPMOVDWZrr (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
7414                                           VR256X:$src, sub_ymm)))), sub_xmm))>;
7415 def: Pat<(v4i32 (X86vtrunc (v4i64 VR256X:$src))),
7416          (v4i32 (EXTRACT_SUBREG
7417                  (v8i32 (VPMOVQDZrr (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
7418                                            VR256X:$src, sub_ymm)))), sub_xmm))>;
7419 }
7420
7421 let Predicates = [HasBWI, NoVLX] in {
7422 def: Pat<(v16i8 (X86vtrunc (v16i16 VR256X:$src))),
7423          (v16i8 (EXTRACT_SUBREG (VPMOVWBZrr (v32i16 (INSERT_SUBREG (IMPLICIT_DEF),
7424                                             VR256X:$src, sub_ymm))), sub_xmm))>;
7425 }
7426
7427 multiclass avx512_extend_common<bits<8> opc, string OpcodeStr,
7428               X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo,
7429               X86MemOperand x86memop, PatFrag LdFrag, SDPatternOperator OpNode>{
7430   let ExeDomain = DestInfo.ExeDomain in {
7431   defm rr   : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
7432                     (ins SrcInfo.RC:$src), OpcodeStr ,"$src", "$src",
7433                     (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src)))>,
7434                   EVEX;
7435
7436   defm rm : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
7437                   (ins x86memop:$src), OpcodeStr ,"$src", "$src",
7438                   (DestInfo.VT (LdFrag addr:$src))>,
7439                 EVEX;
7440   }
7441 }
7442
7443 multiclass avx512_extend_BW<bits<8> opc, string OpcodeStr,
7444           SDPatternOperator OpNode,
7445           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7446   let Predicates = [HasVLX, HasBWI] in {
7447     defm Z128:  avx512_extend_common<opc, OpcodeStr, v8i16x_info,
7448                     v16i8x_info, i64mem, LdFrag, OpNode>,
7449                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V128;
7450
7451     defm Z256:  avx512_extend_common<opc, OpcodeStr, v16i16x_info,
7452                     v16i8x_info, i128mem, LdFrag, OpNode>,
7453                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V256;
7454   }
7455   let Predicates = [HasBWI] in {
7456     defm Z   :  avx512_extend_common<opc, OpcodeStr, v32i16_info,
7457                     v32i8x_info, i256mem, LdFrag, OpNode>,
7458                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V512;
7459   }
7460 }
7461
7462 multiclass avx512_extend_BD<bits<8> opc, string OpcodeStr,
7463           SDPatternOperator OpNode,
7464           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7465   let Predicates = [HasVLX, HasAVX512] in {
7466     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
7467                    v16i8x_info, i32mem, LdFrag, OpNode>,
7468                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V128;
7469
7470     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
7471                    v16i8x_info, i64mem, LdFrag, OpNode>,
7472                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V256;
7473   }
7474   let Predicates = [HasAVX512] in {
7475     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
7476                    v16i8x_info, i128mem, LdFrag, OpNode>,
7477                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V512;
7478   }
7479 }
7480
7481 multiclass avx512_extend_BQ<bits<8> opc, string OpcodeStr,
7482           SDPatternOperator OpNode,
7483           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7484   let Predicates = [HasVLX, HasAVX512] in {
7485     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7486                    v16i8x_info, i16mem, LdFrag, OpNode>,
7487                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V128;
7488
7489     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7490                    v16i8x_info, i32mem, LdFrag, OpNode>,
7491                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V256;
7492   }
7493   let Predicates = [HasAVX512] in {
7494     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7495                    v16i8x_info, i64mem, LdFrag, OpNode>,
7496                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V512;
7497   }
7498 }
7499
7500 multiclass avx512_extend_WD<bits<8> opc, string OpcodeStr,
7501          SDPatternOperator OpNode,
7502          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
7503   let Predicates = [HasVLX, HasAVX512] in {
7504     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
7505                    v8i16x_info, i64mem, LdFrag, OpNode>,
7506                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V128;
7507
7508     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
7509                    v8i16x_info, i128mem, LdFrag, OpNode>,
7510                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V256;
7511   }
7512   let Predicates = [HasAVX512] in {
7513     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
7514                    v16i16x_info, i256mem, LdFrag, OpNode>,
7515                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V512;
7516   }
7517 }
7518
7519 multiclass avx512_extend_WQ<bits<8> opc, string OpcodeStr,
7520          SDPatternOperator OpNode,
7521          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
7522   let Predicates = [HasVLX, HasAVX512] in {
7523     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7524                    v8i16x_info, i32mem, LdFrag, OpNode>,
7525                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V128;
7526
7527     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7528                    v8i16x_info, i64mem, LdFrag, OpNode>,
7529                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V256;
7530   }
7531   let Predicates = [HasAVX512] in {
7532     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7533                    v8i16x_info, i128mem, LdFrag, OpNode>,
7534                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V512;
7535   }
7536 }
7537
7538 multiclass avx512_extend_DQ<bits<8> opc, string OpcodeStr,
7539          SDPatternOperator OpNode,
7540          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi32")> {
7541
7542   let Predicates = [HasVLX, HasAVX512] in {
7543     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7544                    v4i32x_info, i64mem, LdFrag, OpNode>,
7545                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V128;
7546
7547     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7548                    v4i32x_info, i128mem, LdFrag, OpNode>,
7549                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V256;
7550   }
7551   let Predicates = [HasAVX512] in {
7552     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7553                    v8i32x_info, i256mem, LdFrag, OpNode>,
7554                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V512;
7555   }
7556 }
7557
7558 defm VPMOVZXBW : avx512_extend_BW<0x30, "vpmovzxbw", X86vzext, "z">;
7559 defm VPMOVZXBD : avx512_extend_BD<0x31, "vpmovzxbd", X86vzext, "z">;
7560 defm VPMOVZXBQ : avx512_extend_BQ<0x32, "vpmovzxbq", X86vzext, "z">;
7561 defm VPMOVZXWD : avx512_extend_WD<0x33, "vpmovzxwd", X86vzext, "z">;
7562 defm VPMOVZXWQ : avx512_extend_WQ<0x34, "vpmovzxwq", X86vzext, "z">;
7563 defm VPMOVZXDQ : avx512_extend_DQ<0x35, "vpmovzxdq", X86vzext, "z">;
7564
7565 defm VPMOVSXBW: avx512_extend_BW<0x20, "vpmovsxbw", X86vsext, "s">;
7566 defm VPMOVSXBD: avx512_extend_BD<0x21, "vpmovsxbd", X86vsext, "s">;
7567 defm VPMOVSXBQ: avx512_extend_BQ<0x22, "vpmovsxbq", X86vsext, "s">;
7568 defm VPMOVSXWD: avx512_extend_WD<0x23, "vpmovsxwd", X86vsext, "s">;
7569 defm VPMOVSXWQ: avx512_extend_WQ<0x24, "vpmovsxwq", X86vsext, "s">;
7570 defm VPMOVSXDQ: avx512_extend_DQ<0x25, "vpmovsxdq", X86vsext, "s">;
7571
7572 // EXTLOAD patterns, implemented using vpmovz
7573 multiclass avx512_ext_lowering<string InstrStr, X86VectorVTInfo To,
7574                                X86VectorVTInfo From, PatFrag LdFrag> {
7575   def : Pat<(To.VT (LdFrag addr:$src)),
7576             (!cast<Instruction>("VPMOVZX"#InstrStr#"rm") addr:$src)>;
7577   def : Pat<(To.VT (vselect To.KRCWM:$mask, (LdFrag addr:$src), To.RC:$src0)),
7578             (!cast<Instruction>("VPMOVZX"#InstrStr#"rmk") To.RC:$src0,
7579              To.KRC:$mask, addr:$src)>;
7580   def : Pat<(To.VT (vselect To.KRCWM:$mask, (LdFrag addr:$src),
7581                     To.ImmAllZerosV)),
7582             (!cast<Instruction>("VPMOVZX"#InstrStr#"rmkz") To.KRC:$mask,
7583              addr:$src)>;
7584 }
7585
7586 let Predicates = [HasVLX, HasBWI] in {
7587   defm : avx512_ext_lowering<"BWZ128", v8i16x_info,  v16i8x_info,  extloadvi8>;
7588   defm : avx512_ext_lowering<"BWZ256", v16i16x_info, v16i8x_info,  extloadvi8>;
7589 }
7590 let Predicates = [HasBWI] in {
7591   defm : avx512_ext_lowering<"BWZ",    v32i16_info,  v32i8x_info,  extloadvi8>;
7592 }
7593 let Predicates = [HasVLX, HasAVX512] in {
7594   defm : avx512_ext_lowering<"BDZ128", v4i32x_info,  v16i8x_info,  extloadvi8>;
7595   defm : avx512_ext_lowering<"BDZ256", v8i32x_info,  v16i8x_info,  extloadvi8>;
7596   defm : avx512_ext_lowering<"BQZ128", v2i64x_info,  v16i8x_info,  extloadvi8>;
7597   defm : avx512_ext_lowering<"BQZ256", v4i64x_info,  v16i8x_info,  extloadvi8>;
7598   defm : avx512_ext_lowering<"WDZ128", v4i32x_info,  v8i16x_info,  extloadvi16>;
7599   defm : avx512_ext_lowering<"WDZ256", v8i32x_info,  v8i16x_info,  extloadvi16>;
7600   defm : avx512_ext_lowering<"WQZ128", v2i64x_info,  v8i16x_info,  extloadvi16>;
7601   defm : avx512_ext_lowering<"WQZ256", v4i64x_info,  v8i16x_info,  extloadvi16>;
7602   defm : avx512_ext_lowering<"DQZ128", v2i64x_info,  v4i32x_info,  extloadvi32>;
7603   defm : avx512_ext_lowering<"DQZ256", v4i64x_info,  v4i32x_info,  extloadvi32>;
7604 }
7605 let Predicates = [HasAVX512] in {
7606   defm : avx512_ext_lowering<"BDZ",    v16i32_info,  v16i8x_info,  extloadvi8>;
7607   defm : avx512_ext_lowering<"BQZ",    v8i64_info,   v16i8x_info,  extloadvi8>;
7608   defm : avx512_ext_lowering<"WDZ",    v16i32_info,  v16i16x_info, extloadvi16>;
7609   defm : avx512_ext_lowering<"WQZ",    v8i64_info,   v8i16x_info,  extloadvi16>;
7610   defm : avx512_ext_lowering<"DQZ",    v8i64_info,   v8i32x_info,  extloadvi32>;
7611 }
7612
7613 multiclass AVX512_pmovx_patterns<string OpcPrefix, string ExtTy,
7614                                  SDNode ExtOp, PatFrag ExtLoad16> {
7615   // 128-bit patterns
7616   let Predicates = [HasVLX, HasBWI] in {
7617   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7618             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7619   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7620             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7621   def : Pat<(v8i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7622             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7623   def : Pat<(v8i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7624             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7625   def : Pat<(v8i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7626             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7627   }
7628   let Predicates = [HasVLX] in {
7629   def : Pat<(v4i32 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7630             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7631   def : Pat<(v4i32 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7632             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7633   def : Pat<(v4i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7634             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7635   def : Pat<(v4i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7636             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7637
7638   def : Pat<(v2i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (ExtLoad16 addr:$src)))))),
7639             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7640   def : Pat<(v2i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7641             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7642   def : Pat<(v2i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7643             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7644   def : Pat<(v2i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7645             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7646
7647   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7648             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7649   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7650             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7651   def : Pat<(v4i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7652             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7653   def : Pat<(v4i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7654             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7655   def : Pat<(v4i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7656             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7657
7658   def : Pat<(v2i64 (ExtOp (bc_v8i16 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7659             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7660   def : Pat<(v2i64 (ExtOp (v8i16 (vzmovl_v4i32 addr:$src)))),
7661             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7662   def : Pat<(v2i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7663             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7664   def : Pat<(v2i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7665             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7666
7667   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7668             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7669   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7670             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7671   def : Pat<(v2i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
7672             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7673   def : Pat<(v2i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
7674             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7675   def : Pat<(v2i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
7676             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7677   }
7678   // 256-bit patterns
7679   let Predicates = [HasVLX, HasBWI] in {
7680   def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7681             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7682   def : Pat<(v16i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7683             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7684   def : Pat<(v16i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7685             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7686   }
7687   let Predicates = [HasVLX] in {
7688   def : Pat<(v8i32 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7689             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7690   def : Pat<(v8i32 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7691             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7692   def : Pat<(v8i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7693             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7694   def : Pat<(v8i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7695             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7696
7697   def : Pat<(v4i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7698             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7699   def : Pat<(v4i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7700             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7701   def : Pat<(v4i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7702             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7703   def : Pat<(v4i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7704             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7705
7706   def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7707             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7708   def : Pat<(v8i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7709             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7710   def : Pat<(v8i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7711             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7712
7713   def : Pat<(v4i64 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7714             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7715   def : Pat<(v4i64 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7716             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7717   def : Pat<(v4i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7718             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7719   def : Pat<(v4i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7720             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7721
7722   def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
7723             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7724   def : Pat<(v4i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
7725             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7726   def : Pat<(v4i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
7727             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7728   }
7729   // 512-bit patterns
7730   let Predicates = [HasBWI] in {
7731   def : Pat<(v32i16 (ExtOp (bc_v32i8 (loadv4i64 addr:$src)))),
7732             (!cast<I>(OpcPrefix#BWZrm) addr:$src)>;
7733   }
7734   let Predicates = [HasAVX512] in {
7735   def : Pat<(v16i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7736             (!cast<I>(OpcPrefix#BDZrm) addr:$src)>;
7737
7738   def : Pat<(v8i64 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7739             (!cast<I>(OpcPrefix#BQZrm) addr:$src)>;
7740   def : Pat<(v8i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7741             (!cast<I>(OpcPrefix#BQZrm) addr:$src)>;
7742
7743   def : Pat<(v16i32 (ExtOp (bc_v16i16 (loadv4i64 addr:$src)))),
7744             (!cast<I>(OpcPrefix#WDZrm) addr:$src)>;
7745
7746   def : Pat<(v8i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7747             (!cast<I>(OpcPrefix#WQZrm) addr:$src)>;
7748
7749   def : Pat<(v8i64 (ExtOp (bc_v8i32 (loadv4i64 addr:$src)))),
7750             (!cast<I>(OpcPrefix#DQZrm) addr:$src)>;
7751   }
7752 }
7753
7754 defm : AVX512_pmovx_patterns<"VPMOVSX", "s", X86vsext, extloadi32i16>;
7755 defm : AVX512_pmovx_patterns<"VPMOVZX", "z", X86vzext, loadi16_anyext>;
7756
7757 //===----------------------------------------------------------------------===//
7758 // GATHER - SCATTER Operations
7759
7760 multiclass avx512_gather<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7761                          X86MemOperand memop, PatFrag GatherNode> {
7762   let Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb",
7763       ExeDomain = _.ExeDomain in
7764   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst, _.KRCWM:$mask_wb),
7765             (ins _.RC:$src1, _.KRCWM:$mask, memop:$src2),
7766             !strconcat(OpcodeStr#_.Suffix,
7767             "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
7768             [(set _.RC:$dst, _.KRCWM:$mask_wb,
7769               (GatherNode  (_.VT _.RC:$src1), _.KRCWM:$mask,
7770                      vectoraddr:$src2))]>, EVEX, EVEX_K,
7771              EVEX_CD8<_.EltSize, CD8VT1>;
7772 }
7773
7774 multiclass avx512_gather_q_pd<bits<8> dopc, bits<8> qopc,
7775                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7776   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512,
7777                                       vy512mem, mgatherv8i32>, EVEX_V512, VEX_W;
7778   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info512,
7779                                       vz512mem,  mgatherv8i64>, EVEX_V512, VEX_W;
7780 let Predicates = [HasVLX] in {
7781   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
7782                               vx256xmem, mgatherv4i32>, EVEX_V256, VEX_W;
7783   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info256,
7784                               vy256xmem, mgatherv4i64>, EVEX_V256, VEX_W;
7785   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
7786                               vx128xmem, mgatherv4i32>, EVEX_V128, VEX_W;
7787   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7788                               vx128xmem, mgatherv2i64>, EVEX_V128, VEX_W;
7789 }
7790 }
7791
7792 multiclass avx512_gather_d_ps<bits<8> dopc, bits<8> qopc,
7793                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7794   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512, vz512mem,
7795                                        mgatherv16i32>, EVEX_V512;
7796   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info256, vz512mem,
7797                                        mgatherv8i64>, EVEX_V512;
7798 let Predicates = [HasVLX] in {
7799   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
7800                                           vy256xmem, mgatherv8i32>, EVEX_V256;
7801   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7802                                           vy128xmem, mgatherv4i64>, EVEX_V256;
7803   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
7804                                           vx128xmem, mgatherv4i32>, EVEX_V128;
7805   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7806                                           vx64xmem, mgatherv2i64>, EVEX_V128;
7807 }
7808 }
7809
7810
7811 defm VGATHER : avx512_gather_q_pd<0x92, 0x93, avx512vl_f64_info, "vgather", "PD">,
7812                avx512_gather_d_ps<0x92, 0x93, avx512vl_f32_info, "vgather", "PS">;
7813
7814 defm VPGATHER : avx512_gather_q_pd<0x90, 0x91, avx512vl_i64_info, "vpgather", "Q">,
7815                 avx512_gather_d_ps<0x90, 0x91, avx512vl_i32_info, "vpgather", "D">;
7816
7817 multiclass avx512_scatter<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7818                           X86MemOperand memop, PatFrag ScatterNode> {
7819
7820 let mayStore = 1, Constraints = "$mask = $mask_wb", ExeDomain = _.ExeDomain in
7821
7822   def mr  : AVX5128I<opc, MRMDestMem, (outs _.KRCWM:$mask_wb),
7823             (ins memop:$dst, _.KRCWM:$mask, _.RC:$src),
7824             !strconcat(OpcodeStr#_.Suffix,
7825             "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
7826             [(set _.KRCWM:$mask_wb, (ScatterNode (_.VT _.RC:$src),
7827                                      _.KRCWM:$mask,  vectoraddr:$dst))]>,
7828             EVEX, EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
7829 }
7830
7831 multiclass avx512_scatter_q_pd<bits<8> dopc, bits<8> qopc,
7832                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7833   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512,
7834                                       vy512mem, mscatterv8i32>, EVEX_V512, VEX_W;
7835   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info512,
7836                                       vz512mem,  mscatterv8i64>, EVEX_V512, VEX_W;
7837 let Predicates = [HasVLX] in {
7838   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
7839                               vx256xmem, mscatterv4i32>, EVEX_V256, VEX_W;
7840   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info256,
7841                               vy256xmem, mscatterv4i64>, EVEX_V256, VEX_W;
7842   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
7843                               vx128xmem, mscatterv4i32>, EVEX_V128, VEX_W;
7844   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7845                               vx128xmem, mscatterv2i64>, EVEX_V128, VEX_W;
7846 }
7847 }
7848
7849 multiclass avx512_scatter_d_ps<bits<8> dopc, bits<8> qopc,
7850                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7851   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512, vz512mem,
7852                                        mscatterv16i32>, EVEX_V512;
7853   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info256, vz512mem,
7854                                        mscatterv8i64>, EVEX_V512;
7855 let Predicates = [HasVLX] in {
7856   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
7857                                           vy256xmem, mscatterv8i32>, EVEX_V256;
7858   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7859                                           vy128xmem, mscatterv4i64>, EVEX_V256;
7860   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
7861                                           vx128xmem, mscatterv4i32>, EVEX_V128;
7862   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7863                                           vx64xmem, mscatterv2i64>, EVEX_V128;
7864 }
7865 }
7866
7867 defm VSCATTER : avx512_scatter_q_pd<0xA2, 0xA3, avx512vl_f64_info, "vscatter", "PD">,
7868                avx512_scatter_d_ps<0xA2, 0xA3, avx512vl_f32_info, "vscatter", "PS">;
7869
7870 defm VPSCATTER : avx512_scatter_q_pd<0xA0, 0xA1, avx512vl_i64_info, "vpscatter", "Q">,
7871                 avx512_scatter_d_ps<0xA0, 0xA1, avx512vl_i32_info, "vpscatter", "D">;
7872
7873 // prefetch
7874 multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,
7875                        RegisterClass KRC, X86MemOperand memop> {
7876   let Predicates = [HasPFI], hasSideEffects = 1 in
7877   def m  : AVX5128I<opc, F, (outs), (ins KRC:$mask, memop:$src),
7878             !strconcat(OpcodeStr, "\t{$src {${mask}}|{${mask}}, $src}"),
7879             []>, EVEX, EVEX_K;
7880 }
7881
7882 defm VGATHERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dps",
7883                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7884
7885 defm VGATHERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qps",
7886                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7887
7888 defm VGATHERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dpd",
7889                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7890
7891 defm VGATHERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qpd",
7892                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7893
7894 defm VGATHERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dps",
7895                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7896
7897 defm VGATHERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qps",
7898                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7899
7900 defm VGATHERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dpd",
7901                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7902
7903 defm VGATHERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qpd",
7904                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7905
7906 defm VSCATTERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dps",
7907                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7908
7909 defm VSCATTERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qps",
7910                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7911
7912 defm VSCATTERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dpd",
7913                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7914
7915 defm VSCATTERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qpd",
7916                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7917
7918 defm VSCATTERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dps",
7919                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7920
7921 defm VSCATTERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qps",
7922                      VK8WM, vz512mem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7923
7924 defm VSCATTERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dpd",
7925                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7926
7927 defm VSCATTERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qpd",
7928                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7929
7930 // Helper fragments to match sext vXi1 to vXiY.
7931 def v64i1sextv64i8 : PatLeaf<(v64i8
7932                               (X86vsext
7933                                (v64i1 (X86pcmpgtm
7934                                 (bc_v64i8 (v16i32 immAllZerosV)),
7935                                 VR512:$src))))>;
7936 def v32i1sextv32i16 : PatLeaf<(v32i16 (X86vsrai VR512:$src, (i8 15)))>;
7937 def v16i1sextv16i32 : PatLeaf<(v16i32 (X86vsrai VR512:$src, (i8 31)))>;
7938 def v8i1sextv8i64   : PatLeaf<(v8i64 (X86vsrai VR512:$src, (i8 63)))>;
7939
7940 multiclass cvt_by_vec_width<bits<8> opc, X86VectorVTInfo Vec, string OpcodeStr > {
7941 def rr : AVX512XS8I<opc, MRMSrcReg, (outs Vec.RC:$dst), (ins Vec.KRC:$src),
7942                   !strconcat(OpcodeStr##Vec.Suffix, "\t{$src, $dst|$dst, $src}"),
7943                   [(set Vec.RC:$dst, (Vec.VT (X86vsext Vec.KRC:$src)))]>, EVEX;
7944 }
7945
7946 multiclass cvt_mask_by_elt_width<bits<8> opc, AVX512VLVectorVTInfo VTInfo,
7947                                  string OpcodeStr, Predicate prd> {
7948 let Predicates = [prd] in
7949   defm Z : cvt_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
7950
7951   let Predicates = [prd, HasVLX] in {
7952     defm Z256 : cvt_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
7953     defm Z128 : cvt_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
7954   }
7955 }
7956
7957 multiclass avx512_convert_mask_to_vector<string OpcodeStr> {
7958   defm NAME##B : cvt_mask_by_elt_width<0x28, avx512vl_i8_info,  OpcodeStr,
7959                                        HasBWI>;
7960   defm NAME##W : cvt_mask_by_elt_width<0x28, avx512vl_i16_info, OpcodeStr,
7961                                        HasBWI>, VEX_W;
7962   defm NAME##D : cvt_mask_by_elt_width<0x38, avx512vl_i32_info, OpcodeStr,
7963                                        HasDQI>;
7964   defm NAME##Q : cvt_mask_by_elt_width<0x38, avx512vl_i64_info, OpcodeStr,
7965                                        HasDQI>, VEX_W;
7966 }
7967
7968 defm VPMOVM2 : avx512_convert_mask_to_vector<"vpmovm2">;
7969
7970 multiclass convert_vector_to_mask_common<bits<8> opc, X86VectorVTInfo _, string OpcodeStr > {
7971     def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.KRC:$dst), (ins _.RC:$src),
7972                         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7973                         [(set _.KRC:$dst, (X86cvt2mask (_.VT _.RC:$src)))]>, EVEX;
7974 }
7975
7976 // Use 512bit version to implement 128/256 bit in case NoVLX.
7977 multiclass convert_vector_to_mask_lowering<X86VectorVTInfo ExtendInfo,
7978                                                             X86VectorVTInfo _> {
7979
7980   def : Pat<(_.KVT (X86cvt2mask (_.VT _.RC:$src))),
7981             (_.KVT (COPY_TO_REGCLASS
7982                      (!cast<Instruction>(NAME#"Zrr")
7983                        (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
7984                                       _.RC:$src, _.SubRegIdx)),
7985                    _.KRC))>;
7986 }
7987
7988 multiclass avx512_convert_vector_to_mask<bits<8> opc, string OpcodeStr,
7989                                    AVX512VLVectorVTInfo VTInfo, Predicate prd> {
7990   let Predicates = [prd] in
7991     defm Z : convert_vector_to_mask_common <opc, VTInfo.info512, OpcodeStr>,
7992                                             EVEX_V512;
7993
7994   let Predicates = [prd, HasVLX] in {
7995     defm Z256 : convert_vector_to_mask_common<opc, VTInfo.info256, OpcodeStr>,
7996                                               EVEX_V256;
7997     defm Z128 : convert_vector_to_mask_common<opc, VTInfo.info128, OpcodeStr>,
7998                                                EVEX_V128;
7999   }
8000   let Predicates = [prd, NoVLX] in {
8001     defm Z256_Alt : convert_vector_to_mask_lowering<VTInfo.info512, VTInfo.info256>;
8002     defm Z128_Alt : convert_vector_to_mask_lowering<VTInfo.info512, VTInfo.info128>;
8003   }
8004 }
8005
8006 defm VPMOVB2M : avx512_convert_vector_to_mask<0x29, "vpmovb2m",
8007                                               avx512vl_i8_info, HasBWI>;
8008 defm VPMOVW2M : avx512_convert_vector_to_mask<0x29, "vpmovw2m",
8009                                               avx512vl_i16_info, HasBWI>, VEX_W;
8010 defm VPMOVD2M : avx512_convert_vector_to_mask<0x39, "vpmovd2m",
8011                                               avx512vl_i32_info, HasDQI>;
8012 defm VPMOVQ2M : avx512_convert_vector_to_mask<0x39, "vpmovq2m",
8013                                               avx512vl_i64_info, HasDQI>, VEX_W;
8014
8015 //===----------------------------------------------------------------------===//
8016 // AVX-512 - COMPRESS and EXPAND
8017 //
8018
8019 multiclass compress_by_vec_width_common<bits<8> opc, X86VectorVTInfo _,
8020                                  string OpcodeStr> {
8021   defm rr : AVX512_maskable<opc, MRMDestReg, _, (outs _.RC:$dst),
8022               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
8023               (_.VT (X86compress _.RC:$src1))>, AVX5128IBase;
8024
8025   let mayStore = 1, hasSideEffects = 0 in
8026   def mr : AVX5128I<opc, MRMDestMem, (outs),
8027               (ins _.MemOp:$dst, _.RC:$src),
8028               OpcodeStr # "\t{$src, $dst|$dst, $src}",
8029               []>, EVEX_CD8<_.EltSize, CD8VT1>;
8030
8031   def mrk : AVX5128I<opc, MRMDestMem, (outs),
8032               (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
8033               OpcodeStr # "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}",
8034               []>,
8035               EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
8036 }
8037
8038 multiclass compress_by_vec_width_lowering<X86VectorVTInfo _ > {
8039
8040   def : Pat<(X86mCompressingStore addr:$dst, _.KRCWM:$mask,
8041                                                (_.VT _.RC:$src)),
8042             (!cast<Instruction>(NAME#_.ZSuffix##mrk)
8043                             addr:$dst, _.KRCWM:$mask, _.RC:$src)>;
8044 }
8045
8046 multiclass compress_by_elt_width<bits<8> opc, string OpcodeStr,
8047                                  AVX512VLVectorVTInfo VTInfo> {
8048   defm Z : compress_by_vec_width_common<opc, VTInfo.info512, OpcodeStr>,
8049            compress_by_vec_width_lowering<VTInfo.info512>, EVEX_V512;
8050
8051   let Predicates = [HasVLX] in {
8052     defm Z256 : compress_by_vec_width_common<opc, VTInfo.info256, OpcodeStr>,
8053                 compress_by_vec_width_lowering<VTInfo.info256>, EVEX_V256;
8054     defm Z128 : compress_by_vec_width_common<opc, VTInfo.info128, OpcodeStr>,
8055                 compress_by_vec_width_lowering<VTInfo.info128>, EVEX_V128;
8056   }
8057 }
8058
8059 defm VPCOMPRESSD : compress_by_elt_width <0x8B, "vpcompressd", avx512vl_i32_info>,
8060                                          EVEX;
8061 defm VPCOMPRESSQ : compress_by_elt_width <0x8B, "vpcompressq", avx512vl_i64_info>,
8062                                          EVEX, VEX_W;
8063 defm VCOMPRESSPS : compress_by_elt_width <0x8A, "vcompressps", avx512vl_f32_info>,
8064                                          EVEX;
8065 defm VCOMPRESSPD : compress_by_elt_width <0x8A, "vcompresspd", avx512vl_f64_info>,
8066                                          EVEX, VEX_W;
8067
8068 // expand
8069 multiclass expand_by_vec_width<bits<8> opc, X86VectorVTInfo _,
8070                                  string OpcodeStr> {
8071   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8072               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
8073               (_.VT (X86expand _.RC:$src1))>, AVX5128IBase;
8074
8075   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8076               (ins _.MemOp:$src1), OpcodeStr, "$src1", "$src1",
8077               (_.VT (X86expand (_.VT (bitconvert
8078                                       (_.LdFrag addr:$src1)))))>,
8079             AVX5128IBase, EVEX_CD8<_.EltSize, CD8VT1>;
8080 }
8081
8082 multiclass expand_by_vec_width_lowering<X86VectorVTInfo _ > {
8083
8084   def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask, undef)),
8085             (!cast<Instruction>(NAME#_.ZSuffix##rmkz)
8086                                         _.KRCWM:$mask, addr:$src)>;
8087
8088   def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask,
8089                                                (_.VT _.RC:$src0))),
8090             (!cast<Instruction>(NAME#_.ZSuffix##rmk)
8091                             _.RC:$src0, _.KRCWM:$mask, addr:$src)>;
8092 }
8093
8094 multiclass expand_by_elt_width<bits<8> opc, string OpcodeStr,
8095                                  AVX512VLVectorVTInfo VTInfo> {
8096   defm Z : expand_by_vec_width<opc, VTInfo.info512, OpcodeStr>,
8097            expand_by_vec_width_lowering<VTInfo.info512>, EVEX_V512;
8098
8099   let Predicates = [HasVLX] in {
8100     defm Z256 : expand_by_vec_width<opc, VTInfo.info256, OpcodeStr>,
8101                 expand_by_vec_width_lowering<VTInfo.info256>, EVEX_V256;
8102     defm Z128 : expand_by_vec_width<opc, VTInfo.info128, OpcodeStr>,
8103                 expand_by_vec_width_lowering<VTInfo.info128>, EVEX_V128;
8104   }
8105 }
8106
8107 defm VPEXPANDD : expand_by_elt_width <0x89, "vpexpandd", avx512vl_i32_info>,
8108                                          EVEX;
8109 defm VPEXPANDQ : expand_by_elt_width <0x89, "vpexpandq", avx512vl_i64_info>,
8110                                          EVEX, VEX_W;
8111 defm VEXPANDPS : expand_by_elt_width <0x88, "vexpandps", avx512vl_f32_info>,
8112                                          EVEX;
8113 defm VEXPANDPD : expand_by_elt_width <0x88, "vexpandpd", avx512vl_f64_info>,
8114                                          EVEX, VEX_W;
8115
8116 //handle instruction  reg_vec1 = op(reg_vec,imm)
8117 //                               op(mem_vec,imm)
8118 //                               op(broadcast(eltVt),imm)
8119 //all instruction created with FROUND_CURRENT
8120 multiclass avx512_unary_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8121                                       X86VectorVTInfo _>{
8122   let ExeDomain = _.ExeDomain in {
8123   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8124                       (ins _.RC:$src1, i32u8imm:$src2),
8125                       OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
8126                       (OpNode (_.VT _.RC:$src1),
8127                               (i32 imm:$src2),
8128                               (i32 FROUND_CURRENT))>;
8129   defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8130                     (ins _.MemOp:$src1, i32u8imm:$src2),
8131                     OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
8132                     (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
8133                             (i32 imm:$src2),
8134                             (i32 FROUND_CURRENT))>;
8135   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8136                     (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
8137                     OpcodeStr##_.Suffix, "$src2, ${src1}"##_.BroadcastStr,
8138                     "${src1}"##_.BroadcastStr##", $src2",
8139                     (OpNode (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src1))),
8140                             (i32 imm:$src2),
8141                             (i32 FROUND_CURRENT))>, EVEX_B;
8142   }
8143 }
8144
8145 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8146 multiclass avx512_unary_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
8147                                              SDNode OpNode, X86VectorVTInfo _>{
8148   let ExeDomain = _.ExeDomain in
8149   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8150                       (ins _.RC:$src1, i32u8imm:$src2),
8151                       OpcodeStr##_.Suffix, "$src2, {sae}, $src1",
8152                       "$src1, {sae}, $src2",
8153                       (OpNode (_.VT _.RC:$src1),
8154                               (i32 imm:$src2),
8155                               (i32 FROUND_NO_EXC))>, EVEX_B;
8156 }
8157
8158 multiclass avx512_common_unary_fp_sae_packed_imm<string OpcodeStr,
8159             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8160   let Predicates = [prd] in {
8161     defm Z    : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8162                 avx512_unary_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8163                                   EVEX_V512;
8164   }
8165   let Predicates = [prd, HasVLX] in {
8166     defm Z128 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
8167                                   EVEX_V128;
8168     defm Z256 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
8169                                   EVEX_V256;
8170   }
8171 }
8172
8173 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8174 //                               op(reg_vec2,mem_vec,imm)
8175 //                               op(reg_vec2,broadcast(eltVt),imm)
8176 //all instruction created with FROUND_CURRENT
8177 multiclass avx512_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8178                                 X86VectorVTInfo _>{
8179   let ExeDomain = _.ExeDomain in {
8180   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8181                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8182                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8183                       (OpNode (_.VT _.RC:$src1),
8184                               (_.VT _.RC:$src2),
8185                               (i32 imm:$src3),
8186                               (i32 FROUND_CURRENT))>;
8187   defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8188                     (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
8189                     OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8190                     (OpNode (_.VT _.RC:$src1),
8191                             (_.VT (bitconvert (_.LdFrag addr:$src2))),
8192                             (i32 imm:$src3),
8193                             (i32 FROUND_CURRENT))>;
8194   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8195                     (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
8196                     OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
8197                     "$src1, ${src2}"##_.BroadcastStr##", $src3",
8198                     (OpNode (_.VT _.RC:$src1),
8199                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
8200                             (i32 imm:$src3),
8201                             (i32 FROUND_CURRENT))>, EVEX_B;
8202   }
8203 }
8204
8205 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8206 //                               op(reg_vec2,mem_vec,imm)
8207 multiclass avx512_3Op_rm_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
8208                              X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo>{
8209   let ExeDomain = DestInfo.ExeDomain in {
8210   defm rri : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
8211                   (ins SrcInfo.RC:$src1, SrcInfo.RC:$src2, u8imm:$src3),
8212                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8213                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
8214                                (SrcInfo.VT SrcInfo.RC:$src2),
8215                                (i8 imm:$src3)))>;
8216   defm rmi : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
8217                 (ins SrcInfo.RC:$src1, SrcInfo.MemOp:$src2, u8imm:$src3),
8218                 OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8219                 (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
8220                              (SrcInfo.VT (bitconvert
8221                                                 (SrcInfo.LdFrag addr:$src2))),
8222                              (i8 imm:$src3)))>;
8223   }
8224 }
8225
8226 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8227 //                               op(reg_vec2,mem_vec,imm)
8228 //                               op(reg_vec2,broadcast(eltVt),imm)
8229 multiclass avx512_3Op_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
8230                            X86VectorVTInfo _>:
8231   avx512_3Op_rm_imm8<opc, OpcodeStr, OpNode, _, _>{
8232
8233   let ExeDomain = _.ExeDomain in
8234   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8235                     (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
8236                     OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
8237                     "$src1, ${src2}"##_.BroadcastStr##", $src3",
8238                     (OpNode (_.VT _.RC:$src1),
8239                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
8240                             (i8 imm:$src3))>, EVEX_B;
8241 }
8242
8243 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8244 //                                      op(reg_vec2,mem_scalar,imm)
8245 //all instruction created with FROUND_CURRENT
8246 multiclass avx512_fp_scalar_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8247                                 X86VectorVTInfo _> {
8248   let ExeDomain = _.ExeDomain in {
8249   defm rri : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
8250                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8251                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8252                       (OpNode (_.VT _.RC:$src1),
8253                               (_.VT _.RC:$src2),
8254                               (i32 imm:$src3),
8255                               (i32 FROUND_CURRENT))>;
8256   defm rmi : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
8257                     (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
8258                     OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8259                     (OpNode (_.VT _.RC:$src1),
8260                             (_.VT (scalar_to_vector
8261                                       (_.ScalarLdFrag addr:$src2))),
8262                             (i32 imm:$src3),
8263                             (i32 FROUND_CURRENT))>;
8264   }
8265 }
8266
8267 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8268 multiclass avx512_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
8269                                              SDNode OpNode, X86VectorVTInfo _>{
8270   let ExeDomain = _.ExeDomain in
8271   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8272                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8273                       OpcodeStr, "$src3, {sae}, $src2, $src1",
8274                       "$src1, $src2, {sae}, $src3",
8275                       (OpNode (_.VT _.RC:$src1),
8276                               (_.VT _.RC:$src2),
8277                               (i32 imm:$src3),
8278                               (i32 FROUND_NO_EXC))>, EVEX_B;
8279 }
8280 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8281 multiclass avx512_fp_sae_scalar_imm<bits<8> opc, string OpcodeStr,
8282                                              SDNode OpNode, X86VectorVTInfo _> {
8283   defm NAME#rrib : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
8284                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8285                       OpcodeStr, "$src3, {sae}, $src2, $src1",
8286                       "$src1, $src2, {sae}, $src3",
8287                       (OpNode (_.VT _.RC:$src1),
8288                               (_.VT _.RC:$src2),
8289                               (i32 imm:$src3),
8290                               (i32 FROUND_NO_EXC))>, EVEX_B;
8291 }
8292
8293 multiclass avx512_common_fp_sae_packed_imm<string OpcodeStr,
8294             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8295   let Predicates = [prd] in {
8296     defm Z    : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8297                 avx512_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8298                                   EVEX_V512;
8299
8300   }
8301   let Predicates = [prd, HasVLX] in {
8302     defm Z128 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
8303                                   EVEX_V128;
8304     defm Z256 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
8305                                   EVEX_V256;
8306   }
8307 }
8308
8309 multiclass avx512_common_3Op_rm_imm8<bits<8> opc, SDNode OpNode, string OpStr,
8310                    AVX512VLVectorVTInfo DestInfo, AVX512VLVectorVTInfo SrcInfo>{
8311   let Predicates = [HasBWI] in {
8312     defm Z    : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info512,
8313                            SrcInfo.info512>, EVEX_V512, AVX512AIi8Base, EVEX_4V;
8314   }
8315   let Predicates = [HasBWI, HasVLX] in {
8316     defm Z128 : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info128,
8317                            SrcInfo.info128>, EVEX_V128, AVX512AIi8Base, EVEX_4V;
8318     defm Z256 : avx512_3Op_rm_imm8<opc, OpStr, OpNode,  DestInfo.info256,
8319                            SrcInfo.info256>, EVEX_V256, AVX512AIi8Base, EVEX_4V;
8320   }
8321 }
8322
8323 multiclass avx512_common_3Op_imm8<string OpcodeStr, AVX512VLVectorVTInfo _,
8324                                 bits<8> opc, SDNode OpNode>{
8325   let Predicates = [HasAVX512] in {
8326     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
8327   }
8328   let Predicates = [HasAVX512, HasVLX] in {
8329     defm Z128 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
8330     defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
8331   }
8332 }
8333
8334 multiclass avx512_common_fp_sae_scalar_imm<string OpcodeStr,
8335                   X86VectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8336   let Predicates = [prd] in {
8337      defm Z128 : avx512_fp_scalar_imm<opc, OpcodeStr, OpNode, _>,
8338                  avx512_fp_sae_scalar_imm<opc, OpcodeStr, OpNode, _>;
8339   }
8340 }
8341
8342 multiclass avx512_common_unary_fp_sae_packed_imm_all<string OpcodeStr,
8343                     bits<8> opcPs, bits<8> opcPd, SDNode OpNode, Predicate prd>{
8344   defm PS : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f32_info,
8345                             opcPs, OpNode, prd>, EVEX_CD8<32, CD8VF>;
8346   defm PD : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f64_info,
8347                             opcPd, OpNode, prd>, EVEX_CD8<64, CD8VF>, VEX_W;
8348 }
8349
8350
8351 defm VREDUCE   : avx512_common_unary_fp_sae_packed_imm_all<"vreduce", 0x56, 0x56,
8352                               X86VReduce, HasDQI>, AVX512AIi8Base, EVEX;
8353 defm VRNDSCALE : avx512_common_unary_fp_sae_packed_imm_all<"vrndscale", 0x08, 0x09,
8354                               X86VRndScale, HasAVX512>, AVX512AIi8Base, EVEX;
8355 defm VGETMANT : avx512_common_unary_fp_sae_packed_imm_all<"vgetmant", 0x26, 0x26,
8356                               X86VGetMant, HasAVX512>, AVX512AIi8Base, EVEX;
8357
8358
8359 defm VRANGEPD : avx512_common_fp_sae_packed_imm<"vrangepd", avx512vl_f64_info,
8360                                                        0x50, X86VRange, HasDQI>,
8361       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8362 defm VRANGEPS : avx512_common_fp_sae_packed_imm<"vrangeps", avx512vl_f32_info,
8363                                                        0x50, X86VRange, HasDQI>,
8364       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8365
8366 defm VRANGESD: avx512_common_fp_sae_scalar_imm<"vrangesd", f64x_info,
8367                                                  0x51, X86VRange, HasDQI>,
8368       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8369 defm VRANGESS: avx512_common_fp_sae_scalar_imm<"vrangess", f32x_info,
8370                                                  0x51, X86VRange, HasDQI>,
8371       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8372
8373 defm VREDUCESD: avx512_common_fp_sae_scalar_imm<"vreducesd", f64x_info,
8374                                                  0x57, X86Reduces, HasDQI>,
8375       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8376 defm VREDUCESS: avx512_common_fp_sae_scalar_imm<"vreducess", f32x_info,
8377                                                  0x57, X86Reduces, HasDQI>,
8378       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8379
8380 defm VGETMANTSD: avx512_common_fp_sae_scalar_imm<"vgetmantsd", f64x_info,
8381                                                  0x27, X86GetMants, HasAVX512>,
8382       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8383 defm VGETMANTSS: avx512_common_fp_sae_scalar_imm<"vgetmantss", f32x_info,
8384                                                  0x27, X86GetMants, HasAVX512>,
8385       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8386
8387 multiclass avx512_shuff_packed_128<string OpcodeStr, AVX512VLVectorVTInfo _,
8388                                        bits<8> opc, SDNode OpNode = X86Shuf128>{
8389   let Predicates = [HasAVX512] in {
8390     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
8391
8392   }
8393   let Predicates = [HasAVX512, HasVLX] in {
8394      defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
8395   }
8396 }
8397 let Predicates = [HasAVX512] in {
8398 def : Pat<(v16f32 (ffloor VR512:$src)),
8399           (VRNDSCALEPSZrri VR512:$src, (i32 0x1))>;
8400 def : Pat<(v16f32 (fnearbyint VR512:$src)),
8401           (VRNDSCALEPSZrri VR512:$src, (i32 0xC))>;
8402 def : Pat<(v16f32 (fceil VR512:$src)),
8403           (VRNDSCALEPSZrri VR512:$src, (i32 0x2))>;
8404 def : Pat<(v16f32 (frint VR512:$src)),
8405           (VRNDSCALEPSZrri VR512:$src, (i32 0x4))>;
8406 def : Pat<(v16f32 (ftrunc VR512:$src)),
8407           (VRNDSCALEPSZrri VR512:$src, (i32 0x3))>;
8408
8409 def : Pat<(v8f64 (ffloor VR512:$src)),
8410           (VRNDSCALEPDZrri VR512:$src, (i32 0x1))>;
8411 def : Pat<(v8f64 (fnearbyint VR512:$src)),
8412           (VRNDSCALEPDZrri VR512:$src, (i32 0xC))>;
8413 def : Pat<(v8f64 (fceil VR512:$src)),
8414           (VRNDSCALEPDZrri VR512:$src, (i32 0x2))>;
8415 def : Pat<(v8f64 (frint VR512:$src)),
8416           (VRNDSCALEPDZrri VR512:$src, (i32 0x4))>;
8417 def : Pat<(v8f64 (ftrunc VR512:$src)),
8418           (VRNDSCALEPDZrri VR512:$src, (i32 0x3))>;
8419 }
8420
8421 defm VSHUFF32X4 : avx512_shuff_packed_128<"vshuff32x4",avx512vl_f32_info, 0x23>,
8422       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8423 defm VSHUFF64X2 : avx512_shuff_packed_128<"vshuff64x2",avx512vl_f64_info, 0x23>,
8424       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8425 defm VSHUFI32X4 : avx512_shuff_packed_128<"vshufi32x4",avx512vl_i32_info, 0x43>,
8426       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8427 defm VSHUFI64X2 : avx512_shuff_packed_128<"vshufi64x2",avx512vl_i64_info, 0x43>,
8428       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8429
8430 multiclass avx512_valign<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I> {
8431   defm NAME:       avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0x03, X86VAlign>,
8432                            AVX512AIi8Base, EVEX_4V;
8433 }
8434
8435 defm VALIGND: avx512_valign<"valignd", avx512vl_i32_info>,
8436                                                   EVEX_CD8<32, CD8VF>;
8437 defm VALIGNQ: avx512_valign<"valignq", avx512vl_i64_info>,
8438                                                   EVEX_CD8<64, CD8VF>, VEX_W;
8439
8440 multiclass avx512_vpalignr_lowering<X86VectorVTInfo _ , list<Predicate> p>{
8441   let Predicates = p in
8442     def NAME#_.VTName#rri:
8443           Pat<(_.VT (X86PAlignr _.RC:$src1, _.RC:$src2, (i8 imm:$imm))),
8444               (!cast<Instruction>(NAME#_.ZSuffix#rri)
8445                     _.RC:$src1, _.RC:$src2, imm:$imm)>;
8446 }
8447
8448 multiclass avx512_vpalignr_lowering_common<AVX512VLVectorVTInfo _>:
8449       avx512_vpalignr_lowering<_.info512, [HasBWI]>,
8450       avx512_vpalignr_lowering<_.info128, [HasBWI, HasVLX]>,
8451       avx512_vpalignr_lowering<_.info256, [HasBWI, HasVLX]>;
8452
8453 defm VPALIGNR:   avx512_common_3Op_rm_imm8<0x0F, X86PAlignr, "vpalignr" ,
8454                                           avx512vl_i8_info, avx512vl_i8_info>,
8455                 avx512_vpalignr_lowering_common<avx512vl_i16_info>,
8456                 avx512_vpalignr_lowering_common<avx512vl_i32_info>,
8457                 avx512_vpalignr_lowering_common<avx512vl_f32_info>,
8458                 avx512_vpalignr_lowering_common<avx512vl_i64_info>,
8459                 avx512_vpalignr_lowering_common<avx512vl_f64_info>,
8460                 EVEX_CD8<8, CD8VF>;
8461
8462 defm VDBPSADBW: avx512_common_3Op_rm_imm8<0x42, X86dbpsadbw, "vdbpsadbw" ,
8463                     avx512vl_i16_info, avx512vl_i8_info>, EVEX_CD8<8, CD8VF>;
8464
8465 multiclass avx512_unary_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8466                            X86VectorVTInfo _> {
8467   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8468                     (ins _.RC:$src1), OpcodeStr,
8469                     "$src1", "$src1",
8470                     (_.VT (OpNode _.RC:$src1))>, EVEX, AVX5128IBase;
8471
8472   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8473                   (ins _.MemOp:$src1), OpcodeStr,
8474                   "$src1", "$src1",
8475                   (_.VT (OpNode (bitconvert (_.LdFrag addr:$src1))))>,
8476             EVEX, AVX5128IBase, EVEX_CD8<_.EltSize, CD8VF>;
8477 }
8478
8479 multiclass avx512_unary_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
8480                             X86VectorVTInfo _> :
8481            avx512_unary_rm<opc, OpcodeStr, OpNode, _> {
8482   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8483                   (ins _.ScalarMemOp:$src1), OpcodeStr,
8484                   "${src1}"##_.BroadcastStr,
8485                   "${src1}"##_.BroadcastStr,
8486                   (_.VT (OpNode (X86VBroadcast
8487                                     (_.ScalarLdFrag addr:$src1))))>,
8488              EVEX, AVX5128IBase, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
8489 }
8490
8491 multiclass avx512_unary_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
8492                               AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8493   let Predicates = [prd] in
8494     defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
8495
8496   let Predicates = [prd, HasVLX] in {
8497     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
8498                               EVEX_V256;
8499     defm Z128 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info128>,
8500                               EVEX_V128;
8501   }
8502 }
8503
8504 multiclass avx512_unary_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
8505                                AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8506   let Predicates = [prd] in
8507     defm Z : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
8508                               EVEX_V512;
8509
8510   let Predicates = [prd, HasVLX] in {
8511     defm Z256 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
8512                                  EVEX_V256;
8513     defm Z128 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
8514                                  EVEX_V128;
8515   }
8516 }
8517
8518 multiclass avx512_unary_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
8519                                  SDNode OpNode, Predicate prd> {
8520   defm Q : avx512_unary_rmb_vl<opc_q, OpcodeStr#"q", OpNode, avx512vl_i64_info,
8521                                prd>, VEX_W;
8522   defm D : avx512_unary_rmb_vl<opc_d, OpcodeStr#"d", OpNode, avx512vl_i32_info,
8523                                prd>;
8524 }
8525
8526 multiclass avx512_unary_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
8527                                  SDNode OpNode, Predicate prd> {
8528   defm W : avx512_unary_rm_vl<opc_w, OpcodeStr#"w", OpNode, avx512vl_i16_info, prd>;
8529   defm B : avx512_unary_rm_vl<opc_b, OpcodeStr#"b", OpNode, avx512vl_i8_info, prd>;
8530 }
8531
8532 multiclass avx512_unary_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
8533                                   bits<8> opc_d, bits<8> opc_q,
8534                                   string OpcodeStr, SDNode OpNode> {
8535   defm NAME : avx512_unary_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
8536                                     HasAVX512>,
8537               avx512_unary_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
8538                                     HasBWI>;
8539 }
8540
8541 defm VPABS : avx512_unary_rm_vl_all<0x1C, 0x1D, 0x1E, 0x1F, "vpabs", X86Abs>;
8542
8543 def avx512_v16i1sextv16i8 : PatLeaf<(v16i8 (X86pcmpgt (bc_v16i8 (v4i32 immAllZerosV)),
8544                                                       VR128X:$src))>;
8545 def avx512_v8i1sextv8i16 : PatLeaf<(v8i16 (X86vsrai VR128X:$src, (i8 15)))>;
8546 def avx512_v4i1sextv4i32  : PatLeaf<(v4i32 (X86vsrai VR128X:$src, (i8 31)))>;
8547 def avx512_v32i1sextv32i8 : PatLeaf<(v32i8 (X86pcmpgt (bc_v32i8 (v8i32 immAllZerosV)),
8548                                                       VR256X:$src))>;
8549 def avx512_v16i1sextv16i16: PatLeaf<(v16i16 (X86vsrai VR256X:$src, (i8 15)))>;
8550 def avx512_v8i1sextv8i32  : PatLeaf<(v8i32 (X86vsrai VR256X:$src, (i8 31)))>;
8551
8552 let Predicates = [HasBWI, HasVLX] in {
8553   def : Pat<(xor
8554             (bc_v2i64 (avx512_v16i1sextv16i8)),
8555             (bc_v2i64 (add (v16i8 VR128X:$src), (avx512_v16i1sextv16i8)))),
8556             (VPABSBZ128rr VR128X:$src)>;
8557   def : Pat<(xor
8558             (bc_v2i64 (avx512_v8i1sextv8i16)),
8559             (bc_v2i64 (add (v8i16 VR128X:$src), (avx512_v8i1sextv8i16)))),
8560             (VPABSWZ128rr VR128X:$src)>;
8561   def : Pat<(xor
8562             (bc_v4i64 (avx512_v32i1sextv32i8)),
8563             (bc_v4i64 (add (v32i8 VR256X:$src), (avx512_v32i1sextv32i8)))),
8564             (VPABSBZ256rr VR256X:$src)>;
8565   def : Pat<(xor
8566             (bc_v4i64 (avx512_v16i1sextv16i16)),
8567             (bc_v4i64 (add (v16i16 VR256X:$src), (avx512_v16i1sextv16i16)))),
8568             (VPABSWZ256rr VR256X:$src)>;
8569 }
8570 let Predicates = [HasAVX512, HasVLX] in {
8571   def : Pat<(xor
8572             (bc_v2i64 (avx512_v4i1sextv4i32)),
8573             (bc_v2i64 (add (v4i32 VR128X:$src), (avx512_v4i1sextv4i32)))),
8574             (VPABSDZ128rr VR128X:$src)>;
8575   def : Pat<(xor
8576             (bc_v4i64 (avx512_v8i1sextv8i32)),
8577             (bc_v4i64 (add (v8i32 VR256X:$src), (avx512_v8i1sextv8i32)))),
8578             (VPABSDZ256rr VR256X:$src)>;
8579 }
8580
8581 let Predicates = [HasAVX512] in {
8582 def : Pat<(xor
8583           (bc_v8i64 (v16i1sextv16i32)),
8584           (bc_v8i64 (add (v16i32 VR512:$src), (v16i1sextv16i32)))),
8585           (VPABSDZrr VR512:$src)>;
8586 def : Pat<(xor
8587           (bc_v8i64 (v8i1sextv8i64)),
8588           (bc_v8i64 (add (v8i64 VR512:$src), (v8i1sextv8i64)))),
8589           (VPABSQZrr VR512:$src)>;
8590 }
8591 let Predicates = [HasBWI] in {
8592 def : Pat<(xor
8593           (bc_v8i64 (v64i1sextv64i8)),
8594           (bc_v8i64 (add (v64i8 VR512:$src), (v64i1sextv64i8)))),
8595           (VPABSBZrr VR512:$src)>;
8596 def : Pat<(xor
8597           (bc_v8i64 (v32i1sextv32i16)),
8598           (bc_v8i64 (add (v32i16 VR512:$src), (v32i1sextv32i16)))),
8599           (VPABSWZrr VR512:$src)>;
8600 }
8601
8602 multiclass avx512_ctlz<bits<8> opc, string OpcodeStr, Predicate prd>{
8603
8604   defm NAME :          avx512_unary_rm_vl_dq<opc, opc, OpcodeStr, ctlz, prd>;
8605 }
8606
8607 defm VPLZCNT    : avx512_ctlz<0x44, "vplzcnt", HasCDI>;
8608 defm VPCONFLICT : avx512_unary_rm_vl_dq<0xC4, 0xC4, "vpconflict", X86Conflict, HasCDI>;
8609
8610 //===---------------------------------------------------------------------===//
8611 // Replicate Single FP - MOVSHDUP and MOVSLDUP
8612 //===---------------------------------------------------------------------===//
8613 multiclass avx512_replicate<bits<8> opc, string OpcodeStr, SDNode OpNode>{
8614   defm NAME:       avx512_unary_rm_vl<opc, OpcodeStr, OpNode, avx512vl_f32_info,
8615                                       HasAVX512>, XS;
8616 }
8617
8618 defm VMOVSHDUP : avx512_replicate<0x16, "vmovshdup", X86Movshdup>;
8619 defm VMOVSLDUP : avx512_replicate<0x12, "vmovsldup", X86Movsldup>;
8620
8621 //===----------------------------------------------------------------------===//
8622 // AVX-512 - MOVDDUP
8623 //===----------------------------------------------------------------------===//
8624
8625 multiclass avx512_movddup_128<bits<8> opc, string OpcodeStr, SDNode OpNode,
8626                                                             X86VectorVTInfo _> {
8627   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8628                    (ins _.RC:$src), OpcodeStr, "$src", "$src",
8629                    (_.VT (OpNode (_.VT _.RC:$src)))>, EVEX;
8630   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8631                  (ins _.ScalarMemOp:$src), OpcodeStr, "$src", "$src",
8632                  (_.VT (OpNode (_.VT (scalar_to_vector
8633                                        (_.ScalarLdFrag addr:$src)))))>,
8634                  EVEX, EVEX_CD8<_.EltSize, CD8VH>;
8635 }
8636
8637 multiclass avx512_movddup_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
8638                                                   AVX512VLVectorVTInfo VTInfo> {
8639
8640   defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
8641
8642   let Predicates = [HasAVX512, HasVLX] in {
8643     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
8644                                EVEX_V256;
8645     defm Z128 : avx512_movddup_128<opc, OpcodeStr, OpNode, VTInfo.info128>,
8646                                EVEX_V128;
8647   }
8648 }
8649
8650 multiclass avx512_movddup<bits<8> opc, string OpcodeStr, SDNode OpNode>{
8651   defm NAME:      avx512_movddup_common<opc, OpcodeStr, OpNode,
8652                                         avx512vl_f64_info>, XD, VEX_W;
8653 }
8654
8655 defm VMOVDDUP : avx512_movddup<0x12, "vmovddup", X86Movddup>;
8656
8657 let Predicates = [HasVLX] in {
8658 def : Pat<(X86Movddup (loadv2f64 addr:$src)),
8659           (VMOVDDUPZ128rm addr:$src)>;
8660 def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
8661           (VMOVDDUPZ128rm addr:$src)>;
8662 def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8663           (VMOVDDUPZ128rr (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8664
8665 def : Pat<(vselect (v2i1 VK2WM:$mask), (X86Movddup (loadv2f64 addr:$src)),
8666                    (v2f64 VR128X:$src0)),
8667           (VMOVDDUPZ128rmk VR128X:$src0, VK2WM:$mask, addr:$src)>;
8668 def : Pat<(vselect (v2i1 VK2WM:$mask), (X86Movddup (loadv2f64 addr:$src)),
8669                    (bitconvert (v4i32 immAllZerosV))),
8670           (VMOVDDUPZ128rmkz VK2WM:$mask, addr:$src)>;
8671
8672 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast f64:$src)),
8673                    (v2f64 VR128X:$src0)),
8674           (VMOVDDUPZ128rrk VR128X:$src0, VK2WM:$mask,
8675                            (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8676 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast f64:$src)),
8677                    (bitconvert (v4i32 immAllZerosV))),
8678           (VMOVDDUPZ128rrkz VK2WM:$mask, (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8679
8680 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast (loadf64 addr:$src))),
8681                    (v2f64 VR128X:$src0)),
8682           (VMOVDDUPZ128rmk VR128X:$src0, VK2WM:$mask, addr:$src)>;
8683 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast (loadf64 addr:$src))),
8684                    (bitconvert (v4i32 immAllZerosV))),
8685           (VMOVDDUPZ128rmkz VK2WM:$mask, addr:$src)>;
8686 }
8687
8688 //===----------------------------------------------------------------------===//
8689 // AVX-512 - Unpack Instructions
8690 //===----------------------------------------------------------------------===//
8691 defm VUNPCKH : avx512_fp_binop_p<0x15, "vunpckh", X86Unpckh, HasAVX512,
8692                                  SSE_ALU_ITINS_S>;
8693 defm VUNPCKL : avx512_fp_binop_p<0x14, "vunpckl", X86Unpckl, HasAVX512,
8694                                  SSE_ALU_ITINS_S>;
8695
8696 defm VPUNPCKLBW : avx512_binop_rm_vl_b<0x60, "vpunpcklbw", X86Unpckl,
8697                                        SSE_INTALU_ITINS_P, HasBWI>;
8698 defm VPUNPCKHBW : avx512_binop_rm_vl_b<0x68, "vpunpckhbw", X86Unpckh,
8699                                        SSE_INTALU_ITINS_P, HasBWI>;
8700 defm VPUNPCKLWD : avx512_binop_rm_vl_w<0x61, "vpunpcklwd", X86Unpckl,
8701                                        SSE_INTALU_ITINS_P, HasBWI>;
8702 defm VPUNPCKHWD : avx512_binop_rm_vl_w<0x69, "vpunpckhwd", X86Unpckh,
8703                                        SSE_INTALU_ITINS_P, HasBWI>;
8704
8705 defm VPUNPCKLDQ : avx512_binop_rm_vl_d<0x62, "vpunpckldq", X86Unpckl,
8706                                        SSE_INTALU_ITINS_P, HasAVX512>;
8707 defm VPUNPCKHDQ : avx512_binop_rm_vl_d<0x6A, "vpunpckhdq", X86Unpckh,
8708                                        SSE_INTALU_ITINS_P, HasAVX512>;
8709 defm VPUNPCKLQDQ : avx512_binop_rm_vl_q<0x6C, "vpunpcklqdq", X86Unpckl,
8710                                        SSE_INTALU_ITINS_P, HasAVX512>;
8711 defm VPUNPCKHQDQ : avx512_binop_rm_vl_q<0x6D, "vpunpckhqdq", X86Unpckh,
8712                                        SSE_INTALU_ITINS_P, HasAVX512>;
8713
8714 //===----------------------------------------------------------------------===//
8715 // AVX-512 - Extract & Insert Integer Instructions
8716 //===----------------------------------------------------------------------===//
8717
8718 multiclass avx512_extract_elt_bw_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
8719                                                             X86VectorVTInfo _> {
8720   def mr : AVX512Ii8<opc, MRMDestMem, (outs),
8721               (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
8722               OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8723               [(store (_.EltVT (trunc (assertzext (OpNode (_.VT _.RC:$src1),
8724                                                           imm:$src2)))),
8725                       addr:$dst)]>,
8726               EVEX, EVEX_CD8<_.EltSize, CD8VT1>;
8727 }
8728
8729 multiclass avx512_extract_elt_b<string OpcodeStr, X86VectorVTInfo _> {
8730   let Predicates = [HasBWI] in {
8731     def rr : AVX512Ii8<0x14, MRMDestReg, (outs GR32orGR64:$dst),
8732                   (ins _.RC:$src1, u8imm:$src2),
8733                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8734                   [(set GR32orGR64:$dst,
8735                         (X86pextrb (_.VT _.RC:$src1), imm:$src2))]>,
8736                   EVEX, TAPD;
8737
8738     defm NAME : avx512_extract_elt_bw_m<0x14, OpcodeStr, X86pextrb, _>, TAPD;
8739   }
8740 }
8741
8742 multiclass avx512_extract_elt_w<string OpcodeStr, X86VectorVTInfo _> {
8743   let Predicates = [HasBWI] in {
8744     def rr : AVX512Ii8<0xC5, MRMSrcReg, (outs GR32orGR64:$dst),
8745                   (ins _.RC:$src1, u8imm:$src2),
8746                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8747                   [(set GR32orGR64:$dst,
8748                         (X86pextrw (_.VT _.RC:$src1), imm:$src2))]>,
8749                   EVEX, PD;
8750
8751     let hasSideEffects = 0 in
8752     def rr_REV : AVX512Ii8<0x15, MRMDestReg, (outs GR32orGR64:$dst),
8753                    (ins _.RC:$src1, u8imm:$src2),
8754                    OpcodeStr#".s\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8755                    EVEX, TAPD;
8756
8757     defm NAME : avx512_extract_elt_bw_m<0x15, OpcodeStr, X86pextrw, _>, TAPD;
8758   }
8759 }
8760
8761 multiclass avx512_extract_elt_dq<string OpcodeStr, X86VectorVTInfo _,
8762                                                             RegisterClass GRC> {
8763   let Predicates = [HasDQI] in {
8764     def rr : AVX512Ii8<0x16, MRMDestReg, (outs GRC:$dst),
8765                   (ins _.RC:$src1, u8imm:$src2),
8766                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8767                   [(set GRC:$dst,
8768                       (extractelt (_.VT _.RC:$src1), imm:$src2))]>,
8769                   EVEX, TAPD;
8770
8771     def mr : AVX512Ii8<0x16, MRMDestMem, (outs),
8772                 (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
8773                 OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8774                 [(store (extractelt (_.VT _.RC:$src1),
8775                                     imm:$src2),addr:$dst)]>,
8776                 EVEX, EVEX_CD8<_.EltSize, CD8VT1>, TAPD;
8777   }
8778 }
8779
8780 defm VPEXTRBZ : avx512_extract_elt_b<"vpextrb", v16i8x_info>;
8781 defm VPEXTRWZ : avx512_extract_elt_w<"vpextrw", v8i16x_info>;
8782 defm VPEXTRDZ : avx512_extract_elt_dq<"vpextrd", v4i32x_info, GR32>;
8783 defm VPEXTRQZ : avx512_extract_elt_dq<"vpextrq", v2i64x_info, GR64>, VEX_W;
8784
8785 multiclass avx512_insert_elt_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
8786                                             X86VectorVTInfo _, PatFrag LdFrag> {
8787   def rm : AVX512Ii8<opc, MRMSrcMem, (outs _.RC:$dst),
8788       (ins _.RC:$src1,  _.ScalarMemOp:$src2, u8imm:$src3),
8789       OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8790       [(set _.RC:$dst,
8791           (_.VT (OpNode _.RC:$src1, (LdFrag addr:$src2), imm:$src3)))]>,
8792       EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
8793 }
8794
8795 multiclass avx512_insert_elt_bw<bits<8> opc, string OpcodeStr, SDNode OpNode,
8796                                             X86VectorVTInfo _, PatFrag LdFrag> {
8797   let Predicates = [HasBWI] in {
8798     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
8799         (ins _.RC:$src1, GR32orGR64:$src2, u8imm:$src3),
8800         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8801         [(set _.RC:$dst,
8802             (OpNode _.RC:$src1, GR32orGR64:$src2, imm:$src3))]>, EVEX_4V;
8803
8804     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, OpNode, _, LdFrag>;
8805   }
8806 }
8807
8808 multiclass avx512_insert_elt_dq<bits<8> opc, string OpcodeStr,
8809                                          X86VectorVTInfo _, RegisterClass GRC> {
8810   let Predicates = [HasDQI] in {
8811     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
8812         (ins _.RC:$src1, GRC:$src2, u8imm:$src3),
8813         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8814         [(set _.RC:$dst,
8815             (_.VT (insertelt _.RC:$src1, GRC:$src2, imm:$src3)))]>,
8816         EVEX_4V, TAPD;
8817
8818     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, insertelt, _,
8819                                     _.ScalarLdFrag>, TAPD;
8820   }
8821 }
8822
8823 defm VPINSRBZ : avx512_insert_elt_bw<0x20, "vpinsrb", X86pinsrb, v16i8x_info,
8824                                      extloadi8>, TAPD;
8825 defm VPINSRWZ : avx512_insert_elt_bw<0xC4, "vpinsrw", X86pinsrw, v8i16x_info,
8826                                      extloadi16>, PD;
8827 defm VPINSRDZ : avx512_insert_elt_dq<0x22, "vpinsrd", v4i32x_info, GR32>;
8828 defm VPINSRQZ : avx512_insert_elt_dq<0x22, "vpinsrq", v2i64x_info, GR64>, VEX_W;
8829 //===----------------------------------------------------------------------===//
8830 // VSHUFPS - VSHUFPD Operations
8831 //===----------------------------------------------------------------------===//
8832 multiclass avx512_shufp<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
8833                                                 AVX512VLVectorVTInfo VTInfo_FP>{
8834   defm NAME:     avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0xC6, X86Shufp>,
8835                                    EVEX_CD8<VTInfo_FP.info512.EltSize, CD8VF>,
8836                                    AVX512AIi8Base, EVEX_4V;
8837 }
8838
8839 defm VSHUFPS: avx512_shufp<"vshufps", avx512vl_i32_info, avx512vl_f32_info>, PS;
8840 defm VSHUFPD: avx512_shufp<"vshufpd", avx512vl_i64_info, avx512vl_f64_info>, PD, VEX_W;
8841 //===----------------------------------------------------------------------===//
8842 // AVX-512 - Byte shift Left/Right
8843 //===----------------------------------------------------------------------===//
8844
8845 multiclass avx512_shift_packed<bits<8> opc, SDNode OpNode, Format MRMr,
8846                              Format MRMm, string OpcodeStr, X86VectorVTInfo _>{
8847   def rr : AVX512<opc, MRMr,
8848              (outs _.RC:$dst), (ins _.RC:$src1, u8imm:$src2),
8849              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8850              [(set _.RC:$dst,(_.VT (OpNode _.RC:$src1, (i8 imm:$src2))))]>;
8851   def rm : AVX512<opc, MRMm,
8852            (outs _.RC:$dst), (ins _.MemOp:$src1, u8imm:$src2),
8853            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8854            [(set _.RC:$dst,(_.VT (OpNode
8855                                  (_.VT (bitconvert (_.LdFrag addr:$src1))),
8856                                  (i8 imm:$src2))))]>;
8857 }
8858
8859 multiclass avx512_shift_packed_all<bits<8> opc, SDNode OpNode, Format MRMr,
8860                                  Format MRMm, string OpcodeStr, Predicate prd>{
8861   let Predicates = [prd] in
8862     defm Z512 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8863                                     OpcodeStr, v64i8_info>, EVEX_V512;
8864   let Predicates = [prd, HasVLX] in {
8865     defm Z256 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8866                                     OpcodeStr, v32i8x_info>, EVEX_V256;
8867     defm Z128 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8868                                     OpcodeStr, v16i8x_info>, EVEX_V128;
8869   }
8870 }
8871 defm VPSLLDQ : avx512_shift_packed_all<0x73, X86vshldq, MRM7r, MRM7m, "vpslldq",
8872                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
8873 defm VPSRLDQ : avx512_shift_packed_all<0x73, X86vshrdq, MRM3r, MRM3m, "vpsrldq",
8874                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
8875
8876
8877 multiclass avx512_psadbw_packed<bits<8> opc, SDNode OpNode,
8878                                 string OpcodeStr, X86VectorVTInfo _dst,
8879                                 X86VectorVTInfo _src>{
8880   def rr : AVX512BI<opc, MRMSrcReg,
8881              (outs _dst.RC:$dst), (ins _src.RC:$src1, _src.RC:$src2),
8882              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8883              [(set _dst.RC:$dst,(_dst.VT
8884                                 (OpNode (_src.VT _src.RC:$src1),
8885                                         (_src.VT _src.RC:$src2))))]>;
8886   def rm : AVX512BI<opc, MRMSrcMem,
8887            (outs _dst.RC:$dst), (ins _src.RC:$src1, _src.MemOp:$src2),
8888            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8889            [(set _dst.RC:$dst,(_dst.VT
8890                               (OpNode (_src.VT _src.RC:$src1),
8891                               (_src.VT (bitconvert
8892                                         (_src.LdFrag addr:$src2))))))]>;
8893 }
8894
8895 multiclass avx512_psadbw_packed_all<bits<8> opc, SDNode OpNode,
8896                                     string OpcodeStr, Predicate prd> {
8897   let Predicates = [prd] in
8898     defm Z512 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v8i64_info,
8899                                     v64i8_info>, EVEX_V512;
8900   let Predicates = [prd, HasVLX] in {
8901     defm Z256 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v4i64x_info,
8902                                     v32i8x_info>, EVEX_V256;
8903     defm Z128 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v2i64x_info,
8904                                     v16i8x_info>, EVEX_V128;
8905   }
8906 }
8907
8908 defm VPSADBW : avx512_psadbw_packed_all<0xf6, X86psadbw, "vpsadbw",
8909                                        HasBWI>, EVEX_4V;
8910
8911 multiclass avx512_ternlog<bits<8> opc, string OpcodeStr, SDNode OpNode,
8912                           X86VectorVTInfo _>{
8913   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
8914   defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
8915                       (ins _.RC:$src2, _.RC:$src3, u8imm:$src4),
8916                       OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src4",
8917                       (OpNode (_.VT _.RC:$src1),
8918                               (_.VT _.RC:$src2),
8919                               (_.VT _.RC:$src3),
8920                               (i8 imm:$src4)), 1, 1>, AVX512AIi8Base, EVEX_4V;
8921   defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
8922                     (ins _.RC:$src2, _.MemOp:$src3, u8imm:$src4),
8923                     OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src4",
8924                     (OpNode (_.VT _.RC:$src1),
8925                             (_.VT _.RC:$src2),
8926                             (_.VT (bitconvert (_.LdFrag addr:$src3))),
8927                             (i8 imm:$src4)), 1, 0>,
8928                     AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
8929   defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
8930                     (ins _.RC:$src2, _.ScalarMemOp:$src3, u8imm:$src4),
8931                     OpcodeStr, "$src4, ${src3}"##_.BroadcastStr##", $src2",
8932                     "$src2, ${src3}"##_.BroadcastStr##", $src4",
8933                     (OpNode (_.VT _.RC:$src1),
8934                             (_.VT _.RC:$src2),
8935                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
8936                             (i8 imm:$src4)), 1, 0>, EVEX_B,
8937                     AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
8938   }// Constraints = "$src1 = $dst"
8939 }
8940
8941 multiclass avx512_common_ternlog<string OpcodeStr, AVX512VLVectorVTInfo _>{
8942   let Predicates = [HasAVX512] in
8943     defm Z    : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info512>, EVEX_V512;
8944   let Predicates = [HasAVX512, HasVLX] in {
8945     defm Z128 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info128>, EVEX_V128;
8946     defm Z256 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info256>, EVEX_V256;
8947   }
8948 }
8949
8950 defm VPTERNLOGD : avx512_common_ternlog<"vpternlogd", avx512vl_i32_info>;
8951 defm VPTERNLOGQ : avx512_common_ternlog<"vpternlogq", avx512vl_i64_info>, VEX_W;
8952
8953 //===----------------------------------------------------------------------===//
8954 // AVX-512 - FixupImm
8955 //===----------------------------------------------------------------------===//
8956
8957 multiclass avx512_fixupimm_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
8958                                   X86VectorVTInfo _>{
8959   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
8960     defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
8961                         (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
8962                          OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
8963                         (OpNode (_.VT _.RC:$src1),
8964                                 (_.VT _.RC:$src2),
8965                                 (_.IntVT _.RC:$src3),
8966                                 (i32 imm:$src4),
8967                                 (i32 FROUND_CURRENT))>;
8968     defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
8969                       (ins _.RC:$src2, _.MemOp:$src3, i32u8imm:$src4),
8970                       OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
8971                       (OpNode (_.VT _.RC:$src1),
8972                               (_.VT _.RC:$src2),
8973                               (_.IntVT (bitconvert (_.LdFrag addr:$src3))),
8974                               (i32 imm:$src4),
8975                               (i32 FROUND_CURRENT))>;
8976     defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
8977                       (ins _.RC:$src2, _.ScalarMemOp:$src3, i32u8imm:$src4),
8978                     OpcodeStr##_.Suffix, "$src4, ${src3}"##_.BroadcastStr##", $src2",
8979                     "$src2, ${src3}"##_.BroadcastStr##", $src4",
8980                       (OpNode (_.VT _.RC:$src1),
8981                               (_.VT _.RC:$src2),
8982                               (_.IntVT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
8983                               (i32 imm:$src4),
8984                               (i32 FROUND_CURRENT))>, EVEX_B;
8985   } // Constraints = "$src1 = $dst"
8986 }
8987
8988 multiclass avx512_fixupimm_packed_sae<bits<8> opc, string OpcodeStr,
8989                                       SDNode OpNode, X86VectorVTInfo _>{
8990 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
8991   defm rrib : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
8992                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
8993                       OpcodeStr##_.Suffix, "$src4, {sae}, $src3, $src2",
8994                       "$src2, $src3, {sae}, $src4",
8995                       (OpNode (_.VT _.RC:$src1),
8996                                 (_.VT _.RC:$src2),
8997                                 (_.IntVT _.RC:$src3),
8998                                 (i32 imm:$src4),
8999                                 (i32 FROUND_NO_EXC))>, EVEX_B;
9000   }
9001 }
9002
9003 multiclass avx512_fixupimm_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
9004                                   X86VectorVTInfo _, X86VectorVTInfo _src3VT> {
9005   let Constraints = "$src1 = $dst" , Predicates = [HasAVX512],
9006       ExeDomain = _.ExeDomain in {
9007     defm rri : AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
9008                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9009                       OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9010                       (OpNode (_.VT _.RC:$src1),
9011                               (_.VT _.RC:$src2),
9012                               (_src3VT.VT _src3VT.RC:$src3),
9013                               (i32 imm:$src4),
9014                               (i32 FROUND_CURRENT))>;
9015
9016     defm rrib : AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
9017                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9018                       OpcodeStr##_.Suffix, "$src4, {sae}, $src3, $src2",
9019                       "$src2, $src3, {sae}, $src4",
9020                       (OpNode (_.VT _.RC:$src1),
9021                               (_.VT _.RC:$src2),
9022                               (_src3VT.VT _src3VT.RC:$src3),
9023                               (i32 imm:$src4),
9024                               (i32 FROUND_NO_EXC))>, EVEX_B;
9025     defm rmi : AVX512_maskable_3src_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
9026                      (ins _.RC:$src2, _.ScalarMemOp:$src3, i32u8imm:$src4),
9027                      OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9028                      (OpNode (_.VT _.RC:$src1),
9029                              (_.VT _.RC:$src2),
9030                              (_src3VT.VT (scalar_to_vector
9031                                        (_src3VT.ScalarLdFrag addr:$src3))),
9032                              (i32 imm:$src4),
9033                              (i32 FROUND_CURRENT))>;
9034   }
9035 }
9036
9037 multiclass avx512_fixupimm_packed_all<AVX512VLVectorVTInfo _Vec>{
9038   let Predicates = [HasAVX512] in
9039     defm Z    : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>,
9040                 avx512_fixupimm_packed_sae<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>,
9041                                   AVX512AIi8Base, EVEX_4V, EVEX_V512;
9042   let Predicates = [HasAVX512, HasVLX] in {
9043     defm Z128 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info128>,
9044                                   AVX512AIi8Base, EVEX_4V, EVEX_V128;
9045     defm Z256 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info256>,
9046                                   AVX512AIi8Base, EVEX_4V, EVEX_V256;
9047   }
9048 }
9049
9050 defm VFIXUPIMMSS : avx512_fixupimm_scalar<0x55, "vfixupimm", X86VFixupimmScalar,
9051                                           f32x_info, v4i32x_info>,
9052                          AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
9053 defm VFIXUPIMMSD : avx512_fixupimm_scalar<0x55, "vfixupimm", X86VFixupimmScalar,
9054                                           f64x_info, v2i64x_info>,
9055                          AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
9056 defm VFIXUPIMMPS : avx512_fixupimm_packed_all<avx512vl_f32_info>,
9057                          EVEX_CD8<32, CD8VF>;
9058 defm VFIXUPIMMPD : avx512_fixupimm_packed_all<avx512vl_f64_info>,
9059                          EVEX_CD8<64, CD8VF>, VEX_W;
9060
9061
9062
9063 // Patterns used to select SSE scalar fp arithmetic instructions from
9064 // either:
9065 //
9066 // (1) a scalar fp operation followed by a blend
9067 //
9068 // The effect is that the backend no longer emits unnecessary vector
9069 // insert instructions immediately after SSE scalar fp instructions
9070 // like addss or mulss.
9071 //
9072 // For example, given the following code:
9073 //   __m128 foo(__m128 A, __m128 B) {
9074 //     A[0] += B[0];
9075 //     return A;
9076 //   }
9077 //
9078 // Previously we generated:
9079 //   addss %xmm0, %xmm1
9080 //   movss %xmm1, %xmm0
9081 //
9082 // We now generate:
9083 //   addss %xmm1, %xmm0
9084 //
9085 // (2) a vector packed single/double fp operation followed by a vector insert
9086 //
9087 // The effect is that the backend converts the packed fp instruction
9088 // followed by a vector insert into a single SSE scalar fp instruction.
9089 //
9090 // For example, given the following code:
9091 //   __m128 foo(__m128 A, __m128 B) {
9092 //     __m128 C = A + B;
9093 //     return (__m128) {c[0], a[1], a[2], a[3]};
9094 //   }
9095 //
9096 // Previously we generated:
9097 //   addps %xmm0, %xmm1
9098 //   movss %xmm1, %xmm0
9099 //
9100 // We now generate:
9101 //   addss %xmm1, %xmm0
9102
9103 // TODO: Some canonicalization in lowering would simplify the number of
9104 // patterns we have to try to match.
9105 multiclass AVX512_scalar_math_f32_patterns<SDNode Op, string OpcPrefix> {
9106   let Predicates = [HasAVX512] in {
9107     // extracted scalar math op with insert via movss
9108     def : Pat<(v4f32 (X86Movss (v4f32 VR128X:$dst), (v4f32 (scalar_to_vector
9109           (Op (f32 (extractelt (v4f32 VR128X:$dst), (iPTR 0))),
9110           FR32X:$src))))),
9111       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst,
9112           (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
9113
9114     // extracted scalar math op with insert via blend
9115     def : Pat<(v4f32 (X86Blendi (v4f32 VR128X:$dst), (v4f32 (scalar_to_vector
9116           (Op (f32 (extractelt (v4f32 VR128X:$dst), (iPTR 0))),
9117           FR32X:$src))), (i8 1))),
9118       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst,
9119           (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
9120
9121     // vector math op with insert via movss
9122     def : Pat<(v4f32 (X86Movss (v4f32 VR128X:$dst),
9123           (Op (v4f32 VR128X:$dst), (v4f32 VR128X:$src)))),
9124       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst, v4f32:$src)>;
9125
9126     // vector math op with insert via blend
9127     def : Pat<(v4f32 (X86Blendi (v4f32 VR128X:$dst),
9128           (Op (v4f32 VR128X:$dst), (v4f32 VR128X:$src)), (i8 1))),
9129       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst, v4f32:$src)>;
9130
9131     // extracted masked scalar math op with insert via movss
9132     def : Pat<(X86Movss (v4f32 VR128X:$src1),
9133                (scalar_to_vector
9134                 (X86selects VK1WM:$mask,
9135                             (Op (f32 (extractelt (v4f32 VR128X:$src1), (iPTR 0))),
9136                                 FR32X:$src2),
9137                             FR32X:$src0))),
9138       (!cast<I>("V"#OpcPrefix#SSZrr_Intk) (COPY_TO_REGCLASS FR32X:$src0, VR128X),
9139           VK1WM:$mask, v4f32:$src1,
9140           (COPY_TO_REGCLASS FR32X:$src2, VR128X))>;
9141   }
9142 }
9143
9144 defm : AVX512_scalar_math_f32_patterns<fadd, "ADD">;
9145 defm : AVX512_scalar_math_f32_patterns<fsub, "SUB">;
9146 defm : AVX512_scalar_math_f32_patterns<fmul, "MUL">;
9147 defm : AVX512_scalar_math_f32_patterns<fdiv, "DIV">;
9148
9149 multiclass AVX512_scalar_math_f64_patterns<SDNode Op, string OpcPrefix> {
9150   let Predicates = [HasAVX512] in {
9151     // extracted scalar math op with insert via movsd
9152     def : Pat<(v2f64 (X86Movsd (v2f64 VR128X:$dst), (v2f64 (scalar_to_vector
9153           (Op (f64 (extractelt (v2f64 VR128X:$dst), (iPTR 0))),
9154           FR64X:$src))))),
9155       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst,
9156           (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
9157
9158     // extracted scalar math op with insert via blend
9159     def : Pat<(v2f64 (X86Blendi (v2f64 VR128X:$dst), (v2f64 (scalar_to_vector
9160           (Op (f64 (extractelt (v2f64 VR128X:$dst), (iPTR 0))),
9161           FR64X:$src))), (i8 1))),
9162       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst,
9163           (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
9164
9165     // vector math op with insert via movsd
9166     def : Pat<(v2f64 (X86Movsd (v2f64 VR128X:$dst),
9167           (Op (v2f64 VR128X:$dst), (v2f64 VR128X:$src)))),
9168       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst, v2f64:$src)>;
9169
9170     // vector math op with insert via blend
9171     def : Pat<(v2f64 (X86Blendi (v2f64 VR128X:$dst),
9172           (Op (v2f64 VR128X:$dst), (v2f64 VR128X:$src)), (i8 1))),
9173       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst, v2f64:$src)>;
9174
9175     // extracted masked scalar math op with insert via movss
9176     def : Pat<(X86Movsd (v2f64 VR128X:$src1),
9177                (scalar_to_vector
9178                 (X86selects VK1WM:$mask,
9179                             (Op (f64 (extractelt (v2f64 VR128X:$src1), (iPTR 0))),
9180                                 FR64X:$src2),
9181                             FR64X:$src0))),
9182       (!cast<I>("V"#OpcPrefix#SDZrr_Intk) (COPY_TO_REGCLASS FR64X:$src0, VR128X),
9183           VK1WM:$mask, v2f64:$src1,
9184           (COPY_TO_REGCLASS FR64X:$src2, VR128X))>;
9185   }
9186 }
9187
9188 defm : AVX512_scalar_math_f64_patterns<fadd, "ADD">;
9189 defm : AVX512_scalar_math_f64_patterns<fsub, "SUB">;
9190 defm : AVX512_scalar_math_f64_patterns<fmul, "MUL">;
9191 defm : AVX512_scalar_math_f64_patterns<fdiv, "DIV">;