]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86InstrAVX512.td
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302418, and update
[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   // Suffix used in the instruction mnemonic.
38   string Suffix = suffix;
39
40   // VTName is a string name for vector VT. For vector types it will be
41   // v # NumElts # EltVT, so for vector of 8 elements of i32 it will be v8i32
42   // It is a little bit complex for scalar types, where NumElts = 1.
43   // In this case we build v4f32 or v2f64
44   string VTName = "v" # !if (!eq (NumElts, 1),
45                         !if (!eq (EltVT.Size, 32), 4,
46                         !if (!eq (EltVT.Size, 64), 2, NumElts)), NumElts) # EltVT;
47
48   // The vector VT.
49   ValueType VT = !cast<ValueType>(VTName);
50
51   string EltTypeName = !cast<string>(EltVT);
52   // Size of the element type in bits, e.g. 32 for v16i32.
53   string EltSizeName = !subst("i", "", !subst("f", "", EltTypeName));
54   int EltSize = EltVT.Size;
55
56   // "i" for integer types and "f" for floating-point types
57   string TypeVariantName = !subst(EltSizeName, "", EltTypeName);
58
59   // Size of RC in bits, e.g. 512 for VR512.
60   int Size = VT.Size;
61
62   // The corresponding memory operand, e.g. i512mem for VR512.
63   X86MemOperand MemOp = !cast<X86MemOperand>(TypeVariantName # Size # "mem");
64   X86MemOperand ScalarMemOp = !cast<X86MemOperand>(EltVT # "mem");
65   // FP scalar memory operand for intrinsics - ssmem/sdmem.
66   Operand IntScalarMemOp = !if (!eq (EltTypeName, "f32"), !cast<Operand>("ssmem"),
67                            !if (!eq (EltTypeName, "f64"), !cast<Operand>("sdmem"), ?));
68
69   // Load patterns
70   // Note: For 128/256-bit integer VT we choose loadv2i64/loadv4i64
71   //       due to load promotion during legalization
72   PatFrag LdFrag = !cast<PatFrag>("load" #
73                                   !if (!eq (TypeVariantName, "i"),
74                                        !if (!eq (Size, 128), "v2i64",
75                                        !if (!eq (Size, 256), "v4i64",
76                                        !if (!eq (Size, 512), "v8i64",
77                                             VTName))), VTName));
78
79   PatFrag AlignedLdFrag = !cast<PatFrag>("alignedload" #
80                                          !if (!eq (TypeVariantName, "i"),
81                                                !if (!eq (Size, 128), "v2i64",
82                                                !if (!eq (Size, 256), "v4i64",
83                                                !if (!eq (Size, 512), "v8i64",
84                                                    VTName))), VTName));
85
86   PatFrag ScalarLdFrag = !cast<PatFrag>("load" # EltVT);
87
88   ComplexPattern ScalarIntMemCPat = !if (!eq (EltTypeName, "f32"),
89                                           !cast<ComplexPattern>("sse_load_f32"),
90                                     !if (!eq (EltTypeName, "f64"),
91                                           !cast<ComplexPattern>("sse_load_f64"),
92                                     ?));
93
94   // The corresponding float type, e.g. v16f32 for v16i32
95   // Note: For EltSize < 32, FloatVT is illegal and TableGen
96   //       fails to compile, so we choose FloatVT = VT
97   ValueType FloatVT = !cast<ValueType>(
98                         !if (!eq (!srl(EltSize,5),0),
99                              VTName,
100                              !if (!eq(TypeVariantName, "i"),
101                                   "v" # NumElts # "f" # EltSize,
102                                   VTName)));
103
104   ValueType IntVT = !cast<ValueType>(
105                         !if (!eq (!srl(EltSize,5),0),
106                              VTName,
107                              !if (!eq(TypeVariantName, "f"),
108                                   "v" # NumElts # "i" # EltSize,
109                                   VTName)));
110   // The string to specify embedded broadcast in assembly.
111   string BroadcastStr = "{1to" # NumElts # "}";
112
113   // 8-bit compressed displacement tuple/subvector format.  This is only
114   // defined for NumElts <= 8.
115   CD8VForm CD8TupleForm = !if (!eq (!srl(NumElts, 4), 0),
116                                !cast<CD8VForm>("CD8VT" # NumElts), ?);
117
118   SubRegIndex SubRegIdx = !if (!eq (Size, 128), sub_xmm,
119                           !if (!eq (Size, 256), sub_ymm, ?));
120
121   Domain ExeDomain = !if (!eq (EltTypeName, "f32"), SSEPackedSingle,
122                      !if (!eq (EltTypeName, "f64"), SSEPackedDouble,
123                      SSEPackedInt));
124
125   RegisterClass FRC = !if (!eq (EltTypeName, "f32"), FR32X, FR64X);
126
127   // A vector tye of the same width with element type i64. This is used to
128   // create patterns for logic ops.
129   ValueType i64VT = !cast<ValueType>("v" # !srl(Size, 6) # "i64");
130
131   // A vector type of the same width with element type i32.  This is used to
132   // create the canonical constant zero node ImmAllZerosV.
133   ValueType i32VT = !cast<ValueType>("v" # !srl(Size, 5) # "i32");
134   dag ImmAllZerosV = (VT (bitconvert (i32VT immAllZerosV)));
135
136   string ZSuffix = !if (!eq (Size, 128), "Z128",
137                    !if (!eq (Size, 256), "Z256", "Z"));
138 }
139
140 def v64i8_info  : X86VectorVTInfo<64,  i8, VR512, "b">;
141 def v32i16_info : X86VectorVTInfo<32, i16, VR512, "w">;
142 def v16i32_info : X86VectorVTInfo<16, i32, VR512, "d">;
143 def v8i64_info  : X86VectorVTInfo<8,  i64, VR512, "q">;
144 def v16f32_info : X86VectorVTInfo<16, f32, VR512, "ps">;
145 def v8f64_info  : X86VectorVTInfo<8,  f64, VR512, "pd">;
146
147 // "x" in v32i8x_info means RC = VR256X
148 def v32i8x_info  : X86VectorVTInfo<32,  i8, VR256X, "b">;
149 def v16i16x_info : X86VectorVTInfo<16, i16, VR256X, "w">;
150 def v8i32x_info  : X86VectorVTInfo<8,  i32, VR256X, "d">;
151 def v4i64x_info  : X86VectorVTInfo<4,  i64, VR256X, "q">;
152 def v8f32x_info  : X86VectorVTInfo<8,  f32, VR256X, "ps">;
153 def v4f64x_info  : X86VectorVTInfo<4,  f64, VR256X, "pd">;
154
155 def v16i8x_info  : X86VectorVTInfo<16,  i8, VR128X, "b">;
156 def v8i16x_info  : X86VectorVTInfo<8,  i16, VR128X, "w">;
157 def v4i32x_info  : X86VectorVTInfo<4,  i32, VR128X, "d">;
158 def v2i64x_info  : X86VectorVTInfo<2,  i64, VR128X, "q">;
159 def v4f32x_info  : X86VectorVTInfo<4,  f32, VR128X, "ps">;
160 def v2f64x_info  : X86VectorVTInfo<2,  f64, VR128X, "pd">;
161
162 // We map scalar types to the smallest (128-bit) vector type
163 // with the appropriate element type. This allows to use the same masking logic.
164 def i32x_info    : X86VectorVTInfo<1,  i32, GR32, "si">;
165 def i64x_info    : X86VectorVTInfo<1,  i64, GR64, "sq">;
166 def f32x_info    : X86VectorVTInfo<1,  f32, VR128X, "ss">;
167 def f64x_info    : X86VectorVTInfo<1,  f64, VR128X, "sd">;
168
169 class AVX512VLVectorVTInfo<X86VectorVTInfo i512, X86VectorVTInfo i256,
170                            X86VectorVTInfo i128> {
171   X86VectorVTInfo info512 = i512;
172   X86VectorVTInfo info256 = i256;
173   X86VectorVTInfo info128 = i128;
174 }
175
176 def avx512vl_i8_info  : AVX512VLVectorVTInfo<v64i8_info, v32i8x_info,
177                                              v16i8x_info>;
178 def avx512vl_i16_info : AVX512VLVectorVTInfo<v32i16_info, v16i16x_info,
179                                              v8i16x_info>;
180 def avx512vl_i32_info : AVX512VLVectorVTInfo<v16i32_info, v8i32x_info,
181                                              v4i32x_info>;
182 def avx512vl_i64_info : AVX512VLVectorVTInfo<v8i64_info, v4i64x_info,
183                                              v2i64x_info>;
184 def avx512vl_f32_info : AVX512VLVectorVTInfo<v16f32_info, v8f32x_info,
185                                              v4f32x_info>;
186 def avx512vl_f64_info : AVX512VLVectorVTInfo<v8f64_info, v4f64x_info,
187                                              v2f64x_info>;
188
189 // This multiclass generates the masking variants from the non-masking
190 // variant.  It only provides the assembly pieces for the masking variants.
191 // It assumes custom ISel patterns for masking which can be provided as
192 // template arguments.
193 multiclass AVX512_maskable_custom<bits<8> O, Format F,
194                                   dag Outs,
195                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
196                                   string OpcodeStr,
197                                   string AttSrcAsm, string IntelSrcAsm,
198                                   list<dag> Pattern,
199                                   list<dag> MaskingPattern,
200                                   list<dag> ZeroMaskingPattern,
201                                   string MaskingConstraint = "",
202                                   InstrItinClass itin = NoItinerary,
203                                   bit IsCommutable = 0,
204                                   bit IsKCommutable = 0> {
205   let isCommutable = IsCommutable in
206     def NAME: AVX512<O, F, Outs, Ins,
207                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
208                                      "$dst, "#IntelSrcAsm#"}",
209                        Pattern, itin>;
210
211   // Prefer over VMOV*rrk Pat<>
212   let isCommutable = IsKCommutable in
213     def NAME#k: AVX512<O, F, Outs, MaskingIns,
214                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
215                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
216                        MaskingPattern, itin>,
217               EVEX_K {
218       // In case of the 3src subclass this is overridden with a let.
219       string Constraints = MaskingConstraint;
220     }
221
222   // Zero mask does not add any restrictions to commute operands transformation.
223   // So, it is Ok to use IsCommutable instead of IsKCommutable.
224   let isCommutable = IsCommutable in // Prefer over VMOV*rrkz Pat<>
225     def NAME#kz: AVX512<O, F, Outs, ZeroMaskingIns,
226                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}} {z}|"#
227                                      "$dst {${mask}} {z}, "#IntelSrcAsm#"}",
228                        ZeroMaskingPattern,
229                        itin>,
230               EVEX_KZ;
231 }
232
233
234 // Common base class of AVX512_maskable and AVX512_maskable_3src.
235 multiclass AVX512_maskable_common<bits<8> O, Format F, X86VectorVTInfo _,
236                                   dag Outs,
237                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
238                                   string OpcodeStr,
239                                   string AttSrcAsm, string IntelSrcAsm,
240                                   dag RHS, dag MaskingRHS,
241                                   SDNode Select = vselect,
242                                   string MaskingConstraint = "",
243                                   InstrItinClass itin = NoItinerary,
244                                   bit IsCommutable = 0,
245                                   bit IsKCommutable = 0> :
246   AVX512_maskable_custom<O, F, Outs, Ins, MaskingIns, ZeroMaskingIns, OpcodeStr,
247                          AttSrcAsm, IntelSrcAsm,
248                          [(set _.RC:$dst, RHS)],
249                          [(set _.RC:$dst, MaskingRHS)],
250                          [(set _.RC:$dst,
251                                (Select _.KRCWM:$mask, RHS, _.ImmAllZerosV))],
252                          MaskingConstraint, NoItinerary, IsCommutable,
253                          IsKCommutable>;
254
255 // Similar to AVX512_maskable_common, but with scalar types.
256 multiclass AVX512_maskable_fp_common<bits<8> O, Format F, X86VectorVTInfo _,
257                                   dag Outs,
258                                   dag Ins, dag MaskingIns, dag ZeroMaskingIns,
259                                   string OpcodeStr,
260                                   string AttSrcAsm, string IntelSrcAsm,
261                                   SDNode Select = vselect,
262                                   string MaskingConstraint = "",
263                                   InstrItinClass itin = NoItinerary,
264                                   bit IsCommutable = 0,
265                                   bit IsKCommutable = 0> :
266   AVX512_maskable_custom<O, F, Outs, Ins, MaskingIns, ZeroMaskingIns, OpcodeStr,
267                          AttSrcAsm, IntelSrcAsm,
268                          [], [], [],
269                          MaskingConstraint, NoItinerary, IsCommutable,
270                          IsKCommutable>;
271
272 // This multiclass generates the unconditional/non-masking, the masking and
273 // the zero-masking variant of the vector instruction.  In the masking case, the
274 // perserved vector elements come from a new dummy input operand tied to $dst.
275 multiclass AVX512_maskable<bits<8> O, Format F, X86VectorVTInfo _,
276                            dag Outs, dag Ins, string OpcodeStr,
277                            string AttSrcAsm, string IntelSrcAsm,
278                            dag RHS,
279                            InstrItinClass itin = NoItinerary,
280                            bit IsCommutable = 0, bit IsKCommutable = 0,
281                            SDNode Select = vselect> :
282    AVX512_maskable_common<O, F, _, Outs, Ins,
283                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
284                           !con((ins _.KRCWM:$mask), Ins),
285                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
286                           (Select _.KRCWM:$mask, RHS, _.RC:$src0), Select,
287                           "$src0 = $dst", itin, IsCommutable, IsKCommutable>;
288
289 // This multiclass generates the unconditional/non-masking, the masking and
290 // the zero-masking variant of the scalar instruction.
291 multiclass AVX512_maskable_scalar<bits<8> O, Format F, X86VectorVTInfo _,
292                            dag Outs, dag Ins, string OpcodeStr,
293                            string AttSrcAsm, string IntelSrcAsm,
294                            dag RHS,
295                            InstrItinClass itin = NoItinerary,
296                            bit IsCommutable = 0> :
297    AVX512_maskable_common<O, F, _, Outs, Ins,
298                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
299                           !con((ins _.KRCWM:$mask), Ins),
300                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
301                           (X86selects _.KRCWM:$mask, RHS, _.RC:$src0),
302                           X86selects, "$src0 = $dst", itin, IsCommutable>;
303
304 // Similar to AVX512_maskable but in this case one of the source operands
305 // ($src1) is already tied to $dst so we just use that for the preserved
306 // vector elements.  NOTE that the NonTiedIns (the ins dag) should exclude
307 // $src1.
308 multiclass AVX512_maskable_3src<bits<8> O, Format F, X86VectorVTInfo _,
309                                 dag Outs, dag NonTiedIns, string OpcodeStr,
310                                 string AttSrcAsm, string IntelSrcAsm,
311                                 dag RHS, bit IsCommutable = 0,
312                                 bit IsKCommutable = 0> :
313    AVX512_maskable_common<O, F, _, Outs,
314                           !con((ins _.RC:$src1), NonTiedIns),
315                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
316                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
317                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
318                           (vselect _.KRCWM:$mask, RHS, _.RC:$src1),
319                           vselect, "", NoItinerary, IsCommutable, IsKCommutable>;
320
321 multiclass AVX512_maskable_3src_scalar<bits<8> O, Format F, X86VectorVTInfo _,
322                                      dag Outs, dag NonTiedIns, string OpcodeStr,
323                                      string AttSrcAsm, string IntelSrcAsm,
324                                      dag RHS, bit IsCommutable = 0,
325                                      bit IsKCommutable = 0> :
326    AVX512_maskable_common<O, F, _, Outs,
327                           !con((ins _.RC:$src1), NonTiedIns),
328                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
329                           !con((ins _.RC:$src1, _.KRCWM:$mask), NonTiedIns),
330                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
331                           (X86selects _.KRCWM:$mask, RHS, _.RC:$src1),
332                           X86selects, "", NoItinerary, IsCommutable,
333                           IsKCommutable>;
334
335 multiclass AVX512_maskable_in_asm<bits<8> O, Format F, X86VectorVTInfo _,
336                                   dag Outs, dag Ins,
337                                   string OpcodeStr,
338                                   string AttSrcAsm, string IntelSrcAsm,
339                                   list<dag> Pattern> :
340    AVX512_maskable_custom<O, F, Outs, Ins,
341                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
342                           !con((ins _.KRCWM:$mask), Ins),
343                           OpcodeStr, AttSrcAsm, IntelSrcAsm, Pattern, [], [],
344                           "$src0 = $dst">;
345
346
347 // Instruction with mask that puts result in mask register,
348 // like "compare" and "vptest"
349 multiclass AVX512_maskable_custom_cmp<bits<8> O, Format F,
350                                   dag Outs,
351                                   dag Ins, dag MaskingIns,
352                                   string OpcodeStr,
353                                   string AttSrcAsm, string IntelSrcAsm,
354                                   list<dag> Pattern,
355                                   list<dag> MaskingPattern,
356                                   bit IsCommutable = 0> {
357     let isCommutable = IsCommutable in
358     def NAME: AVX512<O, F, Outs, Ins,
359                        OpcodeStr#"\t{"#AttSrcAsm#", $dst|"#
360                                      "$dst, "#IntelSrcAsm#"}",
361                        Pattern, NoItinerary>;
362
363     def NAME#k: AVX512<O, F, Outs, MaskingIns,
364                        OpcodeStr#"\t{"#AttSrcAsm#", $dst {${mask}}|"#
365                                      "$dst {${mask}}, "#IntelSrcAsm#"}",
366                        MaskingPattern, NoItinerary>, EVEX_K;
367 }
368
369 multiclass AVX512_maskable_common_cmp<bits<8> O, Format F, X86VectorVTInfo _,
370                                   dag Outs,
371                                   dag Ins, dag MaskingIns,
372                                   string OpcodeStr,
373                                   string AttSrcAsm, string IntelSrcAsm,
374                                   dag RHS, dag MaskingRHS,
375                                   bit IsCommutable = 0> :
376   AVX512_maskable_custom_cmp<O, F, Outs, Ins, MaskingIns, OpcodeStr,
377                          AttSrcAsm, IntelSrcAsm,
378                          [(set _.KRC:$dst, RHS)],
379                          [(set _.KRC:$dst, MaskingRHS)], IsCommutable>;
380
381 multiclass AVX512_maskable_cmp<bits<8> O, Format F, X86VectorVTInfo _,
382                            dag Outs, dag Ins, string OpcodeStr,
383                            string AttSrcAsm, string IntelSrcAsm,
384                            dag RHS, bit IsCommutable = 0> :
385    AVX512_maskable_common_cmp<O, F, _, Outs, Ins,
386                           !con((ins _.KRCWM:$mask), Ins),
387                           OpcodeStr, AttSrcAsm, IntelSrcAsm, RHS,
388                           (and _.KRCWM:$mask, RHS), IsCommutable>;
389
390 multiclass AVX512_maskable_cmp_alt<bits<8> O, Format F, X86VectorVTInfo _,
391                            dag Outs, dag Ins, string OpcodeStr,
392                            string AttSrcAsm, string IntelSrcAsm> :
393    AVX512_maskable_custom_cmp<O, F, Outs,
394                              Ins, !con((ins _.KRCWM:$mask),Ins), OpcodeStr,
395                              AttSrcAsm, IntelSrcAsm, [],[]>;
396
397 // This multiclass generates the unconditional/non-masking, the masking and
398 // the zero-masking variant of the vector instruction.  In the masking case, the
399 // perserved vector elements come from a new dummy input operand tied to $dst.
400 multiclass AVX512_maskable_logic<bits<8> O, Format F, X86VectorVTInfo _,
401                            dag Outs, dag Ins, string OpcodeStr,
402                            string AttSrcAsm, string IntelSrcAsm,
403                            dag RHS, dag MaskedRHS,
404                            InstrItinClass itin = NoItinerary,
405                            bit IsCommutable = 0, SDNode Select = vselect> :
406    AVX512_maskable_custom<O, F, Outs, Ins,
407                           !con((ins _.RC:$src0, _.KRCWM:$mask), Ins),
408                           !con((ins _.KRCWM:$mask), Ins),
409                           OpcodeStr, AttSrcAsm, IntelSrcAsm,
410                           [(set _.RC:$dst, RHS)],
411                           [(set _.RC:$dst,
412                                 (Select _.KRCWM:$mask, MaskedRHS, _.RC:$src0))],
413                           [(set _.RC:$dst,
414                                 (Select _.KRCWM:$mask, MaskedRHS,
415                                         _.ImmAllZerosV))],
416                           "$src0 = $dst", itin, IsCommutable>;
417
418 // Bitcasts between 512-bit vector types. Return the original type since
419 // no instruction is needed for the conversion.
420 def : Pat<(v8f64  (bitconvert (v8i64  VR512:$src))), (v8f64  VR512:$src)>;
421 def : Pat<(v8f64  (bitconvert (v16i32 VR512:$src))), (v8f64  VR512:$src)>;
422 def : Pat<(v8f64  (bitconvert (v32i16 VR512:$src))), (v8f64  VR512:$src)>;
423 def : Pat<(v8f64  (bitconvert (v64i8  VR512:$src))), (v8f64  VR512:$src)>;
424 def : Pat<(v8f64  (bitconvert (v16f32 VR512:$src))), (v8f64  VR512:$src)>;
425 def : Pat<(v16f32 (bitconvert (v8i64  VR512:$src))), (v16f32 VR512:$src)>;
426 def : Pat<(v16f32 (bitconvert (v16i32 VR512:$src))), (v16f32 VR512:$src)>;
427 def : Pat<(v16f32 (bitconvert (v32i16 VR512:$src))), (v16f32 VR512:$src)>;
428 def : Pat<(v16f32 (bitconvert (v64i8  VR512:$src))), (v16f32 VR512:$src)>;
429 def : Pat<(v16f32 (bitconvert (v8f64  VR512:$src))), (v16f32 VR512:$src)>;
430 def : Pat<(v8i64  (bitconvert (v16i32 VR512:$src))), (v8i64  VR512:$src)>;
431 def : Pat<(v8i64  (bitconvert (v32i16 VR512:$src))), (v8i64  VR512:$src)>;
432 def : Pat<(v8i64  (bitconvert (v64i8  VR512:$src))), (v8i64  VR512:$src)>;
433 def : Pat<(v8i64  (bitconvert (v8f64  VR512:$src))), (v8i64  VR512:$src)>;
434 def : Pat<(v8i64  (bitconvert (v16f32 VR512:$src))), (v8i64  VR512:$src)>;
435 def : Pat<(v16i32 (bitconvert (v8i64  VR512:$src))), (v16i32 VR512:$src)>;
436 def : Pat<(v16i32 (bitconvert (v16f32 VR512:$src))), (v16i32 VR512:$src)>;
437 def : Pat<(v16i32 (bitconvert (v32i16 VR512:$src))), (v16i32 VR512:$src)>;
438 def : Pat<(v16i32 (bitconvert (v64i8  VR512:$src))), (v16i32 VR512:$src)>;
439 def : Pat<(v16i32 (bitconvert (v8f64  VR512:$src))), (v16i32 VR512:$src)>;
440 def : Pat<(v32i16 (bitconvert (v8i64  VR512:$src))), (v32i16 VR512:$src)>;
441 def : Pat<(v32i16 (bitconvert (v16i32 VR512:$src))), (v32i16 VR512:$src)>;
442 def : Pat<(v32i16 (bitconvert (v64i8  VR512:$src))), (v32i16 VR512:$src)>;
443 def : Pat<(v32i16 (bitconvert (v8f64  VR512:$src))), (v32i16 VR512:$src)>;
444 def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
445 def : Pat<(v32i16 (bitconvert (v16f32 VR512:$src))), (v32i16 VR512:$src)>;
446 def : Pat<(v64i8  (bitconvert (v8i64  VR512:$src))), (v64i8  VR512:$src)>;
447 def : Pat<(v64i8  (bitconvert (v16i32 VR512:$src))), (v64i8  VR512:$src)>;
448 def : Pat<(v64i8  (bitconvert (v32i16 VR512:$src))), (v64i8  VR512:$src)>;
449 def : Pat<(v64i8  (bitconvert (v8f64  VR512:$src))), (v64i8  VR512:$src)>;
450 def : Pat<(v64i8  (bitconvert (v16f32 VR512:$src))), (v64i8  VR512:$src)>;
451
452 // Alias instruction that maps zero vector to pxor / xorp* for AVX-512.
453 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
454 // swizzled by ExecutionDepsFix to pxor.
455 // We set canFoldAsLoad because this can be converted to a constant-pool
456 // load of an all-zeros value if folding it would be beneficial.
457 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
458     isPseudo = 1, Predicates = [HasAVX512], SchedRW = [WriteZero] in {
459 def AVX512_512_SET0 : I<0, Pseudo, (outs VR512:$dst), (ins), "",
460                [(set VR512:$dst, (v16i32 immAllZerosV))]>;
461 def AVX512_512_SETALLONES : I<0, Pseudo, (outs VR512:$dst), (ins), "",
462                [(set VR512:$dst, (v16i32 immAllOnesV))]>;
463 }
464
465 // Alias instructions that allow VPTERNLOG to be used with a mask to create
466 // a mix of all ones and all zeros elements. This is done this way to force
467 // the same register to be used as input for all three sources.
468 let isPseudo = 1, Predicates = [HasAVX512] in {
469 def AVX512_512_SEXT_MASK_32 : I<0, Pseudo, (outs VR512:$dst),
470                                 (ins VK16WM:$mask), "",
471                            [(set VR512:$dst, (vselect (v16i1 VK16WM:$mask),
472                                                       (v16i32 immAllOnesV),
473                                                       (v16i32 immAllZerosV)))]>;
474 def AVX512_512_SEXT_MASK_64 : I<0, Pseudo, (outs VR512:$dst),
475                                 (ins VK8WM:$mask), "",
476                 [(set VR512:$dst, (vselect (v8i1 VK8WM:$mask),
477                                            (bc_v8i64 (v16i32 immAllOnesV)),
478                                            (bc_v8i64 (v16i32 immAllZerosV))))]>;
479 }
480
481 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
482     isPseudo = 1, Predicates = [HasAVX512], SchedRW = [WriteZero] in {
483 def AVX512_128_SET0 : I<0, Pseudo, (outs VR128X:$dst), (ins), "",
484                [(set VR128X:$dst, (v4i32 immAllZerosV))]>;
485 def AVX512_256_SET0 : I<0, Pseudo, (outs VR256X:$dst), (ins), "",
486                [(set VR256X:$dst, (v8i32 immAllZerosV))]>;
487 }
488
489 // Alias instructions that map fld0 to xorps for sse or vxorps for avx.
490 // This is expanded by ExpandPostRAPseudos.
491 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
492     isPseudo = 1, SchedRW = [WriteZero], Predicates = [HasAVX512] in {
493   def AVX512_FsFLD0SS : I<0, Pseudo, (outs FR32X:$dst), (ins), "",
494                           [(set FR32X:$dst, fp32imm0)]>;
495   def AVX512_FsFLD0SD : I<0, Pseudo, (outs FR64X:$dst), (ins), "",
496                           [(set FR64X:$dst, fpimm0)]>;
497 }
498
499 //===----------------------------------------------------------------------===//
500 // AVX-512 - VECTOR INSERT
501 //
502 multiclass vinsert_for_size<int Opcode, X86VectorVTInfo From, X86VectorVTInfo To,
503                                                        PatFrag vinsert_insert> {
504   let ExeDomain = To.ExeDomain in {
505     defm rr : AVX512_maskable<Opcode, MRMSrcReg, To, (outs To.RC:$dst),
506                    (ins To.RC:$src1, From.RC:$src2, u8imm:$src3),
507                    "vinsert" # From.EltTypeName # "x" # From.NumElts,
508                    "$src3, $src2, $src1", "$src1, $src2, $src3",
509                    (vinsert_insert:$src3 (To.VT To.RC:$src1),
510                                          (From.VT From.RC:$src2),
511                                          (iPTR imm))>, AVX512AIi8Base, EVEX_4V;
512
513     defm rm : AVX512_maskable<Opcode, MRMSrcMem, To, (outs To.RC:$dst),
514                    (ins To.RC:$src1, From.MemOp:$src2, u8imm:$src3),
515                    "vinsert" # From.EltTypeName # "x" # From.NumElts,
516                    "$src3, $src2, $src1", "$src1, $src2, $src3",
517                    (vinsert_insert:$src3 (To.VT To.RC:$src1),
518                                (From.VT (bitconvert (From.LdFrag addr:$src2))),
519                                (iPTR imm))>, AVX512AIi8Base, EVEX_4V,
520                    EVEX_CD8<From.EltSize, From.CD8TupleForm>;
521   }
522 }
523
524 multiclass vinsert_for_size_lowering<string InstrStr, X86VectorVTInfo From,
525                        X86VectorVTInfo To, PatFrag vinsert_insert,
526                        SDNodeXForm INSERT_get_vinsert_imm , list<Predicate> p> {
527   let Predicates = p in {
528     def : Pat<(vinsert_insert:$ins
529                      (To.VT To.RC:$src1), (From.VT From.RC:$src2), (iPTR imm)),
530               (To.VT (!cast<Instruction>(InstrStr#"rr")
531                      To.RC:$src1, From.RC:$src2,
532                      (INSERT_get_vinsert_imm To.RC:$ins)))>;
533
534     def : Pat<(vinsert_insert:$ins
535                   (To.VT To.RC:$src1),
536                   (From.VT (bitconvert (From.LdFrag addr:$src2))),
537                   (iPTR imm)),
538               (To.VT (!cast<Instruction>(InstrStr#"rm")
539                   To.RC:$src1, addr:$src2,
540                   (INSERT_get_vinsert_imm To.RC:$ins)))>;
541   }
542 }
543
544 multiclass vinsert_for_type<ValueType EltVT32, int Opcode128,
545                             ValueType EltVT64, int Opcode256> {
546
547   let Predicates = [HasVLX] in
548     defm NAME # "32x4Z256" : vinsert_for_size<Opcode128,
549                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
550                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
551                                  vinsert128_insert>, EVEX_V256;
552
553   defm NAME # "32x4Z" : vinsert_for_size<Opcode128,
554                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
555                                  X86VectorVTInfo<16, EltVT32, VR512>,
556                                  vinsert128_insert>, EVEX_V512;
557
558   defm NAME # "64x4Z" : vinsert_for_size<Opcode256,
559                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
560                                  X86VectorVTInfo< 8, EltVT64, VR512>,
561                                  vinsert256_insert>, VEX_W, EVEX_V512;
562
563   let Predicates = [HasVLX, HasDQI] in
564     defm NAME # "64x2Z256" : vinsert_for_size<Opcode128,
565                                    X86VectorVTInfo< 2, EltVT64, VR128X>,
566                                    X86VectorVTInfo< 4, EltVT64, VR256X>,
567                                    vinsert128_insert>, VEX_W, EVEX_V256;
568
569   let Predicates = [HasDQI] in {
570     defm NAME # "64x2Z" : vinsert_for_size<Opcode128,
571                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
572                                  X86VectorVTInfo< 8, EltVT64, VR512>,
573                                  vinsert128_insert>, VEX_W, EVEX_V512;
574
575     defm NAME # "32x8Z" : vinsert_for_size<Opcode256,
576                                    X86VectorVTInfo< 8, EltVT32, VR256X>,
577                                    X86VectorVTInfo<16, EltVT32, VR512>,
578                                    vinsert256_insert>, EVEX_V512;
579   }
580 }
581
582 defm VINSERTF : vinsert_for_type<f32, 0x18, f64, 0x1a>;
583 defm VINSERTI : vinsert_for_type<i32, 0x38, i64, 0x3a>;
584
585 // Codegen pattern with the alternative types,
586 // Only add this if 64x2 and its friends are not supported natively via AVX512DQ.
587 defm : vinsert_for_size_lowering<"VINSERTF32x4Z256", v2f64x_info, v4f64x_info,
588               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX, NoDQI]>;
589 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v2i64x_info, v4i64x_info,
590               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX, NoDQI]>;
591
592 defm : vinsert_for_size_lowering<"VINSERTF32x4Z", v2f64x_info, v8f64_info,
593               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512, NoDQI]>;
594 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v2i64x_info, v8i64_info,
595               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512, NoDQI]>;
596
597 defm : vinsert_for_size_lowering<"VINSERTF64x4Z", v8f32x_info, v16f32_info,
598               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512, NoDQI]>;
599 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v8i32x_info, v16i32_info,
600               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512, NoDQI]>;
601
602 // Codegen pattern with the alternative types insert VEC128 into VEC256
603 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v8i16x_info, v16i16x_info,
604               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX]>;
605 defm : vinsert_for_size_lowering<"VINSERTI32x4Z256", v16i8x_info, v32i8x_info,
606               vinsert128_insert, INSERT_get_vinsert128_imm, [HasVLX]>;
607 // Codegen pattern with the alternative types insert VEC128 into VEC512
608 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v8i16x_info, v32i16_info,
609               vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512]>;
610 defm : vinsert_for_size_lowering<"VINSERTI32x4Z", v16i8x_info, v64i8_info,
611                vinsert128_insert, INSERT_get_vinsert128_imm, [HasAVX512]>;
612 // Codegen pattern with the alternative types insert VEC256 into VEC512
613 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v16i16x_info, v32i16_info,
614               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512]>;
615 defm : vinsert_for_size_lowering<"VINSERTI64x4Z", v32i8x_info, v64i8_info,
616               vinsert256_insert, INSERT_get_vinsert256_imm, [HasAVX512]>;
617
618 // vinsertps - insert f32 to XMM
619 let ExeDomain = SSEPackedSingle in {
620 def VINSERTPSZrr : AVX512AIi8<0x21, MRMSrcReg, (outs VR128X:$dst),
621       (ins VR128X:$src1, VR128X:$src2, u8imm:$src3),
622       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
623       [(set VR128X:$dst, (X86insertps VR128X:$src1, VR128X:$src2, imm:$src3))]>,
624       EVEX_4V;
625 def VINSERTPSZrm: AVX512AIi8<0x21, MRMSrcMem, (outs VR128X:$dst),
626       (ins VR128X:$src1, f32mem:$src2, u8imm:$src3),
627       "vinsertps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
628       [(set VR128X:$dst, (X86insertps VR128X:$src1,
629                           (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
630                           imm:$src3))]>, EVEX_4V, EVEX_CD8<32, CD8VT1>;
631 }
632
633 //===----------------------------------------------------------------------===//
634 // AVX-512 VECTOR EXTRACT
635 //---
636
637 multiclass vextract_for_size<int Opcode,
638                              X86VectorVTInfo From, X86VectorVTInfo To,
639                              PatFrag vextract_extract,
640                              SDNodeXForm EXTRACT_get_vextract_imm> {
641
642   let hasSideEffects = 0, ExeDomain = To.ExeDomain in {
643     // use AVX512_maskable_in_asm (AVX512_maskable can't be used due to
644     // vextract_extract), we interesting only in patterns without mask,
645     // intrinsics pattern match generated bellow.
646     defm rr : AVX512_maskable_in_asm<Opcode, MRMDestReg, To, (outs To.RC:$dst),
647                 (ins From.RC:$src1, u8imm:$idx),
648                 "vextract" # To.EltTypeName # "x" # To.NumElts,
649                 "$idx, $src1", "$src1, $idx",
650                 [(set To.RC:$dst, (vextract_extract:$idx (From.VT From.RC:$src1),
651                                                          (iPTR imm)))]>,
652               AVX512AIi8Base, EVEX;
653     def mr  : AVX512AIi8<Opcode, MRMDestMem, (outs),
654                     (ins To.MemOp:$dst, From.RC:$src1, u8imm:$idx),
655                     "vextract" # To.EltTypeName # "x" # To.NumElts #
656                         "\t{$idx, $src1, $dst|$dst, $src1, $idx}",
657                     [(store (To.VT (vextract_extract:$idx
658                                     (From.VT From.RC:$src1), (iPTR imm))),
659                              addr:$dst)]>, EVEX;
660
661     let mayStore = 1, hasSideEffects = 0 in
662     def mrk : AVX512AIi8<Opcode, MRMDestMem, (outs),
663                     (ins To.MemOp:$dst, To.KRCWM:$mask,
664                                         From.RC:$src1, u8imm:$idx),
665                      "vextract" # To.EltTypeName # "x" # To.NumElts #
666                           "\t{$idx, $src1, $dst {${mask}}|"
667                           "$dst {${mask}}, $src1, $idx}",
668                     []>, EVEX_K, EVEX;
669   }
670
671   def : Pat<(To.VT (vselect To.KRCWM:$mask,
672                             (vextract_extract:$ext (From.VT From.RC:$src1),
673                                                    (iPTR imm)),
674                             To.RC:$src0)),
675             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
676                                 From.ZSuffix # "rrk")
677                 To.RC:$src0, To.KRCWM:$mask, From.RC:$src1,
678                 (EXTRACT_get_vextract_imm To.RC:$ext))>;
679
680   def : Pat<(To.VT (vselect To.KRCWM:$mask,
681                             (vextract_extract:$ext (From.VT From.RC:$src1),
682                                                    (iPTR imm)),
683                             To.ImmAllZerosV)),
684             (!cast<Instruction>(NAME # To.EltSize # "x" # To.NumElts #
685                                 From.ZSuffix # "rrkz")
686                 To.KRCWM:$mask, From.RC:$src1,
687                 (EXTRACT_get_vextract_imm To.RC:$ext))>;
688 }
689
690 // Codegen pattern for the alternative types
691 multiclass vextract_for_size_lowering<string InstrStr, X86VectorVTInfo From,
692                 X86VectorVTInfo To, PatFrag vextract_extract,
693                 SDNodeXForm EXTRACT_get_vextract_imm, list<Predicate> p> {
694   let Predicates = p in {
695      def : Pat<(vextract_extract:$ext (From.VT From.RC:$src1), (iPTR imm)),
696                (To.VT (!cast<Instruction>(InstrStr#"rr")
697                           From.RC:$src1,
698                           (EXTRACT_get_vextract_imm To.RC:$ext)))>;
699      def : Pat<(store (To.VT (vextract_extract:$ext (From.VT From.RC:$src1),
700                               (iPTR imm))), addr:$dst),
701                (!cast<Instruction>(InstrStr#"mr") addr:$dst, From.RC:$src1,
702                 (EXTRACT_get_vextract_imm To.RC:$ext))>;
703   }
704 }
705
706 multiclass vextract_for_type<ValueType EltVT32, int Opcode128,
707                              ValueType EltVT64, int Opcode256> {
708   defm NAME # "32x4Z" : vextract_for_size<Opcode128,
709                                  X86VectorVTInfo<16, EltVT32, VR512>,
710                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
711                                  vextract128_extract,
712                                  EXTRACT_get_vextract128_imm>,
713                                      EVEX_V512, EVEX_CD8<32, CD8VT4>;
714   defm NAME # "64x4Z" : vextract_for_size<Opcode256,
715                                  X86VectorVTInfo< 8, EltVT64, VR512>,
716                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
717                                  vextract256_extract,
718                                  EXTRACT_get_vextract256_imm>,
719                                      VEX_W, EVEX_V512, EVEX_CD8<64, CD8VT4>;
720   let Predicates = [HasVLX] in
721     defm NAME # "32x4Z256" : vextract_for_size<Opcode128,
722                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
723                                  X86VectorVTInfo< 4, EltVT32, VR128X>,
724                                  vextract128_extract,
725                                  EXTRACT_get_vextract128_imm>,
726                                      EVEX_V256, EVEX_CD8<32, CD8VT4>;
727   let Predicates = [HasVLX, HasDQI] in
728     defm NAME # "64x2Z256" : vextract_for_size<Opcode128,
729                                  X86VectorVTInfo< 4, EltVT64, VR256X>,
730                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
731                                  vextract128_extract,
732                                  EXTRACT_get_vextract128_imm>,
733                                      VEX_W, EVEX_V256, EVEX_CD8<64, CD8VT2>;
734   let Predicates = [HasDQI] in {
735     defm NAME # "64x2Z" : vextract_for_size<Opcode128,
736                                  X86VectorVTInfo< 8, EltVT64, VR512>,
737                                  X86VectorVTInfo< 2, EltVT64, VR128X>,
738                                  vextract128_extract,
739                                  EXTRACT_get_vextract128_imm>,
740                                      VEX_W, EVEX_V512, EVEX_CD8<64, CD8VT2>;
741     defm NAME # "32x8Z" : vextract_for_size<Opcode256,
742                                  X86VectorVTInfo<16, EltVT32, VR512>,
743                                  X86VectorVTInfo< 8, EltVT32, VR256X>,
744                                  vextract256_extract,
745                                  EXTRACT_get_vextract256_imm>,
746                                      EVEX_V512, EVEX_CD8<32, CD8VT8>;
747   }
748 }
749
750 defm VEXTRACTF : vextract_for_type<f32, 0x19, f64, 0x1b>;
751 defm VEXTRACTI : vextract_for_type<i32, 0x39, i64, 0x3b>;
752
753 // extract_subvector codegen patterns with the alternative types.
754 // Only add this if 64x2 and its friends are not supported natively via AVX512DQ.
755 defm : vextract_for_size_lowering<"VEXTRACTF32x4Z", v8f64_info, v2f64x_info,
756           vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512, NoDQI]>;
757 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z", v8i64_info, v2i64x_info,
758           vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512, NoDQI]>;
759
760 defm : vextract_for_size_lowering<"VEXTRACTF64x4Z", v16f32_info, v8f32x_info,
761           vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512, NoDQI]>;
762 defm : vextract_for_size_lowering<"VEXTRACTI64x4Z", v16i32_info, v8i32x_info,
763           vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512, NoDQI]>;
764
765 defm : vextract_for_size_lowering<"VEXTRACTF32x4Z256", v4f64x_info, v2f64x_info,
766           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX, NoDQI]>;
767 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z256", v4i64x_info, v2i64x_info,
768           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX, NoDQI]>;
769
770 // Codegen pattern with the alternative types extract VEC128 from VEC256
771 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z256", v16i16x_info, v8i16x_info,
772           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX]>;
773 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z256", v32i8x_info, v16i8x_info,
774           vextract128_extract, EXTRACT_get_vextract128_imm, [HasVLX]>;
775
776 // Codegen pattern with the alternative types extract VEC128 from VEC512
777 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z", v32i16_info, v8i16x_info,
778                  vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512]>;
779 defm : vextract_for_size_lowering<"VEXTRACTI32x4Z", v64i8_info, v16i8x_info,
780                  vextract128_extract, EXTRACT_get_vextract128_imm, [HasAVX512]>;
781 // Codegen pattern with the alternative types extract VEC256 from VEC512
782 defm : vextract_for_size_lowering<"VEXTRACTI64x4Z", v32i16_info, v16i16x_info,
783                  vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512]>;
784 defm : vextract_for_size_lowering<"VEXTRACTI64x4Z", v64i8_info, v32i8x_info,
785                  vextract256_extract, EXTRACT_get_vextract256_imm, [HasAVX512]>;
786
787 // A 128-bit subvector extract from the first 256-bit vector position
788 // is a subregister copy that needs no instruction.
789 def : Pat<(v2i64 (extract_subvector (v8i64 VR512:$src), (iPTR 0))),
790           (v2i64 (EXTRACT_SUBREG (v8i64 VR512:$src), sub_xmm))>;
791 def : Pat<(v2f64 (extract_subvector (v8f64 VR512:$src), (iPTR 0))),
792           (v2f64 (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm))>;
793 def : Pat<(v4i32 (extract_subvector (v16i32 VR512:$src), (iPTR 0))),
794           (v4i32 (EXTRACT_SUBREG (v16i32 VR512:$src), sub_xmm))>;
795 def : Pat<(v4f32 (extract_subvector (v16f32 VR512:$src), (iPTR 0))),
796           (v4f32 (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm))>;
797 def : Pat<(v8i16 (extract_subvector (v32i16 VR512:$src), (iPTR 0))),
798           (v8i16 (EXTRACT_SUBREG (v32i16 VR512:$src), sub_xmm))>;
799 def : Pat<(v16i8 (extract_subvector (v64i8 VR512:$src), (iPTR 0))),
800           (v16i8 (EXTRACT_SUBREG (v64i8 VR512:$src), sub_xmm))>;
801
802 // A 256-bit subvector extract from the first 256-bit vector position
803 // is a subregister copy that needs no instruction.
804 def : Pat<(v4i64 (extract_subvector (v8i64 VR512:$src), (iPTR 0))),
805           (v4i64 (EXTRACT_SUBREG (v8i64 VR512:$src), sub_ymm))>;
806 def : Pat<(v4f64 (extract_subvector (v8f64 VR512:$src), (iPTR 0))),
807           (v4f64 (EXTRACT_SUBREG (v8f64 VR512:$src), sub_ymm))>;
808 def : Pat<(v8i32 (extract_subvector (v16i32 VR512:$src), (iPTR 0))),
809           (v8i32 (EXTRACT_SUBREG (v16i32 VR512:$src), sub_ymm))>;
810 def : Pat<(v8f32 (extract_subvector (v16f32 VR512:$src), (iPTR 0))),
811           (v8f32 (EXTRACT_SUBREG (v16f32 VR512:$src), sub_ymm))>;
812 def : Pat<(v16i16 (extract_subvector (v32i16 VR512:$src), (iPTR 0))),
813           (v16i16 (EXTRACT_SUBREG (v32i16 VR512:$src), sub_ymm))>;
814 def : Pat<(v32i8 (extract_subvector (v64i8 VR512:$src), (iPTR 0))),
815           (v32i8 (EXTRACT_SUBREG (v64i8 VR512:$src), sub_ymm))>;
816
817 let AddedComplexity = 25 in { // to give priority over vinsertf128rm
818 // A 128-bit subvector insert to the first 512-bit vector position
819 // is a subregister copy that needs no instruction.
820 def : Pat<(v8i64 (insert_subvector undef, (v2i64 VR128X:$src), (iPTR 0))),
821           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
822 def : Pat<(v8f64 (insert_subvector undef, (v2f64 VR128X:$src), (iPTR 0))),
823           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
824 def : Pat<(v16i32 (insert_subvector undef, (v4i32 VR128X:$src), (iPTR 0))),
825           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
826 def : Pat<(v16f32 (insert_subvector undef, (v4f32 VR128X:$src), (iPTR 0))),
827           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
828 def : Pat<(v32i16 (insert_subvector undef, (v8i16 VR128X:$src), (iPTR 0))),
829           (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
830 def : Pat<(v64i8 (insert_subvector undef, (v16i8 VR128X:$src), (iPTR 0))),
831           (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)>;
832
833 // A 256-bit subvector insert to the first 512-bit vector position
834 // is a subregister copy that needs no instruction.
835 def : Pat<(v8i64 (insert_subvector undef, (v4i64 VR256X:$src), (iPTR 0))),
836           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
837 def : Pat<(v8f64 (insert_subvector undef, (v4f64 VR256X:$src), (iPTR 0))),
838           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
839 def : Pat<(v16i32 (insert_subvector undef, (v8i32 VR256X:$src), (iPTR 0))),
840           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
841 def : Pat<(v16f32 (insert_subvector undef, (v8f32 VR256X:$src), (iPTR 0))),
842           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
843 def : Pat<(v32i16 (insert_subvector undef, (v16i16 VR256X:$src), (iPTR 0))),
844           (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
845 def : Pat<(v64i8 (insert_subvector undef, (v32i8 VR256X:$src), (iPTR 0))),
846           (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)>;
847 }
848
849 // vextractps - extract 32 bits from XMM
850 def VEXTRACTPSZrr : AVX512AIi8<0x17, MRMDestReg, (outs GR32:$dst),
851       (ins VR128X:$src1, u8imm:$src2),
852       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
853       [(set GR32:$dst, (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2))]>,
854       EVEX;
855
856 def VEXTRACTPSZmr : AVX512AIi8<0x17, MRMDestMem, (outs),
857       (ins f32mem:$dst, VR128X:$src1, u8imm:$src2),
858       "vextractps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
859       [(store (extractelt (bc_v4i32 (v4f32 VR128X:$src1)), imm:$src2),
860                           addr:$dst)]>, EVEX, EVEX_CD8<32, CD8VT1>;
861
862 //===---------------------------------------------------------------------===//
863 // AVX-512 BROADCAST
864 //---
865 // broadcast with a scalar argument.
866 multiclass avx512_broadcast_scalar<bits<8> opc, string OpcodeStr,
867                             X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo> {
868   def : Pat<(DestInfo.VT (X86VBroadcast SrcInfo.FRC:$src)),
869             (!cast<Instruction>(NAME#DestInfo.ZSuffix#r)
870              (COPY_TO_REGCLASS SrcInfo.FRC:$src, SrcInfo.RC))>;
871   def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask,
872                                   (X86VBroadcast SrcInfo.FRC:$src),
873                                   DestInfo.RC:$src0)),
874             (!cast<Instruction>(NAME#DestInfo.ZSuffix#rk)
875              DestInfo.RC:$src0, DestInfo.KRCWM:$mask,
876              (COPY_TO_REGCLASS SrcInfo.FRC:$src, SrcInfo.RC))>;
877   def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask,
878                                   (X86VBroadcast SrcInfo.FRC:$src),
879                                   DestInfo.ImmAllZerosV)),
880             (!cast<Instruction>(NAME#DestInfo.ZSuffix#rkz)
881              DestInfo.KRCWM:$mask, (COPY_TO_REGCLASS SrcInfo.FRC:$src, SrcInfo.RC))>;
882 }
883
884 multiclass avx512_broadcast_rm<bits<8> opc, string OpcodeStr,
885                             X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo> {
886   let ExeDomain = DestInfo.ExeDomain in {
887   defm r : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
888                    (ins SrcInfo.RC:$src), OpcodeStr, "$src", "$src",
889                    (DestInfo.VT (X86VBroadcast (SrcInfo.VT SrcInfo.RC:$src)))>,
890                    T8PD, EVEX;
891   defm m : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
892                    (ins SrcInfo.ScalarMemOp:$src), OpcodeStr, "$src", "$src",
893                    (DestInfo.VT (X86VBroadcast
894                                    (SrcInfo.ScalarLdFrag addr:$src)))>,
895                    T8PD, EVEX, EVEX_CD8<SrcInfo.EltSize, CD8VT1>;
896   }
897
898   def : Pat<(DestInfo.VT (X86VBroadcast
899                           (SrcInfo.VT (scalar_to_vector
900                                        (SrcInfo.ScalarLdFrag addr:$src))))),
901             (!cast<Instruction>(NAME#DestInfo.ZSuffix#m) addr:$src)>;
902   def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask,
903                           (X86VBroadcast
904                            (SrcInfo.VT (scalar_to_vector
905                                         (SrcInfo.ScalarLdFrag addr:$src)))),
906                           DestInfo.RC:$src0)),
907             (!cast<Instruction>(NAME#DestInfo.ZSuffix#mk)
908              DestInfo.RC:$src0, DestInfo.KRCWM:$mask, addr:$src)>;
909   def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask,
910                           (X86VBroadcast
911                            (SrcInfo.VT (scalar_to_vector
912                                         (SrcInfo.ScalarLdFrag addr:$src)))),
913                           DestInfo.ImmAllZerosV)),
914             (!cast<Instruction>(NAME#DestInfo.ZSuffix#mkz)
915              DestInfo.KRCWM:$mask, addr:$src)>;
916 }
917
918 multiclass avx512_fp_broadcast_sd<bits<8> opc, string OpcodeStr,
919                                                        AVX512VLVectorVTInfo _> {
920   let Predicates = [HasAVX512] in
921     defm Z  : avx512_broadcast_rm<opc, OpcodeStr, _.info512, _.info128>,
922               avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128>,
923                                EVEX_V512;
924
925   let Predicates = [HasVLX] in {
926     defm Z256  : avx512_broadcast_rm<opc, OpcodeStr, _.info256, _.info128>,
927                  avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128>,
928                              EVEX_V256;
929   }
930 }
931
932 multiclass avx512_fp_broadcast_ss<bits<8> opc, string OpcodeStr,
933                                                        AVX512VLVectorVTInfo _> {
934   let Predicates = [HasAVX512] in
935     defm Z  : avx512_broadcast_rm<opc, OpcodeStr, _.info512, _.info128>,
936               avx512_broadcast_scalar<opc, OpcodeStr, _.info512, _.info128>,
937                                EVEX_V512;
938
939   let Predicates = [HasVLX] in {
940     defm Z256  : avx512_broadcast_rm<opc, OpcodeStr, _.info256, _.info128>,
941                  avx512_broadcast_scalar<opc, OpcodeStr, _.info256, _.info128>,
942                              EVEX_V256;
943     defm Z128  : avx512_broadcast_rm<opc, OpcodeStr, _.info128, _.info128>,
944                  avx512_broadcast_scalar<opc, OpcodeStr, _.info128, _.info128>,
945                              EVEX_V128;
946   }
947 }
948 defm VBROADCASTSS  : avx512_fp_broadcast_ss<0x18, "vbroadcastss",
949                                        avx512vl_f32_info>;
950 defm VBROADCASTSD  : avx512_fp_broadcast_sd<0x19, "vbroadcastsd",
951                                        avx512vl_f64_info>, VEX_W;
952
953 def : Pat<(int_x86_avx512_vbroadcast_ss_512 addr:$src),
954           (VBROADCASTSSZm addr:$src)>;
955 def : Pat<(int_x86_avx512_vbroadcast_sd_512 addr:$src),
956           (VBROADCASTSDZm addr:$src)>;
957
958 multiclass avx512_int_broadcast_reg<bits<8> opc, X86VectorVTInfo _,
959                                     SDPatternOperator OpNode,
960                                     RegisterClass SrcRC> {
961   let ExeDomain = _.ExeDomain in
962   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
963                          (ins SrcRC:$src),
964                          "vpbroadcast"##_.Suffix, "$src", "$src",
965                          (_.VT (OpNode SrcRC:$src))>, T8PD, EVEX;
966 }
967
968 multiclass avx512_int_broadcast_reg_vl<bits<8> opc, AVX512VLVectorVTInfo _,
969                                        SDPatternOperator OpNode,
970                                        RegisterClass SrcRC, Predicate prd> {
971   let Predicates = [prd] in
972     defm Z : avx512_int_broadcast_reg<opc, _.info512, OpNode, SrcRC>, EVEX_V512;
973   let Predicates = [prd, HasVLX] in {
974     defm Z256 : avx512_int_broadcast_reg<opc, _.info256, OpNode, SrcRC>, EVEX_V256;
975     defm Z128 : avx512_int_broadcast_reg<opc, _.info128, OpNode, SrcRC>, EVEX_V128;
976   }
977 }
978
979 let isCodeGenOnly = 1 in {
980 defm VPBROADCASTBr : avx512_int_broadcast_reg_vl<0x7A, avx512vl_i8_info,
981                                                  X86VBroadcast, GR8, HasBWI>;
982 defm VPBROADCASTWr : avx512_int_broadcast_reg_vl<0x7B, avx512vl_i16_info,
983                                                  X86VBroadcast, GR16, HasBWI>;
984 }
985 let isAsmParserOnly = 1 in {
986   defm VPBROADCASTBr_Alt : avx512_int_broadcast_reg_vl<0x7A, avx512vl_i8_info,
987                                                        null_frag, GR32, HasBWI>;
988   defm VPBROADCASTWr_Alt : avx512_int_broadcast_reg_vl<0x7B, avx512vl_i16_info,
989                                                        null_frag, GR32, HasBWI>;
990 }
991 defm VPBROADCASTDr : avx512_int_broadcast_reg_vl<0x7C, avx512vl_i32_info,
992                                                  X86VBroadcast, GR32, HasAVX512>;
993 defm VPBROADCASTQr : avx512_int_broadcast_reg_vl<0x7C, avx512vl_i64_info,
994                                                  X86VBroadcast, GR64, HasAVX512>, VEX_W;
995
996 def : Pat <(v16i32 (X86vzext VK16WM:$mask)),
997            (VPBROADCASTDrZrkz VK16WM:$mask, (i32 (MOV32ri 0x1)))>;
998 def : Pat <(v8i64 (X86vzext VK8WM:$mask)),
999            (VPBROADCASTQrZrkz VK8WM:$mask, (i64 (MOV64ri 0x1)))>;
1000
1001 // Provide aliases for broadcast from the same register class that
1002 // automatically does the extract.
1003 multiclass avx512_int_broadcast_rm_lowering<X86VectorVTInfo DestInfo,
1004                                             X86VectorVTInfo SrcInfo> {
1005   def : Pat<(DestInfo.VT (X86VBroadcast (SrcInfo.VT SrcInfo.RC:$src))),
1006             (!cast<Instruction>(NAME#DestInfo.ZSuffix#"r")
1007                 (EXTRACT_SUBREG (SrcInfo.VT SrcInfo.RC:$src), sub_xmm))>;
1008 }
1009
1010 multiclass avx512_int_broadcast_rm_vl<bits<8> opc, string OpcodeStr,
1011                                         AVX512VLVectorVTInfo _, Predicate prd> {
1012   let Predicates = [prd] in {
1013     defm Z :   avx512_broadcast_rm<opc, OpcodeStr, _.info512, _.info128>,
1014                avx512_int_broadcast_rm_lowering<_.info512, _.info256>,
1015                                   EVEX_V512;
1016     // Defined separately to avoid redefinition.
1017     defm Z_Alt : avx512_int_broadcast_rm_lowering<_.info512, _.info512>;
1018   }
1019   let Predicates = [prd, HasVLX] in {
1020     defm Z256 : avx512_broadcast_rm<opc, OpcodeStr, _.info256, _.info128>,
1021                 avx512_int_broadcast_rm_lowering<_.info256, _.info256>,
1022                                  EVEX_V256;
1023     defm Z128 : avx512_broadcast_rm<opc, OpcodeStr, _.info128, _.info128>,
1024                                  EVEX_V128;
1025   }
1026 }
1027
1028 defm VPBROADCASTB  : avx512_int_broadcast_rm_vl<0x78, "vpbroadcastb",
1029                                            avx512vl_i8_info, HasBWI>;
1030 defm VPBROADCASTW  : avx512_int_broadcast_rm_vl<0x79, "vpbroadcastw",
1031                                            avx512vl_i16_info, HasBWI>;
1032 defm VPBROADCASTD  : avx512_int_broadcast_rm_vl<0x58, "vpbroadcastd",
1033                                            avx512vl_i32_info, HasAVX512>;
1034 defm VPBROADCASTQ  : avx512_int_broadcast_rm_vl<0x59, "vpbroadcastq",
1035                                            avx512vl_i64_info, HasAVX512>, VEX_W;
1036
1037 multiclass avx512_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
1038                           X86VectorVTInfo _Dst, X86VectorVTInfo _Src> {
1039   defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
1040                            (ins _Src.MemOp:$src), OpcodeStr, "$src", "$src",
1041                            (_Dst.VT (X86SubVBroadcast
1042                              (_Src.VT (bitconvert (_Src.LdFrag addr:$src)))))>,
1043                             AVX5128IBase, EVEX;
1044 }
1045
1046 let Predicates = [HasAVX512] in {
1047   // 32-bit targets will fail to load a i64 directly but can use ZEXT_LOAD.
1048   def : Pat<(v8i64 (X86VBroadcast (v8i64 (X86vzload addr:$src)))),
1049             (VPBROADCASTQZm addr:$src)>;
1050 }
1051
1052 let Predicates = [HasVLX, HasBWI] in {
1053   // 32-bit targets will fail to load a i64 directly but can use ZEXT_LOAD.
1054   def : Pat<(v2i64 (X86VBroadcast (v2i64 (X86vzload addr:$src)))),
1055             (VPBROADCASTQZ128m addr:$src)>;
1056   def : Pat<(v4i64 (X86VBroadcast (v4i64 (X86vzload addr:$src)))),
1057             (VPBROADCASTQZ256m addr:$src)>;
1058   // loadi16 is tricky to fold, because !isTypeDesirableForOp, justifiably.
1059   // This means we'll encounter truncated i32 loads; match that here.
1060   def : Pat<(v8i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
1061             (VPBROADCASTWZ128m addr:$src)>;
1062   def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
1063             (VPBROADCASTWZ256m addr:$src)>;
1064   def : Pat<(v8i16 (X86VBroadcast
1065               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
1066             (VPBROADCASTWZ128m addr:$src)>;
1067   def : Pat<(v16i16 (X86VBroadcast
1068               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
1069             (VPBROADCASTWZ256m addr:$src)>;
1070 }
1071
1072 //===----------------------------------------------------------------------===//
1073 // AVX-512 BROADCAST SUBVECTORS
1074 //
1075
1076 defm VBROADCASTI32X4 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
1077                        v16i32_info, v4i32x_info>,
1078                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
1079 defm VBROADCASTF32X4 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
1080                        v16f32_info, v4f32x_info>,
1081                        EVEX_V512, EVEX_CD8<32, CD8VT4>;
1082 defm VBROADCASTI64X4 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti64x4",
1083                        v8i64_info, v4i64x_info>, VEX_W,
1084                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
1085 defm VBROADCASTF64X4 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf64x4",
1086                        v8f64_info, v4f64x_info>, VEX_W,
1087                        EVEX_V512, EVEX_CD8<64, CD8VT4>;
1088
1089 let Predicates = [HasAVX512] in {
1090 def : Pat<(v32i16 (X86SubVBroadcast (bc_v16i16 (loadv4i64 addr:$src)))),
1091           (VBROADCASTI64X4rm addr:$src)>;
1092 def : Pat<(v64i8 (X86SubVBroadcast (bc_v32i8 (loadv4i64 addr:$src)))),
1093           (VBROADCASTI64X4rm addr:$src)>;
1094
1095 // Provide fallback in case the load node that is used in the patterns above
1096 // is used by additional users, which prevents the pattern selection.
1097 def : Pat<(v8f64 (X86SubVBroadcast (v4f64 VR256X:$src))),
1098           (VINSERTF64x4Zrr (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1099                            (v4f64 VR256X:$src), 1)>;
1100 def : Pat<(v8i64 (X86SubVBroadcast (v4i64 VR256X:$src))),
1101           (VINSERTI64x4Zrr (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1102                            (v4i64 VR256X:$src), 1)>;
1103 def : Pat<(v32i16 (X86SubVBroadcast (v16i16 VR256X:$src))),
1104           (VINSERTI64x4Zrr (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1105                            (v16i16 VR256X:$src), 1)>;
1106 def : Pat<(v64i8 (X86SubVBroadcast (v32i8 VR256X:$src))),
1107           (VINSERTI64x4Zrr (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1108                            (v32i8 VR256X:$src), 1)>;
1109
1110 def : Pat<(v32i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
1111           (VBROADCASTI32X4rm addr:$src)>;
1112 def : Pat<(v64i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
1113           (VBROADCASTI32X4rm addr:$src)>;
1114 }
1115
1116 let Predicates = [HasVLX] in {
1117 defm VBROADCASTI32X4Z256 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti32x4",
1118                            v8i32x_info, v4i32x_info>,
1119                            EVEX_V256, EVEX_CD8<32, CD8VT4>;
1120 defm VBROADCASTF32X4Z256 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf32x4",
1121                            v8f32x_info, v4f32x_info>,
1122                            EVEX_V256, EVEX_CD8<32, CD8VT4>;
1123
1124 def : Pat<(v16i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
1125           (VBROADCASTI32X4Z256rm addr:$src)>;
1126 def : Pat<(v32i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
1127           (VBROADCASTI32X4Z256rm addr:$src)>;
1128
1129 // Provide fallback in case the load node that is used in the patterns above
1130 // is used by additional users, which prevents the pattern selection.
1131 def : Pat<(v8f32 (X86SubVBroadcast (v4f32 VR128X:$src))),
1132           (VINSERTF32x4Z256rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1133                               (v4f32 VR128X:$src), 1)>;
1134 def : Pat<(v8i32 (X86SubVBroadcast (v4i32 VR128X:$src))),
1135           (VINSERTI32x4Z256rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1136                               (v4i32 VR128X:$src), 1)>;
1137 def : Pat<(v16i16 (X86SubVBroadcast (v8i16 VR128X:$src))),
1138           (VINSERTI32x4Z256rr (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1139                               (v8i16 VR128X:$src), 1)>;
1140 def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128X:$src))),
1141           (VINSERTI32x4Z256rr (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1142                               (v16i8 VR128X:$src), 1)>;
1143 }
1144
1145 let Predicates = [HasVLX, HasDQI] in {
1146 defm VBROADCASTI64X2Z128 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti64x2",
1147                            v4i64x_info, v2i64x_info>, VEX_W,
1148                            EVEX_V256, EVEX_CD8<64, CD8VT2>;
1149 defm VBROADCASTF64X2Z128 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf64x2",
1150                            v4f64x_info, v2f64x_info>, VEX_W,
1151                            EVEX_V256, EVEX_CD8<64, CD8VT2>;
1152
1153 // Provide fallback in case the load node that is used in the patterns above
1154 // is used by additional users, which prevents the pattern selection.
1155 def : Pat<(v4f64 (X86SubVBroadcast (v2f64 VR128X:$src))),
1156           (VINSERTF64x2Z256rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1157                               (v2f64 VR128X:$src), 1)>;
1158 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128X:$src))),
1159           (VINSERTI64x2Z256rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1160                               (v2i64 VR128X:$src), 1)>;
1161 }
1162
1163 let Predicates = [HasVLX, NoDQI] in {
1164 def : Pat<(v4f64 (X86SubVBroadcast (loadv2f64 addr:$src))),
1165           (VBROADCASTF32X4Z256rm addr:$src)>;
1166 def : Pat<(v4i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
1167           (VBROADCASTI32X4Z256rm addr:$src)>;
1168
1169 // Provide fallback in case the load node that is used in the patterns above
1170 // is used by additional users, which prevents the pattern selection.
1171 def : Pat<(v4f64 (X86SubVBroadcast (v2f64 VR128X:$src))),
1172           (VINSERTF32x4Z256rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1173                               (v2f64 VR128X:$src), 1)>;
1174 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128X:$src))),
1175           (VINSERTI32x4Z256rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
1176                               (v2i64 VR128X:$src), 1)>;
1177 }
1178
1179 let Predicates = [HasAVX512, NoDQI] in {
1180 def : Pat<(v8f64 (X86SubVBroadcast (loadv2f64 addr:$src))),
1181           (VBROADCASTF32X4rm addr:$src)>;
1182 def : Pat<(v8i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
1183           (VBROADCASTI32X4rm addr:$src)>;
1184
1185 def : Pat<(v16f32 (X86SubVBroadcast (loadv8f32 addr:$src))),
1186           (VBROADCASTF64X4rm addr:$src)>;
1187 def : Pat<(v16i32 (X86SubVBroadcast (bc_v8i32 (loadv4i64 addr:$src)))),
1188           (VBROADCASTI64X4rm addr:$src)>;
1189
1190 // Provide fallback in case the load node that is used in the patterns above
1191 // is used by additional users, which prevents the pattern selection.
1192 def : Pat<(v16f32 (X86SubVBroadcast (v8f32 VR256X:$src))),
1193           (VINSERTF64x4Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1194                            (v8f32 VR256X:$src), 1)>;
1195 def : Pat<(v16i32 (X86SubVBroadcast (v8i32 VR256X:$src))),
1196           (VINSERTI64x4Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1197                            (v8i32 VR256X:$src), 1)>;
1198 }
1199
1200 let Predicates = [HasDQI] in {
1201 defm VBROADCASTI64X2 : avx512_subvec_broadcast_rm<0x5a, "vbroadcasti64x2",
1202                        v8i64_info, v2i64x_info>, VEX_W,
1203                        EVEX_V512, EVEX_CD8<64, CD8VT2>;
1204 defm VBROADCASTI32X8 : avx512_subvec_broadcast_rm<0x5b, "vbroadcasti32x8",
1205                        v16i32_info, v8i32x_info>,
1206                        EVEX_V512, EVEX_CD8<32, CD8VT8>;
1207 defm VBROADCASTF64X2 : avx512_subvec_broadcast_rm<0x1a, "vbroadcastf64x2",
1208                        v8f64_info, v2f64x_info>, VEX_W,
1209                        EVEX_V512, EVEX_CD8<64, CD8VT2>;
1210 defm VBROADCASTF32X8 : avx512_subvec_broadcast_rm<0x1b, "vbroadcastf32x8",
1211                        v16f32_info, v8f32x_info>,
1212                        EVEX_V512, EVEX_CD8<32, CD8VT8>;
1213
1214 // Provide fallback in case the load node that is used in the patterns above
1215 // is used by additional users, which prevents the pattern selection.
1216 def : Pat<(v16f32 (X86SubVBroadcast (v8f32 VR256X:$src))),
1217           (VINSERTF32x8Zrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1218                            (v8f32 VR256X:$src), 1)>;
1219 def : Pat<(v16i32 (X86SubVBroadcast (v8i32 VR256X:$src))),
1220           (VINSERTI32x8Zrr (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm),
1221                            (v8i32 VR256X:$src), 1)>;
1222 }
1223
1224 multiclass avx512_common_broadcast_32x2<bits<8> opc, string OpcodeStr,
1225                          AVX512VLVectorVTInfo _Dst, AVX512VLVectorVTInfo _Src> {
1226   let Predicates = [HasDQI] in
1227     defm Z :    avx512_broadcast_rm<opc, OpcodeStr, _Dst.info512, _Src.info128>,
1228                                   EVEX_V512;
1229   let Predicates = [HasDQI, HasVLX] in
1230     defm Z256 : avx512_broadcast_rm<opc, OpcodeStr, _Dst.info256, _Src.info128>,
1231                                   EVEX_V256;
1232 }
1233
1234 multiclass avx512_common_broadcast_i32x2<bits<8> opc, string OpcodeStr,
1235                          AVX512VLVectorVTInfo _Dst, AVX512VLVectorVTInfo _Src> :
1236   avx512_common_broadcast_32x2<opc, OpcodeStr, _Dst, _Src> {
1237
1238   let Predicates = [HasDQI, HasVLX] in
1239     defm Z128 : avx512_broadcast_rm<opc, OpcodeStr, _Dst.info128, _Src.info128>,
1240                                       EVEX_V128;
1241 }
1242
1243 defm VBROADCASTI32X2  : avx512_common_broadcast_i32x2<0x59, "vbroadcasti32x2",
1244                                           avx512vl_i32_info, avx512vl_i64_info>;
1245 defm VBROADCASTF32X2  : avx512_common_broadcast_32x2<0x19, "vbroadcastf32x2",
1246                                           avx512vl_f32_info, avx512vl_f64_info>;
1247
1248 let Predicates = [HasVLX] in {
1249 def : Pat<(v8f32 (X86VBroadcast (v8f32 VR256X:$src))),
1250           (VBROADCASTSSZ256r (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm))>;
1251 def : Pat<(v4f64 (X86VBroadcast (v4f64 VR256X:$src))),
1252           (VBROADCASTSDZ256r (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm))>;
1253 }
1254
1255 def : Pat<(v16f32 (X86VBroadcast (v16f32 VR512:$src))),
1256           (VBROADCASTSSZr (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm))>;
1257 def : Pat<(v16f32 (X86VBroadcast (v8f32 VR256X:$src))),
1258           (VBROADCASTSSZr (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm))>;
1259
1260 def : Pat<(v8f64 (X86VBroadcast (v8f64 VR512:$src))),
1261           (VBROADCASTSDZr (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm))>;
1262 def : Pat<(v8f64 (X86VBroadcast (v4f64 VR256X:$src))),
1263           (VBROADCASTSDZr (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm))>;
1264
1265 //===----------------------------------------------------------------------===//
1266 // AVX-512 BROADCAST MASK TO VECTOR REGISTER
1267 //---
1268 multiclass avx512_mask_broadcastm<bits<8> opc, string OpcodeStr,
1269                                   X86VectorVTInfo _, RegisterClass KRC> {
1270   def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.RC:$dst), (ins KRC:$src),
1271                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
1272                   [(set _.RC:$dst, (_.VT (X86VBroadcastm KRC:$src)))]>, EVEX;
1273 }
1274
1275 multiclass avx512_mask_broadcast<bits<8> opc, string OpcodeStr,
1276                                  AVX512VLVectorVTInfo VTInfo, RegisterClass KRC> {
1277   let Predicates = [HasCDI] in
1278     defm Z : avx512_mask_broadcastm<opc, OpcodeStr, VTInfo.info512, KRC>, EVEX_V512;
1279   let Predicates = [HasCDI, HasVLX] in {
1280     defm Z256 : avx512_mask_broadcastm<opc, OpcodeStr, VTInfo.info256, KRC>, EVEX_V256;
1281     defm Z128 : avx512_mask_broadcastm<opc, OpcodeStr, VTInfo.info128, KRC>, EVEX_V128;
1282   }
1283 }
1284
1285 defm VPBROADCASTMW2D : avx512_mask_broadcast<0x3A, "vpbroadcastmw2d",
1286                                                avx512vl_i32_info, VK16>;
1287 defm VPBROADCASTMB2Q : avx512_mask_broadcast<0x2A, "vpbroadcastmb2q",
1288                                                avx512vl_i64_info, VK8>, VEX_W;
1289
1290 //===----------------------------------------------------------------------===//
1291 // -- VPERMI2 - 3 source operands form --
1292 multiclass avx512_perm_i<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1293 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
1294   // The index operand in the pattern should really be an integer type. However,
1295   // if we do that and it happens to come from a bitcast, then it becomes
1296   // difficult to find the bitcast needed to convert the index to the
1297   // destination type for the passthru since it will be folded with the bitcast
1298   // of the index operand.
1299   defm rr: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
1300           (ins _.RC:$src2, _.RC:$src3),
1301           OpcodeStr, "$src3, $src2", "$src2, $src3",
1302           (_.VT (X86VPermi2X _.RC:$src1, _.RC:$src2, _.RC:$src3)), 1>, EVEX_4V,
1303          AVX5128IBase;
1304
1305   defm rm: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1306             (ins _.RC:$src2, _.MemOp:$src3),
1307             OpcodeStr, "$src3, $src2", "$src2, $src3",
1308             (_.VT (X86VPermi2X _.RC:$src1, _.RC:$src2,
1309                    (_.VT (bitconvert (_.LdFrag addr:$src3))))), 1>,
1310             EVEX_4V, AVX5128IBase;
1311   }
1312 }
1313 multiclass avx512_perm_i_mb<bits<8> opc, string OpcodeStr,
1314                             X86VectorVTInfo _> {
1315   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
1316   defm rmb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1317               (ins _.RC:$src2, _.ScalarMemOp:$src3),
1318               OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
1319               !strconcat("$src2, ${src3}", _.BroadcastStr ),
1320               (_.VT (X86VPermi2X _.RC:$src1,
1321                _.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))),
1322               1>, AVX5128IBase, EVEX_4V, EVEX_B;
1323 }
1324
1325 multiclass avx512_perm_i_sizes<bits<8> opc, string OpcodeStr,
1326                                AVX512VLVectorVTInfo VTInfo> {
1327   defm NAME: avx512_perm_i<opc, OpcodeStr, VTInfo.info512>,
1328             avx512_perm_i_mb<opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1329   let Predicates = [HasVLX] in {
1330   defm NAME#128: avx512_perm_i<opc, OpcodeStr, VTInfo.info128>,
1331                  avx512_perm_i_mb<opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1332   defm NAME#256: avx512_perm_i<opc, OpcodeStr, VTInfo.info256>,
1333                  avx512_perm_i_mb<opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1334   }
1335 }
1336
1337 multiclass avx512_perm_i_sizes_bw<bits<8> opc, string OpcodeStr,
1338                                  AVX512VLVectorVTInfo VTInfo,
1339                                  Predicate Prd> {
1340   let Predicates = [Prd] in
1341   defm NAME: avx512_perm_i<opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1342   let Predicates = [Prd, HasVLX] in {
1343   defm NAME#128: avx512_perm_i<opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1344   defm NAME#256: avx512_perm_i<opc, OpcodeStr, VTInfo.info256>,  EVEX_V256;
1345   }
1346 }
1347
1348 defm VPERMI2D  : avx512_perm_i_sizes<0x76, "vpermi2d",
1349                   avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1350 defm VPERMI2Q  : avx512_perm_i_sizes<0x76, "vpermi2q",
1351                   avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1352 defm VPERMI2W  : avx512_perm_i_sizes_bw<0x75, "vpermi2w",
1353                   avx512vl_i16_info, HasBWI>,
1354                   VEX_W, EVEX_CD8<16, CD8VF>;
1355 defm VPERMI2B  : avx512_perm_i_sizes_bw<0x75, "vpermi2b",
1356                   avx512vl_i8_info, HasVBMI>,
1357                   EVEX_CD8<8, CD8VF>;
1358 defm VPERMI2PS : avx512_perm_i_sizes<0x77, "vpermi2ps",
1359                   avx512vl_f32_info>, EVEX_CD8<32, CD8VF>;
1360 defm VPERMI2PD : avx512_perm_i_sizes<0x77, "vpermi2pd",
1361                   avx512vl_f64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1362
1363 // VPERMT2
1364 multiclass avx512_perm_t<bits<8> opc, string OpcodeStr,
1365                          X86VectorVTInfo _, X86VectorVTInfo IdxVT> {
1366 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
1367   defm rr: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
1368           (ins IdxVT.RC:$src2, _.RC:$src3),
1369           OpcodeStr, "$src3, $src2", "$src2, $src3",
1370           (_.VT (X86VPermt2 _.RC:$src1, IdxVT.RC:$src2, _.RC:$src3)), 1>,
1371           EVEX_4V, AVX5128IBase;
1372
1373   defm rm: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1374             (ins IdxVT.RC:$src2, _.MemOp:$src3),
1375             OpcodeStr, "$src3, $src2", "$src2, $src3",
1376             (_.VT (X86VPermt2 _.RC:$src1, IdxVT.RC:$src2,
1377                    (bitconvert (_.LdFrag addr:$src3)))), 1>,
1378             EVEX_4V, AVX5128IBase;
1379   }
1380 }
1381 multiclass avx512_perm_t_mb<bits<8> opc, string OpcodeStr,
1382                             X86VectorVTInfo _, X86VectorVTInfo IdxVT> {
1383   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
1384   defm rmb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
1385               (ins IdxVT.RC:$src2, _.ScalarMemOp:$src3),
1386               OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
1387               !strconcat("$src2, ${src3}", _.BroadcastStr ),
1388               (_.VT (X86VPermt2 _.RC:$src1,
1389                IdxVT.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))),
1390               1>, AVX5128IBase, EVEX_4V, EVEX_B;
1391 }
1392
1393 multiclass avx512_perm_t_sizes<bits<8> opc, string OpcodeStr,
1394                                AVX512VLVectorVTInfo VTInfo,
1395                                AVX512VLVectorVTInfo ShuffleMask> {
1396   defm NAME: avx512_perm_t<opc, OpcodeStr, VTInfo.info512,
1397                               ShuffleMask.info512>,
1398             avx512_perm_t_mb<opc, OpcodeStr, VTInfo.info512,
1399                               ShuffleMask.info512>, EVEX_V512;
1400   let Predicates = [HasVLX] in {
1401   defm NAME#128: avx512_perm_t<opc, OpcodeStr, VTInfo.info128,
1402                               ShuffleMask.info128>,
1403                  avx512_perm_t_mb<opc, OpcodeStr, VTInfo.info128,
1404                               ShuffleMask.info128>, EVEX_V128;
1405   defm NAME#256: avx512_perm_t<opc, OpcodeStr, VTInfo.info256,
1406                               ShuffleMask.info256>,
1407                  avx512_perm_t_mb<opc, OpcodeStr, VTInfo.info256,
1408                               ShuffleMask.info256>, EVEX_V256;
1409   }
1410 }
1411
1412 multiclass avx512_perm_t_sizes_bw<bits<8> opc, string OpcodeStr,
1413                                  AVX512VLVectorVTInfo VTInfo,
1414                                  AVX512VLVectorVTInfo Idx,
1415                                  Predicate Prd> {
1416   let Predicates = [Prd] in
1417   defm NAME: avx512_perm_t<opc, OpcodeStr, VTInfo.info512,
1418                            Idx.info512>, EVEX_V512;
1419   let Predicates = [Prd, HasVLX] in {
1420   defm NAME#128: avx512_perm_t<opc, OpcodeStr, VTInfo.info128,
1421                                Idx.info128>, EVEX_V128;
1422   defm NAME#256: avx512_perm_t<opc, OpcodeStr, VTInfo.info256,
1423                                Idx.info256>, EVEX_V256;
1424   }
1425 }
1426
1427 defm VPERMT2D  : avx512_perm_t_sizes<0x7E, "vpermt2d",
1428                   avx512vl_i32_info, avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1429 defm VPERMT2Q  : avx512_perm_t_sizes<0x7E, "vpermt2q",
1430                   avx512vl_i64_info, avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1431 defm VPERMT2W  : avx512_perm_t_sizes_bw<0x7D, "vpermt2w",
1432                   avx512vl_i16_info, avx512vl_i16_info, HasBWI>,
1433                   VEX_W, EVEX_CD8<16, CD8VF>;
1434 defm VPERMT2B  : avx512_perm_t_sizes_bw<0x7D, "vpermt2b",
1435                   avx512vl_i8_info, avx512vl_i8_info, HasVBMI>,
1436                   EVEX_CD8<8, CD8VF>;
1437 defm VPERMT2PS : avx512_perm_t_sizes<0x7F, "vpermt2ps",
1438                   avx512vl_f32_info, avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
1439 defm VPERMT2PD : avx512_perm_t_sizes<0x7F, "vpermt2pd",
1440                   avx512vl_f64_info, avx512vl_i64_info>, VEX_W, EVEX_CD8<64, CD8VF>;
1441
1442 //===----------------------------------------------------------------------===//
1443 // AVX-512 - BLEND using mask
1444 //
1445 multiclass avx512_blendmask<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1446   let ExeDomain = _.ExeDomain, hasSideEffects = 0 in {
1447   def rr : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1448              (ins _.RC:$src1, _.RC:$src2),
1449              !strconcat(OpcodeStr,
1450              "\t{$src2, $src1, ${dst}|${dst}, $src1, $src2}"),
1451              []>, EVEX_4V;
1452   def rrk : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1453              (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1454              !strconcat(OpcodeStr,
1455              "\t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
1456              []>, EVEX_4V, EVEX_K;
1457   def rrkz : AVX5128I<opc, MRMSrcReg, (outs _.RC:$dst),
1458              (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1459              !strconcat(OpcodeStr,
1460              "\t{$src2, $src1, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src1, $src2}"),
1461              []>, EVEX_4V, EVEX_KZ;
1462   let mayLoad = 1 in {
1463   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1464              (ins _.RC:$src1, _.MemOp:$src2),
1465              !strconcat(OpcodeStr,
1466              "\t{$src2, $src1, ${dst}|${dst}, $src1, $src2}"),
1467              []>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
1468   def rmk : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1469              (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1470              !strconcat(OpcodeStr,
1471              "\t{$src2, $src1, ${dst} {${mask}}|${dst} {${mask}}, $src1, $src2}"),
1472              []>, EVEX_4V, EVEX_K, EVEX_CD8<_.EltSize, CD8VF>;
1473   def rmkz : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1474              (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1475              !strconcat(OpcodeStr,
1476              "\t{$src2, $src1, ${dst} {${mask}} {z}|${dst} {${mask}} {z}, $src1, $src2}"),
1477              []>, EVEX_4V, EVEX_KZ, EVEX_CD8<_.EltSize, CD8VF>;
1478   }
1479   }
1480 }
1481 multiclass avx512_blendmask_rmb<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
1482
1483   let mayLoad = 1, hasSideEffects = 0 in {
1484   def rmbk : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1485       (ins _.KRCWM:$mask, _.RC:$src1, _.ScalarMemOp:$src2),
1486        !strconcat(OpcodeStr,
1487             "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1488             "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1489       []>, EVEX_4V, EVEX_K, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
1490
1491   def rmb : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst),
1492       (ins _.RC:$src1, _.ScalarMemOp:$src2),
1493        !strconcat(OpcodeStr,
1494             "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1495             "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1496       []>,  EVEX_4V, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
1497   }
1498 }
1499
1500 multiclass blendmask_dq <bits<8> opc, string OpcodeStr,
1501                                  AVX512VLVectorVTInfo VTInfo> {
1502   defm Z : avx512_blendmask      <opc, OpcodeStr, VTInfo.info512>,
1503            avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1504
1505   let Predicates = [HasVLX] in {
1506     defm Z256 : avx512_blendmask<opc, OpcodeStr, VTInfo.info256>,
1507                 avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1508     defm Z128 : avx512_blendmask<opc, OpcodeStr, VTInfo.info128>,
1509                 avx512_blendmask_rmb  <opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1510   }
1511 }
1512
1513 multiclass blendmask_bw <bits<8> opc, string OpcodeStr,
1514                          AVX512VLVectorVTInfo VTInfo> {
1515   let Predicates = [HasBWI] in
1516     defm Z : avx512_blendmask    <opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
1517
1518   let Predicates = [HasBWI, HasVLX] in {
1519     defm Z256 : avx512_blendmask <opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
1520     defm Z128 : avx512_blendmask <opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
1521   }
1522 }
1523
1524
1525 defm VBLENDMPS : blendmask_dq <0x65, "vblendmps", avx512vl_f32_info>;
1526 defm VBLENDMPD : blendmask_dq <0x65, "vblendmpd", avx512vl_f64_info>, VEX_W;
1527 defm VPBLENDMD : blendmask_dq <0x64, "vpblendmd", avx512vl_i32_info>;
1528 defm VPBLENDMQ : blendmask_dq <0x64, "vpblendmq", avx512vl_i64_info>, VEX_W;
1529 defm VPBLENDMB : blendmask_bw <0x66, "vpblendmb", avx512vl_i8_info>;
1530 defm VPBLENDMW : blendmask_bw <0x66, "vpblendmw", avx512vl_i16_info>, VEX_W;
1531
1532
1533 //===----------------------------------------------------------------------===//
1534 // Compare Instructions
1535 //===----------------------------------------------------------------------===//
1536
1537 // avx512_cmp_scalar - AVX512 CMPSS and CMPSD
1538
1539 multiclass avx512_cmp_scalar<X86VectorVTInfo _, SDNode OpNode, SDNode OpNodeRnd>{
1540
1541   defm  rr_Int  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1542                       (outs _.KRC:$dst),
1543                       (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1544                       "vcmp${cc}"#_.Suffix,
1545                       "$src2, $src1", "$src1, $src2",
1546                       (OpNode (_.VT _.RC:$src1),
1547                               (_.VT _.RC:$src2),
1548                               imm:$cc)>, EVEX_4V;
1549   let mayLoad = 1 in
1550   defm  rm_Int  : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1551                     (outs _.KRC:$dst),
1552                     (ins _.RC:$src1, _.IntScalarMemOp:$src2, AVXCC:$cc),
1553                     "vcmp${cc}"#_.Suffix,
1554                     "$src2, $src1", "$src1, $src2",
1555                     (OpNode (_.VT _.RC:$src1), _.ScalarIntMemCPat:$src2,
1556                         imm:$cc)>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1557
1558   defm  rrb_Int  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1559                      (outs _.KRC:$dst),
1560                      (ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1561                      "vcmp${cc}"#_.Suffix,
1562                      "{sae}, $src2, $src1", "$src1, $src2, {sae}",
1563                      (OpNodeRnd (_.VT _.RC:$src1),
1564                                 (_.VT _.RC:$src2),
1565                                 imm:$cc,
1566                                 (i32 FROUND_NO_EXC))>, EVEX_4V, EVEX_B;
1567   // Accept explicit immediate argument form instead of comparison code.
1568   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1569     defm  rri_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1570                         (outs VK1:$dst),
1571                         (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1572                         "vcmp"#_.Suffix,
1573                         "$cc, $src2, $src1", "$src1, $src2, $cc">, EVEX_4V;
1574   let mayLoad = 1 in
1575     defm  rmi_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1576                         (outs _.KRC:$dst),
1577                         (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$cc),
1578                         "vcmp"#_.Suffix,
1579                         "$cc, $src2, $src1", "$src1, $src2, $cc">,
1580                         EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1581
1582     defm  rrb_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1583                        (outs _.KRC:$dst),
1584                        (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1585                        "vcmp"#_.Suffix,
1586                        "$cc, {sae}, $src2, $src1","$src1, $src2, {sae}, $cc">,
1587                        EVEX_4V, EVEX_B;
1588   }// let isAsmParserOnly = 1, hasSideEffects = 0
1589
1590   let isCodeGenOnly = 1 in {
1591     let isCommutable = 1 in
1592     def rr : AVX512Ii8<0xC2, MRMSrcReg,
1593                 (outs _.KRC:$dst), (ins _.FRC:$src1, _.FRC:$src2, AVXCC:$cc),
1594                 !strconcat("vcmp${cc}", _.Suffix,
1595                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1596                 [(set _.KRC:$dst, (OpNode _.FRC:$src1,
1597                                           _.FRC:$src2,
1598                                           imm:$cc))],
1599                 IIC_SSE_ALU_F32S_RR>, EVEX_4V;
1600     def rm : AVX512Ii8<0xC2, MRMSrcMem,
1601               (outs _.KRC:$dst),
1602               (ins _.FRC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1603               !strconcat("vcmp${cc}", _.Suffix,
1604                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1605               [(set _.KRC:$dst, (OpNode _.FRC:$src1,
1606                                         (_.ScalarLdFrag addr:$src2),
1607                                         imm:$cc))],
1608               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
1609   }
1610 }
1611
1612 let Predicates = [HasAVX512] in {
1613   let ExeDomain = SSEPackedSingle in
1614   defm VCMPSSZ : avx512_cmp_scalar<f32x_info, X86cmpms, X86cmpmsRnd>,
1615                                    AVX512XSIi8Base;
1616   let ExeDomain = SSEPackedDouble in
1617   defm VCMPSDZ : avx512_cmp_scalar<f64x_info, X86cmpms, X86cmpmsRnd>,
1618                                    AVX512XDIi8Base, VEX_W;
1619 }
1620
1621 multiclass avx512_icmp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
1622               X86VectorVTInfo _, bit IsCommutable> {
1623   let isCommutable = IsCommutable in
1624   def rr : AVX512BI<opc, MRMSrcReg,
1625              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2),
1626              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1627              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2)))],
1628              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1629   def rm : AVX512BI<opc, MRMSrcMem,
1630              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2),
1631              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1632              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1633                                      (_.VT (bitconvert (_.LdFrag addr:$src2)))))],
1634              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1635   def rrk : AVX512BI<opc, MRMSrcReg,
1636               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2),
1637               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1638                           "$dst {${mask}}, $src1, $src2}"),
1639               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1640                                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))))],
1641               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1642   def rmk : AVX512BI<opc, MRMSrcMem,
1643               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2),
1644               !strconcat(OpcodeStr, "\t{$src2, $src1, $dst {${mask}}|",
1645                           "$dst {${mask}}, $src1, $src2}"),
1646               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1647                                    (OpNode (_.VT _.RC:$src1),
1648                                        (_.VT (bitconvert
1649                                               (_.LdFrag addr:$src2))))))],
1650               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1651 }
1652
1653 multiclass avx512_icmp_packed_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
1654               X86VectorVTInfo _, bit IsCommutable> :
1655            avx512_icmp_packed<opc, OpcodeStr, OpNode, _, IsCommutable> {
1656   def rmb : AVX512BI<opc, MRMSrcMem,
1657               (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2),
1658               !strconcat(OpcodeStr, "\t{${src2}", _.BroadcastStr, ", $src1, $dst",
1659                                     "|$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1660               [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1661                               (X86VBroadcast (_.ScalarLdFrag addr:$src2))))],
1662               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1663   def rmbk : AVX512BI<opc, MRMSrcMem,
1664                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1665                                        _.ScalarMemOp:$src2),
1666                !strconcat(OpcodeStr,
1667                           "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1668                           "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1669                [(set _.KRC:$dst, (and _.KRCWM:$mask,
1670                                       (OpNode (_.VT _.RC:$src1),
1671                                         (X86VBroadcast
1672                                           (_.ScalarLdFrag addr:$src2)))))],
1673                IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1674 }
1675
1676 multiclass avx512_icmp_packed_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
1677                                  AVX512VLVectorVTInfo VTInfo, Predicate prd,
1678                                  bit IsCommutable = 0> {
1679   let Predicates = [prd] in
1680   defm Z : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info512,
1681                               IsCommutable>, EVEX_V512;
1682
1683   let Predicates = [prd, HasVLX] in {
1684     defm Z256 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info256,
1685                                    IsCommutable>, EVEX_V256;
1686     defm Z128 : avx512_icmp_packed<opc, OpcodeStr, OpNode, VTInfo.info128,
1687                                    IsCommutable>, EVEX_V128;
1688   }
1689 }
1690
1691 multiclass avx512_icmp_packed_rmb_vl<bits<8> opc, string OpcodeStr,
1692                                   SDNode OpNode, AVX512VLVectorVTInfo VTInfo,
1693                                   Predicate prd, bit IsCommutable = 0> {
1694   let Predicates = [prd] in
1695   defm Z : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info512,
1696                                   IsCommutable>, EVEX_V512;
1697
1698   let Predicates = [prd, HasVLX] in {
1699     defm Z256 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info256,
1700                                        IsCommutable>, EVEX_V256;
1701     defm Z128 : avx512_icmp_packed_rmb<opc, OpcodeStr, OpNode, VTInfo.info128,
1702                                        IsCommutable>, EVEX_V128;
1703   }
1704 }
1705
1706 defm VPCMPEQB : avx512_icmp_packed_vl<0x74, "vpcmpeqb", X86pcmpeqm,
1707                       avx512vl_i8_info, HasBWI, 1>,
1708                 EVEX_CD8<8, CD8VF>;
1709
1710 defm VPCMPEQW : avx512_icmp_packed_vl<0x75, "vpcmpeqw", X86pcmpeqm,
1711                       avx512vl_i16_info, HasBWI, 1>,
1712                 EVEX_CD8<16, CD8VF>;
1713
1714 defm VPCMPEQD : avx512_icmp_packed_rmb_vl<0x76, "vpcmpeqd", X86pcmpeqm,
1715                       avx512vl_i32_info, HasAVX512, 1>,
1716                 EVEX_CD8<32, CD8VF>;
1717
1718 defm VPCMPEQQ : avx512_icmp_packed_rmb_vl<0x29, "vpcmpeqq", X86pcmpeqm,
1719                       avx512vl_i64_info, HasAVX512, 1>,
1720                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1721
1722 defm VPCMPGTB : avx512_icmp_packed_vl<0x64, "vpcmpgtb", X86pcmpgtm,
1723                       avx512vl_i8_info, HasBWI>,
1724                 EVEX_CD8<8, CD8VF>;
1725
1726 defm VPCMPGTW : avx512_icmp_packed_vl<0x65, "vpcmpgtw", X86pcmpgtm,
1727                       avx512vl_i16_info, HasBWI>,
1728                 EVEX_CD8<16, CD8VF>;
1729
1730 defm VPCMPGTD : avx512_icmp_packed_rmb_vl<0x66, "vpcmpgtd", X86pcmpgtm,
1731                       avx512vl_i32_info, HasAVX512>,
1732                 EVEX_CD8<32, CD8VF>;
1733
1734 defm VPCMPGTQ : avx512_icmp_packed_rmb_vl<0x37, "vpcmpgtq", X86pcmpgtm,
1735                       avx512vl_i64_info, HasAVX512>,
1736                 T8PD, VEX_W, EVEX_CD8<64, CD8VF>;
1737
1738 let Predicates = [HasAVX512, NoVLX] in {
1739 def : Pat<(v8i1 (X86pcmpgtm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1740             (COPY_TO_REGCLASS (VPCMPGTDZrr
1741             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
1742             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm))), VK8)>;
1743
1744 def : Pat<(v8i1 (X86pcmpeqm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2))),
1745             (COPY_TO_REGCLASS (VPCMPEQDZrr
1746             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
1747             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm))), VK8)>;
1748 }
1749
1750 multiclass avx512_icmp_cc<bits<8> opc, string Suffix, SDNode OpNode,
1751                           X86VectorVTInfo _> {
1752   let isCommutable = 1 in
1753   def rri : AVX512AIi8<opc, MRMSrcReg,
1754              (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, AVX512ICC:$cc),
1755              !strconcat("vpcmp${cc}", Suffix,
1756                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1757              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1758                                        imm:$cc))],
1759              IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1760   def rmi : AVX512AIi8<opc, MRMSrcMem,
1761              (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, AVX512ICC:$cc),
1762              !strconcat("vpcmp${cc}", Suffix,
1763                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1764              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1765                               (_.VT (bitconvert (_.LdFrag addr:$src2))),
1766                               imm:$cc))],
1767              IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1768   def rrik : AVX512AIi8<opc, MRMSrcReg,
1769               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1770                                       AVX512ICC:$cc),
1771               !strconcat("vpcmp${cc}", Suffix,
1772                          "\t{$src2, $src1, $dst {${mask}}|",
1773                          "$dst {${mask}}, $src1, $src2}"),
1774               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1775                                   (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
1776                                           imm:$cc)))],
1777               IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1778   def rmik : AVX512AIi8<opc, MRMSrcMem,
1779               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1780                                     AVX512ICC:$cc),
1781               !strconcat("vpcmp${cc}", Suffix,
1782                          "\t{$src2, $src1, $dst {${mask}}|",
1783                          "$dst {${mask}}, $src1, $src2}"),
1784               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1785                                    (OpNode (_.VT _.RC:$src1),
1786                                       (_.VT (bitconvert (_.LdFrag addr:$src2))),
1787                                       imm:$cc)))],
1788               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1789
1790   // Accept explicit immediate argument form instead of comparison code.
1791   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1792     def rri_alt : AVX512AIi8<opc, MRMSrcReg,
1793                (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1794                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1795                           "$dst, $src1, $src2, $cc}"),
1796                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V;
1797     let mayLoad = 1 in
1798     def rmi_alt : AVX512AIi8<opc, MRMSrcMem,
1799                (outs _.KRC:$dst), (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
1800                !strconcat("vpcmp", Suffix, "\t{$cc, $src2, $src1, $dst|",
1801                           "$dst, $src1, $src2, $cc}"),
1802                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V;
1803     def rrik_alt : AVX512AIi8<opc, MRMSrcReg,
1804                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.RC:$src2,
1805                                        u8imm:$cc),
1806                !strconcat("vpcmp", Suffix,
1807                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1808                           "$dst {${mask}}, $src1, $src2, $cc}"),
1809                [], IIC_SSE_ALU_F32P_RR>, EVEX_4V, EVEX_K;
1810     let mayLoad = 1 in
1811     def rmik_alt : AVX512AIi8<opc, MRMSrcMem,
1812                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1, _.MemOp:$src2,
1813                                        u8imm:$cc),
1814                !strconcat("vpcmp", Suffix,
1815                           "\t{$cc, $src2, $src1, $dst {${mask}}|",
1816                           "$dst {${mask}}, $src1, $src2, $cc}"),
1817                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K;
1818   }
1819 }
1820
1821 multiclass avx512_icmp_cc_rmb<bits<8> opc, string Suffix, SDNode OpNode,
1822                               X86VectorVTInfo _> :
1823            avx512_icmp_cc<opc, Suffix, OpNode, _> {
1824   def rmib : AVX512AIi8<opc, MRMSrcMem,
1825              (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1826                                      AVX512ICC:$cc),
1827              !strconcat("vpcmp${cc}", Suffix,
1828                         "\t{${src2}", _.BroadcastStr, ", $src1, $dst|",
1829                         "$dst, $src1, ${src2}", _.BroadcastStr, "}"),
1830              [(set _.KRC:$dst, (OpNode (_.VT _.RC:$src1),
1831                                (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1832                                imm:$cc))],
1833              IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1834   def rmibk : AVX512AIi8<opc, MRMSrcMem,
1835               (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1836                                        _.ScalarMemOp:$src2, AVX512ICC:$cc),
1837               !strconcat("vpcmp${cc}", Suffix,
1838                        "\t{${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1839                        "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, "}"),
1840               [(set _.KRC:$dst, (and _.KRCWM:$mask,
1841                                   (OpNode (_.VT _.RC:$src1),
1842                                     (X86VBroadcast (_.ScalarLdFrag addr:$src2)),
1843                                     imm:$cc)))],
1844               IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1845
1846   // Accept explicit immediate argument form instead of comparison code.
1847   let isAsmParserOnly = 1, hasSideEffects = 0, mayLoad = 1 in {
1848     def rmib_alt : AVX512AIi8<opc, MRMSrcMem,
1849                (outs _.KRC:$dst), (ins _.RC:$src1, _.ScalarMemOp:$src2,
1850                                        u8imm:$cc),
1851                !strconcat("vpcmp", Suffix,
1852                    "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst|",
1853                    "$dst, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1854                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_B;
1855     def rmibk_alt : AVX512AIi8<opc, MRMSrcMem,
1856                (outs _.KRC:$dst), (ins _.KRCWM:$mask, _.RC:$src1,
1857                                        _.ScalarMemOp:$src2, u8imm:$cc),
1858                !strconcat("vpcmp", Suffix,
1859                   "\t{$cc, ${src2}", _.BroadcastStr, ", $src1, $dst {${mask}}|",
1860                   "$dst {${mask}}, $src1, ${src2}", _.BroadcastStr, ", $cc}"),
1861                [], IIC_SSE_ALU_F32P_RM>, EVEX_4V, EVEX_K, EVEX_B;
1862   }
1863 }
1864
1865 multiclass avx512_icmp_cc_vl<bits<8> opc, string Suffix, SDNode OpNode,
1866                              AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1867   let Predicates = [prd] in
1868   defm Z : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info512>, EVEX_V512;
1869
1870   let Predicates = [prd, HasVLX] in {
1871     defm Z256 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info256>, EVEX_V256;
1872     defm Z128 : avx512_icmp_cc<opc, Suffix, OpNode, VTInfo.info128>, EVEX_V128;
1873   }
1874 }
1875
1876 multiclass avx512_icmp_cc_rmb_vl<bits<8> opc, string Suffix, SDNode OpNode,
1877                                 AVX512VLVectorVTInfo VTInfo, Predicate prd> {
1878   let Predicates = [prd] in
1879   defm Z : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info512>,
1880            EVEX_V512;
1881
1882   let Predicates = [prd, HasVLX] in {
1883     defm Z256 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info256>,
1884                 EVEX_V256;
1885     defm Z128 : avx512_icmp_cc_rmb<opc, Suffix, OpNode, VTInfo.info128>,
1886                 EVEX_V128;
1887   }
1888 }
1889
1890 defm VPCMPB : avx512_icmp_cc_vl<0x3F, "b", X86cmpm, avx512vl_i8_info,
1891                                 HasBWI>, EVEX_CD8<8, CD8VF>;
1892 defm VPCMPUB : avx512_icmp_cc_vl<0x3E, "ub", X86cmpmu, avx512vl_i8_info,
1893                                  HasBWI>, EVEX_CD8<8, CD8VF>;
1894
1895 defm VPCMPW : avx512_icmp_cc_vl<0x3F, "w", X86cmpm, avx512vl_i16_info,
1896                                 HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1897 defm VPCMPUW : avx512_icmp_cc_vl<0x3E, "uw", X86cmpmu, avx512vl_i16_info,
1898                                  HasBWI>, VEX_W, EVEX_CD8<16, CD8VF>;
1899
1900 defm VPCMPD : avx512_icmp_cc_rmb_vl<0x1F, "d", X86cmpm, avx512vl_i32_info,
1901                                     HasAVX512>, EVEX_CD8<32, CD8VF>;
1902 defm VPCMPUD : avx512_icmp_cc_rmb_vl<0x1E, "ud", X86cmpmu, avx512vl_i32_info,
1903                                      HasAVX512>, EVEX_CD8<32, CD8VF>;
1904
1905 defm VPCMPQ : avx512_icmp_cc_rmb_vl<0x1F, "q", X86cmpm, avx512vl_i64_info,
1906                                     HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1907 defm VPCMPUQ : avx512_icmp_cc_rmb_vl<0x1E, "uq", X86cmpmu, avx512vl_i64_info,
1908                                      HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>;
1909
1910 multiclass avx512_vcmp_common<X86VectorVTInfo _> {
1911
1912   defm  rri  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1913                    (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2,AVXCC:$cc),
1914                    "vcmp${cc}"#_.Suffix,
1915                    "$src2, $src1", "$src1, $src2",
1916                    (X86cmpm (_.VT _.RC:$src1),
1917                          (_.VT _.RC:$src2),
1918                            imm:$cc), 1>;
1919
1920   defm  rmi  : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1921                 (outs _.KRC:$dst),(ins _.RC:$src1, _.MemOp:$src2, AVXCC:$cc),
1922                 "vcmp${cc}"#_.Suffix,
1923                 "$src2, $src1", "$src1, $src2",
1924                 (X86cmpm (_.VT _.RC:$src1),
1925                         (_.VT (bitconvert (_.LdFrag addr:$src2))),
1926                         imm:$cc)>;
1927
1928   defm  rmbi : AVX512_maskable_cmp<0xC2, MRMSrcMem, _,
1929                 (outs _.KRC:$dst),
1930                 (ins _.RC:$src1, _.ScalarMemOp:$src2, AVXCC:$cc),
1931                 "vcmp${cc}"#_.Suffix,
1932                 "${src2}"##_.BroadcastStr##", $src1",
1933                 "$src1, ${src2}"##_.BroadcastStr,
1934                 (X86cmpm (_.VT _.RC:$src1),
1935                         (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
1936                         imm:$cc)>,EVEX_B;
1937   // Accept explicit immediate argument form instead of comparison code.
1938   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1939     defm  rri_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1940                          (outs _.KRC:$dst),
1941                          (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1942                          "vcmp"#_.Suffix,
1943                          "$cc, $src2, $src1", "$src1, $src2, $cc">;
1944
1945     let mayLoad = 1 in {
1946       defm rmi_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1947                              (outs _.KRC:$dst),
1948                              (ins _.RC:$src1, _.MemOp:$src2, u8imm:$cc),
1949                              "vcmp"#_.Suffix,
1950                              "$cc, $src2, $src1", "$src1, $src2, $cc">;
1951
1952       defm  rmbi_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcMem, _,
1953                          (outs _.KRC:$dst),
1954                          (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$cc),
1955                          "vcmp"#_.Suffix,
1956                          "$cc, ${src2}"##_.BroadcastStr##", $src1",
1957                          "$src1, ${src2}"##_.BroadcastStr##", $cc">,EVEX_B;
1958     }
1959  }
1960 }
1961
1962 multiclass avx512_vcmp_sae<X86VectorVTInfo _> {
1963   // comparison code form (VCMP[EQ/LT/LE/...]
1964   defm  rrib  : AVX512_maskable_cmp<0xC2, MRMSrcReg, _,
1965                      (outs _.KRC:$dst),(ins _.RC:$src1, _.RC:$src2, AVXCC:$cc),
1966                      "vcmp${cc}"#_.Suffix,
1967                      "{sae}, $src2, $src1", "$src1, $src2, {sae}",
1968                      (X86cmpmRnd (_.VT _.RC:$src1),
1969                                     (_.VT _.RC:$src2),
1970                                     imm:$cc,
1971                                 (i32 FROUND_NO_EXC))>, EVEX_B;
1972
1973   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1974     defm  rrib_alt  : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _,
1975                          (outs _.KRC:$dst),
1976                          (ins _.RC:$src1, _.RC:$src2, u8imm:$cc),
1977                          "vcmp"#_.Suffix,
1978                          "$cc, {sae}, $src2, $src1",
1979                          "$src1, $src2, {sae}, $cc">, EVEX_B;
1980    }
1981 }
1982
1983 multiclass avx512_vcmp<AVX512VLVectorVTInfo _> {
1984   let Predicates = [HasAVX512] in {
1985     defm Z    : avx512_vcmp_common<_.info512>,
1986                 avx512_vcmp_sae<_.info512>, EVEX_V512;
1987
1988   }
1989   let Predicates = [HasAVX512,HasVLX] in {
1990    defm Z128 : avx512_vcmp_common<_.info128>, EVEX_V128;
1991    defm Z256 : avx512_vcmp_common<_.info256>, EVEX_V256;
1992   }
1993 }
1994
1995 defm VCMPPD : avx512_vcmp<avx512vl_f64_info>,
1996                           AVX512PDIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
1997 defm VCMPPS : avx512_vcmp<avx512vl_f32_info>,
1998                           AVX512PSIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
1999
2000 def : Pat<(v8i1 (X86cmpm (v8f32 VR256X:$src1), (v8f32 VR256X:$src2), imm:$cc)),
2001           (COPY_TO_REGCLASS (VCMPPSZrri
2002             (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
2003             (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm)),
2004             imm:$cc), VK8)>;
2005 def : Pat<(v8i1 (X86cmpm (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
2006           (COPY_TO_REGCLASS (VPCMPDZrri
2007             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
2008             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm)),
2009             imm:$cc), VK8)>;
2010 def : Pat<(v8i1 (X86cmpmu (v8i32 VR256X:$src1), (v8i32 VR256X:$src2), imm:$cc)),
2011           (COPY_TO_REGCLASS (VPCMPUDZrri
2012             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
2013             (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src2, sub_ymm)),
2014             imm:$cc), VK8)>;
2015
2016 // ----------------------------------------------------------------
2017 // FPClass
2018 //handle fpclass instruction  mask =  op(reg_scalar,imm)
2019 //                                    op(mem_scalar,imm)
2020 multiclass avx512_scalar_fpclass<bits<8> opc, string OpcodeStr, SDNode OpNode,
2021                                  X86VectorVTInfo _, Predicate prd> {
2022   let Predicates = [prd] in {
2023       def rr : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),//_.KRC:$dst),
2024                       (ins _.RC:$src1, i32u8imm:$src2),
2025                       OpcodeStr##_.Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2026                       [(set _.KRC:$dst,(OpNode (_.VT _.RC:$src1),
2027                               (i32 imm:$src2)))], NoItinerary>;
2028       def rrk : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
2029                       (ins _.KRCWM:$mask, _.RC:$src1, i32u8imm:$src2),
2030                       OpcodeStr##_.Suffix#
2031                       "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2032                       [(set _.KRC:$dst,(or _.KRCWM:$mask,
2033                                       (OpNode (_.VT _.RC:$src1),
2034                                       (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2035     def rm : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2036                     (ins _.MemOp:$src1, i32u8imm:$src2),
2037                     OpcodeStr##_.Suffix##
2038                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2039                     [(set _.KRC:$dst,
2040                           (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
2041                                   (i32 imm:$src2)))], NoItinerary>;
2042     def rmk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2043                     (ins _.KRCWM:$mask, _.MemOp:$src1, i32u8imm:$src2),
2044                     OpcodeStr##_.Suffix##
2045                     "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2046                     [(set _.KRC:$dst,(or _.KRCWM:$mask,
2047                         (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
2048                             (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2049   }
2050 }
2051
2052 //handle fpclass instruction mask = fpclass(reg_vec, reg_vec, imm)
2053 //                                  fpclass(reg_vec, mem_vec, imm)
2054 //                                  fpclass(reg_vec, broadcast(eltVt), imm)
2055 multiclass avx512_vector_fpclass<bits<8> opc, string OpcodeStr, SDNode OpNode,
2056                                  X86VectorVTInfo _, string mem, string broadcast>{
2057   def rr : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
2058                       (ins _.RC:$src1, i32u8imm:$src2),
2059                       OpcodeStr##_.Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2060                       [(set _.KRC:$dst,(OpNode (_.VT _.RC:$src1),
2061                                        (i32 imm:$src2)))], NoItinerary>;
2062   def rrk : AVX512<opc, MRMSrcReg, (outs _.KRC:$dst),
2063                       (ins _.KRCWM:$mask, _.RC:$src1, i32u8imm:$src2),
2064                       OpcodeStr##_.Suffix#
2065                       "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2066                       [(set _.KRC:$dst,(or _.KRCWM:$mask,
2067                                        (OpNode (_.VT _.RC:$src1),
2068                                        (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2069   def rm : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2070                     (ins _.MemOp:$src1, i32u8imm:$src2),
2071                     OpcodeStr##_.Suffix##mem#
2072                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2073                     [(set _.KRC:$dst,(OpNode
2074                                      (_.VT (bitconvert (_.LdFrag addr:$src1))),
2075                                      (i32 imm:$src2)))], NoItinerary>;
2076   def rmk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2077                     (ins _.KRCWM:$mask, _.MemOp:$src1, i32u8imm:$src2),
2078                     OpcodeStr##_.Suffix##mem#
2079                     "\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
2080                     [(set _.KRC:$dst, (or _.KRCWM:$mask, (OpNode
2081                                   (_.VT (bitconvert (_.LdFrag addr:$src1))),
2082                                   (i32 imm:$src2))))], NoItinerary>, EVEX_K;
2083   def rmb : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2084                     (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
2085                     OpcodeStr##_.Suffix##broadcast##"\t{$src2, ${src1}"##
2086                                       _.BroadcastStr##", $dst|$dst, ${src1}"
2087                                                   ##_.BroadcastStr##", $src2}",
2088                     [(set _.KRC:$dst,(OpNode
2089                                      (_.VT (X86VBroadcast
2090                                            (_.ScalarLdFrag addr:$src1))),
2091                                      (i32 imm:$src2)))], NoItinerary>,EVEX_B;
2092   def rmbk : AVX512<opc, MRMSrcMem, (outs _.KRC:$dst),
2093                     (ins _.KRCWM:$mask, _.ScalarMemOp:$src1, i32u8imm:$src2),
2094                     OpcodeStr##_.Suffix##broadcast##"\t{$src2, ${src1}"##
2095                           _.BroadcastStr##", $dst {${mask}}|$dst {${mask}}, ${src1}"##
2096                                                    _.BroadcastStr##", $src2}",
2097                     [(set _.KRC:$dst,(or _.KRCWM:$mask, (OpNode
2098                                      (_.VT (X86VBroadcast
2099                                            (_.ScalarLdFrag addr:$src1))),
2100                                      (i32 imm:$src2))))], NoItinerary>,
2101                                                           EVEX_B, EVEX_K;
2102 }
2103
2104 multiclass avx512_vector_fpclass_all<string OpcodeStr,
2105             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd,
2106                                                               string broadcast>{
2107   let Predicates = [prd] in {
2108     defm Z    : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info512, "{z}",
2109                                       broadcast>, EVEX_V512;
2110   }
2111   let Predicates = [prd, HasVLX] in {
2112     defm Z128 : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info128, "{x}",
2113                                       broadcast>, EVEX_V128;
2114     defm Z256 : avx512_vector_fpclass<opc, OpcodeStr, OpNode, _.info256, "{y}",
2115                                       broadcast>, EVEX_V256;
2116   }
2117 }
2118
2119 multiclass avx512_fp_fpclass_all<string OpcodeStr, bits<8> opcVec,
2120              bits<8> opcScalar, SDNode VecOpNode, SDNode ScalarOpNode, Predicate prd>{
2121   defm PS : avx512_vector_fpclass_all<OpcodeStr,  avx512vl_f32_info, opcVec,
2122                                       VecOpNode, prd, "{l}">, EVEX_CD8<32, CD8VF>;
2123   defm PD : avx512_vector_fpclass_all<OpcodeStr,  avx512vl_f64_info, opcVec,
2124                                       VecOpNode, prd, "{q}">,EVEX_CD8<64, CD8VF> , VEX_W;
2125   defm SS : avx512_scalar_fpclass<opcScalar, OpcodeStr, ScalarOpNode,
2126                                       f32x_info, prd>, EVEX_CD8<32, CD8VT1>;
2127   defm SD : avx512_scalar_fpclass<opcScalar, OpcodeStr, ScalarOpNode,
2128                                       f64x_info, prd>, EVEX_CD8<64, CD8VT1>, VEX_W;
2129 }
2130
2131 defm VFPCLASS : avx512_fp_fpclass_all<"vfpclass", 0x66, 0x67, X86Vfpclass,
2132                                       X86Vfpclasss, HasDQI>, AVX512AIi8Base,EVEX;
2133
2134 //-----------------------------------------------------------------
2135 // Mask register copy, including
2136 // - copy between mask registers
2137 // - load/store mask registers
2138 // - copy from GPR to mask register and vice versa
2139 //
2140 multiclass avx512_mask_mov<bits<8> opc_kk, bits<8> opc_km, bits<8> opc_mk,
2141                          string OpcodeStr, RegisterClass KRC,
2142                          ValueType vvt, X86MemOperand x86memop> {
2143   let hasSideEffects = 0 in
2144   def kk : I<opc_kk, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
2145              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
2146   def km : I<opc_km, MRMSrcMem, (outs KRC:$dst), (ins x86memop:$src),
2147              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2148              [(set KRC:$dst, (vvt (load addr:$src)))]>;
2149   def mk : I<opc_mk, MRMDestMem, (outs), (ins x86memop:$dst, KRC:$src),
2150              !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2151              [(store KRC:$src, addr:$dst)]>;
2152 }
2153
2154 multiclass avx512_mask_mov_gpr<bits<8> opc_kr, bits<8> opc_rk,
2155                              string OpcodeStr,
2156                              RegisterClass KRC, RegisterClass GRC> {
2157   let hasSideEffects = 0 in {
2158     def kr : I<opc_kr, MRMSrcReg, (outs KRC:$dst), (ins GRC:$src),
2159                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
2160     def rk : I<opc_rk, MRMSrcReg, (outs GRC:$dst), (ins KRC:$src),
2161                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>;
2162   }
2163 }
2164
2165 let Predicates = [HasDQI] in
2166   defm KMOVB : avx512_mask_mov<0x90, 0x90, 0x91, "kmovb", VK8, v8i1, i8mem>,
2167                avx512_mask_mov_gpr<0x92, 0x93, "kmovb", VK8, GR32>,
2168                VEX, PD;
2169
2170 let Predicates = [HasAVX512] in
2171   defm KMOVW : avx512_mask_mov<0x90, 0x90, 0x91, "kmovw", VK16, v16i1, i16mem>,
2172                avx512_mask_mov_gpr<0x92, 0x93, "kmovw", VK16, GR32>,
2173                VEX, PS;
2174
2175 let Predicates = [HasBWI] in {
2176   defm KMOVD : avx512_mask_mov<0x90, 0x90, 0x91, "kmovd", VK32, v32i1,i32mem>,
2177                VEX, PD, VEX_W;
2178   defm KMOVD : avx512_mask_mov_gpr<0x92, 0x93, "kmovd", VK32, GR32>,
2179                VEX, XD;
2180   defm KMOVQ : avx512_mask_mov<0x90, 0x90, 0x91, "kmovq", VK64, v64i1, i64mem>,
2181                VEX, PS, VEX_W;
2182   defm KMOVQ : avx512_mask_mov_gpr<0x92, 0x93, "kmovq", VK64, GR64>,
2183                VEX, XD, VEX_W;
2184 }
2185
2186 // GR from/to mask register
2187 def : Pat<(v16i1 (bitconvert (i16 GR16:$src))),
2188           (COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), GR16:$src, sub_16bit)), VK16)>;
2189 def : Pat<(i16 (bitconvert (v16i1 VK16:$src))),
2190           (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK16:$src, GR32)), sub_16bit)>;
2191
2192 def : Pat<(v8i1 (bitconvert (i8 GR8:$src))),
2193           (COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), GR8:$src, sub_8bit)), VK8)>;
2194 def : Pat<(i8 (bitconvert (v8i1 VK8:$src))),
2195           (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK8:$src, GR32)), sub_8bit)>;
2196
2197 def : Pat<(i32 (zext (i16 (bitconvert (v16i1 VK16:$src))))),
2198           (KMOVWrk VK16:$src)>;
2199 def : Pat<(i32 (anyext (i16 (bitconvert (v16i1 VK16:$src))))),
2200           (COPY_TO_REGCLASS VK16:$src, GR32)>;
2201
2202 def : Pat<(i32 (zext (i8 (bitconvert (v8i1 VK8:$src))))),
2203           (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK8:$src, GR32)), sub_8bit))>, Requires<[NoDQI]>;
2204 def : Pat<(i32 (zext (i8 (bitconvert (v8i1 VK8:$src))))),
2205           (KMOVBrk VK8:$src)>, Requires<[HasDQI]>;
2206 def : Pat<(i32 (anyext (i8 (bitconvert (v8i1 VK8:$src))))),
2207           (COPY_TO_REGCLASS VK8:$src, GR32)>;
2208
2209 def : Pat<(v32i1 (bitconvert (i32 GR32:$src))),
2210           (COPY_TO_REGCLASS GR32:$src, VK32)>;
2211 def : Pat<(i32 (bitconvert (v32i1 VK32:$src))),
2212           (COPY_TO_REGCLASS VK32:$src, GR32)>;
2213 def : Pat<(v64i1 (bitconvert (i64 GR64:$src))),
2214           (COPY_TO_REGCLASS GR64:$src, VK64)>;
2215 def : Pat<(i64 (bitconvert (v64i1 VK64:$src))),
2216           (COPY_TO_REGCLASS VK64:$src, GR64)>;
2217
2218 // Load/store kreg
2219 let Predicates = [HasDQI] in {
2220   def : Pat<(store (i8 (bitconvert (v8i1 VK8:$src))), addr:$dst),
2221             (KMOVBmk addr:$dst, VK8:$src)>;
2222   def : Pat<(v8i1 (bitconvert (i8 (load addr:$src)))),
2223             (KMOVBkm addr:$src)>;
2224
2225   def : Pat<(store VK4:$src, addr:$dst),
2226             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK4:$src, VK8))>;
2227   def : Pat<(store VK2:$src, addr:$dst),
2228             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK2:$src, VK8))>;
2229   def : Pat<(store VK1:$src, addr:$dst),
2230             (KMOVBmk addr:$dst, (COPY_TO_REGCLASS VK1:$src, VK8))>;
2231
2232   def : Pat<(v2i1 (load addr:$src)),
2233             (COPY_TO_REGCLASS (KMOVBkm addr:$src), VK2)>;
2234   def : Pat<(v4i1 (load addr:$src)),
2235             (COPY_TO_REGCLASS (KMOVBkm addr:$src), VK4)>;
2236 }
2237 let Predicates = [HasAVX512, NoDQI] in {
2238   def : Pat<(store VK1:$src, addr:$dst),
2239             (MOV8mr addr:$dst,
2240              (i8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK1:$src, GR32)),
2241               sub_8bit)))>;
2242   def : Pat<(store VK2:$src, addr:$dst),
2243             (MOV8mr addr:$dst,
2244              (i8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK2:$src, GR32)),
2245               sub_8bit)))>;
2246   def : Pat<(store VK4:$src, addr:$dst),
2247             (MOV8mr addr:$dst,
2248              (i8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK4:$src, GR32)),
2249               sub_8bit)))>;
2250   def : Pat<(store VK8:$src, addr:$dst),
2251             (MOV8mr addr:$dst,
2252              (i8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK8:$src, GR32)),
2253               sub_8bit)))>;
2254
2255   def : Pat<(v8i1 (load addr:$src)),
2256             (COPY_TO_REGCLASS (MOVZX32rm8 addr:$src), VK8)>;
2257   def : Pat<(v2i1 (load addr:$src)),
2258             (COPY_TO_REGCLASS (MOVZX32rm8 addr:$src), VK2)>;
2259   def : Pat<(v4i1 (load addr:$src)),
2260             (COPY_TO_REGCLASS (MOVZX32rm8 addr:$src), VK4)>;
2261 }
2262
2263 let Predicates = [HasAVX512] in {
2264   def : Pat<(store (i16 (bitconvert (v16i1 VK16:$src))), addr:$dst),
2265             (KMOVWmk addr:$dst, VK16:$src)>;
2266   def : Pat<(i1 (load addr:$src)),
2267             (COPY_TO_REGCLASS (AND32ri8 (MOVZX32rm8 addr:$src), (i32 1)), VK1)>;
2268   def : Pat<(v16i1 (bitconvert (i16 (load addr:$src)))),
2269             (KMOVWkm addr:$src)>;
2270 }
2271 let Predicates = [HasBWI] in {
2272   def : Pat<(store (i32 (bitconvert (v32i1 VK32:$src))), addr:$dst),
2273             (KMOVDmk addr:$dst, VK32:$src)>;
2274   def : Pat<(v32i1 (bitconvert (i32 (load addr:$src)))),
2275             (KMOVDkm addr:$src)>;
2276   def : Pat<(store (i64 (bitconvert (v64i1 VK64:$src))), addr:$dst),
2277             (KMOVQmk addr:$dst, VK64:$src)>;
2278   def : Pat<(v64i1 (bitconvert (i64 (load addr:$src)))),
2279             (KMOVQkm addr:$src)>;
2280 }
2281
2282 let Predicates = [HasAVX512] in {
2283   def : Pat<(i1 (trunc (i64 GR64:$src))),
2284             (COPY_TO_REGCLASS (AND32ri8 (EXTRACT_SUBREG $src, sub_32bit),
2285                                         (i32 1)), VK1)>;
2286
2287   def : Pat<(i1 (trunc (i32 GR32:$src))),
2288             (COPY_TO_REGCLASS (AND32ri8 $src, (i32 1)), VK1)>;
2289
2290   def : Pat<(i1 (trunc (i32 (assertzext_i1 GR32:$src)))),
2291             (COPY_TO_REGCLASS GR32:$src, VK1)>;
2292
2293   def : Pat<(i1 (trunc (i8 GR8:$src))),
2294        (COPY_TO_REGCLASS
2295         (AND32ri8 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
2296                                  GR8:$src, sub_8bit), (i32 1)), VK1)>;
2297
2298   def : Pat<(i1 (trunc (i16 GR16:$src))),
2299        (COPY_TO_REGCLASS
2300         (AND32ri8 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
2301                                  GR16:$src, sub_16bit), (i32 1)), VK1)>;
2302
2303   def : Pat<(i32 (zext VK1:$src)),
2304             (AND32ri8 (COPY_TO_REGCLASS VK1:$src, GR32), (i32 1))>;
2305
2306   def : Pat<(i32 (anyext VK1:$src)),
2307             (COPY_TO_REGCLASS VK1:$src, GR32)>;
2308
2309   def : Pat<(i8 (zext VK1:$src)),
2310             (EXTRACT_SUBREG
2311              (AND32ri8 (COPY_TO_REGCLASS VK1:$src, GR32), (i32 1)), sub_8bit)>;
2312
2313   def : Pat<(i8 (anyext VK1:$src)),
2314             (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK1:$src, GR32)), sub_8bit)>;
2315
2316   def : Pat<(i64 (zext VK1:$src)),
2317             (SUBREG_TO_REG (i64 0),
2318              (AND32ri8 (COPY_TO_REGCLASS VK1:$src, GR32), (i32 1)), sub_32bit)>;
2319
2320   def : Pat<(i64 (anyext VK1:$src)),
2321             (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2322              (i32 (COPY_TO_REGCLASS VK1:$src, GR32)), sub_32bit)>;
2323
2324   def : Pat<(i16 (zext VK1:$src)),
2325             (EXTRACT_SUBREG
2326              (AND32ri8 (COPY_TO_REGCLASS VK1:$src, GR32), (i32 1)), sub_16bit)>;
2327
2328   def : Pat<(i16 (anyext VK1:$src)),
2329             (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS VK1:$src, GR32)), sub_16bit)>;
2330 }
2331 def : Pat<(v16i1 (scalar_to_vector VK1:$src)),
2332           (COPY_TO_REGCLASS VK1:$src, VK16)>;
2333 def : Pat<(v8i1 (scalar_to_vector VK1:$src)),
2334           (COPY_TO_REGCLASS VK1:$src, VK8)>;
2335 def : Pat<(v4i1 (scalar_to_vector VK1:$src)),
2336           (COPY_TO_REGCLASS VK1:$src, VK4)>;
2337 def : Pat<(v2i1 (scalar_to_vector VK1:$src)),
2338           (COPY_TO_REGCLASS VK1:$src, VK2)>;
2339 def : Pat<(v32i1 (scalar_to_vector VK1:$src)),
2340           (COPY_TO_REGCLASS VK1:$src, VK32)>;
2341 def : Pat<(v64i1 (scalar_to_vector VK1:$src)),
2342           (COPY_TO_REGCLASS VK1:$src, VK64)>;
2343
2344 def : Pat<(store (i1 -1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
2345 def : Pat<(store (i1  1), addr:$dst), (MOV8mi addr:$dst, (i8 1))>;
2346 def : Pat<(store (i1  0), addr:$dst), (MOV8mi addr:$dst, (i8 0))>;
2347
2348 def : Pat<(i1 (X86Vextract VK64:$src, (iPTR 0))), (COPY_TO_REGCLASS VK64:$src, VK1)>;
2349 def : Pat<(i1 (X86Vextract VK32:$src, (iPTR 0))), (COPY_TO_REGCLASS VK32:$src, VK1)>;
2350 def : Pat<(i1 (X86Vextract VK16:$src, (iPTR 0))), (COPY_TO_REGCLASS VK16:$src, VK1)>;
2351 def : Pat<(i1 (X86Vextract VK8:$src,  (iPTR 0))), (COPY_TO_REGCLASS VK8:$src,  VK1)>;
2352 def : Pat<(i1 (X86Vextract VK4:$src,  (iPTR 0))), (COPY_TO_REGCLASS VK4:$src,  VK1)>;
2353 def : Pat<(i1 (X86Vextract VK2:$src,  (iPTR 0))), (COPY_TO_REGCLASS VK2:$src,  VK1)>;
2354
2355 // Mask unary operation
2356 // - KNOT
2357 multiclass avx512_mask_unop<bits<8> opc, string OpcodeStr,
2358                             RegisterClass KRC, SDPatternOperator OpNode,
2359                             Predicate prd> {
2360   let Predicates = [prd] in
2361     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src),
2362                !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2363                [(set KRC:$dst, (OpNode KRC:$src))]>;
2364 }
2365
2366 multiclass avx512_mask_unop_all<bits<8> opc, string OpcodeStr,
2367                                 SDPatternOperator OpNode> {
2368   defm B : avx512_mask_unop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
2369                             HasDQI>, VEX, PD;
2370   defm W : avx512_mask_unop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
2371                             HasAVX512>, VEX, PS;
2372   defm D : avx512_mask_unop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
2373                             HasBWI>, VEX, PD, VEX_W;
2374   defm Q : avx512_mask_unop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
2375                             HasBWI>, VEX, PS, VEX_W;
2376 }
2377
2378 defm KNOT : avx512_mask_unop_all<0x44, "knot", vnot>;
2379
2380 // KNL does not support KMOVB, 8-bit mask is promoted to 16-bit
2381 let Predicates = [HasAVX512, NoDQI] in
2382 def : Pat<(vnot VK8:$src),
2383           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$src, VK16)), VK8)>;
2384
2385 def : Pat<(vnot VK4:$src),
2386           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK4:$src, VK16)), VK4)>;
2387 def : Pat<(vnot VK2:$src),
2388           (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK2:$src, VK16)), VK2)>;
2389
2390 // Mask binary operation
2391 // - KAND, KANDN, KOR, KXNOR, KXOR
2392 multiclass avx512_mask_binop<bits<8> opc, string OpcodeStr,
2393                            RegisterClass KRC, SDPatternOperator OpNode,
2394                            Predicate prd, bit IsCommutable> {
2395   let Predicates = [prd], isCommutable = IsCommutable in
2396     def rr : I<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src1, KRC:$src2),
2397                !strconcat(OpcodeStr,
2398                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2399                [(set KRC:$dst, (OpNode KRC:$src1, KRC:$src2))]>;
2400 }
2401
2402 multiclass avx512_mask_binop_all<bits<8> opc, string OpcodeStr,
2403                                SDPatternOperator OpNode, bit IsCommutable,
2404                                Predicate prdW = HasAVX512> {
2405   defm B : avx512_mask_binop<opc, !strconcat(OpcodeStr, "b"), VK8, OpNode,
2406                              HasDQI, IsCommutable>, VEX_4V, VEX_L, PD;
2407   defm W : avx512_mask_binop<opc, !strconcat(OpcodeStr, "w"), VK16, OpNode,
2408                              prdW, IsCommutable>, VEX_4V, VEX_L, PS;
2409   defm D : avx512_mask_binop<opc, !strconcat(OpcodeStr, "d"), VK32, OpNode,
2410                              HasBWI, IsCommutable>, VEX_4V, VEX_L, VEX_W, PD;
2411   defm Q : avx512_mask_binop<opc, !strconcat(OpcodeStr, "q"), VK64, OpNode,
2412                              HasBWI, IsCommutable>, VEX_4V, VEX_L, VEX_W, PS;
2413 }
2414
2415 def andn : PatFrag<(ops node:$i0, node:$i1), (and (not node:$i0), node:$i1)>;
2416 def xnor : PatFrag<(ops node:$i0, node:$i1), (not (xor node:$i0, node:$i1))>;
2417 // These nodes use 'vnot' instead of 'not' to support vectors.
2418 def vandn : PatFrag<(ops node:$i0, node:$i1), (and (vnot node:$i0), node:$i1)>;
2419 def vxnor : PatFrag<(ops node:$i0, node:$i1), (vnot (xor node:$i0, node:$i1))>;
2420
2421 defm KAND  : avx512_mask_binop_all<0x41, "kand",  and,   1>;
2422 defm KOR   : avx512_mask_binop_all<0x45, "kor",   or,    1>;
2423 defm KXNOR : avx512_mask_binop_all<0x46, "kxnor", vxnor, 1>;
2424 defm KXOR  : avx512_mask_binop_all<0x47, "kxor",  xor,   1>;
2425 defm KANDN : avx512_mask_binop_all<0x42, "kandn", vandn, 0>;
2426 defm KADD  : avx512_mask_binop_all<0x4A, "kadd",  add,   1, HasDQI>;
2427
2428 multiclass avx512_binop_pat<SDPatternOperator VOpNode, SDPatternOperator OpNode,
2429                             Instruction Inst> {
2430   // With AVX512F, 8-bit mask is promoted to 16-bit mask,
2431   // for the DQI set, this type is legal and KxxxB instruction is used
2432   let Predicates = [NoDQI] in
2433   def : Pat<(VOpNode VK8:$src1, VK8:$src2),
2434             (COPY_TO_REGCLASS
2435               (Inst (COPY_TO_REGCLASS VK8:$src1, VK16),
2436                     (COPY_TO_REGCLASS VK8:$src2, VK16)), VK8)>;
2437
2438   // All types smaller than 8 bits require conversion anyway
2439   def : Pat<(OpNode VK1:$src1, VK1:$src2),
2440         (COPY_TO_REGCLASS (Inst
2441                            (COPY_TO_REGCLASS VK1:$src1, VK16),
2442                            (COPY_TO_REGCLASS VK1:$src2, VK16)), VK1)>;
2443   def : Pat<(VOpNode VK2:$src1, VK2:$src2),
2444         (COPY_TO_REGCLASS (Inst
2445                            (COPY_TO_REGCLASS VK2:$src1, VK16),
2446                            (COPY_TO_REGCLASS VK2:$src2, VK16)), VK1)>;
2447   def : Pat<(VOpNode VK4:$src1, VK4:$src2),
2448         (COPY_TO_REGCLASS (Inst
2449                            (COPY_TO_REGCLASS VK4:$src1, VK16),
2450                            (COPY_TO_REGCLASS VK4:$src2, VK16)), VK1)>;
2451 }
2452
2453 defm : avx512_binop_pat<and,   and,  KANDWrr>;
2454 defm : avx512_binop_pat<vandn, andn, KANDNWrr>;
2455 defm : avx512_binop_pat<or,    or,   KORWrr>;
2456 defm : avx512_binop_pat<vxnor, xnor, KXNORWrr>;
2457 defm : avx512_binop_pat<xor,   xor,  KXORWrr>;
2458
2459 // Mask unpacking
2460 multiclass avx512_mask_unpck<string Suffix,RegisterClass KRC, ValueType VT,
2461                              RegisterClass KRCSrc, Predicate prd> {
2462   let Predicates = [prd] in {
2463     let hasSideEffects = 0 in
2464     def rr : I<0x4b, MRMSrcReg, (outs KRC:$dst),
2465                (ins KRC:$src1, KRC:$src2),
2466                "kunpck"#Suffix#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
2467                VEX_4V, VEX_L;
2468
2469     def : Pat<(VT (concat_vectors KRCSrc:$src1, KRCSrc:$src2)),
2470               (!cast<Instruction>(NAME##rr)
2471                         (COPY_TO_REGCLASS KRCSrc:$src2, KRC),
2472                         (COPY_TO_REGCLASS KRCSrc:$src1, KRC))>;
2473   }
2474 }
2475
2476 defm KUNPCKBW : avx512_mask_unpck<"bw", VK16, v16i1, VK8, HasAVX512>, PD;
2477 defm KUNPCKWD : avx512_mask_unpck<"wd", VK32, v32i1, VK16, HasBWI>, PS;
2478 defm KUNPCKDQ : avx512_mask_unpck<"dq", VK64, v64i1, VK32, HasBWI>, PS, VEX_W;
2479
2480 // Mask bit testing
2481 multiclass avx512_mask_testop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
2482                               SDNode OpNode, Predicate prd> {
2483   let Predicates = [prd], Defs = [EFLAGS] in
2484     def rr : I<opc, MRMSrcReg, (outs), (ins KRC:$src1, KRC:$src2),
2485                !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2486                [(set EFLAGS, (OpNode KRC:$src1, KRC:$src2))]>;
2487 }
2488
2489 multiclass avx512_mask_testop_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
2490                                 Predicate prdW = HasAVX512> {
2491   defm B : avx512_mask_testop<opc, OpcodeStr#"b", VK8, OpNode, HasDQI>,
2492                                                                 VEX, PD;
2493   defm W : avx512_mask_testop<opc, OpcodeStr#"w", VK16, OpNode, prdW>,
2494                                                                 VEX, PS;
2495   defm Q : avx512_mask_testop<opc, OpcodeStr#"q", VK64, OpNode, HasBWI>,
2496                                                                 VEX, PS, VEX_W;
2497   defm D : avx512_mask_testop<opc, OpcodeStr#"d", VK32, OpNode, HasBWI>,
2498                                                                 VEX, PD, VEX_W;
2499 }
2500
2501 defm KORTEST : avx512_mask_testop_w<0x98, "kortest", X86kortest>;
2502 defm KTEST   : avx512_mask_testop_w<0x99, "ktest", X86ktest, HasDQI>;
2503
2504 // Mask shift
2505 multiclass avx512_mask_shiftop<bits<8> opc, string OpcodeStr, RegisterClass KRC,
2506                              SDNode OpNode> {
2507   let Predicates = [HasAVX512] in
2508     def ri : Ii8<opc, MRMSrcReg, (outs KRC:$dst), (ins KRC:$src, u8imm:$imm),
2509                  !strconcat(OpcodeStr,
2510                             "\t{$imm, $src, $dst|$dst, $src, $imm}"),
2511                             [(set KRC:$dst, (OpNode KRC:$src, (i8 imm:$imm)))]>;
2512 }
2513
2514 multiclass avx512_mask_shiftop_w<bits<8> opc1, bits<8> opc2, string OpcodeStr,
2515                                SDNode OpNode> {
2516   defm W : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "w"), VK16, OpNode>,
2517                                VEX, TAPD, VEX_W;
2518   let Predicates = [HasDQI] in
2519   defm B : avx512_mask_shiftop<opc1, !strconcat(OpcodeStr, "b"), VK8, OpNode>,
2520                                VEX, TAPD;
2521   let Predicates = [HasBWI] in {
2522   defm Q : avx512_mask_shiftop<opc2, !strconcat(OpcodeStr, "q"), VK64, OpNode>,
2523                                VEX, TAPD, VEX_W;
2524   defm D : avx512_mask_shiftop<opc2, !strconcat(OpcodeStr, "d"), VK32, OpNode>,
2525                                VEX, TAPD;
2526   }
2527 }
2528
2529 defm KSHIFTL : avx512_mask_shiftop_w<0x32, 0x33, "kshiftl", X86kshiftl>;
2530 defm KSHIFTR : avx512_mask_shiftop_w<0x30, 0x31, "kshiftr", X86kshiftr>;
2531
2532 // Mask setting all 0s or 1s
2533 multiclass avx512_mask_setop<RegisterClass KRC, ValueType VT, PatFrag Val> {
2534   let Predicates = [HasAVX512] in
2535     let isReMaterializable = 1, isAsCheapAsAMove = 1, isPseudo = 1 in
2536       def #NAME# : I<0, Pseudo, (outs KRC:$dst), (ins), "",
2537                      [(set KRC:$dst, (VT Val))]>;
2538 }
2539
2540 multiclass avx512_mask_setop_w<PatFrag Val> {
2541   defm W : avx512_mask_setop<VK16, v16i1, Val>;
2542   defm D : avx512_mask_setop<VK32,  v32i1, Val>;
2543   defm Q : avx512_mask_setop<VK64, v64i1, Val>;
2544 }
2545
2546 defm KSET0 : avx512_mask_setop_w<immAllZerosV>;
2547 defm KSET1 : avx512_mask_setop_w<immAllOnesV>;
2548
2549 // With AVX-512 only, 8-bit mask is promoted to 16-bit mask.
2550 let Predicates = [HasAVX512] in {
2551   def : Pat<(v8i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK8)>;
2552   def : Pat<(v4i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK4)>;
2553   def : Pat<(v2i1 immAllZerosV), (COPY_TO_REGCLASS (KSET0W), VK2)>;
2554   def : Pat<(v8i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK8)>;
2555   def : Pat<(v4i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK4)>;
2556   def : Pat<(v2i1 immAllOnesV),  (COPY_TO_REGCLASS (KSET1W), VK2)>;
2557   let AddedComplexity = 10 in { // To optimize isel table.
2558     def : Pat<(i1 0), (COPY_TO_REGCLASS (KSET0W), VK1)>;
2559     def : Pat<(i1 1), (COPY_TO_REGCLASS (KSHIFTRWri (KSET1W), (i8 15)), VK1)>;
2560     def : Pat<(i1 -1), (COPY_TO_REGCLASS (KSHIFTRWri (KSET1W), (i8 15)), VK1)>;
2561   }
2562 }
2563
2564 // Patterns for kmask insert_subvector/extract_subvector to/from index=0
2565 multiclass operation_subvector_mask_lowering<RegisterClass subRC, ValueType subVT,
2566                                              RegisterClass RC, ValueType VT> {
2567   def : Pat<(subVT (extract_subvector (VT RC:$src), (iPTR 0))),
2568             (subVT (COPY_TO_REGCLASS RC:$src, subRC))>;
2569
2570   def : Pat<(VT (insert_subvector undef, subRC:$src, (iPTR 0))),
2571             (VT (COPY_TO_REGCLASS subRC:$src, RC))>;
2572 }
2573
2574 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK4,  v4i1>;
2575 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK8,  v8i1>;
2576 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK16, v16i1>;
2577 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK32, v32i1>;
2578 defm : operation_subvector_mask_lowering<VK2,  v2i1,  VK64, v64i1>;
2579
2580 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK8,  v8i1>;
2581 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK16, v16i1>;
2582 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK32, v32i1>;
2583 defm : operation_subvector_mask_lowering<VK4,  v4i1,  VK64, v64i1>;
2584
2585 defm : operation_subvector_mask_lowering<VK8,  v8i1,  VK16, v16i1>;
2586 defm : operation_subvector_mask_lowering<VK8,  v8i1,  VK32, v32i1>;
2587 defm : operation_subvector_mask_lowering<VK8,  v8i1,  VK64, v64i1>;
2588
2589 defm : operation_subvector_mask_lowering<VK16, v16i1, VK32, v32i1>;
2590 defm : operation_subvector_mask_lowering<VK16, v16i1, VK64, v64i1>;
2591
2592 defm : operation_subvector_mask_lowering<VK32, v32i1, VK64, v64i1>;
2593
2594 def : Pat<(v2i1 (extract_subvector (v4i1 VK4:$src), (iPTR 2))),
2595           (v2i1 (COPY_TO_REGCLASS
2596                   (KSHIFTRWri (COPY_TO_REGCLASS VK4:$src, VK16), (i8 2)),
2597                    VK2))>;
2598 def : Pat<(v4i1 (extract_subvector (v8i1 VK8:$src), (iPTR 4))),
2599           (v4i1 (COPY_TO_REGCLASS
2600                   (KSHIFTRWri (COPY_TO_REGCLASS VK8:$src, VK16), (i8 4)),
2601                    VK4))>;
2602 def : Pat<(v8i1 (extract_subvector (v16i1 VK16:$src), (iPTR 8))),
2603           (v8i1 (COPY_TO_REGCLASS (KSHIFTRWri VK16:$src, (i8 8)), VK8))>;
2604 def : Pat<(v16i1 (extract_subvector (v32i1 VK32:$src), (iPTR 16))),
2605           (v16i1 (COPY_TO_REGCLASS (KSHIFTRDri VK32:$src, (i8 16)), VK16))>;
2606 def : Pat<(v32i1 (extract_subvector (v64i1 VK64:$src), (iPTR 32))),
2607           (v32i1 (COPY_TO_REGCLASS (KSHIFTRQri VK64:$src, (i8 32)), VK32))>;
2608
2609
2610 // Patterns for kmask shift
2611 multiclass mask_shift_lowering<RegisterClass RC, ValueType VT> {
2612   def : Pat<(VT (X86kshiftl RC:$src, (i8 imm:$imm))),
2613             (VT (COPY_TO_REGCLASS
2614                    (KSHIFTLWri (COPY_TO_REGCLASS RC:$src, VK16),
2615                                (I8Imm $imm)),
2616                    RC))>;
2617   def : Pat<(VT (X86kshiftr RC:$src, (i8 imm:$imm))),
2618             (VT (COPY_TO_REGCLASS
2619                    (KSHIFTRWri (COPY_TO_REGCLASS RC:$src, VK16),
2620                                (I8Imm $imm)),
2621                    RC))>;
2622 }
2623
2624 defm : mask_shift_lowering<VK8, v8i1>, Requires<[HasAVX512, NoDQI]>;
2625 defm : mask_shift_lowering<VK4, v4i1>, Requires<[HasAVX512]>;
2626 defm : mask_shift_lowering<VK2, v2i1>, Requires<[HasAVX512]>;
2627 //===----------------------------------------------------------------------===//
2628 // AVX-512 - Aligned and unaligned load and store
2629 //
2630
2631
2632 multiclass avx512_load<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
2633                          PatFrag ld_frag, PatFrag mload,
2634                          SDPatternOperator SelectOprr = vselect> {
2635   let hasSideEffects = 0 in {
2636   def rr : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst), (ins _.RC:$src),
2637                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), [],
2638                     _.ExeDomain>, EVEX;
2639   def rrkz : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst),
2640                       (ins _.KRCWM:$mask,  _.RC:$src),
2641                       !strconcat(OpcodeStr, "\t{$src, ${dst} {${mask}} {z}|",
2642                        "${dst} {${mask}} {z}, $src}"),
2643                        [(set _.RC:$dst, (_.VT (SelectOprr _.KRCWM:$mask,
2644                                            (_.VT _.RC:$src),
2645                                            _.ImmAllZerosV)))], _.ExeDomain>,
2646                        EVEX, EVEX_KZ;
2647
2648   let canFoldAsLoad = 1, isReMaterializable = 1,
2649       SchedRW = [WriteLoad] in
2650   def rm : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst), (ins _.MemOp:$src),
2651                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2652                     [(set _.RC:$dst, (_.VT (bitconvert (ld_frag addr:$src))))],
2653                     _.ExeDomain>, EVEX;
2654
2655   let Constraints = "$src0 = $dst", isConvertibleToThreeAddress = 1 in {
2656   def rrk : AVX512PI<opc, MRMSrcReg, (outs _.RC:$dst),
2657                     (ins _.RC:$src0, _.KRCWM:$mask, _.RC:$src1),
2658                     !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
2659                     "${dst} {${mask}}, $src1}"),
2660                     [(set _.RC:$dst, (_.VT (SelectOprr _.KRCWM:$mask,
2661                                         (_.VT _.RC:$src1),
2662                                         (_.VT _.RC:$src0))))], _.ExeDomain>,
2663                      EVEX, EVEX_K;
2664     let SchedRW = [WriteLoad] in
2665     def rmk : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst),
2666                      (ins _.RC:$src0, _.KRCWM:$mask, _.MemOp:$src1),
2667                      !strconcat(OpcodeStr, "\t{$src1, ${dst} {${mask}}|",
2668                       "${dst} {${mask}}, $src1}"),
2669                      [(set _.RC:$dst, (_.VT
2670                          (vselect _.KRCWM:$mask,
2671                           (_.VT (bitconvert (ld_frag addr:$src1))),
2672                            (_.VT _.RC:$src0))))], _.ExeDomain>, EVEX, EVEX_K;
2673   }
2674   let SchedRW = [WriteLoad] in
2675   def rmkz : AVX512PI<opc, MRMSrcMem, (outs _.RC:$dst),
2676                   (ins _.KRCWM:$mask, _.MemOp:$src),
2677                   OpcodeStr #"\t{$src, ${dst} {${mask}} {z}|"#
2678                                 "${dst} {${mask}} {z}, $src}",
2679                   [(set _.RC:$dst, (_.VT (vselect _.KRCWM:$mask,
2680                     (_.VT (bitconvert (ld_frag addr:$src))), _.ImmAllZerosV)))],
2681                   _.ExeDomain>, EVEX, EVEX_KZ;
2682   }
2683   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, undef)),
2684             (!cast<Instruction>(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>;
2685
2686   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, _.ImmAllZerosV)),
2687             (!cast<Instruction>(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>;
2688
2689   def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src0))),
2690             (!cast<Instruction>(NAME#_.ZSuffix##rmk) _.RC:$src0,
2691              _.KRCWM:$mask, addr:$ptr)>;
2692 }
2693
2694 multiclass avx512_alignedload_vl<bits<8> opc, string OpcodeStr,
2695                                   AVX512VLVectorVTInfo _,
2696                                   Predicate prd> {
2697   let Predicates = [prd] in
2698   defm Z : avx512_load<opc, OpcodeStr, _.info512, _.info512.AlignedLdFrag,
2699                        masked_load_aligned512>, EVEX_V512;
2700
2701   let Predicates = [prd, HasVLX] in {
2702   defm Z256 : avx512_load<opc, OpcodeStr, _.info256, _.info256.AlignedLdFrag,
2703                           masked_load_aligned256>, EVEX_V256;
2704   defm Z128 : avx512_load<opc, OpcodeStr, _.info128, _.info128.AlignedLdFrag,
2705                           masked_load_aligned128>, EVEX_V128;
2706   }
2707 }
2708
2709 multiclass avx512_load_vl<bits<8> opc, string OpcodeStr,
2710                                   AVX512VLVectorVTInfo _,
2711                                   Predicate prd,
2712                                   SDPatternOperator SelectOprr = vselect> {
2713   let Predicates = [prd] in
2714   defm Z : avx512_load<opc, OpcodeStr, _.info512, _.info512.LdFrag,
2715                        masked_load_unaligned, SelectOprr>, EVEX_V512;
2716
2717   let Predicates = [prd, HasVLX] in {
2718   defm Z256 : avx512_load<opc, OpcodeStr, _.info256, _.info256.LdFrag,
2719                          masked_load_unaligned, SelectOprr>, EVEX_V256;
2720   defm Z128 : avx512_load<opc, OpcodeStr, _.info128, _.info128.LdFrag,
2721                          masked_load_unaligned, SelectOprr>, EVEX_V128;
2722   }
2723 }
2724
2725 multiclass avx512_store<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
2726                         PatFrag st_frag, PatFrag mstore> {
2727
2728   let hasSideEffects = 0 in {
2729   def rr_REV  : AVX512PI<opc, MRMDestReg, (outs _.RC:$dst), (ins _.RC:$src),
2730                          OpcodeStr # ".s\t{$src, $dst|$dst, $src}",
2731                          [], _.ExeDomain>, EVEX;
2732   def rrk_REV : AVX512PI<opc, MRMDestReg, (outs  _.RC:$dst),
2733                          (ins _.KRCWM:$mask, _.RC:$src),
2734                          OpcodeStr # ".s\t{$src, ${dst} {${mask}}|"#
2735                          "${dst} {${mask}}, $src}",
2736                          [], _.ExeDomain>,  EVEX, EVEX_K;
2737   def rrkz_REV : AVX512PI<opc, MRMDestReg, (outs  _.RC:$dst),
2738                           (ins _.KRCWM:$mask, _.RC:$src),
2739                           OpcodeStr # ".s\t{$src, ${dst} {${mask}} {z}|" #
2740                           "${dst} {${mask}} {z}, $src}",
2741                           [], _.ExeDomain>, EVEX, EVEX_KZ;
2742   }
2743
2744   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins _.MemOp:$dst, _.RC:$src),
2745                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2746                     [(st_frag (_.VT _.RC:$src), addr:$dst)], _.ExeDomain>, EVEX;
2747   def mrk : AVX512PI<opc, MRMDestMem, (outs),
2748                      (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
2749               OpcodeStr # "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}",
2750                [], _.ExeDomain>, EVEX, EVEX_K;
2751
2752   def: Pat<(mstore addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src)),
2753            (!cast<Instruction>(NAME#_.ZSuffix##mrk) addr:$ptr,
2754                                                     _.KRCWM:$mask, _.RC:$src)>;
2755 }
2756
2757
2758 multiclass avx512_store_vl< bits<8> opc, string OpcodeStr,
2759                             AVX512VLVectorVTInfo _, Predicate prd> {
2760   let Predicates = [prd] in
2761   defm Z : avx512_store<opc, OpcodeStr, _.info512, store,
2762                         masked_store_unaligned>, EVEX_V512;
2763
2764   let Predicates = [prd, HasVLX] in {
2765     defm Z256 : avx512_store<opc, OpcodeStr, _.info256, store,
2766                              masked_store_unaligned>, EVEX_V256;
2767     defm Z128 : avx512_store<opc, OpcodeStr, _.info128, store,
2768                              masked_store_unaligned>, EVEX_V128;
2769   }
2770 }
2771
2772 multiclass avx512_alignedstore_vl<bits<8> opc, string OpcodeStr,
2773                                   AVX512VLVectorVTInfo _,  Predicate prd> {
2774   let Predicates = [prd] in
2775   defm Z : avx512_store<opc, OpcodeStr, _.info512, alignedstore512,
2776                         masked_store_aligned512>, EVEX_V512;
2777
2778   let Predicates = [prd, HasVLX] in {
2779     defm Z256 : avx512_store<opc, OpcodeStr, _.info256, alignedstore256,
2780                              masked_store_aligned256>, EVEX_V256;
2781     defm Z128 : avx512_store<opc, OpcodeStr, _.info128, alignedstore,
2782                              masked_store_aligned128>, EVEX_V128;
2783   }
2784 }
2785
2786 defm VMOVAPS : avx512_alignedload_vl<0x28, "vmovaps", avx512vl_f32_info,
2787                                      HasAVX512>,
2788                avx512_alignedstore_vl<0x29, "vmovaps", avx512vl_f32_info,
2789                                       HasAVX512>,  PS, EVEX_CD8<32, CD8VF>;
2790
2791 defm VMOVAPD : avx512_alignedload_vl<0x28, "vmovapd", avx512vl_f64_info,
2792                                      HasAVX512>,
2793                avx512_alignedstore_vl<0x29, "vmovapd", avx512vl_f64_info,
2794                                      HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2795
2796 defm VMOVUPS : avx512_load_vl<0x10, "vmovups", avx512vl_f32_info, HasAVX512,
2797                               null_frag>,
2798                avx512_store_vl<0x11, "vmovups", avx512vl_f32_info, HasAVX512>,
2799                               PS, EVEX_CD8<32, CD8VF>;
2800
2801 defm VMOVUPD : avx512_load_vl<0x10, "vmovupd", avx512vl_f64_info, HasAVX512,
2802                               null_frag>,
2803                avx512_store_vl<0x11, "vmovupd", avx512vl_f64_info, HasAVX512>,
2804                PD, VEX_W, EVEX_CD8<64, CD8VF>;
2805
2806 defm VMOVDQA32 : avx512_alignedload_vl<0x6F, "vmovdqa32", avx512vl_i32_info,
2807                                        HasAVX512>,
2808                  avx512_alignedstore_vl<0x7F, "vmovdqa32", avx512vl_i32_info,
2809                                        HasAVX512>, PD, EVEX_CD8<32, CD8VF>;
2810
2811 defm VMOVDQA64 : avx512_alignedload_vl<0x6F, "vmovdqa64", avx512vl_i64_info,
2812                                        HasAVX512>,
2813                  avx512_alignedstore_vl<0x7F, "vmovdqa64", avx512vl_i64_info,
2814                                     HasAVX512>, PD, VEX_W, EVEX_CD8<64, CD8VF>;
2815
2816 defm VMOVDQU8 : avx512_load_vl<0x6F, "vmovdqu8", avx512vl_i8_info, HasBWI>,
2817                  avx512_store_vl<0x7F, "vmovdqu8", avx512vl_i8_info,
2818                                  HasBWI>, XD, EVEX_CD8<8, CD8VF>;
2819
2820 defm VMOVDQU16 : avx512_load_vl<0x6F, "vmovdqu16", avx512vl_i16_info, HasBWI>,
2821                  avx512_store_vl<0x7F, "vmovdqu16", avx512vl_i16_info,
2822                                  HasBWI>, XD, VEX_W, EVEX_CD8<16, CD8VF>;
2823
2824 defm VMOVDQU32 : avx512_load_vl<0x6F, "vmovdqu32", avx512vl_i32_info, HasAVX512,
2825                                 null_frag>,
2826                  avx512_store_vl<0x7F, "vmovdqu32", avx512vl_i32_info,
2827                                  HasAVX512>, XS, EVEX_CD8<32, CD8VF>;
2828
2829 defm VMOVDQU64 : avx512_load_vl<0x6F, "vmovdqu64", avx512vl_i64_info, HasAVX512,
2830                                 null_frag>,
2831                  avx512_store_vl<0x7F, "vmovdqu64", avx512vl_i64_info,
2832                                  HasAVX512>, XS, VEX_W, EVEX_CD8<64, CD8VF>;
2833
2834 // Special instructions to help with spilling when we don't have VLX. We need
2835 // to load or store from a ZMM register instead. These are converted in
2836 // expandPostRAPseudos.
2837 let isReMaterializable = 1, canFoldAsLoad = 1,
2838     isPseudo = 1, SchedRW = [WriteLoad], mayLoad = 1, hasSideEffects = 0 in {
2839 def VMOVAPSZ128rm_NOVLX : I<0, Pseudo, (outs VR128X:$dst), (ins f128mem:$src),
2840                             "", []>;
2841 def VMOVAPSZ256rm_NOVLX : I<0, Pseudo, (outs VR256X:$dst), (ins f256mem:$src),
2842                             "", []>;
2843 def VMOVUPSZ128rm_NOVLX : I<0, Pseudo, (outs VR128X:$dst), (ins f128mem:$src),
2844                             "", []>;
2845 def VMOVUPSZ256rm_NOVLX : I<0, Pseudo, (outs VR256X:$dst), (ins f256mem:$src),
2846                             "", []>;
2847 }
2848
2849 let isPseudo = 1, mayStore = 1, hasSideEffects = 0 in {
2850 def VMOVAPSZ128mr_NOVLX : I<0, Pseudo, (outs), (ins f128mem:$dst, VR128X:$src),
2851                             "", []>;
2852 def VMOVAPSZ256mr_NOVLX : I<0, Pseudo, (outs), (ins f256mem:$dst, VR256X:$src),
2853                             "", []>;
2854 def VMOVUPSZ128mr_NOVLX : I<0, Pseudo, (outs), (ins f128mem:$dst, VR128X:$src),
2855                             "", []>;
2856 def VMOVUPSZ256mr_NOVLX : I<0, Pseudo, (outs), (ins f256mem:$dst, VR256X:$src),
2857                             "", []>;
2858 }
2859
2860 def : Pat<(v8i64 (vselect VK8WM:$mask, (bc_v8i64 (v16i32 immAllZerosV)),
2861                           (v8i64 VR512:$src))),
2862    (VMOVDQA64Zrrkz (COPY_TO_REGCLASS (KNOTWrr (COPY_TO_REGCLASS VK8:$mask, VK16)),
2863                                               VK8), VR512:$src)>;
2864
2865 def : Pat<(v16i32 (vselect VK16WM:$mask, (v16i32 immAllZerosV),
2866                            (v16i32 VR512:$src))),
2867                   (VMOVDQA32Zrrkz (KNOTWrr VK16WM:$mask), VR512:$src)>;
2868
2869 // These patterns exist to prevent the above patterns from introducing a second
2870 // mask inversion when one already exists.
2871 def : Pat<(v8i64 (vselect (xor VK8:$mask, (v8i1 immAllOnesV)),
2872                           (bc_v8i64 (v16i32 immAllZerosV)),
2873                           (v8i64 VR512:$src))),
2874                  (VMOVDQA64Zrrkz VK8:$mask, VR512:$src)>;
2875 def : Pat<(v16i32 (vselect (xor VK16:$mask, (v16i1 immAllOnesV)),
2876                            (v16i32 immAllZerosV),
2877                            (v16i32 VR512:$src))),
2878                   (VMOVDQA32Zrrkz VK16WM:$mask, VR512:$src)>;
2879
2880 // Patterns for handling v8i1 selects of 256-bit vectors when VLX isn't
2881 // available. Use a 512-bit operation and extract.
2882 let Predicates = [HasAVX512, NoVLX] in {
2883 def : Pat<(v8f32 (vselect (v8i1 VK8WM:$mask), (v8f32 VR256X:$src1),
2884                           (v8f32 VR256X:$src0))),
2885           (EXTRACT_SUBREG
2886            (v16f32
2887             (VMOVAPSZrrk
2888              (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src0, sub_ymm)),
2889              (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
2890              (v16f32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)))),
2891            sub_ymm)>;
2892
2893 def : Pat<(v8i32 (vselect (v8i1 VK8WM:$mask), (v8i32 VR256X:$src1),
2894                           (v8i32 VR256X:$src0))),
2895           (EXTRACT_SUBREG
2896            (v16i32
2897             (VMOVDQA32Zrrk
2898              (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src0, sub_ymm)),
2899              (COPY_TO_REGCLASS VK8WM:$mask, VK16WM),
2900              (v16i32 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)))),
2901            sub_ymm)>;
2902 }
2903
2904 let Predicates = [HasVLX, NoBWI] in {
2905   // 128-bit load/store without BWI.
2906   def : Pat<(alignedstore (v8i16 VR128X:$src), addr:$dst),
2907             (VMOVDQA32Z128mr addr:$dst, VR128X:$src)>;
2908   def : Pat<(alignedstore (v16i8 VR128X:$src), addr:$dst),
2909             (VMOVDQA32Z128mr addr:$dst, VR128X:$src)>;
2910   def : Pat<(store (v8i16 VR128X:$src), addr:$dst),
2911             (VMOVDQU32Z128mr addr:$dst, VR128X:$src)>;
2912   def : Pat<(store (v16i8 VR128X:$src), addr:$dst),
2913             (VMOVDQU32Z128mr addr:$dst, VR128X:$src)>;
2914
2915   // 256-bit load/store without BWI.
2916   def : Pat<(alignedstore256 (v16i16 VR256X:$src), addr:$dst),
2917             (VMOVDQA32Z256mr addr:$dst, VR256X:$src)>;
2918   def : Pat<(alignedstore256 (v32i8 VR256X:$src), addr:$dst),
2919             (VMOVDQA32Z256mr addr:$dst, VR256X:$src)>;
2920   def : Pat<(store (v16i16 VR256X:$src), addr:$dst),
2921             (VMOVDQU32Z256mr addr:$dst, VR256X:$src)>;
2922   def : Pat<(store (v32i8 VR256X:$src), addr:$dst),
2923             (VMOVDQU32Z256mr addr:$dst, VR256X:$src)>;
2924 }
2925
2926 let Predicates = [HasVLX] in {
2927   // Special patterns for storing subvector extracts of lower 128-bits of 256.
2928   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
2929   def : Pat<(alignedstore (v2f64 (extract_subvector
2930                                   (v4f64 VR256X:$src), (iPTR 0))), addr:$dst),
2931      (VMOVAPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2932   def : Pat<(alignedstore (v4f32 (extract_subvector
2933                                   (v8f32 VR256X:$src), (iPTR 0))), addr:$dst),
2934      (VMOVAPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2935   def : Pat<(alignedstore (v2i64 (extract_subvector
2936                                   (v4i64 VR256X:$src), (iPTR 0))), addr:$dst),
2937      (VMOVDQA64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2938   def : Pat<(alignedstore (v4i32 (extract_subvector
2939                                   (v8i32 VR256X:$src), (iPTR 0))), addr:$dst),
2940      (VMOVDQA32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2941   def : Pat<(alignedstore (v8i16 (extract_subvector
2942                                   (v16i16 VR256X:$src), (iPTR 0))), addr:$dst),
2943      (VMOVDQA32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2944   def : Pat<(alignedstore (v16i8 (extract_subvector
2945                                   (v32i8 VR256X:$src), (iPTR 0))), addr:$dst),
2946      (VMOVDQA32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2947
2948   def : Pat<(store (v2f64 (extract_subvector
2949                            (v4f64 VR256X:$src), (iPTR 0))), addr:$dst),
2950      (VMOVUPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2951   def : Pat<(store (v4f32 (extract_subvector
2952                            (v8f32 VR256X:$src), (iPTR 0))), addr:$dst),
2953      (VMOVUPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2954   def : Pat<(store (v2i64 (extract_subvector
2955                            (v4i64 VR256X:$src), (iPTR 0))), addr:$dst),
2956      (VMOVDQU64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2957   def : Pat<(store (v4i32 (extract_subvector
2958                            (v8i32 VR256X:$src), (iPTR 0))), addr:$dst),
2959      (VMOVDQU32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2960   def : Pat<(store (v8i16 (extract_subvector
2961                            (v16i16 VR256X:$src), (iPTR 0))), addr:$dst),
2962      (VMOVDQU32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2963   def : Pat<(store (v16i8 (extract_subvector
2964                            (v32i8 VR256X:$src), (iPTR 0))), addr:$dst),
2965      (VMOVDQU32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256X:$src,sub_xmm)))>;
2966
2967   // Special patterns for storing subvector extracts of lower 128-bits of 512.
2968   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
2969   def : Pat<(alignedstore (v2f64 (extract_subvector
2970                                   (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
2971      (VMOVAPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2972   def : Pat<(alignedstore (v4f32 (extract_subvector
2973                                   (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
2974      (VMOVAPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2975   def : Pat<(alignedstore (v2i64 (extract_subvector
2976                                   (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
2977      (VMOVDQA64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2978   def : Pat<(alignedstore (v4i32 (extract_subvector
2979                                   (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
2980      (VMOVDQA32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2981   def : Pat<(alignedstore (v8i16 (extract_subvector
2982                                   (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
2983      (VMOVDQA32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2984   def : Pat<(alignedstore (v16i8 (extract_subvector
2985                                   (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
2986      (VMOVDQA32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2987
2988   def : Pat<(store (v2f64 (extract_subvector
2989                            (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
2990      (VMOVUPDZ128mr addr:$dst, (v2f64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2991   def : Pat<(store (v4f32 (extract_subvector
2992                            (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
2993      (VMOVUPSZ128mr addr:$dst, (v4f32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2994   def : Pat<(store (v2i64 (extract_subvector
2995                            (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
2996      (VMOVDQU64Z128mr addr:$dst, (v2i64 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
2997   def : Pat<(store (v4i32 (extract_subvector
2998                            (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
2999      (VMOVDQU32Z128mr addr:$dst, (v4i32 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3000   def : Pat<(store (v8i16 (extract_subvector
3001                            (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3002      (VMOVDQU32Z128mr addr:$dst, (v8i16 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3003   def : Pat<(store (v16i8 (extract_subvector
3004                            (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3005      (VMOVDQU32Z128mr addr:$dst, (v16i8 (EXTRACT_SUBREG VR512:$src,sub_xmm)))>;
3006
3007   // Special patterns for storing subvector extracts of lower 256-bits of 512.
3008   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
3009   def : Pat<(alignedstore256 (v4f64 (extract_subvector
3010                                      (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
3011      (VMOVAPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3012   def : Pat<(alignedstore (v8f32 (extract_subvector
3013                                   (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
3014      (VMOVAPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3015   def : Pat<(alignedstore256 (v4i64 (extract_subvector
3016                                      (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
3017      (VMOVDQA64Z256mr addr:$dst, (v4i64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3018   def : Pat<(alignedstore256 (v8i32 (extract_subvector
3019                                      (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
3020      (VMOVDQA32Z256mr addr:$dst, (v8i32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3021   def : Pat<(alignedstore256 (v16i16 (extract_subvector
3022                                       (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3023      (VMOVDQA32Z256mr addr:$dst, (v16i16 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3024   def : Pat<(alignedstore256 (v32i8 (extract_subvector
3025                                      (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3026      (VMOVDQA32Z256mr addr:$dst, (v32i8 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3027
3028   def : Pat<(store (v4f64 (extract_subvector
3029                            (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
3030      (VMOVUPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3031   def : Pat<(store (v8f32 (extract_subvector
3032                            (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
3033      (VMOVUPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3034   def : Pat<(store (v4i64 (extract_subvector
3035                            (v8i64 VR512:$src), (iPTR 0))), addr:$dst),
3036      (VMOVDQU64Z256mr addr:$dst, (v4i64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3037   def : Pat<(store (v8i32 (extract_subvector
3038                            (v16i32 VR512:$src), (iPTR 0))), addr:$dst),
3039      (VMOVDQU32Z256mr addr:$dst, (v8i32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3040   def : Pat<(store (v16i16 (extract_subvector
3041                             (v32i16 VR512:$src), (iPTR 0))), addr:$dst),
3042      (VMOVDQU32Z256mr addr:$dst, (v16i16 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3043   def : Pat<(store (v32i8 (extract_subvector
3044                            (v64i8 VR512:$src), (iPTR 0))), addr:$dst),
3045      (VMOVDQU32Z256mr addr:$dst, (v32i8 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
3046 }
3047
3048
3049 // Move Int Doubleword to Packed Double Int
3050 //
3051 let ExeDomain = SSEPackedInt in {
3052 def VMOVDI2PDIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR32:$src),
3053                       "vmovd\t{$src, $dst|$dst, $src}",
3054                       [(set VR128X:$dst,
3055                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
3056                         EVEX;
3057 def VMOVDI2PDIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst), (ins i32mem:$src),
3058                       "vmovd\t{$src, $dst|$dst, $src}",
3059                       [(set VR128X:$dst,
3060                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
3061                         IIC_SSE_MOVDQ>, EVEX, EVEX_CD8<32, CD8VT1>;
3062 def VMOV64toPQIZrr : AVX512BI<0x6E, MRMSrcReg, (outs VR128X:$dst), (ins GR64:$src),
3063                       "vmovq\t{$src, $dst|$dst, $src}",
3064                         [(set VR128X:$dst,
3065                           (v2i64 (scalar_to_vector GR64:$src)))],
3066                           IIC_SSE_MOVDQ>, EVEX, VEX_W;
3067 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
3068 def VMOV64toPQIZrm : AVX512BI<0x6E, MRMSrcMem, (outs VR128X:$dst),
3069                       (ins i64mem:$src),
3070                       "vmovq\t{$src, $dst|$dst, $src}", []>,
3071                       EVEX, VEX_W, EVEX_CD8<64, CD8VT1>;
3072 let isCodeGenOnly = 1 in {
3073 def VMOV64toSDZrr : AVX512BI<0x6E, MRMSrcReg, (outs FR64X:$dst), (ins GR64:$src),
3074                        "vmovq\t{$src, $dst|$dst, $src}",
3075                        [(set FR64X:$dst, (bitconvert GR64:$src))],
3076                        IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
3077 def VMOV64toSDZrm : AVX512XSI<0x7E, MRMSrcMem, (outs FR64X:$dst), (ins i64mem:$src),
3078                       "vmovq\t{$src, $dst|$dst, $src}",
3079                       [(set FR64X:$dst, (bitconvert (loadi64 addr:$src)))]>,
3080                       EVEX, VEX_W, EVEX_CD8<8, CD8VT8>;
3081 def VMOVSDto64Zrr : AVX512BI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64X:$src),
3082                          "vmovq\t{$src, $dst|$dst, $src}",
3083                          [(set GR64:$dst, (bitconvert FR64X:$src))],
3084                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteMove]>;
3085 def VMOVSDto64Zmr : AVX512BI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64X:$src),
3086                          "vmovq\t{$src, $dst|$dst, $src}",
3087                          [(store (i64 (bitconvert FR64X:$src)), addr:$dst)],
3088                          IIC_SSE_MOVDQ>, EVEX, VEX_W, Sched<[WriteStore]>,
3089                          EVEX_CD8<64, CD8VT1>;
3090 }
3091 } // ExeDomain = SSEPackedInt
3092
3093 // Move Int Doubleword to Single Scalar
3094 //
3095 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
3096 def VMOVDI2SSZrr  : AVX512BI<0x6E, MRMSrcReg, (outs FR32X:$dst), (ins GR32:$src),
3097                       "vmovd\t{$src, $dst|$dst, $src}",
3098                       [(set FR32X:$dst, (bitconvert GR32:$src))],
3099                       IIC_SSE_MOVDQ>, EVEX;
3100
3101 def VMOVDI2SSZrm  : AVX512BI<0x6E, MRMSrcMem, (outs FR32X:$dst), (ins i32mem:$src),
3102                       "vmovd\t{$src, $dst|$dst, $src}",
3103                       [(set FR32X:$dst, (bitconvert (loadi32 addr:$src)))],
3104                       IIC_SSE_MOVDQ>, EVEX, EVEX_CD8<32, CD8VT1>;
3105 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
3106
3107 // Move doubleword from xmm register to r/m32
3108 //
3109 let ExeDomain = SSEPackedInt in {
3110 def VMOVPDI2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128X:$src),
3111                        "vmovd\t{$src, $dst|$dst, $src}",
3112                        [(set GR32:$dst, (extractelt (v4i32 VR128X:$src),
3113                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
3114                        EVEX;
3115 def VMOVPDI2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
3116                        (ins i32mem:$dst, VR128X:$src),
3117                        "vmovd\t{$src, $dst|$dst, $src}",
3118                        [(store (i32 (extractelt (v4i32 VR128X:$src),
3119                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
3120                        EVEX, EVEX_CD8<32, CD8VT1>;
3121 } // ExeDomain = SSEPackedInt
3122
3123 // Move quadword from xmm1 register to r/m64
3124 //
3125 let ExeDomain = SSEPackedInt in {
3126 def VMOVPQIto64Zrr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128X:$src),
3127                       "vmovq\t{$src, $dst|$dst, $src}",
3128                       [(set GR64:$dst, (extractelt (v2i64 VR128X:$src),
3129                                                    (iPTR 0)))],
3130                       IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_W,
3131                       Requires<[HasAVX512, In64BitMode]>;
3132
3133 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
3134 def VMOVPQIto64Zmr : I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, VR128X:$src),
3135                       "vmovq\t{$src, $dst|$dst, $src}",
3136                       [], IIC_SSE_MOVD_ToGP>, PD, EVEX, VEX_W,
3137                       Requires<[HasAVX512, In64BitMode]>;
3138
3139 def VMOVPQI2QIZmr : I<0xD6, MRMDestMem, (outs),
3140                       (ins i64mem:$dst, VR128X:$src),
3141                       "vmovq\t{$src, $dst|$dst, $src}",
3142                       [(store (extractelt (v2i64 VR128X:$src), (iPTR 0)),
3143                               addr:$dst)], IIC_SSE_MOVDQ>,
3144                       EVEX, PD, VEX_W, EVEX_CD8<64, CD8VT1>,
3145                       Sched<[WriteStore]>, Requires<[HasAVX512, In64BitMode]>;
3146
3147 let hasSideEffects = 0 in
3148 def VMOVPQI2QIZrr : AVX512BI<0xD6, MRMDestReg, (outs VR128X:$dst),
3149                              (ins VR128X:$src),
3150                              "vmovq.s\t{$src, $dst|$dst, $src}",[]>,
3151                              EVEX, VEX_W;
3152 } // ExeDomain = SSEPackedInt
3153
3154 // Move Scalar Single to Double Int
3155 //
3156 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
3157 def VMOVSS2DIZrr  : AVX512BI<0x7E, MRMDestReg, (outs GR32:$dst),
3158                       (ins FR32X:$src),
3159                       "vmovd\t{$src, $dst|$dst, $src}",
3160                       [(set GR32:$dst, (bitconvert FR32X:$src))],
3161                       IIC_SSE_MOVD_ToGP>, EVEX;
3162 def VMOVSS2DIZmr  : AVX512BI<0x7E, MRMDestMem, (outs),
3163                       (ins i32mem:$dst, FR32X:$src),
3164                       "vmovd\t{$src, $dst|$dst, $src}",
3165                       [(store (i32 (bitconvert FR32X:$src)), addr:$dst)],
3166                       IIC_SSE_MOVDQ>, EVEX, EVEX_CD8<32, CD8VT1>;
3167 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
3168
3169 // Move Quadword Int to Packed Quadword Int
3170 //
3171 let ExeDomain = SSEPackedInt in {
3172 def VMOVQI2PQIZrm : AVX512XSI<0x7E, MRMSrcMem, (outs VR128X:$dst),
3173                       (ins i64mem:$src),
3174                       "vmovq\t{$src, $dst|$dst, $src}",
3175                       [(set VR128X:$dst,
3176                         (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>,
3177                       EVEX, VEX_W, EVEX_CD8<8, CD8VT8>;
3178 } // ExeDomain = SSEPackedInt
3179
3180 //===----------------------------------------------------------------------===//
3181 // AVX-512  MOVSS, MOVSD
3182 //===----------------------------------------------------------------------===//
3183
3184 multiclass avx512_move_scalar<string asm, SDNode OpNode,
3185                               X86VectorVTInfo _> {
3186   def rr : AVX512PI<0x10, MRMSrcReg, (outs _.RC:$dst),
3187              (ins _.RC:$src1, _.FRC:$src2),
3188              !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3189              [(set _.RC:$dst, (_.VT (OpNode _.RC:$src1,
3190                                     (scalar_to_vector _.FRC:$src2))))],
3191              _.ExeDomain,IIC_SSE_MOV_S_RR>, EVEX_4V;
3192   def rrkz : AVX512PI<0x10, MRMSrcReg, (outs _.RC:$dst),
3193               (ins _.KRCWM:$mask, _.RC:$src1, _.FRC:$src2),
3194               !strconcat(asm, "\t{$src2, $src1, $dst {${mask}} {z}|",
3195               "$dst {${mask}} {z}, $src1, $src2}"),
3196               [(set _.RC:$dst, (_.VT (X86selects _.KRCWM:$mask,
3197                                       (_.VT (OpNode _.RC:$src1,
3198                                             (scalar_to_vector _.FRC:$src2))),
3199                                       _.ImmAllZerosV)))],
3200               _.ExeDomain,IIC_SSE_MOV_S_RR>, EVEX_4V, EVEX_KZ;
3201   let Constraints = "$src0 = $dst"  in
3202   def rrk : AVX512PI<0x10, MRMSrcReg, (outs _.RC:$dst),
3203              (ins _.RC:$src0, _.KRCWM:$mask, _.RC:$src1, _.FRC:$src2),
3204              !strconcat(asm, "\t{$src2, $src1, $dst {${mask}}|",
3205              "$dst {${mask}}, $src1, $src2}"),
3206              [(set _.RC:$dst, (_.VT (X86selects _.KRCWM:$mask,
3207                                      (_.VT (OpNode _.RC:$src1,
3208                                            (scalar_to_vector _.FRC:$src2))),
3209                                      (_.VT _.RC:$src0))))],
3210              _.ExeDomain,IIC_SSE_MOV_S_RR>, EVEX_4V, EVEX_K;
3211   let canFoldAsLoad = 1, isReMaterializable = 1 in
3212   def rm : AVX512PI<0x10, MRMSrcMem, (outs _.FRC:$dst), (ins _.ScalarMemOp:$src),
3213              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
3214              [(set _.FRC:$dst, (_.ScalarLdFrag addr:$src))],
3215              _.ExeDomain, IIC_SSE_MOV_S_RM>, EVEX;
3216   let mayLoad = 1, hasSideEffects = 0 in {
3217     let Constraints = "$src0 = $dst" in
3218     def rmk : AVX512PI<0x10, MRMSrcMem, (outs _.RC:$dst),
3219                (ins _.RC:$src0, _.KRCWM:$mask, _.ScalarMemOp:$src),
3220                !strconcat(asm, "\t{$src, $dst {${mask}}|",
3221                "$dst {${mask}}, $src}"),
3222                [], _.ExeDomain, IIC_SSE_MOV_S_RM>, EVEX, EVEX_K;
3223     def rmkz : AVX512PI<0x10, MRMSrcMem, (outs _.RC:$dst),
3224                (ins _.KRCWM:$mask, _.ScalarMemOp:$src),
3225                !strconcat(asm, "\t{$src, $dst {${mask}} {z}|",
3226                "$dst {${mask}} {z}, $src}"),
3227                [], _.ExeDomain, IIC_SSE_MOV_S_RM>, EVEX, EVEX_KZ;
3228   }
3229   def mr: AVX512PI<0x11, MRMDestMem, (outs), (ins _.ScalarMemOp:$dst, _.FRC:$src),
3230              !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
3231              [(store _.FRC:$src, addr:$dst)],  _.ExeDomain, IIC_SSE_MOV_S_MR>,
3232              EVEX;
3233   let mayStore = 1, hasSideEffects = 0 in
3234   def mrk: AVX512PI<0x11, MRMDestMem, (outs),
3235               (ins _.ScalarMemOp:$dst, VK1WM:$mask, _.FRC:$src),
3236               !strconcat(asm, "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}"),
3237               [], _.ExeDomain, IIC_SSE_MOV_S_MR>, EVEX, EVEX_K;
3238 }
3239
3240 defm VMOVSSZ : avx512_move_scalar<"vmovss", X86Movss, f32x_info>,
3241                                   VEX_LIG, XS, EVEX_CD8<32, CD8VT1>;
3242
3243 defm VMOVSDZ : avx512_move_scalar<"vmovsd", X86Movsd, f64x_info>,
3244                                   VEX_LIG, XD, VEX_W, EVEX_CD8<64, CD8VT1>;
3245
3246
3247 multiclass avx512_move_scalar_lowering<string InstrStr, SDNode OpNode,
3248                                        PatLeaf ZeroFP, X86VectorVTInfo _> {
3249
3250 def : Pat<(_.VT (OpNode _.RC:$src0,
3251                         (_.VT (scalar_to_vector
3252                                   (_.EltVT (X86selects (i1 (trunc GR32:$mask)),
3253                                                        (_.EltVT _.FRC:$src1),
3254                                                        (_.EltVT _.FRC:$src2))))))),
3255           (COPY_TO_REGCLASS (!cast<Instruction>(InstrStr#rrk)
3256                                           (COPY_TO_REGCLASS _.FRC:$src2, _.RC),
3257                                           (COPY_TO_REGCLASS GR32:$mask, VK1WM),
3258                                           (_.VT _.RC:$src0), _.FRC:$src1),
3259                             _.RC)>;
3260
3261 def : Pat<(_.VT (OpNode _.RC:$src0,
3262                         (_.VT (scalar_to_vector
3263                                   (_.EltVT (X86selects (i1 (trunc GR32:$mask)),
3264                                                        (_.EltVT _.FRC:$src1),
3265                                                        (_.EltVT ZeroFP))))))),
3266           (COPY_TO_REGCLASS (!cast<Instruction>(InstrStr#rrkz)
3267                                           (COPY_TO_REGCLASS GR32:$mask, VK1WM),
3268                                           (_.VT _.RC:$src0), _.FRC:$src1),
3269                             _.RC)>;
3270 }
3271
3272 multiclass avx512_store_scalar_lowering<string InstrStr, AVX512VLVectorVTInfo _,
3273                                         dag Mask, RegisterClass MaskRC> {
3274
3275 def : Pat<(masked_store addr:$dst, Mask,
3276              (_.info512.VT (insert_subvector undef,
3277                                (_.info256.VT (insert_subvector undef,
3278                                                  (_.info128.VT _.info128.RC:$src),
3279                                                  (iPTR 0))),
3280                                (iPTR 0)))),
3281           (!cast<Instruction>(InstrStr#mrk) addr:$dst,
3282                       (i1 (COPY_TO_REGCLASS MaskRC:$mask, VK1WM)),
3283                       (COPY_TO_REGCLASS _.info128.RC:$src, _.info128.FRC))>;
3284
3285 }
3286
3287 multiclass avx512_store_scalar_lowering_subreg<string InstrStr,
3288                                                AVX512VLVectorVTInfo _,
3289                                                dag Mask, RegisterClass MaskRC,
3290                                                SubRegIndex subreg> {
3291
3292 def : Pat<(masked_store addr:$dst, Mask,
3293              (_.info512.VT (insert_subvector undef,
3294                                (_.info256.VT (insert_subvector undef,
3295                                                  (_.info128.VT _.info128.RC:$src),
3296                                                  (iPTR 0))),
3297                                (iPTR 0)))),
3298           (!cast<Instruction>(InstrStr#mrk) addr:$dst,
3299                       (i1 (COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), MaskRC:$mask, subreg)), VK1WM)),
3300                       (COPY_TO_REGCLASS _.info128.RC:$src, _.info128.FRC))>;
3301
3302 }
3303
3304 multiclass avx512_load_scalar_lowering<string InstrStr, AVX512VLVectorVTInfo _,
3305                                        dag Mask, RegisterClass MaskRC> {
3306
3307 def : Pat<(_.info128.VT (extract_subvector
3308                          (_.info512.VT (masked_load addr:$srcAddr, Mask,
3309                                         (_.info512.VT (bitconvert
3310                                                        (v16i32 immAllZerosV))))),
3311                            (iPTR 0))),
3312           (!cast<Instruction>(InstrStr#rmkz)
3313                       (i1 (COPY_TO_REGCLASS MaskRC:$mask, VK1WM)),
3314                       addr:$srcAddr)>;
3315
3316 def : Pat<(_.info128.VT (extract_subvector
3317                 (_.info512.VT (masked_load addr:$srcAddr, Mask,
3318                       (_.info512.VT (insert_subvector undef,
3319                             (_.info256.VT (insert_subvector undef,
3320                                   (_.info128.VT (X86vzmovl _.info128.RC:$src)),
3321                                   (iPTR 0))),
3322                             (iPTR 0))))),
3323                 (iPTR 0))),
3324           (!cast<Instruction>(InstrStr#rmk) _.info128.RC:$src,
3325                       (i1 (COPY_TO_REGCLASS MaskRC:$mask, VK1WM)),
3326                       addr:$srcAddr)>;
3327
3328 }
3329
3330 multiclass avx512_load_scalar_lowering_subreg<string InstrStr,
3331                                               AVX512VLVectorVTInfo _,
3332                                               dag Mask, RegisterClass MaskRC,
3333                                               SubRegIndex subreg> {
3334
3335 def : Pat<(_.info128.VT (extract_subvector
3336                          (_.info512.VT (masked_load addr:$srcAddr, Mask,
3337                                         (_.info512.VT (bitconvert
3338                                                        (v16i32 immAllZerosV))))),
3339                            (iPTR 0))),
3340           (!cast<Instruction>(InstrStr#rmkz)
3341                       (i1 (COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), MaskRC:$mask, subreg)), VK1WM)),
3342                       addr:$srcAddr)>;
3343
3344 def : Pat<(_.info128.VT (extract_subvector
3345                 (_.info512.VT (masked_load addr:$srcAddr, Mask,
3346                       (_.info512.VT (insert_subvector undef,
3347                             (_.info256.VT (insert_subvector undef,
3348                                   (_.info128.VT (X86vzmovl _.info128.RC:$src)),
3349                                   (iPTR 0))),
3350                             (iPTR 0))))),
3351                 (iPTR 0))),
3352           (!cast<Instruction>(InstrStr#rmk) _.info128.RC:$src,
3353                       (i1 (COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), MaskRC:$mask, subreg)), VK1WM)),
3354                       addr:$srcAddr)>;
3355
3356 }
3357
3358 defm : avx512_move_scalar_lowering<"VMOVSSZ", X86Movss, fp32imm0, v4f32x_info>;
3359 defm : avx512_move_scalar_lowering<"VMOVSDZ", X86Movsd, fp64imm0, v2f64x_info>;
3360
3361 defm : avx512_store_scalar_lowering<"VMOVSSZ", avx512vl_f32_info,
3362                    (v16i1 (bitconvert (i16 (trunc (and GR32:$mask, (i32 1)))))), GR32>;
3363 defm : avx512_store_scalar_lowering_subreg<"VMOVSSZ", avx512vl_f32_info,
3364                    (v16i1 (bitconvert (i16 (and GR16:$mask, (i16 1))))), GR16, sub_16bit>;
3365 defm : avx512_store_scalar_lowering_subreg<"VMOVSDZ", avx512vl_f64_info,
3366                    (v8i1 (bitconvert (i8 (and GR8:$mask, (i8 1))))), GR8, sub_8bit>;
3367
3368 defm : avx512_load_scalar_lowering<"VMOVSSZ", avx512vl_f32_info,
3369                    (v16i1 (bitconvert (i16 (trunc (and GR32:$mask, (i32 1)))))), GR32>;
3370 defm : avx512_load_scalar_lowering_subreg<"VMOVSSZ", avx512vl_f32_info,
3371                    (v16i1 (bitconvert (i16 (and GR16:$mask, (i16 1))))), GR16, sub_16bit>;
3372 defm : avx512_load_scalar_lowering_subreg<"VMOVSDZ", avx512vl_f64_info,
3373                    (v8i1 (bitconvert (i8 (and GR8:$mask, (i8 1))))), GR8, sub_8bit>;
3374
3375 def : Pat<(f32 (X86selects VK1WM:$mask, (f32 FR32X:$src1), (f32 FR32X:$src2))),
3376           (COPY_TO_REGCLASS (VMOVSSZrrk (COPY_TO_REGCLASS FR32X:$src2, VR128X),
3377            VK1WM:$mask, (v4f32 (IMPLICIT_DEF)), FR32X:$src1), FR32X)>;
3378
3379 def : Pat<(f64 (X86selects VK1WM:$mask, (f64 FR64X:$src1), (f64 FR64X:$src2))),
3380           (COPY_TO_REGCLASS (VMOVSDZrrk (COPY_TO_REGCLASS FR64X:$src2, VR128X),
3381            VK1WM:$mask, (v2f64 (IMPLICIT_DEF)), FR64X:$src1), FR64X)>;
3382
3383 def : Pat<(int_x86_avx512_mask_store_ss addr:$dst, VR128X:$src, GR8:$mask),
3384           (VMOVSSZmrk addr:$dst, (i1 (COPY_TO_REGCLASS (i32 (INSERT_SUBREG (IMPLICIT_DEF), GR8:$mask, sub_8bit)), VK1WM)),
3385            (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
3386
3387 let hasSideEffects = 0 in
3388 defm VMOVSSZrr_REV : AVX512_maskable_in_asm<0x11, MRMDestReg, f32x_info,
3389                            (outs VR128X:$dst), (ins VR128X:$src1, FR32X:$src2),
3390                            "vmovss.s", "$src2, $src1", "$src1, $src2", []>,
3391                            XS, EVEX_4V, VEX_LIG;
3392
3393 let hasSideEffects = 0 in
3394 defm VMOVSDZrr_REV : AVX512_maskable_in_asm<0x11, MRMDestReg, f64x_info,
3395                            (outs VR128X:$dst), (ins VR128X:$src1, FR64X:$src2),
3396                            "vmovsd.s", "$src2, $src1", "$src1, $src2", []>,
3397                            XD, EVEX_4V, VEX_LIG, VEX_W;
3398
3399 let Predicates = [HasAVX512] in {
3400   let AddedComplexity = 15 in {
3401   // Move scalar to XMM zero-extended, zeroing a VR128X then do a
3402   // MOVS{S,D} to the lower bits.
3403   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32X:$src)))),
3404             (VMOVSSZrr (v4f32 (AVX512_128_SET0)), FR32X:$src)>;
3405   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128X:$src))),
3406             (VMOVSSZrr (v4f32 (AVX512_128_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
3407   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128X:$src))),
3408             (VMOVSSZrr (v4i32 (AVX512_128_SET0)), (COPY_TO_REGCLASS VR128X:$src, FR32X))>;
3409   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64X:$src)))),
3410             (VMOVSDZrr (v2f64 (AVX512_128_SET0)), FR64X:$src)>;
3411   }
3412
3413   // Move low f32 and clear high bits.
3414   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256X:$src))),
3415             (SUBREG_TO_REG (i32 0),
3416              (VMOVSSZrr (v4f32 (AVX512_128_SET0)),
3417               (EXTRACT_SUBREG (v8f32 VR256X:$src), sub_xmm)), sub_xmm)>;
3418   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256X:$src))),
3419             (SUBREG_TO_REG (i32 0),
3420              (VMOVSSZrr (v4i32 (AVX512_128_SET0)),
3421               (EXTRACT_SUBREG (v8i32 VR256X:$src), sub_xmm)), sub_xmm)>;
3422   def : Pat<(v16f32 (X86vzmovl (v16f32 VR512:$src))),
3423             (SUBREG_TO_REG (i32 0),
3424              (VMOVSSZrr (v4f32 (AVX512_128_SET0)),
3425               (EXTRACT_SUBREG (v16f32 VR512:$src), sub_xmm)), sub_xmm)>;
3426   def : Pat<(v16i32 (X86vzmovl (v16i32 VR512:$src))),
3427             (SUBREG_TO_REG (i32 0),
3428              (VMOVSSZrr (v4i32 (AVX512_128_SET0)),
3429               (EXTRACT_SUBREG (v16i32 VR512:$src), sub_xmm)), sub_xmm)>;
3430
3431   let AddedComplexity = 20 in {
3432   // MOVSSrm zeros the high parts of the register; represent this
3433   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
3434   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
3435             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3436   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
3437             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3438   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
3439             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3440   def : Pat<(v4f32 (X86vzload addr:$src)),
3441             (COPY_TO_REGCLASS (VMOVSSZrm addr:$src), VR128X)>;
3442
3443   // MOVSDrm zeros the high parts of the register; represent this
3444   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
3445   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
3446             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3447   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
3448             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3449   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
3450             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3451   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
3452             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3453   def : Pat<(v2f64 (X86vzload addr:$src)),
3454             (COPY_TO_REGCLASS (VMOVSDZrm addr:$src), VR128X)>;
3455
3456   // Represent the same patterns above but in the form they appear for
3457   // 256-bit types
3458   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
3459                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
3460             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3461   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
3462                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
3463             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3464   def : Pat<(v8f32 (X86vzload addr:$src)),
3465             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3466   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
3467                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
3468             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3469   def : Pat<(v4f64 (X86vzload addr:$src)),
3470             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3471
3472   // Represent the same patterns above but in the form they appear for
3473   // 512-bit types
3474   def : Pat<(v16i32 (X86vzmovl (insert_subvector undef,
3475                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
3476             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3477   def : Pat<(v16f32 (X86vzmovl (insert_subvector undef,
3478                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
3479             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3480   def : Pat<(v16f32 (X86vzload addr:$src)),
3481             (SUBREG_TO_REG (i32 0), (VMOVSSZrm addr:$src), sub_xmm)>;
3482   def : Pat<(v8f64 (X86vzmovl (insert_subvector undef,
3483                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
3484             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3485   def : Pat<(v8f64 (X86vzload addr:$src)),
3486             (SUBREG_TO_REG (i32 0), (VMOVSDZrm addr:$src), sub_xmm)>;
3487   }
3488   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
3489                    (v4f32 (scalar_to_vector FR32X:$src)), (iPTR 0)))),
3490             (SUBREG_TO_REG (i32 0), (v4f32 (VMOVSSZrr (v4f32 (AVX512_128_SET0)),
3491                                             FR32X:$src)), sub_xmm)>;
3492   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
3493                    (v2f64 (scalar_to_vector FR64X:$src)), (iPTR 0)))),
3494             (SUBREG_TO_REG (i64 0), (v2f64 (VMOVSDZrr (v2f64 (AVX512_128_SET0)),
3495                                      FR64X:$src)), sub_xmm)>;
3496   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
3497                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
3498             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
3499
3500   // Move low f64 and clear high bits.
3501   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256X:$src))),
3502             (SUBREG_TO_REG (i32 0),
3503              (VMOVSDZrr (v2f64 (AVX512_128_SET0)),
3504                        (EXTRACT_SUBREG (v4f64 VR256X:$src), sub_xmm)), sub_xmm)>;
3505   def : Pat<(v8f64 (X86vzmovl (v8f64 VR512:$src))),
3506             (SUBREG_TO_REG (i32 0),
3507              (VMOVSDZrr (v2f64 (AVX512_128_SET0)),
3508                        (EXTRACT_SUBREG (v8f64 VR512:$src), sub_xmm)), sub_xmm)>;
3509
3510   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256X:$src))),
3511             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (AVX512_128_SET0)),
3512                        (EXTRACT_SUBREG (v4i64 VR256X:$src), sub_xmm)), sub_xmm)>;
3513   def : Pat<(v8i64 (X86vzmovl (v8i64 VR512:$src))),
3514             (SUBREG_TO_REG (i32 0), (VMOVSDZrr (v2i64 (AVX512_128_SET0)),
3515                        (EXTRACT_SUBREG (v8i64 VR512:$src), sub_xmm)), sub_xmm)>;
3516
3517   // Extract and store.
3518   def : Pat<(store (f32 (extractelt (v4f32 VR128X:$src), (iPTR 0))),
3519                    addr:$dst),
3520             (VMOVSSZmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128X:$src), FR32X))>;
3521
3522   // Shuffle with VMOVSS
3523   def : Pat<(v4i32 (X86Movss VR128X:$src1, VR128X:$src2)),
3524             (VMOVSSZrr (v4i32 VR128X:$src1),
3525                       (COPY_TO_REGCLASS (v4i32 VR128X:$src2), FR32X))>;
3526   def : Pat<(v4f32 (X86Movss VR128X:$src1, VR128X:$src2)),
3527             (VMOVSSZrr (v4f32 VR128X:$src1),
3528                       (COPY_TO_REGCLASS (v4f32 VR128X:$src2), FR32X))>;
3529
3530   // 256-bit variants
3531   def : Pat<(v8i32 (X86Movss VR256X:$src1, VR256X:$src2)),
3532             (SUBREG_TO_REG (i32 0),
3533               (VMOVSSZrr (EXTRACT_SUBREG (v8i32 VR256X:$src1), sub_xmm),
3534                         (EXTRACT_SUBREG (v8i32 VR256X:$src2), sub_xmm)),
3535               sub_xmm)>;
3536   def : Pat<(v8f32 (X86Movss VR256X:$src1, VR256X:$src2)),
3537             (SUBREG_TO_REG (i32 0),
3538               (VMOVSSZrr (EXTRACT_SUBREG (v8f32 VR256X:$src1), sub_xmm),
3539                         (EXTRACT_SUBREG (v8f32 VR256X:$src2), sub_xmm)),
3540               sub_xmm)>;
3541
3542   // Shuffle with VMOVSD
3543   def : Pat<(v2i64 (X86Movsd VR128X:$src1, VR128X:$src2)),
3544             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3545   def : Pat<(v2f64 (X86Movsd VR128X:$src1, VR128X:$src2)),
3546             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3547
3548   // 256-bit variants
3549   def : Pat<(v4i64 (X86Movsd VR256X:$src1, VR256X:$src2)),
3550             (SUBREG_TO_REG (i32 0),
3551               (VMOVSDZrr (EXTRACT_SUBREG (v4i64 VR256X:$src1), sub_xmm),
3552                         (EXTRACT_SUBREG (v4i64 VR256X:$src2), sub_xmm)),
3553               sub_xmm)>;
3554   def : Pat<(v4f64 (X86Movsd VR256X:$src1, VR256X:$src2)),
3555             (SUBREG_TO_REG (i32 0),
3556               (VMOVSDZrr (EXTRACT_SUBREG (v4f64 VR256X:$src1), sub_xmm),
3557                         (EXTRACT_SUBREG (v4f64 VR256X:$src2), sub_xmm)),
3558               sub_xmm)>;
3559
3560   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
3561             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3562   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, VR128X:$src2)),
3563             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3564   def : Pat<(v4f32 (X86Movlps VR128X:$src1, VR128X:$src2)),
3565             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3566   def : Pat<(v4i32 (X86Movlps VR128X:$src1, VR128X:$src2)),
3567             (VMOVSDZrr VR128X:$src1, (COPY_TO_REGCLASS VR128X:$src2, FR64X))>;
3568 }
3569
3570 let AddedComplexity = 15 in
3571 def VMOVZPQILo2PQIZrr : AVX512XSI<0x7E, MRMSrcReg, (outs VR128X:$dst),
3572                                 (ins VR128X:$src),
3573                                 "vmovq\t{$src, $dst|$dst, $src}",
3574                                 [(set VR128X:$dst, (v2i64 (X86vzmovl
3575                                                    (v2i64 VR128X:$src))))],
3576                                 IIC_SSE_MOVQ_RR>, EVEX, VEX_W;
3577
3578 let Predicates = [HasAVX512] in {
3579   let AddedComplexity = 15 in {
3580     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
3581               (VMOVDI2PDIZrr GR32:$src)>;
3582
3583     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
3584               (VMOV64toPQIZrr GR64:$src)>;
3585
3586     def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
3587                                  (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
3588               (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
3589
3590     def : Pat<(v8i64 (X86vzmovl (insert_subvector undef,
3591                                  (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
3592               (SUBREG_TO_REG (i64 0), (VMOV64toPQIZrr GR64:$src), sub_xmm)>;
3593   }
3594   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
3595   let AddedComplexity = 20 in {
3596     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (zextloadi64i32 addr:$src))))),
3597               (VMOVDI2PDIZrm addr:$src)>;
3598     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
3599               (VMOVDI2PDIZrm addr:$src)>;
3600     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
3601               (VMOVDI2PDIZrm addr:$src)>;
3602     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
3603               (VMOVDI2PDIZrm addr:$src)>;
3604     def : Pat<(v4i32 (X86vzload addr:$src)),
3605               (VMOVDI2PDIZrm addr:$src)>;
3606     def : Pat<(v8i32 (X86vzload addr:$src)),
3607               (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3608     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
3609               (VMOVQI2PQIZrm addr:$src)>;
3610     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128X:$src))),
3611               (VMOVZPQILo2PQIZrr VR128X:$src)>;
3612     def : Pat<(v2i64 (X86vzload addr:$src)),
3613               (VMOVQI2PQIZrm addr:$src)>;
3614     def : Pat<(v4i64 (X86vzload addr:$src)),
3615               (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
3616   }
3617
3618   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
3619   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
3620                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
3621             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
3622   def : Pat<(v16i32 (X86vzmovl (insert_subvector undef,
3623                                 (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
3624             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrr GR32:$src), sub_xmm)>;
3625
3626   // Use regular 128-bit instructions to match 512-bit scalar_to_vec+zext.
3627   def : Pat<(v16i32 (X86vzload addr:$src)),
3628             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIZrm addr:$src), sub_xmm)>;
3629   def : Pat<(v8i64 (X86vzload addr:$src)),
3630             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIZrm addr:$src), sub_xmm)>;
3631 }
3632 //===----------------------------------------------------------------------===//
3633 // AVX-512 - Non-temporals
3634 //===----------------------------------------------------------------------===//
3635 let SchedRW = [WriteLoad] in {
3636   def VMOVNTDQAZrm : AVX512PI<0x2A, MRMSrcMem, (outs VR512:$dst),
3637                         (ins i512mem:$src), "vmovntdqa\t{$src, $dst|$dst, $src}",
3638                         [], SSEPackedInt>, EVEX, T8PD, EVEX_V512,
3639                         EVEX_CD8<64, CD8VF>;
3640
3641   let Predicates = [HasVLX] in {
3642     def VMOVNTDQAZ256rm : AVX512PI<0x2A, MRMSrcMem, (outs VR256X:$dst),
3643                          (ins i256mem:$src),
3644                          "vmovntdqa\t{$src, $dst|$dst, $src}",
3645                          [], SSEPackedInt>, EVEX, T8PD, EVEX_V256,
3646                          EVEX_CD8<64, CD8VF>;
3647
3648     def VMOVNTDQAZ128rm : AVX512PI<0x2A, MRMSrcMem, (outs VR128X:$dst),
3649                         (ins i128mem:$src),
3650                         "vmovntdqa\t{$src, $dst|$dst, $src}",
3651                         [], SSEPackedInt>, EVEX, T8PD, EVEX_V128,
3652                         EVEX_CD8<64, CD8VF>;
3653   }
3654 }
3655
3656 multiclass avx512_movnt<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
3657                         PatFrag st_frag = alignednontemporalstore,
3658                         InstrItinClass itin = IIC_SSE_MOVNT> {
3659   let SchedRW = [WriteStore], AddedComplexity = 400 in
3660   def mr : AVX512PI<opc, MRMDestMem, (outs), (ins _.MemOp:$dst, _.RC:$src),
3661                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3662                     [(st_frag (_.VT _.RC:$src), addr:$dst)],
3663                     _.ExeDomain, itin>, EVEX, EVEX_CD8<_.EltSize, CD8VF>;
3664 }
3665
3666 multiclass avx512_movnt_vl<bits<8> opc, string OpcodeStr,
3667                                                   AVX512VLVectorVTInfo VTInfo> {
3668   let Predicates = [HasAVX512] in
3669     defm Z : avx512_movnt<opc, OpcodeStr, VTInfo.info512>, EVEX_V512;
3670
3671   let Predicates = [HasAVX512, HasVLX] in {
3672     defm Z256 : avx512_movnt<opc, OpcodeStr, VTInfo.info256>, EVEX_V256;
3673     defm Z128 : avx512_movnt<opc, OpcodeStr, VTInfo.info128>, EVEX_V128;
3674   }
3675 }
3676
3677 defm VMOVNTDQ : avx512_movnt_vl<0xE7, "vmovntdq", avx512vl_i64_info>, PD;
3678 defm VMOVNTPD : avx512_movnt_vl<0x2B, "vmovntpd", avx512vl_f64_info>, PD, VEX_W;
3679 defm VMOVNTPS : avx512_movnt_vl<0x2B, "vmovntps", avx512vl_f32_info>, PS;
3680
3681 let Predicates = [HasAVX512], AddedComplexity = 400 in {
3682   def : Pat<(alignednontemporalstore (v16i32 VR512:$src), addr:$dst),
3683             (VMOVNTDQZmr addr:$dst, VR512:$src)>;
3684   def : Pat<(alignednontemporalstore (v32i16 VR512:$src), addr:$dst),
3685             (VMOVNTDQZmr addr:$dst, VR512:$src)>;
3686   def : Pat<(alignednontemporalstore (v64i8 VR512:$src), addr:$dst),
3687             (VMOVNTDQZmr addr:$dst, VR512:$src)>;
3688
3689   def : Pat<(v8f64 (alignednontemporalload addr:$src)),
3690             (VMOVNTDQAZrm addr:$src)>;
3691   def : Pat<(v16f32 (alignednontemporalload addr:$src)),
3692             (VMOVNTDQAZrm addr:$src)>;
3693   def : Pat<(v8i64 (alignednontemporalload addr:$src)),
3694             (VMOVNTDQAZrm addr:$src)>;
3695   def : Pat<(v16i32 (bitconvert (v8i64 (alignednontemporalload addr:$src)))),
3696             (VMOVNTDQAZrm addr:$src)>;
3697   def : Pat<(v32i16 (bitconvert (v8i64 (alignednontemporalload addr:$src)))),
3698             (VMOVNTDQAZrm addr:$src)>;
3699   def : Pat<(v64i8 (bitconvert (v8i64 (alignednontemporalload addr:$src)))),
3700             (VMOVNTDQAZrm addr:$src)>;
3701 }
3702
3703 let Predicates = [HasVLX], AddedComplexity = 400 in {
3704   def : Pat<(alignednontemporalstore (v8i32 VR256X:$src), addr:$dst),
3705             (VMOVNTDQZ256mr addr:$dst, VR256X:$src)>;
3706   def : Pat<(alignednontemporalstore (v16i16 VR256X:$src), addr:$dst),
3707             (VMOVNTDQZ256mr addr:$dst, VR256X:$src)>;
3708   def : Pat<(alignednontemporalstore (v32i8 VR256X:$src), addr:$dst),
3709             (VMOVNTDQZ256mr addr:$dst, VR256X:$src)>;
3710
3711   def : Pat<(v4f64 (alignednontemporalload addr:$src)),
3712             (VMOVNTDQAZ256rm addr:$src)>;
3713   def : Pat<(v8f32 (alignednontemporalload addr:$src)),
3714             (VMOVNTDQAZ256rm addr:$src)>;
3715   def : Pat<(v4i64 (alignednontemporalload addr:$src)),
3716             (VMOVNTDQAZ256rm addr:$src)>;
3717   def : Pat<(v8i32 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3718             (VMOVNTDQAZ256rm addr:$src)>;
3719   def : Pat<(v16i16 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3720             (VMOVNTDQAZ256rm addr:$src)>;
3721   def : Pat<(v32i8 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3722             (VMOVNTDQAZ256rm addr:$src)>;
3723
3724   def : Pat<(alignednontemporalstore (v4i32 VR128X:$src), addr:$dst),
3725             (VMOVNTDQZ128mr addr:$dst, VR128X:$src)>;
3726   def : Pat<(alignednontemporalstore (v8i16 VR128X:$src), addr:$dst),
3727             (VMOVNTDQZ128mr addr:$dst, VR128X:$src)>;
3728   def : Pat<(alignednontemporalstore (v16i8 VR128X:$src), addr:$dst),
3729             (VMOVNTDQZ128mr addr:$dst, VR128X:$src)>;
3730
3731   def : Pat<(v2f64 (alignednontemporalload addr:$src)),
3732             (VMOVNTDQAZ128rm addr:$src)>;
3733   def : Pat<(v4f32 (alignednontemporalload addr:$src)),
3734             (VMOVNTDQAZ128rm addr:$src)>;
3735   def : Pat<(v2i64 (alignednontemporalload addr:$src)),
3736             (VMOVNTDQAZ128rm addr:$src)>;
3737   def : Pat<(v4i32 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3738             (VMOVNTDQAZ128rm addr:$src)>;
3739   def : Pat<(v8i16 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3740             (VMOVNTDQAZ128rm addr:$src)>;
3741   def : Pat<(v16i8 (bitconvert (v2i64 (alignednontemporalload addr:$src)))),
3742             (VMOVNTDQAZ128rm addr:$src)>;
3743 }
3744
3745 //===----------------------------------------------------------------------===//
3746 // AVX-512 - Integer arithmetic
3747 //
3748 multiclass avx512_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3749                            X86VectorVTInfo _, OpndItins itins,
3750                            bit IsCommutable = 0> {
3751   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
3752                     (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
3753                     "$src2, $src1", "$src1, $src2",
3754                     (_.VT (OpNode _.RC:$src1, _.RC:$src2)),
3755                     itins.rr, IsCommutable>,
3756             AVX512BIBase, EVEX_4V;
3757
3758   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3759                   (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
3760                   "$src2, $src1", "$src1, $src2",
3761                   (_.VT (OpNode _.RC:$src1,
3762                                 (bitconvert (_.LdFrag addr:$src2)))),
3763                   itins.rm>,
3764             AVX512BIBase, EVEX_4V;
3765 }
3766
3767 multiclass avx512_binop_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3768                             X86VectorVTInfo _, OpndItins itins,
3769                             bit IsCommutable = 0> :
3770            avx512_binop_rm<opc, OpcodeStr, OpNode, _, itins, IsCommutable> {
3771   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
3772                   (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
3773                   "${src2}"##_.BroadcastStr##", $src1",
3774                   "$src1, ${src2}"##_.BroadcastStr,
3775                   (_.VT (OpNode _.RC:$src1,
3776                                 (X86VBroadcast
3777                                     (_.ScalarLdFrag addr:$src2)))),
3778                   itins.rm>,
3779              AVX512BIBase, EVEX_4V, EVEX_B;
3780 }
3781
3782 multiclass avx512_binop_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
3783                               AVX512VLVectorVTInfo VTInfo, OpndItins itins,
3784                               Predicate prd, bit IsCommutable = 0> {
3785   let Predicates = [prd] in
3786     defm Z : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
3787                              IsCommutable>, EVEX_V512;
3788
3789   let Predicates = [prd, HasVLX] in {
3790     defm Z256 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
3791                              IsCommutable>, EVEX_V256;
3792     defm Z128 : avx512_binop_rm<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
3793                              IsCommutable>, EVEX_V128;
3794   }
3795 }
3796
3797 multiclass avx512_binop_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
3798                                AVX512VLVectorVTInfo VTInfo, OpndItins itins,
3799                                Predicate prd, bit IsCommutable = 0> {
3800   let Predicates = [prd] in
3801     defm Z : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info512, itins,
3802                              IsCommutable>, EVEX_V512;
3803
3804   let Predicates = [prd, HasVLX] in {
3805     defm Z256 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info256, itins,
3806                              IsCommutable>, EVEX_V256;
3807     defm Z128 : avx512_binop_rmb<opc, OpcodeStr, OpNode, VTInfo.info128, itins,
3808                              IsCommutable>, EVEX_V128;
3809   }
3810 }
3811
3812 multiclass avx512_binop_rm_vl_q<bits<8> opc, string OpcodeStr, SDNode OpNode,
3813                                 OpndItins itins, Predicate prd,
3814                                 bit IsCommutable = 0> {
3815   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i64_info,
3816                                itins, prd, IsCommutable>,
3817                                VEX_W, EVEX_CD8<64, CD8VF>;
3818 }
3819
3820 multiclass avx512_binop_rm_vl_d<bits<8> opc, string OpcodeStr, SDNode OpNode,
3821                                 OpndItins itins, Predicate prd,
3822                                 bit IsCommutable = 0> {
3823   defm NAME : avx512_binop_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i32_info,
3824                                itins, prd, IsCommutable>, EVEX_CD8<32, CD8VF>;
3825 }
3826
3827 multiclass avx512_binop_rm_vl_w<bits<8> opc, string OpcodeStr, SDNode OpNode,
3828                                 OpndItins itins, Predicate prd,
3829                                 bit IsCommutable = 0> {
3830   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i16_info,
3831                               itins, prd, IsCommutable>, EVEX_CD8<16, CD8VF>;
3832 }
3833
3834 multiclass avx512_binop_rm_vl_b<bits<8> opc, string OpcodeStr, SDNode OpNode,
3835                                 OpndItins itins, Predicate prd,
3836                                 bit IsCommutable = 0> {
3837   defm NAME : avx512_binop_rm_vl<opc, OpcodeStr, OpNode, avx512vl_i8_info,
3838                               itins, prd, IsCommutable>, EVEX_CD8<8, CD8VF>;
3839 }
3840
3841 multiclass avx512_binop_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
3842                                  SDNode OpNode, OpndItins itins, Predicate prd,
3843                                  bit IsCommutable = 0> {
3844   defm Q : avx512_binop_rm_vl_q<opc_q, OpcodeStr#"q", OpNode, itins, prd,
3845                                    IsCommutable>;
3846
3847   defm D : avx512_binop_rm_vl_d<opc_d, OpcodeStr#"d", OpNode, itins, prd,
3848                                    IsCommutable>;
3849 }
3850
3851 multiclass avx512_binop_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
3852                                  SDNode OpNode, OpndItins itins, Predicate prd,
3853                                  bit IsCommutable = 0> {
3854   defm W : avx512_binop_rm_vl_w<opc_w, OpcodeStr#"w", OpNode, itins, prd,
3855                                    IsCommutable>;
3856
3857   defm B : avx512_binop_rm_vl_b<opc_b, OpcodeStr#"b", OpNode, itins, prd,
3858                                    IsCommutable>;
3859 }
3860
3861 multiclass avx512_binop_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
3862                                   bits<8> opc_d, bits<8> opc_q,
3863                                   string OpcodeStr, SDNode OpNode,
3864                                   OpndItins itins, bit IsCommutable = 0> {
3865   defm NAME : avx512_binop_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
3866                                     itins, HasAVX512, IsCommutable>,
3867               avx512_binop_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
3868                                     itins, HasBWI, IsCommutable>;
3869 }
3870
3871 multiclass avx512_binop_rm2<bits<8> opc, string OpcodeStr, OpndItins itins,
3872                             SDNode OpNode,X86VectorVTInfo _Src,
3873                             X86VectorVTInfo _Dst, X86VectorVTInfo _Brdct,
3874                             bit IsCommutable = 0> {
3875   defm rr : AVX512_maskable<opc, MRMSrcReg, _Dst, (outs _Dst.RC:$dst),
3876                             (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
3877                             "$src2, $src1","$src1, $src2",
3878                             (_Dst.VT (OpNode
3879                                          (_Src.VT _Src.RC:$src1),
3880                                          (_Src.VT _Src.RC:$src2))),
3881                             itins.rr, IsCommutable>,
3882                             AVX512BIBase, EVEX_4V;
3883   defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3884                         (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr,
3885                         "$src2, $src1", "$src1, $src2",
3886                         (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1),
3887                                       (bitconvert (_Src.LdFrag addr:$src2)))),
3888                         itins.rm>,
3889                         AVX512BIBase, EVEX_4V;
3890
3891   defm rmb : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3892                     (ins _Src.RC:$src1, _Brdct.ScalarMemOp:$src2),
3893                     OpcodeStr,
3894                     "${src2}"##_Brdct.BroadcastStr##", $src1",
3895                      "$src1, ${src2}"##_Brdct.BroadcastStr,
3896                     (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1), (bitconvert
3897                                  (_Brdct.VT (X86VBroadcast
3898                                           (_Brdct.ScalarLdFrag addr:$src2)))))),
3899                     itins.rm>,
3900                     AVX512BIBase, EVEX_4V, EVEX_B;
3901 }
3902
3903 defm VPADD : avx512_binop_rm_vl_all<0xFC, 0xFD, 0xFE, 0xD4, "vpadd", add,
3904                                     SSE_INTALU_ITINS_P, 1>;
3905 defm VPSUB : avx512_binop_rm_vl_all<0xF8, 0xF9, 0xFA, 0xFB, "vpsub", sub,
3906                                     SSE_INTALU_ITINS_P, 0>;
3907 defm VPADDS : avx512_binop_rm_vl_bw<0xEC, 0xED, "vpadds", X86adds,
3908                                     SSE_INTALU_ITINS_P, HasBWI, 1>;
3909 defm VPSUBS : avx512_binop_rm_vl_bw<0xE8, 0xE9, "vpsubs", X86subs,
3910                                     SSE_INTALU_ITINS_P, HasBWI, 0>;
3911 defm VPADDUS : avx512_binop_rm_vl_bw<0xDC, 0xDD, "vpaddus", X86addus,
3912                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
3913 defm VPSUBUS : avx512_binop_rm_vl_bw<0xD8, 0xD9, "vpsubus", X86subus,
3914                                      SSE_INTALU_ITINS_P, HasBWI, 0>;
3915 defm VPMULLD : avx512_binop_rm_vl_d<0x40, "vpmulld", mul,
3916                                     SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
3917 defm VPMULLW : avx512_binop_rm_vl_w<0xD5, "vpmullw", mul,
3918                                     SSE_INTALU_ITINS_P, HasBWI, 1>;
3919 defm VPMULLQ : avx512_binop_rm_vl_q<0x40, "vpmullq", mul,
3920                                     SSE_INTALU_ITINS_P, HasDQI, 1>, T8PD;
3921 defm VPMULHW : avx512_binop_rm_vl_w<0xE5, "vpmulhw", mulhs, SSE_INTALU_ITINS_P,
3922                                     HasBWI, 1>;
3923 defm VPMULHUW : avx512_binop_rm_vl_w<0xE4, "vpmulhuw", mulhu, SSE_INTMUL_ITINS_P,
3924                                      HasBWI, 1>;
3925 defm VPMULHRSW : avx512_binop_rm_vl_w<0x0B, "vpmulhrsw", X86mulhrs, SSE_INTMUL_ITINS_P,
3926                                       HasBWI, 1>, T8PD;
3927 defm VPAVG : avx512_binop_rm_vl_bw<0xE0, 0xE3, "vpavg", X86avg,
3928                                    SSE_INTALU_ITINS_P, HasBWI, 1>;
3929
3930 multiclass avx512_binop_all<bits<8> opc, string OpcodeStr, OpndItins itins,
3931                             AVX512VLVectorVTInfo _SrcVTInfo, AVX512VLVectorVTInfo _DstVTInfo,
3932                             SDNode OpNode, Predicate prd,  bit IsCommutable = 0> {
3933   let Predicates = [prd] in
3934     defm NAME#Z : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3935                                  _SrcVTInfo.info512, _DstVTInfo.info512,
3936                                  v8i64_info, IsCommutable>,
3937                                   EVEX_V512, EVEX_CD8<64, CD8VF>, VEX_W;
3938   let Predicates = [HasVLX, prd] in {
3939     defm NAME#Z256 : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3940                                       _SrcVTInfo.info256, _DstVTInfo.info256,
3941                                       v4i64x_info, IsCommutable>,
3942                                       EVEX_V256, EVEX_CD8<64, CD8VF>, VEX_W;
3943     defm NAME#Z128 : avx512_binop_rm2<opc, OpcodeStr, itins, OpNode,
3944                                       _SrcVTInfo.info128, _DstVTInfo.info128,
3945                                       v2i64x_info, IsCommutable>,
3946                                      EVEX_V128, EVEX_CD8<64, CD8VF>, VEX_W;
3947   }
3948 }
3949
3950 defm VPMULDQ : avx512_binop_all<0x28, "vpmuldq", SSE_INTALU_ITINS_P,
3951                                 avx512vl_i32_info, avx512vl_i64_info,
3952                                 X86pmuldq, HasAVX512, 1>,T8PD;
3953 defm VPMULUDQ : avx512_binop_all<0xF4, "vpmuludq", SSE_INTMUL_ITINS_P,
3954                                 avx512vl_i32_info, avx512vl_i64_info,
3955                                 X86pmuludq, HasAVX512, 1>;
3956 defm VPMULTISHIFTQB : avx512_binop_all<0x83, "vpmultishiftqb", SSE_INTALU_ITINS_P,
3957                                 avx512vl_i8_info, avx512vl_i8_info,
3958                                 X86multishift, HasVBMI, 0>, T8PD;
3959
3960 multiclass avx512_packs_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
3961                             X86VectorVTInfo _Src, X86VectorVTInfo _Dst> {
3962   defm rmb : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3963                     (ins _Src.RC:$src1, _Src.ScalarMemOp:$src2),
3964                     OpcodeStr,
3965                     "${src2}"##_Src.BroadcastStr##", $src1",
3966                      "$src1, ${src2}"##_Src.BroadcastStr,
3967                     (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1), (bitconvert
3968                                  (_Src.VT (X86VBroadcast
3969                                           (_Src.ScalarLdFrag addr:$src2))))))>,
3970                     EVEX_4V, EVEX_B, EVEX_CD8<_Src.EltSize, CD8VF>;
3971 }
3972
3973 multiclass avx512_packs_rm<bits<8> opc, string OpcodeStr,
3974                             SDNode OpNode,X86VectorVTInfo _Src,
3975                             X86VectorVTInfo _Dst, bit IsCommutable = 0> {
3976   defm rr : AVX512_maskable<opc, MRMSrcReg, _Dst, (outs _Dst.RC:$dst),
3977                             (ins _Src.RC:$src1, _Src.RC:$src2), OpcodeStr,
3978                             "$src2, $src1","$src1, $src2",
3979                             (_Dst.VT (OpNode
3980                                          (_Src.VT _Src.RC:$src1),
3981                                          (_Src.VT _Src.RC:$src2))),
3982                             NoItinerary, IsCommutable>,
3983                             EVEX_CD8<_Src.EltSize, CD8VF>, EVEX_4V;
3984   defm rm : AVX512_maskable<opc, MRMSrcMem, _Dst, (outs _Dst.RC:$dst),
3985                         (ins _Src.RC:$src1, _Src.MemOp:$src2), OpcodeStr,
3986                         "$src2, $src1", "$src1, $src2",
3987                         (_Dst.VT (OpNode (_Src.VT _Src.RC:$src1),
3988                                       (bitconvert (_Src.LdFrag addr:$src2))))>,
3989                          EVEX_4V, EVEX_CD8<_Src.EltSize, CD8VF>;
3990 }
3991
3992 multiclass avx512_packs_all_i32_i16<bits<8> opc, string OpcodeStr,
3993                                     SDNode OpNode> {
3994   let Predicates = [HasBWI] in
3995   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, v16i32_info,
3996                                  v32i16_info>,
3997                 avx512_packs_rmb<opc, OpcodeStr, OpNode, v16i32_info,
3998                                  v32i16_info>, EVEX_V512;
3999   let Predicates = [HasBWI, HasVLX] in {
4000     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, v8i32x_info,
4001                                      v16i16x_info>,
4002                      avx512_packs_rmb<opc, OpcodeStr, OpNode, v8i32x_info,
4003                                      v16i16x_info>, EVEX_V256;
4004     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, v4i32x_info,
4005                                      v8i16x_info>,
4006                      avx512_packs_rmb<opc, OpcodeStr, OpNode, v4i32x_info,
4007                                      v8i16x_info>, EVEX_V128;
4008   }
4009 }
4010 multiclass avx512_packs_all_i16_i8<bits<8> opc, string OpcodeStr,
4011                             SDNode OpNode> {
4012   let Predicates = [HasBWI] in
4013   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, v32i16_info,
4014                                 v64i8_info>, EVEX_V512;
4015   let Predicates = [HasBWI, HasVLX] in {
4016     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, v16i16x_info,
4017                                     v32i8x_info>, EVEX_V256;
4018     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, v8i16x_info,
4019                                     v16i8x_info>, EVEX_V128;
4020   }
4021 }
4022
4023 multiclass avx512_vpmadd<bits<8> opc, string OpcodeStr,
4024                             SDNode OpNode, AVX512VLVectorVTInfo _Src,
4025                             AVX512VLVectorVTInfo _Dst, bit IsCommutable = 0> {
4026   let Predicates = [HasBWI] in
4027   defm NAME#Z : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info512,
4028                                 _Dst.info512, IsCommutable>, EVEX_V512;
4029   let Predicates = [HasBWI, HasVLX] in {
4030     defm NAME#Z256 : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info256,
4031                                      _Dst.info256, IsCommutable>, EVEX_V256;
4032     defm NAME#Z128 : avx512_packs_rm<opc, OpcodeStr, OpNode, _Src.info128,
4033                                      _Dst.info128, IsCommutable>, EVEX_V128;
4034   }
4035 }
4036
4037 defm VPACKSSDW : avx512_packs_all_i32_i16<0x6B, "vpackssdw", X86Packss>, AVX512BIBase;
4038 defm VPACKUSDW : avx512_packs_all_i32_i16<0x2b, "vpackusdw", X86Packus>, AVX5128IBase;
4039 defm VPACKSSWB : avx512_packs_all_i16_i8 <0x63, "vpacksswb", X86Packss>, AVX512BIBase;
4040 defm VPACKUSWB : avx512_packs_all_i16_i8 <0x67, "vpackuswb", X86Packus>, AVX512BIBase;
4041
4042 defm VPMADDUBSW : avx512_vpmadd<0x04, "vpmaddubsw", X86vpmaddubsw,
4043                      avx512vl_i8_info, avx512vl_i16_info>, AVX512BIBase, T8PD;
4044 defm VPMADDWD   : avx512_vpmadd<0xF5, "vpmaddwd", X86vpmaddwd,
4045                      avx512vl_i16_info, avx512vl_i32_info, 1>, AVX512BIBase;
4046
4047 defm VPMAXSB : avx512_binop_rm_vl_b<0x3C, "vpmaxsb", smax,
4048                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4049 defm VPMAXSW : avx512_binop_rm_vl_w<0xEE, "vpmaxsw", smax,
4050                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4051 defm VPMAXS : avx512_binop_rm_vl_dq<0x3D, 0x3D, "vpmaxs", smax,
4052                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4053
4054 defm VPMAXUB : avx512_binop_rm_vl_b<0xDE, "vpmaxub", umax,
4055                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4056 defm VPMAXUW : avx512_binop_rm_vl_w<0x3E, "vpmaxuw", umax,
4057                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4058 defm VPMAXU : avx512_binop_rm_vl_dq<0x3F, 0x3F, "vpmaxu", umax,
4059                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4060
4061 defm VPMINSB : avx512_binop_rm_vl_b<0x38, "vpminsb", smin,
4062                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4063 defm VPMINSW : avx512_binop_rm_vl_w<0xEA, "vpminsw", smin,
4064                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4065 defm VPMINS : avx512_binop_rm_vl_dq<0x39, 0x39, "vpmins", smin,
4066                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4067
4068 defm VPMINUB : avx512_binop_rm_vl_b<0xDA, "vpminub", umin,
4069                                      SSE_INTALU_ITINS_P, HasBWI, 1>;
4070 defm VPMINUW : avx512_binop_rm_vl_w<0x3A, "vpminuw", umin,
4071                                      SSE_INTALU_ITINS_P, HasBWI, 1>, T8PD;
4072 defm VPMINU : avx512_binop_rm_vl_dq<0x3B, 0x3B, "vpminu", umin,
4073                                      SSE_INTALU_ITINS_P, HasAVX512, 1>, T8PD;
4074
4075 // PMULLQ: Use 512bit version to implement 128/256 bit in case NoVLX.
4076 let Predicates = [HasDQI, NoVLX] in {
4077   def : Pat<(v4i64 (mul (v4i64 VR256X:$src1), (v4i64 VR256X:$src2))),
4078             (EXTRACT_SUBREG
4079                 (VPMULLQZrr
4080                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src1, sub_ymm),
4081                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src2, sub_ymm)),
4082              sub_ymm)>;
4083
4084   def : Pat<(v2i64 (mul (v2i64 VR128X:$src1), (v2i64 VR128X:$src2))),
4085             (EXTRACT_SUBREG
4086                 (VPMULLQZrr
4087                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src1, sub_xmm),
4088                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src2, sub_xmm)),
4089              sub_xmm)>;
4090 }
4091
4092 //===----------------------------------------------------------------------===//
4093 // AVX-512  Logical Instructions
4094 //===----------------------------------------------------------------------===//
4095
4096 multiclass avx512_logic_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4097                            X86VectorVTInfo _, bit IsCommutable = 0> {
4098   defm rr : AVX512_maskable_logic<opc, MRMSrcReg, _, (outs _.RC:$dst),
4099                     (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4100                     "$src2, $src1", "$src1, $src2",
4101                     (_.i64VT (OpNode (bitconvert (_.VT _.RC:$src1)),
4102                                      (bitconvert (_.VT _.RC:$src2)))),
4103                     (_.VT (bitconvert (_.i64VT (OpNode _.RC:$src1,
4104                                                        _.RC:$src2)))),
4105                     IIC_SSE_BIT_P_RR, IsCommutable>,
4106             AVX512BIBase, EVEX_4V;
4107
4108   defm rm : AVX512_maskable_logic<opc, MRMSrcMem, _, (outs _.RC:$dst),
4109                   (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
4110                   "$src2, $src1", "$src1, $src2",
4111                   (_.i64VT (OpNode (bitconvert (_.VT _.RC:$src1)),
4112                                    (bitconvert (_.LdFrag addr:$src2)))),
4113                   (_.VT (bitconvert (_.i64VT (OpNode _.RC:$src1,
4114                                      (bitconvert (_.LdFrag addr:$src2)))))),
4115                   IIC_SSE_BIT_P_RM>,
4116             AVX512BIBase, EVEX_4V;
4117 }
4118
4119 multiclass avx512_logic_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4120                             X86VectorVTInfo _, bit IsCommutable = 0> :
4121            avx512_logic_rm<opc, OpcodeStr, OpNode, _, IsCommutable> {
4122   defm rmb : AVX512_maskable_logic<opc, MRMSrcMem, _, (outs _.RC:$dst),
4123                   (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4124                   "${src2}"##_.BroadcastStr##", $src1",
4125                   "$src1, ${src2}"##_.BroadcastStr,
4126                   (_.i64VT (OpNode _.RC:$src1,
4127                                    (bitconvert
4128                                     (_.VT (X86VBroadcast
4129                                             (_.ScalarLdFrag addr:$src2)))))),
4130                   (_.VT (bitconvert (_.i64VT (OpNode _.RC:$src1,
4131                                      (bitconvert
4132                                       (_.VT (X86VBroadcast
4133                                              (_.ScalarLdFrag addr:$src2)))))))),
4134                   IIC_SSE_BIT_P_RM>,
4135              AVX512BIBase, EVEX_4V, EVEX_B;
4136 }
4137
4138 multiclass avx512_logic_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
4139                                AVX512VLVectorVTInfo VTInfo,
4140                                bit IsCommutable = 0> {
4141   let Predicates = [HasAVX512] in
4142     defm Z : avx512_logic_rmb<opc, OpcodeStr, OpNode, VTInfo.info512,
4143                              IsCommutable>, EVEX_V512;
4144
4145   let Predicates = [HasAVX512, HasVLX] in {
4146     defm Z256 : avx512_logic_rmb<opc, OpcodeStr, OpNode, VTInfo.info256,
4147                              IsCommutable>, EVEX_V256;
4148     defm Z128 : avx512_logic_rmb<opc, OpcodeStr, OpNode, VTInfo.info128,
4149                              IsCommutable>, EVEX_V128;
4150   }
4151 }
4152
4153 multiclass avx512_logic_rm_vl_d<bits<8> opc, string OpcodeStr, SDNode OpNode,
4154                                 bit IsCommutable = 0> {
4155   defm NAME : avx512_logic_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i32_info,
4156                                   IsCommutable>, EVEX_CD8<32, CD8VF>;
4157 }
4158
4159 multiclass avx512_logic_rm_vl_q<bits<8> opc, string OpcodeStr, SDNode OpNode,
4160                                 bit IsCommutable = 0> {
4161   defm NAME : avx512_logic_rmb_vl<opc, OpcodeStr, OpNode, avx512vl_i64_info,
4162                                   IsCommutable>,
4163                                   VEX_W, EVEX_CD8<64, CD8VF>;
4164 }
4165
4166 multiclass avx512_logic_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
4167                                  SDNode OpNode, bit IsCommutable = 0> {
4168   defm Q : avx512_logic_rm_vl_q<opc_q, OpcodeStr#"q", OpNode, IsCommutable>;
4169   defm D : avx512_logic_rm_vl_d<opc_d, OpcodeStr#"d", OpNode, IsCommutable>;
4170 }
4171
4172 defm VPAND : avx512_logic_rm_vl_dq<0xDB, 0xDB, "vpand", and, 1>;
4173 defm VPOR : avx512_logic_rm_vl_dq<0xEB, 0xEB, "vpor", or, 1>;
4174 defm VPXOR : avx512_logic_rm_vl_dq<0xEF, 0xEF, "vpxor", xor, 1>;
4175 defm VPANDN : avx512_logic_rm_vl_dq<0xDF, 0xDF, "vpandn", X86andnp>;
4176
4177 //===----------------------------------------------------------------------===//
4178 // AVX-512  FP arithmetic
4179 //===----------------------------------------------------------------------===//
4180 multiclass avx512_fp_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
4181                          SDNode OpNode, SDNode VecNode, OpndItins itins,
4182                          bit IsCommutable> {
4183   let ExeDomain = _.ExeDomain in {
4184   defm rr_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4185                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4186                            "$src2, $src1", "$src1, $src2",
4187                            (_.VT (VecNode _.RC:$src1, _.RC:$src2,
4188                                           (i32 FROUND_CURRENT))),
4189                            itins.rr>;
4190
4191   defm rm_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4192                          (ins _.RC:$src1, _.IntScalarMemOp:$src2), OpcodeStr,
4193                          "$src2, $src1", "$src1, $src2",
4194                          (_.VT (VecNode _.RC:$src1,
4195                                         _.ScalarIntMemCPat:$src2,
4196                                         (i32 FROUND_CURRENT))),
4197                          itins.rm>;
4198   let isCodeGenOnly = 1, Predicates = [HasAVX512] in {
4199   def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
4200                          (ins _.FRC:$src1, _.FRC:$src2),
4201                           OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4202                           [(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
4203                           itins.rr> {
4204     let isCommutable = IsCommutable;
4205   }
4206   def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
4207                          (ins _.FRC:$src1, _.ScalarMemOp:$src2),
4208                          OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4209                          [(set _.FRC:$dst, (OpNode _.FRC:$src1,
4210                          (_.ScalarLdFrag addr:$src2)))], itins.rm>;
4211   }
4212   }
4213 }
4214
4215 multiclass avx512_fp_scalar_round<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
4216                          SDNode VecNode, OpndItins itins, bit IsCommutable = 0> {
4217   let ExeDomain = _.ExeDomain in
4218   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4219                           (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
4220                           "$rc, $src2, $src1", "$src1, $src2, $rc",
4221                           (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
4222                           (i32 imm:$rc)), itins.rr, IsCommutable>,
4223                           EVEX_B, EVEX_RC;
4224 }
4225 multiclass avx512_fp_scalar_sae<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
4226                                 SDNode OpNode, SDNode VecNode, SDNode SaeNode,
4227                                 OpndItins itins, bit IsCommutable> {
4228   let ExeDomain = _.ExeDomain in {
4229   defm rr_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4230                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4231                            "$src2, $src1", "$src1, $src2",
4232                            (_.VT (VecNode _.RC:$src1, _.RC:$src2)),
4233                            itins.rr>;
4234
4235   defm rm_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4236                          (ins _.RC:$src1, _.IntScalarMemOp:$src2), OpcodeStr,
4237                          "$src2, $src1", "$src1, $src2",
4238                          (_.VT (VecNode _.RC:$src1,
4239                                         _.ScalarIntMemCPat:$src2)),
4240                          itins.rm>;
4241
4242   let isCodeGenOnly = 1, Predicates = [HasAVX512] in {
4243   def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
4244                          (ins _.FRC:$src1, _.FRC:$src2),
4245                           OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4246                           [(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
4247                           itins.rr> {
4248     let isCommutable = IsCommutable;
4249   }
4250   def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
4251                          (ins _.FRC:$src1, _.ScalarMemOp:$src2),
4252                          OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4253                          [(set _.FRC:$dst, (OpNode _.FRC:$src1,
4254                          (_.ScalarLdFrag addr:$src2)))], itins.rm>;
4255   }
4256
4257   defm rrb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4258                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4259                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
4260                             (SaeNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
4261                             (i32 FROUND_NO_EXC))>, EVEX_B;
4262   }
4263 }
4264
4265 multiclass avx512_binop_s_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
4266                                   SDNode VecNode,
4267                                   SizeItins itins, bit IsCommutable> {
4268   defm SSZ : avx512_fp_scalar<opc, OpcodeStr#"ss", f32x_info, OpNode, VecNode,
4269                               itins.s, IsCommutable>,
4270              avx512_fp_scalar_round<opc, OpcodeStr#"ss", f32x_info, VecNode,
4271                               itins.s, IsCommutable>,
4272                               XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
4273   defm SDZ : avx512_fp_scalar<opc, OpcodeStr#"sd", f64x_info, OpNode, VecNode,
4274                               itins.d,                  IsCommutable>,
4275              avx512_fp_scalar_round<opc, OpcodeStr#"sd", f64x_info, VecNode,
4276                               itins.d, IsCommutable>,
4277                               XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
4278 }
4279
4280 multiclass avx512_binop_s_sae<bits<8> opc, string OpcodeStr, SDNode OpNode,
4281                                   SDNode VecNode, SDNode SaeNode,
4282                                   SizeItins itins, bit IsCommutable> {
4283   defm SSZ : avx512_fp_scalar_sae<opc, OpcodeStr#"ss", f32x_info, OpNode,
4284                               VecNode, SaeNode, itins.s, IsCommutable>,
4285                               XS, EVEX_4V, VEX_LIG,  EVEX_CD8<32, CD8VT1>;
4286   defm SDZ : avx512_fp_scalar_sae<opc, OpcodeStr#"sd", f64x_info, OpNode,
4287                               VecNode, SaeNode, itins.d, IsCommutable>,
4288                               XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>;
4289 }
4290 defm VADD : avx512_binop_s_round<0x58, "vadd", fadd, X86faddRnds, SSE_ALU_ITINS_S, 1>;
4291 defm VMUL : avx512_binop_s_round<0x59, "vmul", fmul, X86fmulRnds, SSE_MUL_ITINS_S, 1>;
4292 defm VSUB : avx512_binop_s_round<0x5C, "vsub", fsub, X86fsubRnds, SSE_ALU_ITINS_S, 0>;
4293 defm VDIV : avx512_binop_s_round<0x5E, "vdiv", fdiv, X86fdivRnds, SSE_DIV_ITINS_S, 0>;
4294 defm VMIN : avx512_binop_s_sae  <0x5D, "vmin", X86fmin, X86fmins, X86fminRnds,
4295                                  SSE_ALU_ITINS_S, 0>;
4296 defm VMAX : avx512_binop_s_sae  <0x5F, "vmax", X86fmax, X86fmaxs, X86fmaxRnds,
4297                                  SSE_ALU_ITINS_S, 0>;
4298
4299 // MIN/MAX nodes are commutable under "unsafe-fp-math". In this case we use
4300 // X86fminc and X86fmaxc instead of X86fmin and X86fmax
4301 multiclass avx512_comutable_binop_s<bits<8> opc, string OpcodeStr,
4302                           X86VectorVTInfo _, SDNode OpNode, OpndItins itins> {
4303   let isCodeGenOnly = 1, Predicates = [HasAVX512], ExeDomain = _.ExeDomain in {
4304   def rr : I< opc, MRMSrcReg, (outs _.FRC:$dst),
4305                          (ins _.FRC:$src1, _.FRC:$src2),
4306                           OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4307                           [(set _.FRC:$dst, (OpNode _.FRC:$src1, _.FRC:$src2))],
4308                           itins.rr> {
4309     let isCommutable = 1;
4310   }
4311   def rm : I< opc, MRMSrcMem, (outs _.FRC:$dst),
4312                          (ins _.FRC:$src1, _.ScalarMemOp:$src2),
4313                          OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4314                          [(set _.FRC:$dst, (OpNode _.FRC:$src1,
4315                          (_.ScalarLdFrag addr:$src2)))], itins.rm>;
4316   }
4317 }
4318 defm VMINCSSZ : avx512_comutable_binop_s<0x5D, "vminss", f32x_info, X86fminc,
4319                                 SSE_ALU_ITINS_S.s>, XS, EVEX_4V, VEX_LIG,
4320                                 EVEX_CD8<32, CD8VT1>;
4321
4322 defm VMINCSDZ : avx512_comutable_binop_s<0x5D, "vminsd", f64x_info, X86fminc,
4323                                 SSE_ALU_ITINS_S.d>, XD, VEX_W, EVEX_4V, VEX_LIG,
4324                                 EVEX_CD8<64, CD8VT1>;
4325
4326 defm VMAXCSSZ : avx512_comutable_binop_s<0x5F, "vmaxss", f32x_info, X86fmaxc,
4327                                 SSE_ALU_ITINS_S.s>, XS, EVEX_4V, VEX_LIG,
4328                                 EVEX_CD8<32, CD8VT1>;
4329
4330 defm VMAXCSDZ : avx512_comutable_binop_s<0x5F, "vmaxsd", f64x_info, X86fmaxc,
4331                                 SSE_ALU_ITINS_S.d>, XD, VEX_W, EVEX_4V, VEX_LIG,
4332                                 EVEX_CD8<64, CD8VT1>;
4333
4334 multiclass avx512_fp_packed<bits<8> opc, string OpcodeStr, SDPatternOperator OpNode,
4335                             X86VectorVTInfo _, OpndItins itins,
4336                             bit IsCommutable> {
4337   let ExeDomain = _.ExeDomain, hasSideEffects = 0 in {
4338   defm rr: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4339                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4340                   "$src2, $src1", "$src1, $src2",
4341                   (_.VT (OpNode _.RC:$src1, _.RC:$src2)), itins.rr,
4342                   IsCommutable>, EVEX_4V;
4343   let mayLoad = 1 in {
4344     defm rm: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4345                     (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
4346                     "$src2, $src1", "$src1, $src2",
4347                     (OpNode _.RC:$src1, (_.LdFrag addr:$src2)), itins.rm>,
4348                     EVEX_4V;
4349     defm rmb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4350                      (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
4351                      "${src2}"##_.BroadcastStr##", $src1",
4352                      "$src1, ${src2}"##_.BroadcastStr,
4353                      (OpNode  _.RC:$src1, (_.VT (X86VBroadcast
4354                                                 (_.ScalarLdFrag addr:$src2)))),
4355                      itins.rm>, EVEX_4V, EVEX_B;
4356     }
4357   }
4358 }
4359
4360 multiclass avx512_fp_round_packed<bits<8> opc, string OpcodeStr, SDPatternOperator OpNodeRnd,
4361                                   X86VectorVTInfo _> {
4362   let ExeDomain = _.ExeDomain in
4363   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4364                   (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr##_.Suffix,
4365                   "$rc, $src2, $src1", "$src1, $src2, $rc",
4366                   (_.VT (OpNodeRnd _.RC:$src1, _.RC:$src2, (i32 imm:$rc)))>,
4367                   EVEX_4V, EVEX_B, EVEX_RC;
4368 }
4369
4370
4371 multiclass avx512_fp_sae_packed<bits<8> opc, string OpcodeStr, SDPatternOperator OpNodeRnd,
4372                                 X86VectorVTInfo _> {
4373   let ExeDomain = _.ExeDomain in
4374   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4375                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4376                   "{sae}, $src2, $src1", "$src1, $src2, {sae}",
4377                   (_.VT (OpNodeRnd _.RC:$src1, _.RC:$src2, (i32 FROUND_NO_EXC)))>,
4378                   EVEX_4V, EVEX_B;
4379 }
4380
4381 multiclass avx512_fp_binop_p<bits<8> opc, string OpcodeStr, SDPatternOperator OpNode,
4382                              Predicate prd, SizeItins itins,
4383                              bit IsCommutable = 0> {
4384   let Predicates = [prd] in {
4385   defm PSZ : avx512_fp_packed<opc, OpcodeStr, OpNode, v16f32_info,
4386                               itins.s, IsCommutable>, EVEX_V512, PS,
4387                               EVEX_CD8<32, CD8VF>;
4388   defm PDZ : avx512_fp_packed<opc, OpcodeStr, OpNode, v8f64_info,
4389                               itins.d, IsCommutable>, EVEX_V512, PD, VEX_W,
4390                               EVEX_CD8<64, CD8VF>;
4391   }
4392
4393     // Define only if AVX512VL feature is present.
4394   let Predicates = [prd, HasVLX] in {
4395     defm PSZ128 : avx512_fp_packed<opc, OpcodeStr, OpNode, v4f32x_info,
4396                                    itins.s, IsCommutable>, EVEX_V128, PS,
4397                                    EVEX_CD8<32, CD8VF>;
4398     defm PSZ256 : avx512_fp_packed<opc, OpcodeStr, OpNode, v8f32x_info,
4399                                    itins.s, IsCommutable>, EVEX_V256, PS,
4400                                    EVEX_CD8<32, CD8VF>;
4401     defm PDZ128 : avx512_fp_packed<opc, OpcodeStr, OpNode, v2f64x_info,
4402                                    itins.d, IsCommutable>, EVEX_V128, PD, VEX_W,
4403                                    EVEX_CD8<64, CD8VF>;
4404     defm PDZ256 : avx512_fp_packed<opc, OpcodeStr, OpNode, v4f64x_info,
4405                                    itins.d, IsCommutable>, EVEX_V256, PD, VEX_W,
4406                                    EVEX_CD8<64, CD8VF>;
4407   }
4408 }
4409
4410 multiclass avx512_fp_binop_p_round<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd> {
4411   defm PSZ : avx512_fp_round_packed<opc, OpcodeStr, OpNodeRnd, v16f32_info>,
4412                               EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
4413   defm PDZ : avx512_fp_round_packed<opc, OpcodeStr, OpNodeRnd, v8f64_info>,
4414                               EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>;
4415 }
4416
4417 multiclass avx512_fp_binop_p_sae<bits<8> opc, string OpcodeStr, SDNode OpNodeRnd> {
4418   defm PSZ : avx512_fp_sae_packed<opc, OpcodeStr, OpNodeRnd, v16f32_info>,
4419                               EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
4420   defm PDZ : avx512_fp_sae_packed<opc, OpcodeStr, OpNodeRnd, v8f64_info>,
4421                               EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>;
4422 }
4423
4424 defm VADD : avx512_fp_binop_p<0x58, "vadd", fadd, HasAVX512,
4425                               SSE_ALU_ITINS_P, 1>,
4426             avx512_fp_binop_p_round<0x58, "vadd", X86faddRnd>;
4427 defm VMUL : avx512_fp_binop_p<0x59, "vmul", fmul, HasAVX512,
4428                               SSE_MUL_ITINS_P, 1>,
4429             avx512_fp_binop_p_round<0x59, "vmul", X86fmulRnd>;
4430 defm VSUB : avx512_fp_binop_p<0x5C, "vsub", fsub, HasAVX512, SSE_ALU_ITINS_P>,
4431             avx512_fp_binop_p_round<0x5C, "vsub", X86fsubRnd>;
4432 defm VDIV : avx512_fp_binop_p<0x5E, "vdiv", fdiv, HasAVX512, SSE_DIV_ITINS_P>,
4433             avx512_fp_binop_p_round<0x5E, "vdiv", X86fdivRnd>;
4434 defm VMIN : avx512_fp_binop_p<0x5D, "vmin", X86fmin, HasAVX512,
4435                               SSE_ALU_ITINS_P, 0>,
4436             avx512_fp_binop_p_sae<0x5D, "vmin", X86fminRnd>;
4437 defm VMAX : avx512_fp_binop_p<0x5F, "vmax", X86fmax, HasAVX512,
4438                               SSE_ALU_ITINS_P, 0>,
4439             avx512_fp_binop_p_sae<0x5F, "vmax", X86fmaxRnd>;
4440 let isCodeGenOnly = 1 in {
4441   defm VMINC : avx512_fp_binop_p<0x5D, "vmin", X86fminc, HasAVX512,
4442                                  SSE_ALU_ITINS_P, 1>;
4443   defm VMAXC : avx512_fp_binop_p<0x5F, "vmax", X86fmaxc, HasAVX512,
4444                                  SSE_ALU_ITINS_P, 1>;
4445 }
4446 defm VAND  : avx512_fp_binop_p<0x54, "vand", null_frag, HasDQI,
4447                                SSE_ALU_ITINS_P, 1>;
4448 defm VANDN : avx512_fp_binop_p<0x55, "vandn", null_frag, HasDQI,
4449                                SSE_ALU_ITINS_P, 0>;
4450 defm VOR   : avx512_fp_binop_p<0x56, "vor", null_frag, HasDQI,
4451                                SSE_ALU_ITINS_P, 1>;
4452 defm VXOR  : avx512_fp_binop_p<0x57, "vxor", null_frag, HasDQI,
4453                                SSE_ALU_ITINS_P, 1>;
4454
4455 // Patterns catch floating point selects with bitcasted integer logic ops.
4456 multiclass avx512_fp_logical_lowering<string InstrStr, SDNode OpNode,
4457                                       X86VectorVTInfo _, Predicate prd> {
4458 let Predicates = [prd] in {
4459   // Masked register-register logical operations.
4460   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4461                    (bitconvert (_.i64VT (OpNode _.RC:$src1, _.RC:$src2))),
4462                    _.RC:$src0)),
4463             (!cast<Instruction>(InstrStr#rrk) _.RC:$src0, _.KRCWM:$mask,
4464              _.RC:$src1, _.RC:$src2)>;
4465   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4466                    (bitconvert (_.i64VT (OpNode _.RC:$src1, _.RC:$src2))),
4467                    _.ImmAllZerosV)),
4468             (!cast<Instruction>(InstrStr#rrkz) _.KRCWM:$mask, _.RC:$src1,
4469              _.RC:$src2)>;
4470   // Masked register-memory logical operations.
4471   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4472                    (bitconvert (_.i64VT (OpNode _.RC:$src1,
4473                                          (load addr:$src2)))),
4474                    _.RC:$src0)),
4475             (!cast<Instruction>(InstrStr#rmk) _.RC:$src0, _.KRCWM:$mask,
4476              _.RC:$src1, addr:$src2)>;
4477   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4478                    (bitconvert (_.i64VT (OpNode _.RC:$src1, (load addr:$src2)))),
4479                    _.ImmAllZerosV)),
4480             (!cast<Instruction>(InstrStr#rmkz) _.KRCWM:$mask, _.RC:$src1,
4481              addr:$src2)>;
4482   // Register-broadcast logical operations.
4483   def : Pat<(_.i64VT (OpNode _.RC:$src1,
4484                       (bitconvert (_.VT (X86VBroadcast
4485                                          (_.ScalarLdFrag addr:$src2)))))),
4486             (!cast<Instruction>(InstrStr#rmb) _.RC:$src1, addr:$src2)>;
4487   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4488                    (bitconvert
4489                     (_.i64VT (OpNode _.RC:$src1,
4490                               (bitconvert (_.VT
4491                                            (X86VBroadcast
4492                                             (_.ScalarLdFrag addr:$src2))))))),
4493                    _.RC:$src0)),
4494             (!cast<Instruction>(InstrStr#rmbk) _.RC:$src0, _.KRCWM:$mask,
4495              _.RC:$src1, addr:$src2)>;
4496   def : Pat<(_.VT (vselect _.KRCWM:$mask,
4497                    (bitconvert
4498                     (_.i64VT (OpNode _.RC:$src1,
4499                               (bitconvert (_.VT
4500                                            (X86VBroadcast
4501                                             (_.ScalarLdFrag addr:$src2))))))),
4502                    _.ImmAllZerosV)),
4503             (!cast<Instruction>(InstrStr#rmbkz)  _.KRCWM:$mask,
4504              _.RC:$src1, addr:$src2)>;
4505 }
4506 }
4507
4508 multiclass avx512_fp_logical_lowering_sizes<string InstrStr, SDNode OpNode> {
4509   defm : avx512_fp_logical_lowering<InstrStr#DZ128, OpNode, v4f32x_info, HasVLX>;
4510   defm : avx512_fp_logical_lowering<InstrStr#QZ128, OpNode, v2f64x_info, HasVLX>;
4511   defm : avx512_fp_logical_lowering<InstrStr#DZ256, OpNode, v8f32x_info, HasVLX>;
4512   defm : avx512_fp_logical_lowering<InstrStr#QZ256, OpNode, v4f64x_info, HasVLX>;
4513   defm : avx512_fp_logical_lowering<InstrStr#DZ, OpNode, v16f32_info, HasAVX512>;
4514   defm : avx512_fp_logical_lowering<InstrStr#QZ, OpNode, v8f64_info, HasAVX512>;
4515 }
4516
4517 defm : avx512_fp_logical_lowering_sizes<"VPAND", and>;
4518 defm : avx512_fp_logical_lowering_sizes<"VPOR", or>;
4519 defm : avx512_fp_logical_lowering_sizes<"VPXOR", xor>;
4520 defm : avx512_fp_logical_lowering_sizes<"VPANDN", X86andnp>;
4521
4522 let Predicates = [HasVLX,HasDQI] in {
4523   // Use packed logical operations for scalar ops.
4524   def : Pat<(f64 (X86fand FR64X:$src1, FR64X:$src2)),
4525             (COPY_TO_REGCLASS (VANDPDZ128rr
4526                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4527                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4528   def : Pat<(f64 (X86for FR64X:$src1, FR64X:$src2)),
4529             (COPY_TO_REGCLASS (VORPDZ128rr
4530                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4531                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4532   def : Pat<(f64 (X86fxor FR64X:$src1, FR64X:$src2)),
4533             (COPY_TO_REGCLASS (VXORPDZ128rr
4534                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4535                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4536   def : Pat<(f64 (X86fandn FR64X:$src1, FR64X:$src2)),
4537             (COPY_TO_REGCLASS (VANDNPDZ128rr
4538                                (COPY_TO_REGCLASS FR64X:$src1, VR128X),
4539                                (COPY_TO_REGCLASS FR64X:$src2, VR128X)), FR64X)>;
4540
4541   def : Pat<(f32 (X86fand FR32X:$src1, FR32X:$src2)),
4542             (COPY_TO_REGCLASS (VANDPSZ128rr
4543                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4544                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4545   def : Pat<(f32 (X86for FR32X:$src1, FR32X:$src2)),
4546             (COPY_TO_REGCLASS (VORPSZ128rr
4547                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4548                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4549   def : Pat<(f32 (X86fxor FR32X:$src1, FR32X:$src2)),
4550             (COPY_TO_REGCLASS (VXORPSZ128rr
4551                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4552                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4553   def : Pat<(f32 (X86fandn FR32X:$src1, FR32X:$src2)),
4554             (COPY_TO_REGCLASS (VANDNPSZ128rr
4555                                (COPY_TO_REGCLASS FR32X:$src1, VR128X),
4556                                (COPY_TO_REGCLASS FR32X:$src2, VR128X)), FR32X)>;
4557 }
4558
4559 multiclass avx512_fp_scalef_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
4560                             X86VectorVTInfo _> {
4561   let ExeDomain = _.ExeDomain in {
4562   defm rr: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4563                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4564                   "$src2, $src1", "$src1, $src2",
4565                   (_.VT (OpNode _.RC:$src1, _.RC:$src2, (i32 FROUND_CURRENT)))>, EVEX_4V;
4566   defm rm: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4567                   (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr##_.Suffix,
4568                   "$src2, $src1", "$src1, $src2",
4569                   (OpNode _.RC:$src1, (_.LdFrag addr:$src2), (i32 FROUND_CURRENT))>, EVEX_4V;
4570   defm rmb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4571                    (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
4572                    "${src2}"##_.BroadcastStr##", $src1",
4573                    "$src1, ${src2}"##_.BroadcastStr,
4574                    (OpNode  _.RC:$src1, (_.VT (X86VBroadcast
4575                                               (_.ScalarLdFrag addr:$src2))), (i32 FROUND_CURRENT))>,
4576                    EVEX_4V, EVEX_B;
4577   }
4578 }
4579
4580 multiclass avx512_fp_scalef_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
4581                             X86VectorVTInfo _> {
4582   let ExeDomain = _.ExeDomain in {
4583   defm rr: AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
4584                   (ins _.RC:$src1, _.RC:$src2), OpcodeStr##_.Suffix,
4585                   "$src2, $src1", "$src1, $src2",
4586                   (_.VT (OpNode _.RC:$src1, _.RC:$src2, (i32 FROUND_CURRENT)))>;
4587   defm rm: AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
4588                   (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr##_.Suffix,
4589                   "$src2, $src1", "$src1, $src2",
4590                   (OpNode _.RC:$src1,
4591                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
4592                           (i32 FROUND_CURRENT))>;
4593   }
4594 }
4595
4596 multiclass avx512_fp_scalef_all<bits<8> opc, bits<8> opcScaler, string OpcodeStr, SDNode OpNode, SDNode OpNodeScal> {
4597   defm PSZ : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v16f32_info>,
4598              avx512_fp_round_packed<opc, OpcodeStr, OpNode, v16f32_info>,
4599                               EVEX_V512, EVEX_CD8<32, CD8VF>;
4600   defm PDZ : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v8f64_info>,
4601              avx512_fp_round_packed<opc, OpcodeStr, OpNode, v8f64_info>,
4602                               EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
4603   defm SSZ128 : avx512_fp_scalef_scalar<opcScaler, OpcodeStr, OpNodeScal, f32x_info>,
4604                 avx512_fp_scalar_round<opcScaler, OpcodeStr##"ss", f32x_info, OpNodeScal, SSE_ALU_ITINS_S.s>,
4605                               EVEX_4V,EVEX_CD8<32, CD8VT1>;
4606   defm SDZ128 : avx512_fp_scalef_scalar<opcScaler, OpcodeStr, OpNodeScal, f64x_info>,
4607                 avx512_fp_scalar_round<opcScaler, OpcodeStr##"sd", f64x_info, OpNodeScal, SSE_ALU_ITINS_S.d>,
4608                               EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
4609
4610   // Define only if AVX512VL feature is present.
4611   let Predicates = [HasVLX] in {
4612     defm PSZ128 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v4f32x_info>,
4613                                    EVEX_V128, EVEX_CD8<32, CD8VF>;
4614     defm PSZ256 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v8f32x_info>,
4615                                    EVEX_V256, EVEX_CD8<32, CD8VF>;
4616     defm PDZ128 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v2f64x_info>,
4617                                    EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
4618     defm PDZ256 : avx512_fp_scalef_p<opc, OpcodeStr, OpNode, v4f64x_info>,
4619                                    EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
4620   }
4621 }
4622 defm VSCALEF : avx512_fp_scalef_all<0x2C, 0x2D, "vscalef", X86scalef, X86scalefs>, T8PD;
4623
4624 //===----------------------------------------------------------------------===//
4625 // AVX-512  VPTESTM instructions
4626 //===----------------------------------------------------------------------===//
4627
4628 multiclass avx512_vptest<bits<8> opc, string OpcodeStr, SDNode OpNode,
4629                             X86VectorVTInfo _> {
4630   let isCommutable = 1 in
4631   defm rr : AVX512_maskable_cmp<opc, MRMSrcReg, _, (outs _.KRC:$dst),
4632                    (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4633                       "$src2, $src1", "$src1, $src2",
4634                    (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>,
4635                     EVEX_4V;
4636   defm rm : AVX512_maskable_cmp<opc, MRMSrcMem, _, (outs _.KRC:$dst),
4637                    (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
4638                        "$src2, $src1", "$src1, $src2",
4639                    (OpNode (_.VT _.RC:$src1),
4640                     (_.VT (bitconvert (_.LdFrag addr:$src2))))>,
4641                     EVEX_4V,
4642                    EVEX_CD8<_.EltSize, CD8VF>;
4643 }
4644
4645 multiclass avx512_vptest_mb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4646                             X86VectorVTInfo _> {
4647   defm rmb : AVX512_maskable_cmp<opc, MRMSrcMem, _, (outs _.KRC:$dst),
4648                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4649                     "${src2}"##_.BroadcastStr##", $src1",
4650                     "$src1, ${src2}"##_.BroadcastStr,
4651                     (OpNode (_.VT _.RC:$src1), (_.VT (X86VBroadcast
4652                                                 (_.ScalarLdFrag addr:$src2))))>,
4653                     EVEX_B, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
4654 }
4655
4656 // Use 512bit version to implement 128/256 bit in case NoVLX.
4657 multiclass avx512_vptest_lowering<SDNode OpNode, X86VectorVTInfo ExtendInfo,
4658                                   X86VectorVTInfo _, string Suffix> {
4659     def : Pat<(_.KVT (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))),
4660               (_.KVT (COPY_TO_REGCLASS
4661                        (!cast<Instruction>(NAME # Suffix # "Zrr")
4662                          (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
4663                                         _.RC:$src1, _.SubRegIdx),
4664                          (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
4665                                         _.RC:$src2, _.SubRegIdx)),
4666                      _.KRC))>;
4667 }
4668
4669 multiclass avx512_vptest_dq_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4670                                   AVX512VLVectorVTInfo _, string Suffix> {
4671   let Predicates  = [HasAVX512] in
4672   defm Z : avx512_vptest<opc, OpcodeStr, OpNode, _.info512>,
4673            avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
4674
4675   let Predicates = [HasAVX512, HasVLX] in {
4676   defm Z256 : avx512_vptest<opc, OpcodeStr, OpNode, _.info256>,
4677               avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
4678   defm Z128 : avx512_vptest<opc, OpcodeStr, OpNode, _.info128>,
4679               avx512_vptest_mb<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
4680   }
4681   let Predicates = [HasAVX512, NoVLX] in {
4682   defm Z256_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info256, Suffix>;
4683   defm Z128_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info128, Suffix>;
4684   }
4685 }
4686
4687 multiclass avx512_vptest_dq<bits<8> opc, string OpcodeStr, SDNode OpNode> {
4688   defm D : avx512_vptest_dq_sizes<opc, OpcodeStr#"d", OpNode,
4689                                  avx512vl_i32_info, "D">;
4690   defm Q : avx512_vptest_dq_sizes<opc, OpcodeStr#"q", OpNode,
4691                                  avx512vl_i64_info, "Q">, VEX_W;
4692 }
4693
4694 multiclass avx512_vptest_wb<bits<8> opc, string OpcodeStr,
4695                                  SDNode OpNode> {
4696   let Predicates = [HasBWI] in {
4697   defm WZ:    avx512_vptest<opc, OpcodeStr#"w", OpNode, v32i16_info>,
4698               EVEX_V512, VEX_W;
4699   defm BZ:    avx512_vptest<opc, OpcodeStr#"b", OpNode, v64i8_info>,
4700               EVEX_V512;
4701   }
4702   let Predicates = [HasVLX, HasBWI] in {
4703
4704   defm WZ256: avx512_vptest<opc, OpcodeStr#"w", OpNode, v16i16x_info>,
4705               EVEX_V256, VEX_W;
4706   defm WZ128: avx512_vptest<opc, OpcodeStr#"w", OpNode, v8i16x_info>,
4707               EVEX_V128, VEX_W;
4708   defm BZ256: avx512_vptest<opc, OpcodeStr#"b", OpNode, v32i8x_info>,
4709               EVEX_V256;
4710   defm BZ128: avx512_vptest<opc, OpcodeStr#"b", OpNode, v16i8x_info>,
4711               EVEX_V128;
4712   }
4713
4714   let Predicates = [HasAVX512, NoVLX] in {
4715   defm BZ256_Alt : avx512_vptest_lowering< OpNode, v64i8_info, v32i8x_info, "B">;
4716   defm BZ128_Alt : avx512_vptest_lowering< OpNode, v64i8_info, v16i8x_info, "B">;
4717   defm WZ256_Alt : avx512_vptest_lowering< OpNode, v32i16_info, v16i16x_info, "W">;
4718   defm WZ128_Alt : avx512_vptest_lowering< OpNode, v32i16_info, v8i16x_info, "W">;
4719   }
4720
4721 }
4722
4723 multiclass avx512_vptest_all_forms<bits<8> opc_wb, bits<8> opc_dq, string OpcodeStr,
4724                                    SDNode OpNode> :
4725   avx512_vptest_wb <opc_wb, OpcodeStr, OpNode>,
4726   avx512_vptest_dq<opc_dq, OpcodeStr, OpNode>;
4727
4728 defm VPTESTM   : avx512_vptest_all_forms<0x26, 0x27, "vptestm", X86testm>, T8PD;
4729 defm VPTESTNM  : avx512_vptest_all_forms<0x26, 0x27, "vptestnm", X86testnm>, T8XS;
4730
4731
4732 //===----------------------------------------------------------------------===//
4733 // AVX-512  Shift instructions
4734 //===----------------------------------------------------------------------===//
4735 multiclass avx512_shift_rmi<bits<8> opc, Format ImmFormR, Format ImmFormM,
4736                          string OpcodeStr, SDNode OpNode, X86VectorVTInfo _> {
4737   let ExeDomain = _.ExeDomain in {
4738   defm ri : AVX512_maskable<opc, ImmFormR, _, (outs _.RC:$dst),
4739                    (ins _.RC:$src1, u8imm:$src2), OpcodeStr,
4740                       "$src2, $src1", "$src1, $src2",
4741                    (_.VT (OpNode _.RC:$src1, (i8 imm:$src2))),
4742                    SSE_INTSHIFT_ITINS_P.rr>;
4743   defm mi : AVX512_maskable<opc, ImmFormM, _, (outs _.RC:$dst),
4744                    (ins _.MemOp:$src1, u8imm:$src2), OpcodeStr,
4745                        "$src2, $src1", "$src1, $src2",
4746                    (_.VT (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
4747                           (i8 imm:$src2))),
4748                    SSE_INTSHIFT_ITINS_P.rm>;
4749   }
4750 }
4751
4752 multiclass avx512_shift_rmbi<bits<8> opc, Format ImmFormM,
4753                          string OpcodeStr, SDNode OpNode, X86VectorVTInfo _> {
4754   let ExeDomain = _.ExeDomain in
4755   defm mbi : AVX512_maskable<opc, ImmFormM, _, (outs _.RC:$dst),
4756                    (ins _.ScalarMemOp:$src1, u8imm:$src2), OpcodeStr,
4757       "$src2, ${src1}"##_.BroadcastStr, "${src1}"##_.BroadcastStr##", $src2",
4758      (_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src1)), (i8 imm:$src2))),
4759      SSE_INTSHIFT_ITINS_P.rm>, EVEX_B;
4760 }
4761
4762 multiclass avx512_shift_rrm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4763                          ValueType SrcVT, PatFrag bc_frag, X86VectorVTInfo _> {
4764    // src2 is always 128-bit
4765   let ExeDomain = _.ExeDomain in {
4766   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4767                    (ins _.RC:$src1, VR128X:$src2), OpcodeStr,
4768                       "$src2, $src1", "$src1, $src2",
4769                    (_.VT (OpNode _.RC:$src1, (SrcVT VR128X:$src2))),
4770                    SSE_INTSHIFT_ITINS_P.rr>, AVX512BIBase, EVEX_4V;
4771   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4772                    (ins _.RC:$src1, i128mem:$src2), OpcodeStr,
4773                        "$src2, $src1", "$src1, $src2",
4774                    (_.VT (OpNode _.RC:$src1, (bc_frag (loadv2i64 addr:$src2)))),
4775                    SSE_INTSHIFT_ITINS_P.rm>, AVX512BIBase,
4776                    EVEX_4V;
4777   }
4778 }
4779
4780 multiclass avx512_shift_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4781                                   ValueType SrcVT, PatFrag bc_frag,
4782                                   AVX512VLVectorVTInfo VTInfo, Predicate prd> {
4783   let Predicates = [prd] in
4784   defm Z    : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
4785                             VTInfo.info512>, EVEX_V512,
4786                             EVEX_CD8<VTInfo.info512.EltSize, CD8VQ> ;
4787   let Predicates = [prd, HasVLX] in {
4788   defm Z256 : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
4789                             VTInfo.info256>, EVEX_V256,
4790                             EVEX_CD8<VTInfo.info256.EltSize, CD8VH>;
4791   defm Z128 : avx512_shift_rrm<opc, OpcodeStr, OpNode, SrcVT, bc_frag,
4792                             VTInfo.info128>, EVEX_V128,
4793                             EVEX_CD8<VTInfo.info128.EltSize, CD8VF>;
4794   }
4795 }
4796
4797 multiclass avx512_shift_types<bits<8> opcd, bits<8> opcq, bits<8> opcw,
4798                               string OpcodeStr, SDNode OpNode> {
4799   defm D : avx512_shift_sizes<opcd, OpcodeStr#"d", OpNode, v4i32, bc_v4i32,
4800                                  avx512vl_i32_info, HasAVX512>;
4801   defm Q : avx512_shift_sizes<opcq, OpcodeStr#"q", OpNode, v2i64, bc_v2i64,
4802                                  avx512vl_i64_info, HasAVX512>, VEX_W;
4803   defm W : avx512_shift_sizes<opcw, OpcodeStr#"w", OpNode, v8i16, bc_v8i16,
4804                                  avx512vl_i16_info, HasBWI>;
4805 }
4806
4807 multiclass avx512_shift_rmi_sizes<bits<8> opc, Format ImmFormR, Format ImmFormM,
4808                                  string OpcodeStr, SDNode OpNode,
4809                                  AVX512VLVectorVTInfo VTInfo> {
4810   let Predicates = [HasAVX512] in
4811   defm Z:    avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4812                               VTInfo.info512>,
4813              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4814                               VTInfo.info512>, EVEX_V512;
4815   let Predicates = [HasAVX512, HasVLX] in {
4816   defm Z256: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4817                               VTInfo.info256>,
4818              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4819                               VTInfo.info256>, EVEX_V256;
4820   defm Z128: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4821                               VTInfo.info128>,
4822              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
4823                               VTInfo.info128>, EVEX_V128;
4824   }
4825 }
4826
4827 multiclass avx512_shift_rmi_w<bits<8> opcw,
4828                                  Format ImmFormR, Format ImmFormM,
4829                                  string OpcodeStr, SDNode OpNode> {
4830   let Predicates = [HasBWI] in
4831   defm WZ:    avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4832                                v32i16_info>, EVEX_V512;
4833   let Predicates = [HasVLX, HasBWI] in {
4834   defm WZ256: avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4835                                v16i16x_info>, EVEX_V256;
4836   defm WZ128: avx512_shift_rmi<opcw, ImmFormR, ImmFormM, OpcodeStr, OpNode,
4837                                v8i16x_info>, EVEX_V128;
4838   }
4839 }
4840
4841 multiclass avx512_shift_rmi_dq<bits<8> opcd, bits<8> opcq,
4842                                  Format ImmFormR, Format ImmFormM,
4843                                  string OpcodeStr, SDNode OpNode> {
4844   defm D: avx512_shift_rmi_sizes<opcd, ImmFormR, ImmFormM, OpcodeStr#"d", OpNode,
4845                                  avx512vl_i32_info>, EVEX_CD8<32, CD8VF>;
4846   defm Q: avx512_shift_rmi_sizes<opcq, ImmFormR, ImmFormM, OpcodeStr#"q", OpNode,
4847                                  avx512vl_i64_info>, EVEX_CD8<64, CD8VF>, VEX_W;
4848 }
4849
4850 defm VPSRL : avx512_shift_rmi_dq<0x72, 0x73, MRM2r, MRM2m, "vpsrl", X86vsrli>,
4851              avx512_shift_rmi_w<0x71, MRM2r, MRM2m, "vpsrlw", X86vsrli>, AVX512BIi8Base, EVEX_4V;
4852
4853 defm VPSLL : avx512_shift_rmi_dq<0x72, 0x73, MRM6r, MRM6m, "vpsll", X86vshli>,
4854              avx512_shift_rmi_w<0x71, MRM6r, MRM6m, "vpsllw", X86vshli>, AVX512BIi8Base, EVEX_4V;
4855
4856 defm VPSRA : avx512_shift_rmi_dq<0x72, 0x72, MRM4r, MRM4m, "vpsra", X86vsrai>,
4857              avx512_shift_rmi_w<0x71, MRM4r, MRM4m, "vpsraw", X86vsrai>, AVX512BIi8Base, EVEX_4V;
4858
4859 defm VPROR : avx512_shift_rmi_dq<0x72, 0x72, MRM0r, MRM0m, "vpror", X86vrotri>, AVX512BIi8Base, EVEX_4V;
4860 defm VPROL : avx512_shift_rmi_dq<0x72, 0x72, MRM1r, MRM1m, "vprol", X86vrotli>, AVX512BIi8Base, EVEX_4V;
4861
4862 defm VPSLL : avx512_shift_types<0xF2, 0xF3, 0xF1, "vpsll", X86vshl>;
4863 defm VPSRA : avx512_shift_types<0xE2, 0xE2, 0xE1, "vpsra", X86vsra>;
4864 defm VPSRL : avx512_shift_types<0xD2, 0xD3, 0xD1, "vpsrl", X86vsrl>;
4865
4866 // Use 512bit VPSRA/VPSRAI version to implement v2i64/v4i64 in case NoVLX.
4867 let Predicates = [HasAVX512, NoVLX] in {
4868   def : Pat<(v4i64 (X86vsra (v4i64 VR256X:$src1), (v2i64 VR128X:$src2))),
4869             (EXTRACT_SUBREG (v8i64
4870               (VPSRAQZrr
4871                 (v8i64 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
4872                  VR128X:$src2)), sub_ymm)>;
4873
4874   def : Pat<(v2i64 (X86vsra (v2i64 VR128X:$src1), (v2i64 VR128X:$src2))),
4875             (EXTRACT_SUBREG (v8i64
4876               (VPSRAQZrr
4877                 (v8i64 (INSERT_SUBREG (IMPLICIT_DEF), VR128X:$src1, sub_xmm)),
4878                  VR128X:$src2)), sub_xmm)>;
4879
4880   def : Pat<(v4i64 (X86vsrai (v4i64 VR256X:$src1), (i8 imm:$src2))),
4881             (EXTRACT_SUBREG (v8i64
4882               (VPSRAQZri
4883                 (v8i64 (INSERT_SUBREG (IMPLICIT_DEF), VR256X:$src1, sub_ymm)),
4884                  imm:$src2)), sub_ymm)>;
4885
4886   def : Pat<(v2i64 (X86vsrai (v2i64 VR128X:$src1), (i8 imm:$src2))),
4887             (EXTRACT_SUBREG (v8i64
4888               (VPSRAQZri
4889                 (v8i64 (INSERT_SUBREG (IMPLICIT_DEF), VR128X:$src1, sub_xmm)),
4890                  imm:$src2)), sub_xmm)>;
4891 }
4892
4893 //===-------------------------------------------------------------------===//
4894 // Variable Bit Shifts
4895 //===-------------------------------------------------------------------===//
4896 multiclass avx512_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
4897                             X86VectorVTInfo _> {
4898   let ExeDomain = _.ExeDomain in {
4899   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
4900                    (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
4901                       "$src2, $src1", "$src1, $src2",
4902                    (_.VT (OpNode _.RC:$src1, (_.VT _.RC:$src2))),
4903                    SSE_INTSHIFT_ITINS_P.rr>, AVX5128IBase, EVEX_4V;
4904   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4905                    (ins _.RC:$src1, _.MemOp:$src2), OpcodeStr,
4906                        "$src2, $src1", "$src1, $src2",
4907                    (_.VT (OpNode _.RC:$src1,
4908                    (_.VT (bitconvert (_.LdFrag addr:$src2))))),
4909                    SSE_INTSHIFT_ITINS_P.rm>, AVX5128IBase, EVEX_4V,
4910                    EVEX_CD8<_.EltSize, CD8VF>;
4911   }
4912 }
4913
4914 multiclass avx512_var_shift_mb<bits<8> opc, string OpcodeStr, SDNode OpNode,
4915                             X86VectorVTInfo _> {
4916   let ExeDomain = _.ExeDomain in
4917   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
4918                     (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
4919                     "${src2}"##_.BroadcastStr##", $src1",
4920                     "$src1, ${src2}"##_.BroadcastStr,
4921                     (_.VT (OpNode _.RC:$src1, (_.VT (X86VBroadcast
4922                                                 (_.ScalarLdFrag addr:$src2))))),
4923                     SSE_INTSHIFT_ITINS_P.rm>, AVX5128IBase, EVEX_B,
4924                     EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
4925 }
4926
4927 multiclass avx512_var_shift_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
4928                                   AVX512VLVectorVTInfo _> {
4929   let Predicates  = [HasAVX512] in
4930   defm Z : avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
4931            avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
4932
4933   let Predicates = [HasAVX512, HasVLX] in {
4934   defm Z256 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
4935               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
4936   defm Z128 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info128>,
4937               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
4938   }
4939 }
4940
4941 multiclass avx512_var_shift_types<bits<8> opc, string OpcodeStr,
4942                                  SDNode OpNode> {
4943   defm D : avx512_var_shift_sizes<opc, OpcodeStr#"d", OpNode,
4944                                  avx512vl_i32_info>;
4945   defm Q : avx512_var_shift_sizes<opc, OpcodeStr#"q", OpNode,
4946                                  avx512vl_i64_info>, VEX_W;
4947 }
4948
4949 // Use 512bit version to implement 128/256 bit in case NoVLX.
4950 multiclass avx512_var_shift_lowering<AVX512VLVectorVTInfo _, string OpcodeStr,
4951                                      SDNode OpNode, list<Predicate> p> {
4952   let Predicates = p in {
4953   def : Pat<(_.info256.VT (OpNode (_.info256.VT _.info256.RC:$src1),
4954                                   (_.info256.VT _.info256.RC:$src2))),
4955             (EXTRACT_SUBREG
4956                 (!cast<Instruction>(OpcodeStr#"Zrr")
4957                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR256X:$src1, sub_ymm),
4958                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR256X:$src2, sub_ymm)),
4959              sub_ymm)>;
4960
4961   def : Pat<(_.info128.VT (OpNode (_.info128.VT _.info128.RC:$src1),
4962                                   (_.info128.VT _.info128.RC:$src2))),
4963             (EXTRACT_SUBREG
4964                 (!cast<Instruction>(OpcodeStr#"Zrr")
4965                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR128X:$src1, sub_xmm),
4966                     (INSERT_SUBREG (_.info512.VT (IMPLICIT_DEF)), VR128X:$src2, sub_xmm)),
4967              sub_xmm)>;
4968   }
4969 }
4970 multiclass avx512_var_shift_w<bits<8> opc, string OpcodeStr,
4971                                  SDNode OpNode> {
4972   let Predicates = [HasBWI] in
4973   defm WZ:    avx512_var_shift<opc, OpcodeStr, OpNode, v32i16_info>,
4974               EVEX_V512, VEX_W;
4975   let Predicates = [HasVLX, HasBWI] in {
4976
4977   defm WZ256: avx512_var_shift<opc, OpcodeStr, OpNode, v16i16x_info>,
4978               EVEX_V256, VEX_W;
4979   defm WZ128: avx512_var_shift<opc, OpcodeStr, OpNode, v8i16x_info>,
4980               EVEX_V128, VEX_W;
4981   }
4982 }
4983
4984 defm VPSLLV : avx512_var_shift_types<0x47, "vpsllv", shl>,
4985               avx512_var_shift_w<0x12, "vpsllvw", shl>;
4986
4987 defm VPSRAV : avx512_var_shift_types<0x46, "vpsrav", sra>,
4988               avx512_var_shift_w<0x11, "vpsravw", sra>;
4989
4990 defm VPSRLV : avx512_var_shift_types<0x45, "vpsrlv", srl>,
4991               avx512_var_shift_w<0x10, "vpsrlvw", srl>;
4992
4993 defm VPRORV : avx512_var_shift_types<0x14, "vprorv", rotr>;
4994 defm VPROLV : avx512_var_shift_types<0x15, "vprolv", rotl>;
4995
4996 defm : avx512_var_shift_lowering<avx512vl_i64_info, "VPSRAVQ", sra, [HasAVX512, NoVLX]>;
4997 defm : avx512_var_shift_lowering<avx512vl_i16_info, "VPSLLVW", shl, [HasBWI, NoVLX]>;
4998 defm : avx512_var_shift_lowering<avx512vl_i16_info, "VPSRAVW", sra, [HasBWI, NoVLX]>;
4999 defm : avx512_var_shift_lowering<avx512vl_i16_info, "VPSRLVW", srl, [HasBWI, NoVLX]>;
5000
5001 // Special handing for handling VPSRAV intrinsics.
5002 multiclass avx512_var_shift_int_lowering<string InstrStr, X86VectorVTInfo _,
5003                                          list<Predicate> p> {
5004   let Predicates = p in {
5005     def : Pat<(_.VT (X86vsrav _.RC:$src1, _.RC:$src2)),
5006               (!cast<Instruction>(InstrStr#_.ZSuffix#rr) _.RC:$src1,
5007                _.RC:$src2)>;
5008     def : Pat<(_.VT (X86vsrav _.RC:$src1, (bitconvert (_.LdFrag addr:$src2)))),
5009               (!cast<Instruction>(InstrStr#_.ZSuffix##rm)
5010                _.RC:$src1, addr:$src2)>;
5011     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5012                      (X86vsrav _.RC:$src1, _.RC:$src2), _.RC:$src0)),
5013               (!cast<Instruction>(InstrStr#_.ZSuffix#rrk) _.RC:$src0,
5014                _.KRC:$mask, _.RC:$src1, _.RC:$src2)>;
5015     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5016                      (X86vsrav _.RC:$src1, (bitconvert (_.LdFrag addr:$src2))),
5017                      _.RC:$src0)),
5018               (!cast<Instruction>(InstrStr#_.ZSuffix##rmk) _.RC:$src0,
5019                _.KRC:$mask, _.RC:$src1, addr:$src2)>;
5020     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5021                      (X86vsrav _.RC:$src1, _.RC:$src2), _.ImmAllZerosV)),
5022               (!cast<Instruction>(InstrStr#_.ZSuffix#rrkz) _.KRC:$mask,
5023                _.RC:$src1, _.RC:$src2)>;
5024     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5025                      (X86vsrav _.RC:$src1, (bitconvert (_.LdFrag addr:$src2))),
5026                      _.ImmAllZerosV)),
5027               (!cast<Instruction>(InstrStr#_.ZSuffix##rmkz) _.KRC:$mask,
5028                _.RC:$src1, addr:$src2)>;
5029   }
5030 }
5031
5032 multiclass avx512_var_shift_int_lowering_mb<string InstrStr, X86VectorVTInfo _,
5033                                          list<Predicate> p> :
5034            avx512_var_shift_int_lowering<InstrStr, _, p> {
5035   let Predicates = p in {
5036     def : Pat<(_.VT (X86vsrav _.RC:$src1,
5037                      (X86VBroadcast (_.ScalarLdFrag addr:$src2)))),
5038               (!cast<Instruction>(InstrStr#_.ZSuffix##rmb)
5039                _.RC:$src1, addr:$src2)>;
5040     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5041                      (X86vsrav _.RC:$src1,
5042                       (X86VBroadcast (_.ScalarLdFrag addr:$src2))),
5043                      _.RC:$src0)),
5044               (!cast<Instruction>(InstrStr#_.ZSuffix##rmbk) _.RC:$src0,
5045                _.KRC:$mask, _.RC:$src1, addr:$src2)>;
5046     def : Pat<(_.VT (vselect _.KRCWM:$mask,
5047                      (X86vsrav _.RC:$src1,
5048                       (X86VBroadcast (_.ScalarLdFrag addr:$src2))),
5049                      _.ImmAllZerosV)),
5050               (!cast<Instruction>(InstrStr#_.ZSuffix##rmbkz) _.KRC:$mask,
5051                _.RC:$src1, addr:$src2)>;
5052   }
5053 }
5054
5055 defm : avx512_var_shift_int_lowering<"VPSRAVW", v8i16x_info, [HasVLX, HasBWI]>;
5056 defm : avx512_var_shift_int_lowering<"VPSRAVW", v16i16x_info, [HasVLX, HasBWI]>;
5057 defm : avx512_var_shift_int_lowering<"VPSRAVW", v32i16_info, [HasBWI]>;
5058 defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v4i32x_info, [HasVLX]>;
5059 defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v8i32x_info, [HasVLX]>;
5060 defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v16i32_info, [HasAVX512]>;
5061 defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v2i64x_info, [HasVLX]>;
5062 defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v4i64x_info, [HasVLX]>;
5063 defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v8i64_info, [HasAVX512]>;
5064
5065 //===-------------------------------------------------------------------===//
5066 // 1-src variable permutation VPERMW/D/Q
5067 //===-------------------------------------------------------------------===//
5068 multiclass avx512_vperm_dq_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode,
5069                                   AVX512VLVectorVTInfo _> {
5070   let Predicates  = [HasAVX512] in
5071   defm Z : avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
5072            avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
5073
5074   let Predicates = [HasAVX512, HasVLX] in
5075   defm Z256 : avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
5076               avx512_var_shift_mb<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
5077 }
5078
5079 multiclass avx512_vpermi_dq_sizes<bits<8> opc, Format ImmFormR, Format ImmFormM,
5080                                  string OpcodeStr, SDNode OpNode,
5081                                  AVX512VLVectorVTInfo VTInfo> {
5082   let Predicates = [HasAVX512] in
5083   defm Z:    avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
5084                               VTInfo.info512>,
5085              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
5086                               VTInfo.info512>, EVEX_V512;
5087   let Predicates = [HasAVX512, HasVLX] in
5088   defm Z256: avx512_shift_rmi<opc, ImmFormR, ImmFormM, OpcodeStr, OpNode,
5089                               VTInfo.info256>,
5090              avx512_shift_rmbi<opc, ImmFormM, OpcodeStr, OpNode,
5091                               VTInfo.info256>, EVEX_V256;
5092 }
5093
5094 multiclass avx512_vperm_bw<bits<8> opc, string OpcodeStr,
5095                               Predicate prd, SDNode OpNode,
5096                               AVX512VLVectorVTInfo _> {
5097   let Predicates = [prd] in
5098   defm Z:    avx512_var_shift<opc, OpcodeStr, OpNode, _.info512>,
5099               EVEX_V512 ;
5100   let Predicates = [HasVLX, prd] in {
5101   defm Z256: avx512_var_shift<opc, OpcodeStr, OpNode, _.info256>,
5102               EVEX_V256 ;
5103   defm Z128: avx512_var_shift<opc, OpcodeStr, OpNode, _.info128>,
5104               EVEX_V128 ;
5105   }
5106 }
5107
5108 defm VPERMW  : avx512_vperm_bw<0x8D, "vpermw", HasBWI, X86VPermv,
5109                                   avx512vl_i16_info>, VEX_W;
5110 defm VPERMB  : avx512_vperm_bw<0x8D, "vpermb", HasVBMI, X86VPermv,
5111                                   avx512vl_i8_info>;
5112
5113 defm VPERMD : avx512_vperm_dq_sizes<0x36, "vpermd", X86VPermv,
5114                                     avx512vl_i32_info>;
5115 defm VPERMQ : avx512_vperm_dq_sizes<0x36, "vpermq", X86VPermv,
5116                                     avx512vl_i64_info>, VEX_W;
5117 defm VPERMPS : avx512_vperm_dq_sizes<0x16, "vpermps", X86VPermv,
5118                                     avx512vl_f32_info>;
5119 defm VPERMPD : avx512_vperm_dq_sizes<0x16, "vpermpd", X86VPermv,
5120                                     avx512vl_f64_info>, VEX_W;
5121
5122 defm VPERMQ : avx512_vpermi_dq_sizes<0x00, MRMSrcReg, MRMSrcMem, "vpermq",
5123                              X86VPermi, avx512vl_i64_info>,
5124                              EVEX, AVX512AIi8Base, EVEX_CD8<64, CD8VF>, VEX_W;
5125 defm VPERMPD : avx512_vpermi_dq_sizes<0x01, MRMSrcReg, MRMSrcMem, "vpermpd",
5126                              X86VPermi, avx512vl_f64_info>,
5127                              EVEX, AVX512AIi8Base, EVEX_CD8<64, CD8VF>, VEX_W;
5128 //===----------------------------------------------------------------------===//
5129 // AVX-512 - VPERMIL
5130 //===----------------------------------------------------------------------===//
5131
5132 multiclass avx512_permil_vec<bits<8> OpcVar, string OpcodeStr,  SDNode OpNode,
5133                              X86VectorVTInfo _, X86VectorVTInfo Ctrl> {
5134   defm rr: AVX512_maskable<OpcVar, MRMSrcReg, _, (outs _.RC:$dst),
5135                   (ins _.RC:$src1, Ctrl.RC:$src2), OpcodeStr,
5136                   "$src2, $src1", "$src1, $src2",
5137                   (_.VT (OpNode _.RC:$src1,
5138                                (Ctrl.VT Ctrl.RC:$src2)))>,
5139                   T8PD, EVEX_4V;
5140   defm rm: AVX512_maskable<OpcVar, MRMSrcMem, _, (outs _.RC:$dst),
5141                   (ins _.RC:$src1, Ctrl.MemOp:$src2), OpcodeStr,
5142                   "$src2, $src1", "$src1, $src2",
5143                   (_.VT (OpNode
5144                            _.RC:$src1,
5145                            (Ctrl.VT (bitconvert(Ctrl.LdFrag addr:$src2)))))>,
5146                   T8PD, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
5147   defm rmb: AVX512_maskable<OpcVar, MRMSrcMem, _, (outs _.RC:$dst),
5148                    (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
5149                    "${src2}"##_.BroadcastStr##", $src1",
5150                    "$src1, ${src2}"##_.BroadcastStr,
5151                    (_.VT (OpNode
5152                             _.RC:$src1,
5153                             (Ctrl.VT (X86VBroadcast
5154                                        (Ctrl.ScalarLdFrag addr:$src2)))))>,
5155                    T8PD, EVEX_4V, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
5156 }
5157
5158 multiclass avx512_permil_vec_common<string OpcodeStr, bits<8> OpcVar,
5159                              AVX512VLVectorVTInfo _, AVX512VLVectorVTInfo Ctrl>{
5160   let Predicates = [HasAVX512] in {
5161     defm Z    : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info512,
5162                                   Ctrl.info512>, EVEX_V512;
5163   }
5164   let Predicates = [HasAVX512, HasVLX] in {
5165     defm Z128 : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info128,
5166                                   Ctrl.info128>, EVEX_V128;
5167     defm Z256 : avx512_permil_vec<OpcVar, OpcodeStr, X86VPermilpv, _.info256,
5168                                   Ctrl.info256>, EVEX_V256;
5169   }
5170 }
5171
5172 multiclass avx512_permil<string OpcodeStr, bits<8> OpcImm, bits<8> OpcVar,
5173                          AVX512VLVectorVTInfo _, AVX512VLVectorVTInfo Ctrl>{
5174
5175   defm NAME: avx512_permil_vec_common<OpcodeStr, OpcVar, _, Ctrl>;
5176   defm NAME: avx512_shift_rmi_sizes<OpcImm, MRMSrcReg, MRMSrcMem, OpcodeStr,
5177                                     X86VPermilpi, _>,
5178                     EVEX, AVX512AIi8Base, EVEX_CD8<_.info128.EltSize, CD8VF>;
5179 }
5180
5181 let ExeDomain = SSEPackedSingle in
5182 defm VPERMILPS : avx512_permil<"vpermilps", 0x04, 0x0C, avx512vl_f32_info,
5183                                avx512vl_i32_info>;
5184 let ExeDomain = SSEPackedDouble in
5185 defm VPERMILPD : avx512_permil<"vpermilpd", 0x05, 0x0D, avx512vl_f64_info,
5186                                avx512vl_i64_info>, VEX_W;
5187 //===----------------------------------------------------------------------===//
5188 // AVX-512 - VPSHUFD, VPSHUFLW, VPSHUFHW
5189 //===----------------------------------------------------------------------===//
5190
5191 defm VPSHUFD : avx512_shift_rmi_sizes<0x70, MRMSrcReg, MRMSrcMem, "vpshufd",
5192                              X86PShufd, avx512vl_i32_info>,
5193                              EVEX, AVX512BIi8Base, EVEX_CD8<32, CD8VF>;
5194 defm VPSHUFH : avx512_shift_rmi_w<0x70, MRMSrcReg, MRMSrcMem, "vpshufhw",
5195                                   X86PShufhw>, EVEX, AVX512XSIi8Base;
5196 defm VPSHUFL : avx512_shift_rmi_w<0x70, MRMSrcReg, MRMSrcMem, "vpshuflw",
5197                                   X86PShuflw>, EVEX, AVX512XDIi8Base;
5198
5199 multiclass avx512_pshufb_sizes<bits<8> opc, string OpcodeStr, SDNode OpNode> {
5200   let Predicates = [HasBWI] in
5201   defm Z:    avx512_var_shift<opc, OpcodeStr, OpNode, v64i8_info>, EVEX_V512;
5202
5203   let Predicates = [HasVLX, HasBWI] in {
5204   defm Z256: avx512_var_shift<opc, OpcodeStr, OpNode, v32i8x_info>, EVEX_V256;
5205   defm Z128: avx512_var_shift<opc, OpcodeStr, OpNode, v16i8x_info>, EVEX_V128;
5206   }
5207 }
5208
5209 defm VPSHUFB: avx512_pshufb_sizes<0x00, "vpshufb", X86pshufb>;
5210
5211 //===----------------------------------------------------------------------===//
5212 // Move Low to High and High to Low packed FP Instructions
5213 //===----------------------------------------------------------------------===//
5214 def VMOVLHPSZrr : AVX512PSI<0x16, MRMSrcReg, (outs VR128X:$dst),
5215           (ins VR128X:$src1, VR128X:$src2),
5216           "vmovlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
5217           [(set VR128X:$dst, (v4f32 (X86Movlhps VR128X:$src1, VR128X:$src2)))],
5218            IIC_SSE_MOV_LH>, EVEX_4V;
5219 def VMOVHLPSZrr : AVX512PSI<0x12, MRMSrcReg, (outs VR128X:$dst),
5220           (ins VR128X:$src1, VR128X:$src2),
5221           "vmovhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
5222           [(set VR128X:$dst, (v4f32 (X86Movhlps VR128X:$src1, VR128X:$src2)))],
5223           IIC_SSE_MOV_LH>, EVEX_4V;
5224
5225 let Predicates = [HasAVX512] in {
5226   // MOVLHPS patterns
5227   def : Pat<(v4i32 (X86Movlhps VR128X:$src1, VR128X:$src2)),
5228             (VMOVLHPSZrr VR128X:$src1, VR128X:$src2)>;
5229   def : Pat<(v2i64 (X86Movlhps VR128X:$src1, VR128X:$src2)),
5230             (VMOVLHPSZrr (v2i64 VR128X:$src1), VR128X:$src2)>;
5231
5232   // MOVHLPS patterns
5233   def : Pat<(v4i32 (X86Movhlps VR128X:$src1, VR128X:$src2)),
5234             (VMOVHLPSZrr VR128X:$src1, VR128X:$src2)>;
5235 }
5236
5237 //===----------------------------------------------------------------------===//
5238 // VMOVHPS/PD VMOVLPS Instructions
5239 // All patterns was taken from SSS implementation.
5240 //===----------------------------------------------------------------------===//
5241 multiclass avx512_mov_hilo_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
5242                                   X86VectorVTInfo _> {
5243   let ExeDomain = _.ExeDomain in
5244   def rm : AVX512<opc, MRMSrcMem, (outs _.RC:$dst),
5245                   (ins _.RC:$src1, f64mem:$src2),
5246                   !strconcat(OpcodeStr,
5247                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5248                   [(set _.RC:$dst,
5249                      (OpNode _.RC:$src1,
5250                        (_.VT (bitconvert
5251                          (v2f64 (scalar_to_vector (loadf64 addr:$src2)))))))],
5252                   IIC_SSE_MOV_LH>, EVEX_4V;
5253 }
5254
5255 defm VMOVHPSZ128 : avx512_mov_hilo_packed<0x16, "vmovhps", X86Movlhps,
5256                                   v4f32x_info>, EVEX_CD8<32, CD8VT2>, PS;
5257 defm VMOVHPDZ128 : avx512_mov_hilo_packed<0x16, "vmovhpd", X86Movlhpd,
5258                                   v2f64x_info>, EVEX_CD8<64, CD8VT1>, PD, VEX_W;
5259 defm VMOVLPSZ128 : avx512_mov_hilo_packed<0x12, "vmovlps", X86Movlps,
5260                                   v4f32x_info>, EVEX_CD8<32, CD8VT2>, PS;
5261 defm VMOVLPDZ128 : avx512_mov_hilo_packed<0x12, "vmovlpd", X86Movlpd,
5262                                   v2f64x_info>, EVEX_CD8<64, CD8VT1>, PD, VEX_W;
5263
5264 let Predicates = [HasAVX512] in {
5265   // VMOVHPS patterns
5266   def : Pat<(X86Movlhps VR128X:$src1,
5267                (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
5268           (VMOVHPSZ128rm VR128X:$src1, addr:$src2)>;
5269   def : Pat<(X86Movlhps VR128X:$src1,
5270                (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
5271           (VMOVHPSZ128rm VR128X:$src1, addr:$src2)>;
5272   // VMOVHPD patterns
5273   def : Pat<(v2f64 (X86Unpckl VR128X:$src1,
5274                     (scalar_to_vector (loadf64 addr:$src2)))),
5275            (VMOVHPDZ128rm VR128X:$src1, addr:$src2)>;
5276   def : Pat<(v2f64 (X86Unpckl VR128X:$src1,
5277                     (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
5278            (VMOVHPDZ128rm VR128X:$src1, addr:$src2)>;
5279   // VMOVLPS patterns
5280   def : Pat<(v4f32 (X86Movlps VR128X:$src1, (load addr:$src2))),
5281           (VMOVLPSZ128rm VR128X:$src1, addr:$src2)>;
5282   def : Pat<(v4i32 (X86Movlps VR128X:$src1, (load addr:$src2))),
5283           (VMOVLPSZ128rm VR128X:$src1, addr:$src2)>;
5284   // VMOVLPD patterns
5285   def : Pat<(v2f64 (X86Movlpd VR128X:$src1, (load addr:$src2))),
5286           (VMOVLPDZ128rm VR128X:$src1, addr:$src2)>;
5287   def : Pat<(v2i64 (X86Movlpd VR128X:$src1, (load addr:$src2))),
5288           (VMOVLPDZ128rm VR128X:$src1, addr:$src2)>;
5289   def : Pat<(v2f64 (X86Movsd VR128X:$src1,
5290                            (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
5291           (VMOVLPDZ128rm VR128X:$src1, addr:$src2)>;
5292 }
5293
5294 def VMOVHPSZ128mr : AVX512PSI<0x17, MRMDestMem, (outs),
5295                        (ins f64mem:$dst, VR128X:$src),
5296                        "vmovhps\t{$src, $dst|$dst, $src}",
5297                        [(store (f64 (extractelt
5298                                      (X86Unpckh (bc_v2f64 (v4f32 VR128X:$src)),
5299                                                 (bc_v2f64 (v4f32 VR128X:$src))),
5300                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>,
5301                        EVEX, EVEX_CD8<32, CD8VT2>;
5302 def VMOVHPDZ128mr : AVX512PDI<0x17, MRMDestMem, (outs),
5303                        (ins f64mem:$dst, VR128X:$src),
5304                        "vmovhpd\t{$src, $dst|$dst, $src}",
5305                        [(store (f64 (extractelt
5306                                      (v2f64 (X86Unpckh VR128X:$src, VR128X:$src)),
5307                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>,
5308                        EVEX, EVEX_CD8<64, CD8VT1>, VEX_W;
5309 def VMOVLPSZ128mr : AVX512PSI<0x13, MRMDestMem, (outs),
5310                        (ins f64mem:$dst, VR128X:$src),
5311                        "vmovlps\t{$src, $dst|$dst, $src}",
5312                        [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128X:$src)),
5313                                      (iPTR 0))), addr:$dst)],
5314                                      IIC_SSE_MOV_LH>,
5315                        EVEX, EVEX_CD8<32, CD8VT2>;
5316 def VMOVLPDZ128mr : AVX512PDI<0x13, MRMDestMem, (outs),
5317                        (ins f64mem:$dst, VR128X:$src),
5318                        "vmovlpd\t{$src, $dst|$dst, $src}",
5319                        [(store (f64 (extractelt (v2f64 VR128X:$src),
5320                                      (iPTR 0))), addr:$dst)],
5321                                      IIC_SSE_MOV_LH>,
5322                        EVEX, EVEX_CD8<64, CD8VT1>, VEX_W;
5323
5324 let Predicates = [HasAVX512] in {
5325   // VMOVHPD patterns
5326   def : Pat<(store (f64 (extractelt
5327                            (v2f64 (X86VPermilpi VR128X:$src, (i8 1))),
5328                            (iPTR 0))), addr:$dst),
5329            (VMOVHPDZ128mr addr:$dst, VR128X:$src)>;
5330   // VMOVLPS patterns
5331   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128X:$src2)),
5332                    addr:$src1),
5333             (VMOVLPSZ128mr addr:$src1, VR128X:$src2)>;
5334   def : Pat<(store (v4i32 (X86Movlps
5335                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128X:$src2)), addr:$src1),
5336             (VMOVLPSZ128mr addr:$src1, VR128X:$src2)>;
5337   // VMOVLPD patterns
5338   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128X:$src2)),
5339                    addr:$src1),
5340             (VMOVLPDZ128mr addr:$src1, VR128X:$src2)>;
5341   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128X:$src2)),
5342                    addr:$src1),
5343             (VMOVLPDZ128mr addr:$src1, VR128X:$src2)>;
5344 }
5345 //===----------------------------------------------------------------------===//
5346 // FMA - Fused Multiply Operations
5347 //
5348
5349 multiclass avx512_fma3p_213_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5350                                X86VectorVTInfo _, string Suff> {
5351   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
5352   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5353           (ins _.RC:$src2, _.RC:$src3),
5354           OpcodeStr, "$src3, $src2", "$src2, $src3",
5355           (_.VT (OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3)), 1, 1>,
5356          AVX512FMA3Base;
5357
5358   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5359           (ins _.RC:$src2, _.MemOp:$src3),
5360           OpcodeStr, "$src3, $src2", "$src2, $src3",
5361           (_.VT (OpNode _.RC:$src2, _.RC:$src1, (_.LdFrag addr:$src3))), 1, 0>,
5362           AVX512FMA3Base;
5363
5364   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5365             (ins _.RC:$src2, _.ScalarMemOp:$src3),
5366             OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
5367             !strconcat("$src2, ${src3}", _.BroadcastStr ),
5368             (OpNode _.RC:$src2,
5369              _.RC:$src1,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3)))), 1, 0>,
5370             AVX512FMA3Base, EVEX_B;
5371   }
5372
5373   // Additional pattern for folding broadcast nodes in other orders.
5374   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5375                    (OpNode _.RC:$src1, _.RC:$src2,
5376                     (X86VBroadcast (_.ScalarLdFrag addr:$src3))),
5377                    _.RC:$src1)),
5378             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbk) _.RC:$src1,
5379              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5380 }
5381
5382 multiclass avx512_fma3_213_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
5383                                  X86VectorVTInfo _, string Suff> {
5384   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
5385   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5386           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5387           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
5388           (_.VT ( OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3, (i32 imm:$rc))), 1, 1>,
5389           AVX512FMA3Base, EVEX_B, EVEX_RC;
5390 }
5391
5392 multiclass avx512_fma3p_213_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5393                                    SDNode OpNodeRnd, AVX512VLVectorVTInfo _,
5394                                    string Suff> {
5395   let Predicates = [HasAVX512] in {
5396     defm Z      : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info512, Suff>,
5397                   avx512_fma3_213_round<opc, OpcodeStr, OpNodeRnd, _.info512,
5398                       Suff>, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5399   }
5400   let Predicates = [HasVLX, HasAVX512] in {
5401     defm Z256 : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info256, Suff>,
5402                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5403     defm Z128 : avx512_fma3p_213_rm<opc, OpcodeStr, OpNode, _.info128, Suff>,
5404                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5405   }
5406 }
5407
5408 multiclass avx512_fma3p_213_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
5409                               SDNode OpNodeRnd > {
5410     defm PS : avx512_fma3p_213_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
5411                                       avx512vl_f32_info, "PS">;
5412     defm PD : avx512_fma3p_213_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
5413                                       avx512vl_f64_info, "PD">, VEX_W;
5414 }
5415
5416 defm VFMADD213    : avx512_fma3p_213_f<0xA8, "vfmadd213", X86Fmadd, X86FmaddRnd>;
5417 defm VFMSUB213    : avx512_fma3p_213_f<0xAA, "vfmsub213", X86Fmsub, X86FmsubRnd>;
5418 defm VFMADDSUB213 : avx512_fma3p_213_f<0xA6, "vfmaddsub213", X86Fmaddsub, X86FmaddsubRnd>;
5419 defm VFMSUBADD213 : avx512_fma3p_213_f<0xA7, "vfmsubadd213", X86Fmsubadd, X86FmsubaddRnd>;
5420 defm VFNMADD213   : avx512_fma3p_213_f<0xAC, "vfnmadd213", X86Fnmadd, X86FnmaddRnd>;
5421 defm VFNMSUB213   : avx512_fma3p_213_f<0xAE, "vfnmsub213", X86Fnmsub, X86FnmsubRnd>;
5422
5423
5424 multiclass avx512_fma3p_231_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5425                                X86VectorVTInfo _, string Suff> {
5426   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
5427   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5428           (ins _.RC:$src2, _.RC:$src3),
5429           OpcodeStr, "$src3, $src2", "$src2, $src3",
5430           (_.VT (OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1)), 1, 1>,
5431          AVX512FMA3Base;
5432
5433   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5434           (ins _.RC:$src2, _.MemOp:$src3),
5435           OpcodeStr, "$src3, $src2", "$src2, $src3",
5436           (_.VT (OpNode _.RC:$src2, (_.LdFrag addr:$src3), _.RC:$src1)), 1, 0>,
5437          AVX512FMA3Base;
5438
5439   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5440          (ins _.RC:$src2, _.ScalarMemOp:$src3),
5441          OpcodeStr, "${src3}"##_.BroadcastStr##", $src2",
5442          "$src2, ${src3}"##_.BroadcastStr,
5443          (_.VT (OpNode _.RC:$src2,
5444                       (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
5445                       _.RC:$src1)), 1, 0>, AVX512FMA3Base, EVEX_B;
5446   }
5447
5448   // Additional patterns for folding broadcast nodes in other orders.
5449   def : Pat<(_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5450                    _.RC:$src2, _.RC:$src1)),
5451             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mb) _.RC:$src1,
5452              _.RC:$src2, addr:$src3)>;
5453   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5454                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5455                     _.RC:$src2, _.RC:$src1),
5456                    _.RC:$src1)),
5457             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbk) _.RC:$src1,
5458              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5459   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5460                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5461                     _.RC:$src2, _.RC:$src1),
5462                    _.ImmAllZerosV)),
5463             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbkz) _.RC:$src1,
5464              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5465 }
5466
5467 multiclass avx512_fma3_231_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
5468                                  X86VectorVTInfo _, string Suff> {
5469   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
5470   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5471           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5472           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
5473           (_.VT ( OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1, (i32 imm:$rc))), 1, 1>,
5474           AVX512FMA3Base, EVEX_B, EVEX_RC;
5475 }
5476
5477 multiclass avx512_fma3p_231_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5478                                    SDNode OpNodeRnd, AVX512VLVectorVTInfo _,
5479                                    string Suff> {
5480   let Predicates = [HasAVX512] in {
5481     defm Z      : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info512, Suff>,
5482                   avx512_fma3_231_round<opc, OpcodeStr, OpNodeRnd, _.info512,
5483                       Suff>, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5484   }
5485   let Predicates = [HasVLX, HasAVX512] in {
5486     defm Z256 : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info256, Suff>,
5487                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5488     defm Z128 : avx512_fma3p_231_rm<opc, OpcodeStr, OpNode, _.info128, Suff>,
5489                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5490   }
5491 }
5492
5493 multiclass avx512_fma3p_231_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
5494                               SDNode OpNodeRnd > {
5495     defm PS : avx512_fma3p_231_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
5496                                       avx512vl_f32_info, "PS">;
5497     defm PD : avx512_fma3p_231_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
5498                                       avx512vl_f64_info, "PD">, VEX_W;
5499 }
5500
5501 defm VFMADD231    : avx512_fma3p_231_f<0xB8, "vfmadd231", X86Fmadd, X86FmaddRnd>;
5502 defm VFMSUB231    : avx512_fma3p_231_f<0xBA, "vfmsub231", X86Fmsub, X86FmsubRnd>;
5503 defm VFMADDSUB231 : avx512_fma3p_231_f<0xB6, "vfmaddsub231", X86Fmaddsub, X86FmaddsubRnd>;
5504 defm VFMSUBADD231 : avx512_fma3p_231_f<0xB7, "vfmsubadd231", X86Fmsubadd, X86FmsubaddRnd>;
5505 defm VFNMADD231   : avx512_fma3p_231_f<0xBC, "vfnmadd231", X86Fnmadd, X86FnmaddRnd>;
5506 defm VFNMSUB231   : avx512_fma3p_231_f<0xBE, "vfnmsub231", X86Fnmsub, X86FnmsubRnd>;
5507
5508 multiclass avx512_fma3p_132_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5509                                X86VectorVTInfo _, string Suff> {
5510   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
5511   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5512           (ins _.RC:$src2, _.RC:$src3),
5513           OpcodeStr, "$src3, $src2", "$src2, $src3",
5514           (_.VT (OpNode _.RC:$src1, _.RC:$src3, _.RC:$src2)), 1, 1>,
5515          AVX512FMA3Base;
5516
5517   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5518           (ins _.RC:$src2, _.MemOp:$src3),
5519           OpcodeStr, "$src3, $src2", "$src2, $src3",
5520           (_.VT (OpNode _.RC:$src1, (_.LdFrag addr:$src3), _.RC:$src2)), 1, 0>,
5521          AVX512FMA3Base;
5522
5523   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5524          (ins _.RC:$src2, _.ScalarMemOp:$src3),
5525          OpcodeStr, "${src3}"##_.BroadcastStr##", $src2",
5526          "$src2, ${src3}"##_.BroadcastStr,
5527          (_.VT (OpNode _.RC:$src1,
5528                       (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
5529                       _.RC:$src2)), 1, 0>, AVX512FMA3Base, EVEX_B;
5530   }
5531
5532   // Additional patterns for folding broadcast nodes in other orders.
5533   def : Pat<(_.VT (vselect _.KRCWM:$mask,
5534                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
5535                     _.RC:$src1, _.RC:$src2),
5536                    _.RC:$src1)),
5537             (!cast<Instruction>(NAME#Suff#_.ZSuffix#mbk) _.RC:$src1,
5538              _.KRCWM:$mask, _.RC:$src2, addr:$src3)>;
5539 }
5540
5541 multiclass avx512_fma3_132_round<bits<8> opc, string OpcodeStr, SDNode OpNode,
5542                                  X86VectorVTInfo _, string Suff> {
5543   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in
5544   defm rb: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5545           (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5546           OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc",
5547           (_.VT ( OpNode _.RC:$src1, _.RC:$src3, _.RC:$src2, (i32 imm:$rc))), 1, 1>,
5548           AVX512FMA3Base, EVEX_B, EVEX_RC;
5549 }
5550
5551 multiclass avx512_fma3p_132_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5552                                    SDNode OpNodeRnd, AVX512VLVectorVTInfo _,
5553                                    string Suff> {
5554   let Predicates = [HasAVX512] in {
5555     defm Z      : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info512, Suff>,
5556                   avx512_fma3_132_round<opc, OpcodeStr, OpNodeRnd, _.info512,
5557                       Suff>, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5558   }
5559   let Predicates = [HasVLX, HasAVX512] in {
5560     defm Z256 : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info256, Suff>,
5561                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5562     defm Z128 : avx512_fma3p_132_rm<opc, OpcodeStr, OpNode, _.info128, Suff>,
5563                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5564   }
5565 }
5566
5567 multiclass avx512_fma3p_132_f<bits<8> opc, string OpcodeStr, SDNode OpNode,
5568                               SDNode OpNodeRnd > {
5569     defm PS : avx512_fma3p_132_common<opc, OpcodeStr#"ps", OpNode, OpNodeRnd,
5570                                       avx512vl_f32_info, "PS">;
5571     defm PD : avx512_fma3p_132_common<opc, OpcodeStr#"pd", OpNode, OpNodeRnd,
5572                                       avx512vl_f64_info, "PD">, VEX_W;
5573 }
5574
5575 defm VFMADD132    : avx512_fma3p_132_f<0x98, "vfmadd132", X86Fmadd, X86FmaddRnd>;
5576 defm VFMSUB132    : avx512_fma3p_132_f<0x9A, "vfmsub132", X86Fmsub, X86FmsubRnd>;
5577 defm VFMADDSUB132 : avx512_fma3p_132_f<0x96, "vfmaddsub132", X86Fmaddsub, X86FmaddsubRnd>;
5578 defm VFMSUBADD132 : avx512_fma3p_132_f<0x97, "vfmsubadd132", X86Fmsubadd, X86FmsubaddRnd>;
5579 defm VFNMADD132   : avx512_fma3p_132_f<0x9C, "vfnmadd132", X86Fnmadd, X86FnmaddRnd>;
5580 defm VFNMSUB132   : avx512_fma3p_132_f<0x9E, "vfnmsub132", X86Fnmsub, X86FnmsubRnd>;
5581
5582 // Scalar FMA
5583 let Constraints = "$src1 = $dst" in {
5584 multiclass avx512_fma3s_common<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
5585                                dag RHS_VEC_r, dag RHS_VEC_m, dag RHS_VEC_rb,
5586                                                         dag RHS_r, dag RHS_m > {
5587   defm r_Int: AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5588           (ins _.RC:$src2, _.RC:$src3), OpcodeStr,
5589           "$src3, $src2", "$src2, $src3", RHS_VEC_r, 1, 1>, AVX512FMA3Base;
5590
5591   defm m_Int: AVX512_maskable_3src_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
5592           (ins _.RC:$src2, _.IntScalarMemOp:$src3), OpcodeStr,
5593           "$src3, $src2", "$src2, $src3", RHS_VEC_m, 1, 1>, AVX512FMA3Base;
5594
5595   defm rb_Int: AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
5596          (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc),
5597          OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc", RHS_VEC_rb, 1, 1>,
5598                                        AVX512FMA3Base, EVEX_B, EVEX_RC;
5599
5600   let isCodeGenOnly = 1, isCommutable = 1 in {
5601     def r     : AVX512FMA3<opc, MRMSrcReg, (outs _.FRC:$dst),
5602                      (ins _.FRC:$src1, _.FRC:$src2, _.FRC:$src3),
5603                      !strconcat(OpcodeStr,
5604                               "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5605                      [RHS_r]>;
5606     def m     : AVX512FMA3<opc, MRMSrcMem, (outs _.FRC:$dst),
5607                     (ins _.FRC:$src1, _.FRC:$src2, _.ScalarMemOp:$src3),
5608                     !strconcat(OpcodeStr,
5609                                "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5610                     [RHS_m]>;
5611   }// isCodeGenOnly = 1
5612 }
5613 }// Constraints = "$src1 = $dst"
5614
5615 multiclass avx512_fma3s_all<bits<8> opc213, bits<8> opc231, bits<8> opc132,
5616                             string OpcodeStr, SDNode OpNode, SDNode OpNodeRnds1,
5617                             SDNode OpNodeRnds3, X86VectorVTInfo _ , string SUFF> {
5618   let ExeDomain = _.ExeDomain in {
5619   defm NAME#213#SUFF#Z: avx512_fma3s_common<opc213, OpcodeStr#"213"#_.Suffix , _ ,
5620                 // Operands for intrinsic are in 123 order to preserve passthu
5621                 // semantics.
5622                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src2, _.RC:$src3, (i32 FROUND_CURRENT))),
5623                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src2,
5624                          _.ScalarIntMemCPat:$src3, (i32 FROUND_CURRENT))),
5625                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src2, _.RC:$src3,
5626                          (i32 imm:$rc))),
5627                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src1,
5628                          _.FRC:$src3))),
5629                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src1,
5630                          (_.ScalarLdFrag addr:$src3))))>;
5631
5632   defm NAME#231#SUFF#Z: avx512_fma3s_common<opc231, OpcodeStr#"231"#_.Suffix , _ ,
5633                 (_.VT (OpNodeRnds3 _.RC:$src2, _.RC:$src3, _.RC:$src1, (i32 FROUND_CURRENT))),
5634                 (_.VT (OpNodeRnds3 _.RC:$src2, _.ScalarIntMemCPat:$src3,
5635                               _.RC:$src1, (i32 FROUND_CURRENT))),
5636                 (_.VT ( OpNodeRnds3 _.RC:$src2, _.RC:$src3, _.RC:$src1,
5637                                   (i32 imm:$rc))),
5638                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2, _.FRC:$src3,
5639                                           _.FRC:$src1))),
5640                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src2,
5641                             (_.ScalarLdFrag addr:$src3), _.FRC:$src1)))>;
5642
5643   defm NAME#132#SUFF#Z: avx512_fma3s_common<opc132, OpcodeStr#"132"#_.Suffix , _ ,
5644                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src3, _.RC:$src2, (i32 FROUND_CURRENT))),
5645                 (_.VT (OpNodeRnds1 _.RC:$src1, _.ScalarIntMemCPat:$src3,
5646                               _.RC:$src2, (i32 FROUND_CURRENT))),
5647                 (_.VT (OpNodeRnds1 _.RC:$src1, _.RC:$src3, _.RC:$src2,
5648                          (i32 imm:$rc))),
5649                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src1, _.FRC:$src3,
5650                          _.FRC:$src2))),
5651                 (set _.FRC:$dst, (_.EltVT (OpNode _.FRC:$src1,
5652                           (_.ScalarLdFrag addr:$src3), _.FRC:$src2)))>;
5653   }
5654 }
5655
5656 multiclass avx512_fma3s<bits<8> opc213, bits<8> opc231, bits<8> opc132,
5657                         string OpcodeStr, SDNode OpNode, SDNode OpNodeRnds1,
5658                         SDNode OpNodeRnds3> {
5659   let Predicates = [HasAVX512] in {
5660     defm NAME : avx512_fma3s_all<opc213, opc231, opc132, OpcodeStr, OpNode,
5661                                  OpNodeRnds1, OpNodeRnds3, f32x_info, "SS">,
5662                                  EVEX_CD8<32, CD8VT1>, VEX_LIG;
5663     defm NAME : avx512_fma3s_all<opc213, opc231, opc132, OpcodeStr, OpNode,
5664                                  OpNodeRnds1, OpNodeRnds3, f64x_info, "SD">,
5665                                  EVEX_CD8<64, CD8VT1>, VEX_LIG, VEX_W;
5666   }
5667 }
5668
5669 defm VFMADD  : avx512_fma3s<0xA9, 0xB9, 0x99, "vfmadd", X86Fmadd, X86FmaddRnds1,
5670                             X86FmaddRnds3>;
5671 defm VFMSUB  : avx512_fma3s<0xAB, 0xBB, 0x9B, "vfmsub", X86Fmsub, X86FmsubRnds1,
5672                             X86FmsubRnds3>;
5673 defm VFNMADD : avx512_fma3s<0xAD, 0xBD, 0x9D, "vfnmadd", X86Fnmadd,
5674                             X86FnmaddRnds1, X86FnmaddRnds3>;
5675 defm VFNMSUB : avx512_fma3s<0xAF, 0xBF, 0x9F, "vfnmsub", X86Fnmsub,
5676                             X86FnmsubRnds1, X86FnmsubRnds3>;
5677
5678 //===----------------------------------------------------------------------===//
5679 // AVX-512  Packed Multiply of Unsigned 52-bit Integers and Add the Low 52-bit IFMA
5680 //===----------------------------------------------------------------------===//
5681 let Constraints = "$src1 = $dst" in {
5682 multiclass avx512_pmadd52_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5683                                                             X86VectorVTInfo _> {
5684   let ExeDomain = _.ExeDomain in {
5685   defm r: AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
5686           (ins _.RC:$src2, _.RC:$src3),
5687           OpcodeStr, "$src3, $src2", "$src2, $src3",
5688           (_.VT (OpNode _.RC:$src1, _.RC:$src2, _.RC:$src3))>,
5689          AVX512FMA3Base;
5690
5691   defm m: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5692           (ins _.RC:$src2, _.MemOp:$src3),
5693           OpcodeStr, "$src3, $src2", "$src2, $src3",
5694           (_.VT (OpNode _.RC:$src1, _.RC:$src2, (_.LdFrag addr:$src3)))>,
5695           AVX512FMA3Base;
5696
5697   defm mb: AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
5698             (ins _.RC:$src2, _.ScalarMemOp:$src3),
5699             OpcodeStr,   !strconcat("${src3}", _.BroadcastStr,", $src2"),
5700             !strconcat("$src2, ${src3}", _.BroadcastStr ),
5701             (OpNode _.RC:$src1,
5702              _.RC:$src2,(_.VT (X86VBroadcast (_.ScalarLdFrag addr:$src3))))>,
5703             AVX512FMA3Base, EVEX_B;
5704   }
5705 }
5706 } // Constraints = "$src1 = $dst"
5707
5708 multiclass avx512_pmadd52_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
5709                                      AVX512VLVectorVTInfo _> {
5710   let Predicates = [HasIFMA] in {
5711     defm Z      : avx512_pmadd52_rm<opc, OpcodeStr, OpNode, _.info512>,
5712                       EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>;
5713   }
5714   let Predicates = [HasVLX, HasIFMA] in {
5715     defm Z256 : avx512_pmadd52_rm<opc, OpcodeStr, OpNode, _.info256>,
5716                       EVEX_V256, EVEX_CD8<_.info256.EltSize, CD8VF>;
5717     defm Z128 : avx512_pmadd52_rm<opc, OpcodeStr, OpNode, _.info128>,
5718                       EVEX_V128, EVEX_CD8<_.info128.EltSize, CD8VF>;
5719   }
5720 }
5721
5722 defm VPMADD52LUQ : avx512_pmadd52_common<0xb4, "vpmadd52luq", x86vpmadd52l,
5723                                   avx512vl_i64_info>, VEX_W;
5724 defm VPMADD52HUQ : avx512_pmadd52_common<0xb5, "vpmadd52huq", x86vpmadd52h,
5725                                   avx512vl_i64_info>, VEX_W;
5726
5727 //===----------------------------------------------------------------------===//
5728 // AVX-512  Scalar convert from sign integer to float/double
5729 //===----------------------------------------------------------------------===//
5730
5731 multiclass avx512_vcvtsi<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
5732                     X86VectorVTInfo DstVT, X86MemOperand x86memop,
5733                     PatFrag ld_frag, string asm> {
5734   let hasSideEffects = 0 in {
5735     def rr : SI<opc, MRMSrcReg, (outs DstVT.FRC:$dst),
5736               (ins DstVT.FRC:$src1, SrcRC:$src),
5737               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
5738               EVEX_4V;
5739     let mayLoad = 1 in
5740       def rm : SI<opc, MRMSrcMem, (outs DstVT.FRC:$dst),
5741               (ins DstVT.FRC:$src1, x86memop:$src),
5742               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
5743               EVEX_4V;
5744   } // hasSideEffects = 0
5745   let isCodeGenOnly = 1 in {
5746     def rr_Int : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst),
5747                   (ins DstVT.RC:$src1, SrcRC:$src2),
5748                   !strconcat(asm,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5749                   [(set DstVT.RC:$dst,
5750                         (OpNode (DstVT.VT DstVT.RC:$src1),
5751                                  SrcRC:$src2,
5752                                  (i32 FROUND_CURRENT)))]>, EVEX_4V;
5753
5754     def rm_Int : SI<opc, MRMSrcMem, (outs DstVT.RC:$dst),
5755                   (ins DstVT.RC:$src1, x86memop:$src2),
5756                   !strconcat(asm,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5757                   [(set DstVT.RC:$dst,
5758                         (OpNode (DstVT.VT DstVT.RC:$src1),
5759                                  (ld_frag addr:$src2),
5760                                  (i32 FROUND_CURRENT)))]>, EVEX_4V;
5761   }//isCodeGenOnly = 1
5762 }
5763
5764 multiclass avx512_vcvtsi_round<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
5765                     X86VectorVTInfo DstVT, string asm> {
5766   def rrb_Int : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst),
5767               (ins DstVT.RC:$src1, SrcRC:$src2, AVX512RC:$rc),
5768               !strconcat(asm,
5769                   "\t{$src2, $rc, $src1, $dst|$dst, $src1, $rc, $src2}"),
5770               [(set DstVT.RC:$dst,
5771                     (OpNode (DstVT.VT DstVT.RC:$src1),
5772                              SrcRC:$src2,
5773                              (i32 imm:$rc)))]>, EVEX_4V, EVEX_B, EVEX_RC;
5774 }
5775
5776 multiclass avx512_vcvtsi_common<bits<8> opc, SDNode OpNode, RegisterClass SrcRC,
5777                     X86VectorVTInfo DstVT, X86MemOperand x86memop,
5778                     PatFrag ld_frag, string asm> {
5779   defm NAME : avx512_vcvtsi_round<opc, OpNode, SrcRC, DstVT, asm>,
5780               avx512_vcvtsi<opc, OpNode, SrcRC, DstVT, x86memop, ld_frag, asm>,
5781                         VEX_LIG;
5782 }
5783
5784 let Predicates = [HasAVX512] in {
5785 defm VCVTSI2SSZ  : avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR32,
5786                                  v4f32x_info, i32mem, loadi32, "cvtsi2ss{l}">,
5787                                  XS, EVEX_CD8<32, CD8VT1>;
5788 defm VCVTSI642SSZ: avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR64,
5789                                  v4f32x_info, i64mem, loadi64, "cvtsi2ss{q}">,
5790                                  XS, VEX_W, EVEX_CD8<64, CD8VT1>;
5791 defm VCVTSI2SDZ  : avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR32,
5792                                  v2f64x_info, i32mem, loadi32, "cvtsi2sd{l}">,
5793                                  XD, EVEX_CD8<32, CD8VT1>;
5794 defm VCVTSI642SDZ: avx512_vcvtsi_common<0x2A, X86SintToFpRnd, GR64,
5795                                  v2f64x_info, i64mem, loadi64, "cvtsi2sd{q}">,
5796                                  XD, VEX_W, EVEX_CD8<64, CD8VT1>;
5797
5798 def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
5799               (VCVTSI2SSZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5800 def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
5801               (VCVTSI2SDZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5802
5803 def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
5804           (VCVTSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5805 def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
5806           (VCVTSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5807 def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
5808           (VCVTSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5809 def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
5810           (VCVTSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5811
5812 def : Pat<(f32 (sint_to_fp GR32:$src)),
5813           (VCVTSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
5814 def : Pat<(f32 (sint_to_fp GR64:$src)),
5815           (VCVTSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
5816 def : Pat<(f64 (sint_to_fp GR32:$src)),
5817           (VCVTSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
5818 def : Pat<(f64 (sint_to_fp GR64:$src)),
5819           (VCVTSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
5820
5821 defm VCVTUSI2SSZ   : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR32,
5822                                   v4f32x_info, i32mem, loadi32,
5823                                   "cvtusi2ss{l}">, XS, EVEX_CD8<32, CD8VT1>;
5824 defm VCVTUSI642SSZ : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR64,
5825                                   v4f32x_info, i64mem, loadi64, "cvtusi2ss{q}">,
5826                                   XS, VEX_W, EVEX_CD8<64, CD8VT1>;
5827 defm VCVTUSI2SDZ   : avx512_vcvtsi<0x7B, X86UintToFpRnd, GR32, v2f64x_info,
5828                                   i32mem, loadi32, "cvtusi2sd{l}">,
5829                                   XD, VEX_LIG, EVEX_CD8<32, CD8VT1>;
5830 defm VCVTUSI642SDZ : avx512_vcvtsi_common<0x7B, X86UintToFpRnd, GR64,
5831                                   v2f64x_info, i64mem, loadi64, "cvtusi2sd{q}">,
5832                                   XD, VEX_W, EVEX_CD8<64, CD8VT1>;
5833
5834 def : InstAlias<"vcvtusi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
5835               (VCVTUSI2SSZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5836 def : InstAlias<"vcvtusi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
5837               (VCVTUSI2SDZrm FR64X:$dst, FR64X:$src1, i32mem:$src), 0>;
5838
5839 def : Pat<(f32 (uint_to_fp (loadi32 addr:$src))),
5840           (VCVTUSI2SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5841 def : Pat<(f32 (uint_to_fp (loadi64 addr:$src))),
5842           (VCVTUSI642SSZrm (f32 (IMPLICIT_DEF)), addr:$src)>;
5843 def : Pat<(f64 (uint_to_fp (loadi32 addr:$src))),
5844           (VCVTUSI2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5845 def : Pat<(f64 (uint_to_fp (loadi64 addr:$src))),
5846           (VCVTUSI642SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>;
5847
5848 def : Pat<(f32 (uint_to_fp GR32:$src)),
5849           (VCVTUSI2SSZrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
5850 def : Pat<(f32 (uint_to_fp GR64:$src)),
5851           (VCVTUSI642SSZrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
5852 def : Pat<(f64 (uint_to_fp GR32:$src)),
5853           (VCVTUSI2SDZrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
5854 def : Pat<(f64 (uint_to_fp GR64:$src)),
5855           (VCVTUSI642SDZrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
5856 }
5857
5858 //===----------------------------------------------------------------------===//
5859 // AVX-512  Scalar convert from float/double to integer
5860 //===----------------------------------------------------------------------===//
5861 multiclass avx512_cvt_s_int_round<bits<8> opc, X86VectorVTInfo SrcVT ,
5862                                   X86VectorVTInfo DstVT, SDNode OpNode, string asm> {
5863   let Predicates = [HasAVX512] in {
5864     def rr : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst), (ins SrcVT.RC:$src),
5865                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5866                 [(set DstVT.RC:$dst, (OpNode (SrcVT.VT SrcVT.RC:$src),(i32 FROUND_CURRENT)))]>,
5867                 EVEX, VEX_LIG;
5868     def rb : SI<opc, MRMSrcReg, (outs DstVT.RC:$dst), (ins SrcVT.RC:$src, AVX512RC:$rc),
5869                 !strconcat(asm,"\t{$rc, $src, $dst|$dst, $src, $rc}"),
5870                 [(set DstVT.RC:$dst, (OpNode (SrcVT.VT SrcVT.RC:$src),(i32 imm:$rc)))]>,
5871                 EVEX, VEX_LIG, EVEX_B, EVEX_RC;
5872     def rm : SI<opc, MRMSrcMem, (outs DstVT.RC:$dst), (ins SrcVT.IntScalarMemOp:$src),
5873                 !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5874                 [(set DstVT.RC:$dst, (OpNode
5875                       (SrcVT.VT SrcVT.ScalarIntMemCPat:$src),
5876                       (i32 FROUND_CURRENT)))]>,
5877                 EVEX, VEX_LIG;
5878   } // Predicates = [HasAVX512]
5879 }
5880
5881 // Convert float/double to signed/unsigned int 32/64
5882 defm VCVTSS2SIZ: avx512_cvt_s_int_round<0x2D, f32x_info, i32x_info,
5883                                    X86cvts2si, "cvtss2si">,
5884                                    XS, EVEX_CD8<32, CD8VT1>;
5885 defm VCVTSS2SI64Z: avx512_cvt_s_int_round<0x2D, f32x_info, i64x_info,
5886                                    X86cvts2si, "cvtss2si">,
5887                                    XS, VEX_W, EVEX_CD8<32, CD8VT1>;
5888 defm VCVTSS2USIZ: avx512_cvt_s_int_round<0x79, f32x_info, i32x_info,
5889                                    X86cvts2usi, "cvtss2usi">,
5890                                    XS, EVEX_CD8<32, CD8VT1>;
5891 defm VCVTSS2USI64Z: avx512_cvt_s_int_round<0x79, f32x_info, i64x_info,
5892                                    X86cvts2usi, "cvtss2usi">, XS, VEX_W,
5893                                    EVEX_CD8<32, CD8VT1>;
5894 defm VCVTSD2SIZ: avx512_cvt_s_int_round<0x2D, f64x_info, i32x_info,
5895                                    X86cvts2si, "cvtsd2si">,
5896                                    XD, EVEX_CD8<64, CD8VT1>;
5897 defm VCVTSD2SI64Z: avx512_cvt_s_int_round<0x2D, f64x_info, i64x_info,
5898                                    X86cvts2si, "cvtsd2si">,
5899                                    XD, VEX_W, EVEX_CD8<64, CD8VT1>;
5900 defm VCVTSD2USIZ:   avx512_cvt_s_int_round<0x79, f64x_info, i32x_info,
5901                                    X86cvts2usi, "cvtsd2usi">,
5902                                    XD, EVEX_CD8<64, CD8VT1>;
5903 defm VCVTSD2USI64Z: avx512_cvt_s_int_round<0x79, f64x_info, i64x_info,
5904                                    X86cvts2usi, "cvtsd2usi">, XD, VEX_W,
5905                                    EVEX_CD8<64, CD8VT1>;
5906
5907 // The SSE version of these instructions are disabled for AVX512.
5908 // Therefore, the SSE intrinsics are mapped to the AVX512 instructions.
5909 let Predicates = [HasAVX512] in {
5910   def : Pat<(i32 (int_x86_sse_cvtss2si (v4f32 VR128X:$src))),
5911             (VCVTSS2SIZrr VR128X:$src)>;
5912   def : Pat<(i32 (int_x86_sse_cvtss2si sse_load_f32:$src)),
5913             (VCVTSS2SIZrm sse_load_f32:$src)>;
5914   def : Pat<(i64 (int_x86_sse_cvtss2si64 (v4f32 VR128X:$src))),
5915             (VCVTSS2SI64Zrr VR128X:$src)>;
5916   def : Pat<(i64 (int_x86_sse_cvtss2si64 sse_load_f32:$src)),
5917             (VCVTSS2SI64Zrm sse_load_f32:$src)>;
5918   def : Pat<(i32 (int_x86_sse2_cvtsd2si (v2f64 VR128X:$src))),
5919             (VCVTSD2SIZrr VR128X:$src)>;
5920   def : Pat<(i32 (int_x86_sse2_cvtsd2si sse_load_f64:$src)),
5921             (VCVTSD2SIZrm sse_load_f64:$src)>;
5922   def : Pat<(i64 (int_x86_sse2_cvtsd2si64 (v2f64 VR128X:$src))),
5923             (VCVTSD2SI64Zrr VR128X:$src)>;
5924   def : Pat<(i64 (int_x86_sse2_cvtsd2si64 sse_load_f64:$src)),
5925             (VCVTSD2SI64Zrm sse_load_f64:$src)>;
5926 } // HasAVX512
5927
5928 let Predicates = [HasAVX512] in {
5929   def : Pat<(int_x86_sse_cvtsi2ss VR128X:$src1, GR32:$src2),
5930             (VCVTSI2SSZrr_Int VR128X:$src1, GR32:$src2)>;
5931   def : Pat<(int_x86_sse_cvtsi2ss VR128X:$src1, (loadi32 addr:$src2)),
5932             (VCVTSI2SSZrm_Int VR128X:$src1, addr:$src2)>;
5933   def : Pat<(int_x86_sse_cvtsi642ss VR128X:$src1, GR64:$src2),
5934             (VCVTSI642SSZrr_Int VR128X:$src1, GR64:$src2)>;
5935   def : Pat<(int_x86_sse_cvtsi642ss VR128X:$src1, (loadi64 addr:$src2)),
5936             (VCVTSI642SSZrm_Int VR128X:$src1, addr:$src2)>;
5937   def : Pat<(int_x86_sse2_cvtsi2sd VR128X:$src1, GR32:$src2),
5938             (VCVTSI2SDZrr_Int VR128X:$src1, GR32:$src2)>;
5939   def : Pat<(int_x86_sse2_cvtsi2sd VR128X:$src1, (loadi32 addr:$src2)),
5940             (VCVTSI2SDZrm_Int VR128X:$src1, addr:$src2)>;
5941   def : Pat<(int_x86_sse2_cvtsi642sd VR128X:$src1, GR64:$src2),
5942             (VCVTSI642SDZrr_Int VR128X:$src1, GR64:$src2)>;
5943   def : Pat<(int_x86_sse2_cvtsi642sd VR128X:$src1, (loadi64 addr:$src2)),
5944             (VCVTSI642SDZrm_Int VR128X:$src1, addr:$src2)>;
5945   def : Pat<(int_x86_avx512_cvtusi2sd VR128X:$src1, GR32:$src2),
5946             (VCVTUSI2SDZrr_Int VR128X:$src1, GR32:$src2)>;
5947   def : Pat<(int_x86_avx512_cvtusi2sd VR128X:$src1, (loadi32 addr:$src2)),
5948             (VCVTUSI2SDZrm_Int VR128X:$src1, addr:$src2)>;
5949 } // Predicates = [HasAVX512]
5950
5951 // Patterns used for matching vcvtsi2s{s,d} intrinsic sequences from clang
5952 // which produce unnecessary vmovs{s,d} instructions
5953 let Predicates = [HasAVX512] in {
5954 def : Pat<(v4f32 (X86Movss
5955                    (v4f32 VR128X:$dst),
5956                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR64:$src)))))),
5957           (VCVTSI642SSZrr_Int VR128X:$dst, GR64:$src)>;
5958
5959 def : Pat<(v4f32 (X86Movss
5960                    (v4f32 VR128X:$dst),
5961                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR32:$src)))))),
5962           (VCVTSI2SSZrr_Int VR128X:$dst, GR32:$src)>;
5963
5964 def : Pat<(v2f64 (X86Movsd
5965                    (v2f64 VR128X:$dst),
5966                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR64:$src)))))),
5967           (VCVTSI642SDZrr_Int VR128X:$dst, GR64:$src)>;
5968
5969 def : Pat<(v2f64 (X86Movsd
5970                    (v2f64 VR128X:$dst),
5971                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR32:$src)))))),
5972           (VCVTSI2SDZrr_Int VR128X:$dst, GR32:$src)>;
5973 } // Predicates = [HasAVX512]
5974
5975 // Convert float/double to signed/unsigned int 32/64 with truncation
5976 multiclass avx512_cvt_s_all<bits<8> opc, string asm, X86VectorVTInfo _SrcRC,
5977                             X86VectorVTInfo _DstRC, SDNode OpNode,
5978                             SDNode OpNodeRnd, string aliasStr>{
5979 let Predicates = [HasAVX512] in {
5980   def rr : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
5981               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5982               [(set _DstRC.RC:$dst, (OpNode _SrcRC.FRC:$src))]>, EVEX;
5983   let hasSideEffects = 0 in
5984   def rb : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.FRC:$src),
5985                 !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
5986                 []>, EVEX, EVEX_B;
5987   def rm : AVX512<opc, MRMSrcMem, (outs _DstRC.RC:$dst), (ins _SrcRC.ScalarMemOp:$src),
5988               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
5989               [(set _DstRC.RC:$dst, (OpNode (_SrcRC.ScalarLdFrag addr:$src)))]>,
5990               EVEX;
5991
5992   def : InstAlias<asm # aliasStr # "\t{$src, $dst|$dst, $src}",
5993           (!cast<Instruction>(NAME # "rr") _DstRC.RC:$dst, _SrcRC.FRC:$src), 0>;
5994   def : InstAlias<asm # aliasStr # "\t\t{{sae}, $src, $dst|$dst, $src, {sae}}",
5995           (!cast<Instruction>(NAME # "rb") _DstRC.RC:$dst, _SrcRC.FRC:$src), 0>;
5996   def : InstAlias<asm # aliasStr # "\t{$src, $dst|$dst, $src}",
5997           (!cast<Instruction>(NAME # "rm") _DstRC.RC:$dst,
5998                                           _SrcRC.ScalarMemOp:$src), 0>;
5999
6000   let isCodeGenOnly = 1 in {
6001     def rr_Int : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
6002               !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
6003              [(set _DstRC.RC:$dst, (OpNodeRnd (_SrcRC.VT _SrcRC.RC:$src),
6004                                    (i32 FROUND_CURRENT)))]>, EVEX, VEX_LIG;
6005     def rb_Int : AVX512<opc, MRMSrcReg, (outs _DstRC.RC:$dst), (ins _SrcRC.RC:$src),
6006               !strconcat(asm,"\t{{sae}, $src, $dst|$dst, $src, {sae}}"),
6007               [(set _DstRC.RC:$dst, (OpNodeRnd (_SrcRC.VT _SrcRC.RC:$src),
6008                                     (i32 FROUND_NO_EXC)))]>,
6009                                     EVEX,VEX_LIG , EVEX_B;
6010     let mayLoad = 1, hasSideEffects = 0 in
6011       def rm_Int : AVX512<opc, MRMSrcMem, (outs _DstRC.RC:$dst),
6012                   (ins _SrcRC.IntScalarMemOp:$src),
6013                   !strconcat(asm,"\t{$src, $dst|$dst, $src}"),
6014                   []>, EVEX, VEX_LIG;
6015
6016   } // isCodeGenOnly = 1
6017 } //HasAVX512
6018 }
6019
6020
6021 defm VCVTTSS2SIZ: avx512_cvt_s_all<0x2C, "vcvttss2si", f32x_info, i32x_info,
6022                         fp_to_sint, X86cvtts2IntRnd, "{l}">,
6023                         XS, EVEX_CD8<32, CD8VT1>;
6024 defm VCVTTSS2SI64Z: avx512_cvt_s_all<0x2C, "vcvttss2si", f32x_info, i64x_info,
6025                         fp_to_sint, X86cvtts2IntRnd, "{q}">,
6026                         VEX_W, XS, EVEX_CD8<32, CD8VT1>;
6027 defm VCVTTSD2SIZ: avx512_cvt_s_all<0x2C, "vcvttsd2si", f64x_info, i32x_info,
6028                         fp_to_sint, X86cvtts2IntRnd, "{l}">,
6029                         XD, EVEX_CD8<64, CD8VT1>;
6030 defm VCVTTSD2SI64Z: avx512_cvt_s_all<0x2C, "vcvttsd2si", f64x_info, i64x_info,
6031                         fp_to_sint, X86cvtts2IntRnd, "{q}">,
6032                         VEX_W, XD, EVEX_CD8<64, CD8VT1>;
6033
6034 defm VCVTTSS2USIZ: avx512_cvt_s_all<0x78, "vcvttss2usi", f32x_info, i32x_info,
6035                         fp_to_uint, X86cvtts2UIntRnd, "{l}">,
6036                         XS, EVEX_CD8<32, CD8VT1>;
6037 defm VCVTTSS2USI64Z: avx512_cvt_s_all<0x78, "vcvttss2usi", f32x_info, i64x_info,
6038                         fp_to_uint, X86cvtts2UIntRnd, "{q}">,
6039                         XS,VEX_W, EVEX_CD8<32, CD8VT1>;
6040 defm VCVTTSD2USIZ: avx512_cvt_s_all<0x78, "vcvttsd2usi", f64x_info, i32x_info,
6041                         fp_to_uint, X86cvtts2UIntRnd, "{l}">,
6042                         XD, EVEX_CD8<64, CD8VT1>;
6043 defm VCVTTSD2USI64Z: avx512_cvt_s_all<0x78, "vcvttsd2usi", f64x_info, i64x_info,
6044                         fp_to_uint, X86cvtts2UIntRnd, "{q}">,
6045                         XD, VEX_W, EVEX_CD8<64, CD8VT1>;
6046 let Predicates = [HasAVX512] in {
6047   def : Pat<(i32 (int_x86_sse_cvttss2si (v4f32 VR128X:$src))),
6048             (VCVTTSS2SIZrr_Int VR128X:$src)>;
6049   def : Pat<(i32 (int_x86_sse_cvttss2si sse_load_f32:$src)),
6050             (VCVTTSS2SIZrm_Int ssmem:$src)>;
6051   def : Pat<(i64 (int_x86_sse_cvttss2si64 (v4f32 VR128X:$src))),
6052             (VCVTTSS2SI64Zrr_Int VR128X:$src)>;
6053   def : Pat<(i64 (int_x86_sse_cvttss2si64 sse_load_f32:$src)),
6054             (VCVTTSS2SI64Zrm_Int ssmem:$src)>;
6055   def : Pat<(i32 (int_x86_sse2_cvttsd2si (v2f64 VR128X:$src))),
6056             (VCVTTSD2SIZrr_Int VR128X:$src)>;
6057   def : Pat<(i32 (int_x86_sse2_cvttsd2si sse_load_f64:$src)),
6058             (VCVTTSD2SIZrm_Int sdmem:$src)>;
6059   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 (v2f64 VR128X:$src))),
6060             (VCVTTSD2SI64Zrr_Int VR128X:$src)>;
6061   def : Pat<(i64 (int_x86_sse2_cvttsd2si64 sse_load_f64:$src)),
6062             (VCVTTSD2SI64Zrm_Int sdmem:$src)>;
6063 } // HasAVX512
6064 //===----------------------------------------------------------------------===//
6065 // AVX-512  Convert form float to double and back
6066 //===----------------------------------------------------------------------===//
6067 multiclass avx512_cvt_fp_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6068                          X86VectorVTInfo _Src, SDNode OpNode> {
6069   defm rr_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6070                          (ins _.RC:$src1, _Src.RC:$src2), OpcodeStr,
6071                          "$src2, $src1", "$src1, $src2",
6072                          (_.VT (OpNode (_.VT _.RC:$src1),
6073                                        (_Src.VT _Src.RC:$src2),
6074                                        (i32 FROUND_CURRENT)))>,
6075                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2F]>;
6076   defm rm_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6077                          (ins _.RC:$src1, _Src.IntScalarMemOp:$src2), OpcodeStr,
6078                          "$src2, $src1", "$src1, $src2",
6079                          (_.VT (OpNode (_.VT _.RC:$src1),
6080                                   (_Src.VT _Src.ScalarIntMemCPat:$src2),
6081                                   (i32 FROUND_CURRENT)))>,
6082                          EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
6083
6084   let isCodeGenOnly = 1, hasSideEffects = 0 in {
6085     def rr : I<opc, MRMSrcReg, (outs _.FRC:$dst),
6086                (ins _.FRC:$src1, _Src.FRC:$src2),
6087                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
6088                EVEX_4V, VEX_LIG, Sched<[WriteCvtF2F]>;
6089     let mayLoad = 1 in
6090     def rm : I<opc, MRMSrcMem, (outs _.FRC:$dst),
6091                (ins _.FRC:$src1, _Src.ScalarMemOp:$src2),
6092                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
6093                EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
6094   }
6095 }
6096
6097 // Scalar Coversion with SAE - suppress all exceptions
6098 multiclass avx512_cvt_fp_sae_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6099                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6100   defm rrb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6101                         (ins _.RC:$src1, _Src.RC:$src2), OpcodeStr,
6102                         "{sae}, $src2, $src1", "$src1, $src2, {sae}",
6103                         (_.VT (OpNodeRnd (_.VT _.RC:$src1),
6104                                          (_Src.VT _Src.RC:$src2),
6105                                          (i32 FROUND_NO_EXC)))>,
6106                         EVEX_4V, VEX_LIG, EVEX_B;
6107 }
6108
6109 // Scalar Conversion with rounding control (RC)
6110 multiclass avx512_cvt_fp_rc_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6111                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6112   defm rrb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6113                         (ins _.RC:$src1, _Src.RC:$src2, AVX512RC:$rc), OpcodeStr,
6114                         "$rc, $src2, $src1", "$src1, $src2, $rc",
6115                         (_.VT (OpNodeRnd (_.VT _.RC:$src1),
6116                                          (_Src.VT _Src.RC:$src2), (i32 imm:$rc)))>,
6117                         EVEX_4V, VEX_LIG, Sched<[WriteCvtF2FLd, ReadAfterLd]>,
6118                         EVEX_B, EVEX_RC;
6119 }
6120 multiclass avx512_cvt_fp_scalar_sd2ss<bits<8> opc, string OpcodeStr,
6121                                   SDNode OpNodeRnd, X86VectorVTInfo _src,
6122                                                         X86VectorVTInfo _dst> {
6123   let Predicates = [HasAVX512] in {
6124     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6125              avx512_cvt_fp_rc_scalar<opc, OpcodeStr, _dst, _src,
6126                                OpNodeRnd>, VEX_W, EVEX_CD8<64, CD8VT1>, XD;
6127   }
6128 }
6129
6130 multiclass avx512_cvt_fp_scalar_ss2sd<bits<8> opc, string OpcodeStr,
6131                                     SDNode OpNodeRnd, X86VectorVTInfo _src,
6132                                                           X86VectorVTInfo _dst> {
6133   let Predicates = [HasAVX512] in {
6134     defm Z : avx512_cvt_fp_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6135              avx512_cvt_fp_sae_scalar<opc, OpcodeStr, _dst, _src, OpNodeRnd>,
6136              EVEX_CD8<32, CD8VT1>, XS;
6137   }
6138 }
6139 defm VCVTSD2SS : avx512_cvt_fp_scalar_sd2ss<0x5A, "vcvtsd2ss",
6140                                          X86froundRnd, f64x_info, f32x_info>;
6141 defm VCVTSS2SD : avx512_cvt_fp_scalar_ss2sd<0x5A, "vcvtss2sd",
6142                                           X86fpextRnd,f32x_info, f64x_info >;
6143
6144 def : Pat<(f64 (fpextend FR32X:$src)),
6145           (VCVTSS2SDZrr (COPY_TO_REGCLASS FR32X:$src, FR64X), FR32X:$src)>,
6146           Requires<[HasAVX512]>;
6147 def : Pat<(f64 (fpextend (loadf32 addr:$src))),
6148           (VCVTSS2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>,
6149           Requires<[HasAVX512]>;
6150
6151 def : Pat<(f64 (extloadf32 addr:$src)),
6152           (VCVTSS2SDZrm (f64 (IMPLICIT_DEF)), addr:$src)>,
6153       Requires<[HasAVX512, OptForSize]>;
6154
6155 def : Pat<(f64 (extloadf32 addr:$src)),
6156           (VCVTSS2SDZrr (f64 (IMPLICIT_DEF)), (VMOVSSZrm addr:$src))>,
6157           Requires<[HasAVX512, OptForSpeed]>;
6158
6159 def : Pat<(f32 (fpround FR64X:$src)),
6160           (VCVTSD2SSZrr (COPY_TO_REGCLASS FR64X:$src, FR32X), FR64X:$src)>,
6161            Requires<[HasAVX512]>;
6162
6163 def : Pat<(v4f32 (X86Movss
6164                    (v4f32 VR128X:$dst),
6165                    (v4f32 (scalar_to_vector
6166                      (f32 (fpround (f64 (extractelt VR128X:$src, (iPTR 0))))))))),
6167           (VCVTSD2SSZrr_Int VR128X:$dst, VR128X:$src)>,
6168           Requires<[HasAVX512]>;
6169
6170 def : Pat<(v2f64 (X86Movsd
6171                    (v2f64 VR128X:$dst),
6172                    (v2f64 (scalar_to_vector
6173                      (f64 (fpextend (f32 (extractelt VR128X:$src, (iPTR 0))))))))),
6174           (VCVTSS2SDZrr_Int VR128X:$dst, VR128X:$src)>,
6175           Requires<[HasAVX512]>;
6176
6177 //===----------------------------------------------------------------------===//
6178 // AVX-512  Vector convert from signed/unsigned integer to float/double
6179 //          and from float/double to signed/unsigned integer
6180 //===----------------------------------------------------------------------===//
6181
6182 multiclass avx512_vcvt_fp<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6183                          X86VectorVTInfo _Src, SDNode OpNode,
6184                          string Broadcast = _.BroadcastStr,
6185                          string Alias = "", X86MemOperand MemOp = _Src.MemOp> {
6186
6187   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6188                          (ins _Src.RC:$src), OpcodeStr, "$src", "$src",
6189                          (_.VT (OpNode (_Src.VT _Src.RC:$src)))>, EVEX;
6190
6191   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6192                          (ins MemOp:$src), OpcodeStr#Alias, "$src", "$src",
6193                          (_.VT (OpNode (_Src.VT
6194                              (bitconvert (_Src.LdFrag addr:$src)))))>, EVEX;
6195
6196   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6197                          (ins _Src.ScalarMemOp:$src), OpcodeStr,
6198                          "${src}"##Broadcast, "${src}"##Broadcast,
6199                          (_.VT (OpNode (_Src.VT
6200                                   (X86VBroadcast (_Src.ScalarLdFrag addr:$src)))
6201                             ))>, EVEX, EVEX_B;
6202 }
6203 // Coversion with SAE - suppress all exceptions
6204 multiclass avx512_vcvt_fp_sae<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6205                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6206   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6207                         (ins _Src.RC:$src), OpcodeStr,
6208                         "{sae}, $src", "$src, {sae}",
6209                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src),
6210                                (i32 FROUND_NO_EXC)))>,
6211                         EVEX, EVEX_B;
6212 }
6213
6214 // Conversion with rounding control (RC)
6215 multiclass avx512_vcvt_fp_rc<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
6216                          X86VectorVTInfo _Src, SDNode OpNodeRnd> {
6217   defm rrb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6218                         (ins _Src.RC:$src, AVX512RC:$rc), OpcodeStr,
6219                         "$rc, $src", "$src, $rc",
6220                         (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src), (i32 imm:$rc)))>,
6221                         EVEX, EVEX_B, EVEX_RC;
6222 }
6223
6224 // Extend Float to Double
6225 multiclass avx512_cvtps2pd<bits<8> opc, string OpcodeStr> {
6226   let Predicates = [HasAVX512] in {
6227     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8f32x_info, fpextend>,
6228              avx512_vcvt_fp_sae<opc, OpcodeStr, v8f64_info, v8f32x_info,
6229                                 X86vfpextRnd>, EVEX_V512;
6230   }
6231   let Predicates = [HasVLX] in {
6232     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4f32x_info,
6233                                X86vfpext, "{1to2}", "", f64mem>, EVEX_V128;
6234     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4f32x_info, fpextend>,
6235                                      EVEX_V256;
6236   }
6237 }
6238
6239 // Truncate Double to Float
6240 multiclass avx512_cvtpd2ps<bits<8> opc, string OpcodeStr> {
6241   let Predicates = [HasAVX512] in {
6242     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8f64_info, fpround>,
6243              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8f64_info,
6244                                X86vfproundRnd>, EVEX_V512;
6245   }
6246   let Predicates = [HasVLX] in {
6247     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2f64x_info,
6248                                X86vfpround, "{1to2}", "{x}">, EVEX_V128;
6249     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4f64x_info, fpround,
6250                                "{1to4}", "{y}">, EVEX_V256;
6251
6252     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6253                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6254     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6255                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, f128mem:$src), 0>;
6256     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6257                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6258     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6259                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, f256mem:$src), 0>;
6260   }
6261 }
6262
6263 defm VCVTPD2PS : avx512_cvtpd2ps<0x5A, "vcvtpd2ps">,
6264                                   VEX_W, PD, EVEX_CD8<64, CD8VF>;
6265 defm VCVTPS2PD : avx512_cvtps2pd<0x5A, "vcvtps2pd">,
6266                                   PS, EVEX_CD8<32, CD8VH>;
6267
6268 def : Pat<(v8f64 (extloadv8f32 addr:$src)),
6269             (VCVTPS2PDZrm addr:$src)>;
6270
6271 let Predicates = [HasVLX] in {
6272   let AddedComplexity = 15 in
6273   def : Pat<(X86vzmovl (v2f64 (bitconvert
6274                                (v4f32 (X86vfpround (v2f64 VR128X:$src)))))),
6275             (VCVTPD2PSZ128rr VR128X:$src)>;
6276   def : Pat<(v2f64 (extloadv2f32 addr:$src)),
6277               (VCVTPS2PDZ128rm addr:$src)>;
6278   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
6279               (VCVTPS2PDZ256rm addr:$src)>;
6280 }
6281
6282 // Convert Signed/Unsigned Doubleword to Double
6283 multiclass avx512_cvtdq2pd<bits<8> opc, string OpcodeStr, SDNode OpNode,
6284                            SDNode OpNode128> {
6285   // No rounding in this op
6286   let Predicates = [HasAVX512] in
6287     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i32x_info, OpNode>,
6288                                      EVEX_V512;
6289
6290   let Predicates = [HasVLX] in {
6291     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v4i32x_info,
6292                                      OpNode128, "{1to2}", "", i64mem>, EVEX_V128;
6293     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i32x_info, OpNode>,
6294                                      EVEX_V256;
6295   }
6296 }
6297
6298 // Convert Signed/Unsigned Doubleword to Float
6299 multiclass avx512_cvtdq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
6300                            SDNode OpNodeRnd> {
6301   let Predicates = [HasAVX512] in
6302     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16f32_info, v16i32_info, OpNode>,
6303              avx512_vcvt_fp_rc<opc, OpcodeStr, v16f32_info, v16i32_info,
6304                                OpNodeRnd>, EVEX_V512;
6305
6306   let Predicates = [HasVLX] in {
6307     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i32x_info, OpNode>,
6308                                      EVEX_V128;
6309     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i32x_info, OpNode>,
6310                                      EVEX_V256;
6311   }
6312 }
6313
6314 // Convert Float to Signed/Unsigned Doubleword with truncation
6315 multiclass avx512_cvttps2dq<bits<8> opc, string OpcodeStr,
6316                                   SDNode OpNode, SDNode OpNodeRnd> {
6317   let Predicates = [HasAVX512] in {
6318     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
6319              avx512_vcvt_fp_sae<opc, OpcodeStr, v16i32_info, v16f32_info,
6320                                 OpNodeRnd>, EVEX_V512;
6321   }
6322   let Predicates = [HasVLX] in {
6323     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
6324                                      EVEX_V128;
6325     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
6326                                      EVEX_V256;
6327   }
6328 }
6329
6330 // Convert Float to Signed/Unsigned Doubleword
6331 multiclass avx512_cvtps2dq<bits<8> opc, string OpcodeStr,
6332                                   SDNode OpNode, SDNode OpNodeRnd> {
6333   let Predicates = [HasAVX512] in {
6334     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v16i32_info, v16f32_info, OpNode>,
6335              avx512_vcvt_fp_rc<opc, OpcodeStr, v16i32_info, v16f32_info,
6336                                 OpNodeRnd>, EVEX_V512;
6337   }
6338   let Predicates = [HasVLX] in {
6339     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f32x_info, OpNode>,
6340                                      EVEX_V128;
6341     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f32x_info, OpNode>,
6342                                      EVEX_V256;
6343   }
6344 }
6345
6346 // Convert Double to Signed/Unsigned Doubleword with truncation
6347 multiclass avx512_cvttpd2dq<bits<8> opc, string OpcodeStr, SDNode OpNode,
6348                             SDNode OpNode128, SDNode OpNodeRnd> {
6349   let Predicates = [HasAVX512] in {
6350     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
6351              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i32x_info, v8f64_info,
6352                                 OpNodeRnd>, EVEX_V512;
6353   }
6354   let Predicates = [HasVLX] in {
6355     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6356     // memory forms of these instructions in Asm Parser. They have the same
6357     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6358     // due to the same reason.
6359     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info,
6360                                OpNode128, "{1to2}", "{x}">, EVEX_V128;
6361     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
6362                                "{1to4}", "{y}">, EVEX_V256;
6363
6364     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6365                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6366     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6367                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, i128mem:$src), 0>;
6368     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6369                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6370     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6371                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, i256mem:$src), 0>;
6372   }
6373 }
6374
6375 // Convert Double to Signed/Unsigned Doubleword
6376 multiclass avx512_cvtpd2dq<bits<8> opc, string OpcodeStr,
6377                                   SDNode OpNode, SDNode OpNodeRnd> {
6378   let Predicates = [HasAVX512] in {
6379     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i32x_info, v8f64_info, OpNode>,
6380              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i32x_info, v8f64_info,
6381                                OpNodeRnd>, EVEX_V512;
6382   }
6383   let Predicates = [HasVLX] in {
6384     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6385     // memory forms of these instructions in Asm Parcer. They have the same
6386     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6387     // due to the same reason.
6388     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v2f64x_info, OpNode,
6389                                "{1to2}", "{x}">, EVEX_V128;
6390     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i32x_info, v4f64x_info, OpNode,
6391                                "{1to4}", "{y}">, EVEX_V256;
6392
6393     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6394                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6395     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6396                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, f128mem:$src), 0>;
6397     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6398                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6399     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6400                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, f256mem:$src), 0>;
6401   }
6402 }
6403
6404 // Convert Double to Signed/Unsigned Quardword
6405 multiclass avx512_cvtpd2qq<bits<8> opc, string OpcodeStr,
6406                                   SDNode OpNode, SDNode OpNodeRnd> {
6407   let Predicates = [HasDQI] in {
6408     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
6409              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f64_info,
6410                                OpNodeRnd>, EVEX_V512;
6411   }
6412   let Predicates = [HasDQI, HasVLX] in {
6413     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
6414                                EVEX_V128;
6415     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
6416                                EVEX_V256;
6417   }
6418 }
6419
6420 // Convert Double to Signed/Unsigned Quardword with truncation
6421 multiclass avx512_cvttpd2qq<bits<8> opc, string OpcodeStr,
6422                                   SDNode OpNode, SDNode OpNodeRnd> {
6423   let Predicates = [HasDQI] in {
6424     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f64_info, OpNode>,
6425              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f64_info,
6426                                OpNodeRnd>, EVEX_V512;
6427   }
6428   let Predicates = [HasDQI, HasVLX] in {
6429     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v2f64x_info, OpNode>,
6430                                EVEX_V128;
6431     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f64x_info, OpNode>,
6432                                EVEX_V256;
6433   }
6434 }
6435
6436 // Convert Signed/Unsigned Quardword to Double
6437 multiclass avx512_cvtqq2pd<bits<8> opc, string OpcodeStr,
6438                                   SDNode OpNode, SDNode OpNodeRnd> {
6439   let Predicates = [HasDQI] in {
6440     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f64_info, v8i64_info, OpNode>,
6441              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f64_info, v8i64_info,
6442                                OpNodeRnd>, EVEX_V512;
6443   }
6444   let Predicates = [HasDQI, HasVLX] in {
6445     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2f64x_info, v2i64x_info, OpNode>,
6446                                EVEX_V128;
6447     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f64x_info, v4i64x_info, OpNode>,
6448                                EVEX_V256;
6449   }
6450 }
6451
6452 // Convert Float to Signed/Unsigned Quardword
6453 multiclass avx512_cvtps2qq<bits<8> opc, string OpcodeStr,
6454                                   SDNode OpNode, SDNode OpNodeRnd> {
6455   let Predicates = [HasDQI] in {
6456     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
6457              avx512_vcvt_fp_rc<opc, OpcodeStr, v8i64_info, v8f32x_info,
6458                                OpNodeRnd>, EVEX_V512;
6459   }
6460   let Predicates = [HasDQI, HasVLX] in {
6461     // Explicitly specified broadcast string, since we take only 2 elements
6462     // from v4f32x_info source
6463     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode,
6464                                "{1to2}", "", f64mem>, EVEX_V128;
6465     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
6466                                EVEX_V256;
6467   }
6468 }
6469
6470 // Convert Float to Signed/Unsigned Quardword with truncation
6471 multiclass avx512_cvttps2qq<bits<8> opc, string OpcodeStr, SDNode OpNode,
6472                             SDNode OpNode128, SDNode OpNodeRnd> {
6473   let Predicates = [HasDQI] in {
6474     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8i64_info, v8f32x_info, OpNode>,
6475              avx512_vcvt_fp_sae<opc, OpcodeStr, v8i64_info, v8f32x_info,
6476                                OpNodeRnd>, EVEX_V512;
6477   }
6478   let Predicates = [HasDQI, HasVLX] in {
6479     // Explicitly specified broadcast string, since we take only 2 elements
6480     // from v4f32x_info source
6481     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v2i64x_info, v4f32x_info, OpNode128,
6482                                "{1to2}", "", f64mem>, EVEX_V128;
6483     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4i64x_info, v4f32x_info, OpNode>,
6484                                EVEX_V256;
6485   }
6486 }
6487
6488 // Convert Signed/Unsigned Quardword to Float
6489 multiclass avx512_cvtqq2ps<bits<8> opc, string OpcodeStr, SDNode OpNode,
6490                                   SDNode OpNode128, SDNode OpNodeRnd> {
6491   let Predicates = [HasDQI] in {
6492     defm Z : avx512_vcvt_fp<opc, OpcodeStr, v8f32x_info, v8i64_info, OpNode>,
6493              avx512_vcvt_fp_rc<opc, OpcodeStr, v8f32x_info, v8i64_info,
6494                                OpNodeRnd>, EVEX_V512;
6495   }
6496   let Predicates = [HasDQI, HasVLX] in {
6497     // we need "x"/"y" suffixes in order to distinguish between 128 and 256
6498     // memory forms of these instructions in Asm Parcer. They have the same
6499     // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly
6500     // due to the same reason.
6501     defm Z128 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v2i64x_info, OpNode128,
6502                                "{1to2}", "{x}">, EVEX_V128;
6503     defm Z256 : avx512_vcvt_fp<opc, OpcodeStr, v4f32x_info, v4i64x_info, OpNode,
6504                                "{1to4}", "{y}">, EVEX_V256;
6505
6506     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6507                     (!cast<Instruction>(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>;
6508     def : InstAlias<OpcodeStr##"x\t{$src, $dst|$dst, $src}",
6509                     (!cast<Instruction>(NAME # "Z128rm") VR128X:$dst, i128mem:$src), 0>;
6510     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6511                     (!cast<Instruction>(NAME # "Z256rr") VR128X:$dst, VR256X:$src), 0>;
6512     def : InstAlias<OpcodeStr##"y\t{$src, $dst|$dst, $src}",
6513                     (!cast<Instruction>(NAME # "Z256rm") VR128X:$dst, i256mem:$src), 0>;
6514   }
6515 }
6516
6517 defm VCVTDQ2PD : avx512_cvtdq2pd<0xE6, "vcvtdq2pd", sint_to_fp, X86VSintToFP>,
6518                                 XS, EVEX_CD8<32, CD8VH>;
6519
6520 defm VCVTDQ2PS : avx512_cvtdq2ps<0x5B, "vcvtdq2ps", sint_to_fp,
6521                                 X86VSintToFpRnd>,
6522                                 PS, EVEX_CD8<32, CD8VF>;
6523
6524 defm VCVTTPS2DQ : avx512_cvttps2dq<0x5B, "vcvttps2dq", fp_to_sint,
6525                                 X86cvttp2siRnd>,
6526                                 XS, EVEX_CD8<32, CD8VF>;
6527
6528 defm VCVTTPD2DQ : avx512_cvttpd2dq<0xE6, "vcvttpd2dq", fp_to_sint, X86cvttp2si,
6529                                  X86cvttp2siRnd>,
6530                                  PD, VEX_W, EVEX_CD8<64, CD8VF>;
6531
6532 defm VCVTTPS2UDQ : avx512_cvttps2dq<0x78, "vcvttps2udq", fp_to_uint,
6533                                  X86cvttp2uiRnd>, PS,
6534                                  EVEX_CD8<32, CD8VF>;
6535
6536 defm VCVTTPD2UDQ : avx512_cvttpd2dq<0x78, "vcvttpd2udq", fp_to_uint,
6537                                  X86cvttp2ui, X86cvttp2uiRnd>, PS, VEX_W,
6538                                  EVEX_CD8<64, CD8VF>;
6539
6540 defm VCVTUDQ2PD : avx512_cvtdq2pd<0x7A, "vcvtudq2pd", uint_to_fp, X86VUintToFP>,
6541                                  XS, EVEX_CD8<32, CD8VH>;
6542
6543 defm VCVTUDQ2PS : avx512_cvtdq2ps<0x7A, "vcvtudq2ps", uint_to_fp,
6544                                  X86VUintToFpRnd>, XD,
6545                                  EVEX_CD8<32, CD8VF>;
6546
6547 defm VCVTPS2DQ : avx512_cvtps2dq<0x5B, "vcvtps2dq", X86cvtp2Int,
6548                                  X86cvtp2IntRnd>, PD, EVEX_CD8<32, CD8VF>;
6549
6550 defm VCVTPD2DQ : avx512_cvtpd2dq<0xE6, "vcvtpd2dq", X86cvtp2Int,
6551                                  X86cvtp2IntRnd>, XD, VEX_W,
6552                                  EVEX_CD8<64, CD8VF>;
6553
6554 defm VCVTPS2UDQ : avx512_cvtps2dq<0x79, "vcvtps2udq", X86cvtp2UInt,
6555                                  X86cvtp2UIntRnd>,
6556                                  PS, EVEX_CD8<32, CD8VF>;
6557 defm VCVTPD2UDQ : avx512_cvtpd2dq<0x79, "vcvtpd2udq", X86cvtp2UInt,
6558                                  X86cvtp2UIntRnd>, VEX_W,
6559                                  PS, EVEX_CD8<64, CD8VF>;
6560
6561 defm VCVTPD2QQ : avx512_cvtpd2qq<0x7B, "vcvtpd2qq", X86cvtp2Int,
6562                                  X86cvtp2IntRnd>, VEX_W,
6563                                  PD, EVEX_CD8<64, CD8VF>;
6564
6565 defm VCVTPS2QQ : avx512_cvtps2qq<0x7B, "vcvtps2qq", X86cvtp2Int,
6566                                  X86cvtp2IntRnd>, PD, EVEX_CD8<32, CD8VH>;
6567
6568 defm VCVTPD2UQQ : avx512_cvtpd2qq<0x79, "vcvtpd2uqq", X86cvtp2UInt,
6569                                  X86cvtp2UIntRnd>, VEX_W,
6570                                  PD, EVEX_CD8<64, CD8VF>;
6571
6572 defm VCVTPS2UQQ : avx512_cvtps2qq<0x79, "vcvtps2uqq", X86cvtp2UInt,
6573                                  X86cvtp2UIntRnd>, PD, EVEX_CD8<32, CD8VH>;
6574
6575 defm VCVTTPD2QQ : avx512_cvttpd2qq<0x7A, "vcvttpd2qq", fp_to_sint,
6576                                  X86cvttp2siRnd>, VEX_W,
6577                                  PD, EVEX_CD8<64, CD8VF>;
6578
6579 defm VCVTTPS2QQ : avx512_cvttps2qq<0x7A, "vcvttps2qq", fp_to_sint, X86cvttp2si,
6580                                  X86cvttp2siRnd>, PD, EVEX_CD8<32, CD8VH>;
6581
6582 defm VCVTTPD2UQQ : avx512_cvttpd2qq<0x78, "vcvttpd2uqq", fp_to_uint,
6583                                  X86cvttp2uiRnd>, VEX_W,
6584                                  PD, EVEX_CD8<64, CD8VF>;
6585
6586 defm VCVTTPS2UQQ : avx512_cvttps2qq<0x78, "vcvttps2uqq", fp_to_uint, X86cvttp2ui,
6587                                  X86cvttp2uiRnd>, PD, EVEX_CD8<32, CD8VH>;
6588
6589 defm VCVTQQ2PD : avx512_cvtqq2pd<0xE6, "vcvtqq2pd", sint_to_fp,
6590                             X86VSintToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
6591
6592 defm VCVTUQQ2PD : avx512_cvtqq2pd<0x7A, "vcvtuqq2pd", uint_to_fp,
6593                             X86VUintToFpRnd>, VEX_W, XS, EVEX_CD8<64, CD8VF>;
6594
6595 defm VCVTQQ2PS : avx512_cvtqq2ps<0x5B, "vcvtqq2ps", sint_to_fp, X86VSintToFP,
6596                             X86VSintToFpRnd>, VEX_W, PS, EVEX_CD8<64, CD8VF>;
6597
6598 defm VCVTUQQ2PS : avx512_cvtqq2ps<0x7A, "vcvtuqq2ps", uint_to_fp, X86VUintToFP,
6599                             X86VUintToFpRnd>, VEX_W, XD, EVEX_CD8<64, CD8VF>;
6600
6601 let Predicates = [HasAVX512, NoVLX] in {
6602 def : Pat<(v8i32 (fp_to_uint (v8f32 VR256X:$src1))),
6603           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
6604            (v16f32 (INSERT_SUBREG (IMPLICIT_DEF),
6605                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6606
6607 def : Pat<(v4i32 (fp_to_uint (v4f32 VR128X:$src1))),
6608           (EXTRACT_SUBREG (v16i32 (VCVTTPS2UDQZrr
6609            (v16f32 (INSERT_SUBREG (IMPLICIT_DEF),
6610                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6611
6612 def : Pat<(v4i32 (fp_to_uint (v4f64 VR256X:$src1))),
6613           (EXTRACT_SUBREG (v8i32 (VCVTTPD2UDQZrr
6614            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6615                                  VR256X:$src1, sub_ymm)))), sub_xmm)>;
6616
6617 def : Pat<(v4i32 (X86cvttp2ui (v2f64 VR128X:$src))),
6618           (EXTRACT_SUBREG (v8i32 (VCVTTPD2UDQZrr
6619            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6620                                  VR128X:$src, sub_xmm)))), sub_xmm)>;
6621
6622 def : Pat<(v8f32 (uint_to_fp (v8i32 VR256X:$src1))),
6623           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
6624            (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
6625                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6626
6627 def : Pat<(v4f32 (uint_to_fp (v4i32 VR128X:$src1))),
6628           (EXTRACT_SUBREG (v16f32 (VCVTUDQ2PSZrr
6629            (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
6630                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6631
6632 def : Pat<(v4f64 (uint_to_fp (v4i32 VR128X:$src1))),
6633           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
6634            (v8i32 (INSERT_SUBREG (IMPLICIT_DEF),
6635                                  VR128X:$src1, sub_xmm)))), sub_ymm)>;
6636
6637 def : Pat<(v2f64 (X86VUintToFP (v4i32 VR128X:$src1))),
6638           (EXTRACT_SUBREG (v8f64 (VCVTUDQ2PDZrr
6639            (v8i32 (INSERT_SUBREG (IMPLICIT_DEF),
6640                                  VR128X:$src1, sub_xmm)))), sub_xmm)>;
6641 }
6642
6643 let Predicates = [HasAVX512, HasVLX] in {
6644   let AddedComplexity = 15 in {
6645     def : Pat<(X86vzmovl (v2i64 (bitconvert
6646                                 (v4i32 (X86cvtp2Int (v2f64 VR128X:$src)))))),
6647               (VCVTPD2DQZ128rr VR128X:$src)>;
6648     def : Pat<(v4i32 (bitconvert (X86vzmovl (v2i64 (bitconvert
6649                                  (v4i32 (X86cvtp2UInt (v2f64 VR128X:$src)))))))),
6650               (VCVTPD2UDQZ128rr VR128X:$src)>;
6651     def : Pat<(X86vzmovl (v2i64 (bitconvert
6652                                 (v4i32 (X86cvttp2si (v2f64 VR128X:$src)))))),
6653               (VCVTTPD2DQZ128rr VR128X:$src)>;
6654     def : Pat<(v4i32 (bitconvert (X86vzmovl (v2i64 (bitconvert
6655                                  (v4i32 (X86cvttp2ui (v2f64 VR128X:$src)))))))),
6656               (VCVTTPD2UDQZ128rr VR128X:$src)>;
6657   }
6658 }
6659
6660 let Predicates = [HasAVX512] in {
6661   def : Pat<(v8f32 (fpround (loadv8f64 addr:$src))),
6662             (VCVTPD2PSZrm addr:$src)>;
6663   def : Pat<(v8f64 (extloadv8f32 addr:$src)),
6664             (VCVTPS2PDZrm addr:$src)>;
6665 }
6666
6667 let Predicates = [HasDQI, HasVLX] in {
6668   let AddedComplexity = 15 in {
6669     def : Pat<(X86vzmovl (v2f64 (bitconvert
6670                                 (v4f32 (X86VSintToFP (v2i64 VR128X:$src)))))),
6671               (VCVTQQ2PSZ128rr VR128X:$src)>;
6672     def : Pat<(X86vzmovl (v2f64 (bitconvert
6673                                 (v4f32 (X86VUintToFP (v2i64 VR128X:$src)))))),
6674               (VCVTUQQ2PSZ128rr VR128X:$src)>;
6675   }
6676 }
6677
6678 let Predicates = [HasDQI, NoVLX] in {
6679 def : Pat<(v2i64 (fp_to_sint (v2f64 VR128X:$src1))),
6680           (EXTRACT_SUBREG (v8i64 (VCVTTPD2QQZrr
6681            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6682                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6683
6684 def : Pat<(v4i64 (fp_to_sint (v4f32 VR128X:$src1))),
6685           (EXTRACT_SUBREG (v8i64 (VCVTTPS2QQZrr
6686            (v8f32 (INSERT_SUBREG (IMPLICIT_DEF),
6687                                   VR128X:$src1, sub_xmm)))), sub_ymm)>;
6688
6689 def : Pat<(v4i64 (fp_to_sint (v4f64 VR256X:$src1))),
6690           (EXTRACT_SUBREG (v8i64 (VCVTTPD2QQZrr
6691            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6692                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6693
6694 def : Pat<(v2i64 (fp_to_uint (v2f64 VR128X:$src1))),
6695           (EXTRACT_SUBREG (v8i64 (VCVTTPD2UQQZrr
6696            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6697                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6698
6699 def : Pat<(v4i64 (fp_to_uint (v4f32 VR128X:$src1))),
6700           (EXTRACT_SUBREG (v8i64 (VCVTTPS2UQQZrr
6701            (v8f32 (INSERT_SUBREG (IMPLICIT_DEF),
6702                                   VR128X:$src1, sub_xmm)))), sub_ymm)>;
6703
6704 def : Pat<(v4i64 (fp_to_uint (v4f64 VR256X:$src1))),
6705           (EXTRACT_SUBREG (v8i64 (VCVTTPD2UQQZrr
6706            (v8f64 (INSERT_SUBREG (IMPLICIT_DEF),
6707                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6708
6709 def : Pat<(v4f32 (sint_to_fp (v4i64 VR256X:$src1))),
6710           (EXTRACT_SUBREG (v8f32 (VCVTQQ2PSZrr
6711            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6712                                   VR256X:$src1, sub_ymm)))), sub_xmm)>;
6713
6714 def : Pat<(v2f64 (sint_to_fp (v2i64 VR128X:$src1))),
6715           (EXTRACT_SUBREG (v8f64 (VCVTQQ2PDZrr
6716            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6717                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6718
6719 def : Pat<(v4f64 (sint_to_fp (v4i64 VR256X:$src1))),
6720           (EXTRACT_SUBREG (v8f64 (VCVTQQ2PDZrr
6721            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6722                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6723
6724 def : Pat<(v4f32 (uint_to_fp (v4i64 VR256X:$src1))),
6725           (EXTRACT_SUBREG (v8f32 (VCVTUQQ2PSZrr
6726            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6727                                   VR256X:$src1, sub_ymm)))), sub_xmm)>;
6728
6729 def : Pat<(v2f64 (uint_to_fp (v2i64 VR128X:$src1))),
6730           (EXTRACT_SUBREG (v8f64 (VCVTUQQ2PDZrr
6731            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6732                                   VR128X:$src1, sub_xmm)))), sub_xmm)>;
6733
6734 def : Pat<(v4f64 (uint_to_fp (v4i64 VR256X:$src1))),
6735           (EXTRACT_SUBREG (v8f64 (VCVTUQQ2PDZrr
6736            (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
6737                                   VR256X:$src1, sub_ymm)))), sub_ymm)>;
6738 }
6739
6740 //===----------------------------------------------------------------------===//
6741 // Half precision conversion instructions
6742 //===----------------------------------------------------------------------===//
6743 multiclass avx512_cvtph2ps<X86VectorVTInfo _dest, X86VectorVTInfo _src,
6744                            X86MemOperand x86memop, PatFrag ld_frag> {
6745   defm rr : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src),
6746                     "vcvtph2ps", "$src", "$src",
6747                    (X86cvtph2ps (_src.VT _src.RC:$src),
6748                                                 (i32 FROUND_CURRENT))>, T8PD;
6749   defm rm : AVX512_maskable<0x13, MRMSrcMem, _dest, (outs _dest.RC:$dst), (ins x86memop:$src),
6750                     "vcvtph2ps", "$src", "$src",
6751                     (X86cvtph2ps (_src.VT (bitconvert (ld_frag addr:$src))),
6752                                      (i32 FROUND_CURRENT))>, T8PD;
6753 }
6754
6755 multiclass avx512_cvtph2ps_sae<X86VectorVTInfo _dest, X86VectorVTInfo _src> {
6756   defm rb : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src),
6757                     "vcvtph2ps", "{sae}, $src", "$src, {sae}",
6758                    (X86cvtph2ps (_src.VT _src.RC:$src),
6759                                                 (i32 FROUND_NO_EXC))>, T8PD, EVEX_B;
6760
6761 }
6762
6763 let Predicates = [HasAVX512] in {
6764   defm VCVTPH2PSZ : avx512_cvtph2ps<v16f32_info, v16i16x_info, f256mem, loadv4i64>,
6765                     avx512_cvtph2ps_sae<v16f32_info, v16i16x_info>,
6766                     EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>;
6767   let Predicates = [HasVLX] in {
6768     defm VCVTPH2PSZ256 : avx512_cvtph2ps<v8f32x_info, v8i16x_info, f128mem,
6769                          loadv2i64>,EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>;
6770     defm VCVTPH2PSZ128 : avx512_cvtph2ps<v4f32x_info, v8i16x_info, f64mem,
6771                          loadv2i64>, EVEX, EVEX_V128, EVEX_CD8<32, CD8VH>;
6772   }
6773 }
6774
6775 multiclass avx512_cvtps2ph<X86VectorVTInfo _dest, X86VectorVTInfo _src,
6776                            X86MemOperand x86memop> {
6777   defm rr : AVX512_maskable<0x1D, MRMDestReg, _dest ,(outs _dest.RC:$dst),
6778                    (ins _src.RC:$src1, i32u8imm:$src2),
6779                    "vcvtps2ph", "$src2, $src1", "$src1, $src2",
6780                    (X86cvtps2ph (_src.VT _src.RC:$src1),
6781                                 (i32 imm:$src2)),
6782                    NoItinerary, 0, 0, X86select>, AVX512AIi8Base;
6783   def mr : AVX512AIi8<0x1D, MRMDestMem, (outs),
6784              (ins x86memop:$dst, _src.RC:$src1, i32u8imm:$src2),
6785              "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6786              [(store (_dest.VT (X86cvtps2ph (_src.VT _src.RC:$src1),
6787                                      (i32 imm:$src2))),
6788                                      addr:$dst)]>;
6789   let hasSideEffects = 0, mayStore = 1 in
6790   def mrk : AVX512AIi8<0x1D, MRMDestMem, (outs),
6791              (ins x86memop:$dst, _dest.KRCWM:$mask, _src.RC:$src1, i32u8imm:$src2),
6792              "vcvtps2ph\t{$src2, $src1, $dst {${mask}}|$dst {${mask}}, $src1, $src2}",
6793               []>, EVEX_K;
6794 }
6795 multiclass avx512_cvtps2ph_sae<X86VectorVTInfo _dest, X86VectorVTInfo _src> {
6796   let hasSideEffects = 0 in
6797   defm rb : AVX512_maskable_in_asm<0x1D, MRMDestReg, _dest,
6798                    (outs _dest.RC:$dst),
6799                    (ins _src.RC:$src1, i32u8imm:$src2),
6800                    "vcvtps2ph", "$src2, {sae}, $src1", "$src1, {sae}, $src2",
6801                    []>, EVEX_B, AVX512AIi8Base;
6802 }
6803 let Predicates = [HasAVX512] in {
6804   defm VCVTPS2PHZ : avx512_cvtps2ph<v16i16x_info, v16f32_info, f256mem>,
6805                     avx512_cvtps2ph_sae<v16i16x_info, v16f32_info>,
6806                       EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>;
6807   let Predicates = [HasVLX] in {
6808     defm VCVTPS2PHZ256 : avx512_cvtps2ph<v8i16x_info, v8f32x_info, f128mem>,
6809                         EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>;
6810     defm VCVTPS2PHZ128 : avx512_cvtps2ph<v8i16x_info, v4f32x_info, f64mem>,
6811                         EVEX, EVEX_V128, EVEX_CD8<32, CD8VH>;
6812   }
6813 }
6814
6815 // Patterns for matching conversions from float to half-float and vice versa.
6816 let Predicates = [HasVLX] in {
6817   // Use MXCSR.RC for rounding instead of explicitly specifying the default
6818   // rounding mode (Nearest-Even, encoded as 0). Both are equivalent in the
6819   // configurations we support (the default). However, falling back to MXCSR is
6820   // more consistent with other instructions, which are always controlled by it.
6821   // It's encoded as 0b100.
6822   def : Pat<(fp_to_f16 FR32X:$src),
6823             (i16 (EXTRACT_SUBREG (VMOVPDI2DIZrr (VCVTPS2PHZ128rr
6824               (COPY_TO_REGCLASS FR32X:$src, VR128X), 4)), sub_16bit))>;
6825
6826   def : Pat<(f16_to_fp GR16:$src),
6827             (f32 (COPY_TO_REGCLASS (VCVTPH2PSZ128rr
6828               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128X)), FR32X)) >;
6829
6830   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32X:$src))),
6831             (f32 (COPY_TO_REGCLASS (VCVTPH2PSZ128rr
6832               (VCVTPS2PHZ128rr (COPY_TO_REGCLASS FR32X:$src, VR128X), 4)), FR32X)) >;
6833 }
6834
6835 // Patterns for matching float to half-float conversion when AVX512 is supported
6836 // but F16C isn't. In that case we have to use 512-bit vectors.
6837 let Predicates = [HasAVX512, NoVLX, NoF16C] in {
6838   def : Pat<(fp_to_f16 FR32X:$src),
6839             (i16 (EXTRACT_SUBREG
6840                   (VMOVPDI2DIZrr
6841                    (v8i16 (EXTRACT_SUBREG
6842                     (VCVTPS2PHZrr
6843                      (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
6844                       (v4f32 (COPY_TO_REGCLASS FR32X:$src, VR128X)),
6845                       sub_xmm), 4), sub_xmm))), sub_16bit))>;
6846
6847   def : Pat<(f16_to_fp GR16:$src),
6848             (f32 (COPY_TO_REGCLASS
6849                   (v4f32 (EXTRACT_SUBREG
6850                    (VCVTPH2PSZrr
6851                     (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)),
6852                      (v8i16 (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128X)),
6853                      sub_xmm)), sub_xmm)), FR32X))>;
6854
6855   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32X:$src))),
6856             (f32 (COPY_TO_REGCLASS
6857                   (v4f32 (EXTRACT_SUBREG
6858                           (VCVTPH2PSZrr
6859                            (VCVTPS2PHZrr (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)),
6860                             (v4f32 (COPY_TO_REGCLASS FR32X:$src, VR128X)),
6861                             sub_xmm), 4)), sub_xmm)), FR32X))>;
6862 }
6863
6864 //  Unordered/Ordered scalar fp compare with Sea and set EFLAGS
6865 multiclass avx512_ord_cmp_sae<bits<8> opc, X86VectorVTInfo _,
6866                             string OpcodeStr> {
6867   def rb: AVX512<opc, MRMSrcReg, (outs), (ins _.RC:$src1, _.RC:$src2),
6868                  !strconcat(OpcodeStr, "\t{{sae}, $src2, $src1|$src1, $src2, {sae}}"),
6869                  [], IIC_SSE_COMIS_RR>, EVEX, EVEX_B, VEX_LIG, EVEX_V128,
6870                  Sched<[WriteFAdd]>;
6871 }
6872
6873 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
6874   defm VUCOMISSZ : avx512_ord_cmp_sae<0x2E, v4f32x_info, "vucomiss">,
6875                                    AVX512PSIi8Base, EVEX_CD8<32, CD8VT1>;
6876   defm VUCOMISDZ : avx512_ord_cmp_sae<0x2E, v2f64x_info, "vucomisd">,
6877                                    AVX512PDIi8Base, VEX_W, EVEX_CD8<64, CD8VT1>;
6878   defm VCOMISSZ : avx512_ord_cmp_sae<0x2F, v4f32x_info, "vcomiss">,
6879                                    AVX512PSIi8Base, EVEX_CD8<32, CD8VT1>;
6880   defm VCOMISDZ : avx512_ord_cmp_sae<0x2F, v2f64x_info, "vcomisd">,
6881                                    AVX512PDIi8Base, VEX_W, EVEX_CD8<64, CD8VT1>;
6882 }
6883
6884 let Defs = [EFLAGS], Predicates = [HasAVX512] in {
6885   defm VUCOMISSZ : sse12_ord_cmp<0x2E, FR32X, X86cmp, f32, f32mem, loadf32,
6886                                  "ucomiss">, PS, EVEX, VEX_LIG,
6887                                  EVEX_CD8<32, CD8VT1>;
6888   defm VUCOMISDZ : sse12_ord_cmp<0x2E, FR64X, X86cmp, f64, f64mem, loadf64,
6889                                   "ucomisd">, PD, EVEX,
6890                                   VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6891   let Pattern = []<dag> in {
6892     defm VCOMISSZ  : sse12_ord_cmp<0x2F, FR32X, undef, f32, f32mem, loadf32,
6893                                    "comiss">, PS, EVEX, VEX_LIG,
6894                                    EVEX_CD8<32, CD8VT1>;
6895     defm VCOMISDZ  : sse12_ord_cmp<0x2F, FR64X, undef, f64, f64mem, loadf64,
6896                                    "comisd">, PD, EVEX,
6897                                     VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6898   }
6899   let isCodeGenOnly = 1 in {
6900     defm Int_VUCOMISSZ  : sse12_ord_cmp_int<0x2E, VR128X, X86ucomi, v4f32, ssmem,
6901                               sse_load_f32, "ucomiss">, PS, EVEX, VEX_LIG,
6902                               EVEX_CD8<32, CD8VT1>;
6903     defm Int_VUCOMISDZ  : sse12_ord_cmp_int<0x2E, VR128X, X86ucomi, v2f64, sdmem,
6904                               sse_load_f64, "ucomisd">, PD, EVEX,
6905                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6906
6907     defm Int_VCOMISSZ  : sse12_ord_cmp_int<0x2F, VR128X, X86comi, v4f32, ssmem,
6908                               sse_load_f32, "comiss">, PS, EVEX, VEX_LIG,
6909                               EVEX_CD8<32, CD8VT1>;
6910     defm Int_VCOMISDZ  : sse12_ord_cmp_int<0x2F, VR128X, X86comi, v2f64, sdmem,
6911                               sse_load_f64, "comisd">, PD, EVEX,
6912                               VEX_LIG, VEX_W, EVEX_CD8<64, CD8VT1>;
6913   }
6914 }
6915
6916 /// avx512_fp14_s rcp14ss, rcp14sd, rsqrt14ss, rsqrt14sd
6917 multiclass avx512_fp14_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
6918                             X86VectorVTInfo _> {
6919   let Predicates = [HasAVX512], ExeDomain = _.ExeDomain in {
6920   defm rr : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6921                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6922                            "$src2, $src1", "$src1, $src2",
6923                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2))>, EVEX_4V;
6924   defm rm : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
6925                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
6926                          "$src2, $src1", "$src1, $src2",
6927                          (OpNode (_.VT _.RC:$src1),
6928                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))))>, EVEX_4V;
6929 }
6930 }
6931
6932 defm VRCP14SS   : avx512_fp14_s<0x4D, "vrcp14ss", X86frcp14s, f32x_info>,
6933                   EVEX_CD8<32, CD8VT1>, T8PD;
6934 defm VRCP14SD   : avx512_fp14_s<0x4D, "vrcp14sd", X86frcp14s, f64x_info>,
6935                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
6936 defm VRSQRT14SS   : avx512_fp14_s<0x4F, "vrsqrt14ss", X86frsqrt14s, f32x_info>,
6937                   EVEX_CD8<32, CD8VT1>, T8PD;
6938 defm VRSQRT14SD   : avx512_fp14_s<0x4F, "vrsqrt14sd", X86frsqrt14s, f64x_info>,
6939                   VEX_W, EVEX_CD8<64, CD8VT1>, T8PD;
6940
6941 /// avx512_fp14_p rcp14ps, rcp14pd, rsqrt14ps, rsqrt14pd
6942 multiclass avx512_fp14_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
6943                          X86VectorVTInfo _> {
6944   let ExeDomain = _.ExeDomain in {
6945   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
6946                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
6947                          (_.FloatVT (OpNode _.RC:$src))>, EVEX, T8PD;
6948   defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6949                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
6950                          (OpNode (_.FloatVT
6951                            (bitconvert (_.LdFrag addr:$src))))>, EVEX, T8PD;
6952   defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
6953                           (ins _.ScalarMemOp:$src), OpcodeStr,
6954                           "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
6955                           (OpNode (_.FloatVT
6956                             (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
6957                           EVEX, T8PD, EVEX_B;
6958   }
6959 }
6960
6961 multiclass avx512_fp14_p_vl_all<bits<8> opc, string OpcodeStr, SDNode OpNode> {
6962   defm PSZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"), OpNode, v16f32_info>,
6963                           EVEX_V512, EVEX_CD8<32, CD8VF>;
6964   defm PDZ : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"), OpNode, v8f64_info>,
6965                           EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
6966
6967   // Define only if AVX512VL feature is present.
6968   let Predicates = [HasVLX] in {
6969     defm PSZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
6970                                 OpNode, v4f32x_info>,
6971                                EVEX_V128, EVEX_CD8<32, CD8VF>;
6972     defm PSZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "ps"),
6973                                 OpNode, v8f32x_info>,
6974                                EVEX_V256, EVEX_CD8<32, CD8VF>;
6975     defm PDZ128 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
6976                                 OpNode, v2f64x_info>,
6977                                EVEX_V128, VEX_W, EVEX_CD8<64, CD8VF>;
6978     defm PDZ256 : avx512_fp14_p<opc, !strconcat(OpcodeStr, "pd"),
6979                                 OpNode, v4f64x_info>,
6980                                EVEX_V256, VEX_W, EVEX_CD8<64, CD8VF>;
6981   }
6982 }
6983
6984 defm VRSQRT14 : avx512_fp14_p_vl_all<0x4E, "vrsqrt14", X86frsqrt>;
6985 defm VRCP14 : avx512_fp14_p_vl_all<0x4C, "vrcp14", X86frcp>;
6986
6987 /// avx512_fp28_s rcp28ss, rcp28sd, rsqrt28ss, rsqrt28sd
6988 multiclass avx512_fp28_s<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
6989                          SDNode OpNode> {
6990   let ExeDomain = _.ExeDomain in {
6991   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6992                            (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6993                            "$src2, $src1", "$src1, $src2",
6994                            (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
6995                            (i32 FROUND_CURRENT))>;
6996
6997   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
6998                             (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
6999                             "{sae}, $src2, $src1", "$src1, $src2, {sae}",
7000                             (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7001                             (i32 FROUND_NO_EXC))>, EVEX_B;
7002
7003   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7004                          (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
7005                          "$src2, $src1", "$src1, $src2",
7006                          (OpNode (_.VT _.RC:$src1),
7007                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
7008                          (i32 FROUND_CURRENT))>;
7009   }
7010 }
7011
7012 multiclass avx512_eri_s<bits<8> opc, string OpcodeStr, SDNode OpNode> {
7013   defm SS : avx512_fp28_s<opc, OpcodeStr#"ss", f32x_info, OpNode>,
7014               EVEX_CD8<32, CD8VT1>;
7015   defm SD : avx512_fp28_s<opc, OpcodeStr#"sd", f64x_info, OpNode>,
7016               EVEX_CD8<64, CD8VT1>, VEX_W;
7017 }
7018
7019 let Predicates = [HasERI] in {
7020   defm VRCP28   : avx512_eri_s<0xCB, "vrcp28",   X86rcp28s>,   T8PD, EVEX_4V;
7021   defm VRSQRT28 : avx512_eri_s<0xCD, "vrsqrt28", X86rsqrt28s>, T8PD, EVEX_4V;
7022 }
7023
7024 defm VGETEXP   : avx512_eri_s<0x43, "vgetexp", X86fgetexpRnds>, T8PD, EVEX_4V;
7025 /// avx512_fp28_p rcp28ps, rcp28pd, rsqrt28ps, rsqrt28pd
7026
7027 multiclass avx512_fp28_p<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7028                          SDNode OpNode> {
7029   let ExeDomain = _.ExeDomain in {
7030   defm r : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7031                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
7032                          (OpNode (_.VT _.RC:$src), (i32 FROUND_CURRENT))>;
7033
7034   defm m : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7035                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
7036                          (OpNode (_.FloatVT
7037                              (bitconvert (_.LdFrag addr:$src))),
7038                           (i32 FROUND_CURRENT))>;
7039
7040   defm mb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7041                          (ins _.ScalarMemOp:$src), OpcodeStr,
7042                          "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
7043                          (OpNode (_.FloatVT
7044                                   (X86VBroadcast (_.ScalarLdFrag addr:$src))),
7045                                  (i32 FROUND_CURRENT))>, EVEX_B;
7046   }
7047 }
7048 multiclass avx512_fp28_p_round<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7049                          SDNode OpNode> {
7050   let ExeDomain = _.ExeDomain in
7051   defm rb : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7052                         (ins _.RC:$src), OpcodeStr,
7053                         "{sae}, $src", "$src, {sae}",
7054                         (OpNode (_.VT _.RC:$src), (i32 FROUND_NO_EXC))>, EVEX_B;
7055 }
7056
7057 multiclass  avx512_eri<bits<8> opc, string OpcodeStr, SDNode OpNode> {
7058    defm PS : avx512_fp28_p<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
7059              avx512_fp28_p_round<opc, OpcodeStr#"ps", v16f32_info, OpNode>,
7060              T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>;
7061    defm PD : avx512_fp28_p<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
7062              avx512_fp28_p_round<opc, OpcodeStr#"pd", v8f64_info, OpNode>,
7063              T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>;
7064 }
7065
7066 multiclass avx512_fp_unaryop_packed<bits<8> opc, string OpcodeStr,
7067                                   SDNode OpNode> {
7068   // Define only if AVX512VL feature is present.
7069   let Predicates = [HasVLX] in {
7070     defm PSZ128 : avx512_fp28_p<opc, OpcodeStr#"ps", v4f32x_info, OpNode>,
7071                                      EVEX_V128, T8PD, EVEX_CD8<32, CD8VF>;
7072     defm PSZ256 : avx512_fp28_p<opc, OpcodeStr#"ps", v8f32x_info, OpNode>,
7073                                      EVEX_V256, T8PD, EVEX_CD8<32, CD8VF>;
7074     defm PDZ128 : avx512_fp28_p<opc, OpcodeStr#"pd", v2f64x_info, OpNode>,
7075                                      EVEX_V128, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
7076     defm PDZ256 : avx512_fp28_p<opc, OpcodeStr#"pd", v4f64x_info, OpNode>,
7077                                      EVEX_V256, VEX_W, T8PD, EVEX_CD8<64, CD8VF>;
7078   }
7079 }
7080 let Predicates = [HasERI] in {
7081
7082  defm VRSQRT28 : avx512_eri<0xCC, "vrsqrt28", X86rsqrt28>, EVEX;
7083  defm VRCP28   : avx512_eri<0xCA, "vrcp28",   X86rcp28>,   EVEX;
7084  defm VEXP2    : avx512_eri<0xC8, "vexp2",    X86exp2>,    EVEX;
7085 }
7086 defm VGETEXP   : avx512_eri<0x42, "vgetexp", X86fgetexpRnd>,
7087                  avx512_fp_unaryop_packed<0x42, "vgetexp", X86fgetexpRnd> , EVEX;
7088
7089 multiclass avx512_sqrt_packed_round<bits<8> opc, string OpcodeStr,
7090                               SDNode OpNodeRnd, X86VectorVTInfo _>{
7091   let ExeDomain = _.ExeDomain in
7092   defm rb: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7093                          (ins _.RC:$src, AVX512RC:$rc), OpcodeStr, "$rc, $src", "$src, $rc",
7094                          (_.VT (OpNodeRnd _.RC:$src, (i32 imm:$rc)))>,
7095                          EVEX, EVEX_B, EVEX_RC;
7096 }
7097
7098 multiclass avx512_sqrt_packed<bits<8> opc, string OpcodeStr,
7099                               SDNode OpNode, X86VectorVTInfo _>{
7100   let ExeDomain = _.ExeDomain in {
7101   defm r: AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
7102                          (ins _.RC:$src), OpcodeStr, "$src", "$src",
7103                          (_.FloatVT (OpNode _.RC:$src))>, EVEX;
7104   defm m: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7105                          (ins _.MemOp:$src), OpcodeStr, "$src", "$src",
7106                          (OpNode (_.FloatVT
7107                            (bitconvert (_.LdFrag addr:$src))))>, EVEX;
7108
7109   defm mb: AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
7110                           (ins _.ScalarMemOp:$src), OpcodeStr,
7111                           "${src}"##_.BroadcastStr, "${src}"##_.BroadcastStr,
7112                           (OpNode (_.FloatVT
7113                             (X86VBroadcast (_.ScalarLdFrag addr:$src))))>,
7114                           EVEX, EVEX_B;
7115   }
7116 }
7117
7118 multiclass avx512_sqrt_packed_all<bits<8> opc, string OpcodeStr,
7119                                   SDNode OpNode> {
7120   defm PSZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
7121                                 v16f32_info>,
7122                                 EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
7123   defm PDZ : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
7124                                 v8f64_info>,
7125                                 EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7126   // Define only if AVX512VL feature is present.
7127   let Predicates = [HasVLX] in {
7128     defm PSZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
7129                                      OpNode, v4f32x_info>,
7130                                      EVEX_V128, PS, EVEX_CD8<32, CD8VF>;
7131     defm PSZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "ps"),
7132                                      OpNode, v8f32x_info>,
7133                                      EVEX_V256, PS, EVEX_CD8<32, CD8VF>;
7134     defm PDZ128 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
7135                                      OpNode, v2f64x_info>,
7136                                      EVEX_V128, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7137     defm PDZ256 : avx512_sqrt_packed<opc, !strconcat(OpcodeStr, "pd"),
7138                                      OpNode, v4f64x_info>,
7139                                      EVEX_V256, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7140   }
7141 }
7142
7143 multiclass avx512_sqrt_packed_all_round<bits<8> opc, string OpcodeStr,
7144                                           SDNode OpNodeRnd> {
7145   defm PSZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "ps"), OpNodeRnd,
7146                                 v16f32_info>, EVEX_V512, PS, EVEX_CD8<32, CD8VF>;
7147   defm PDZ : avx512_sqrt_packed_round<opc, !strconcat(OpcodeStr, "pd"), OpNodeRnd,
7148                                 v8f64_info>, EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>;
7149 }
7150
7151 multiclass avx512_sqrt_scalar<bits<8> opc, string OpcodeStr,X86VectorVTInfo _,
7152                               string SUFF, SDNode OpNode, SDNode OpNodeRnd> {
7153   let ExeDomain = _.ExeDomain in {
7154   defm r_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7155                          (ins _.RC:$src1, _.RC:$src2), OpcodeStr,
7156                          "$src2, $src1", "$src1, $src2",
7157                          (OpNodeRnd (_.VT _.RC:$src1),
7158                                     (_.VT _.RC:$src2),
7159                                     (i32 FROUND_CURRENT))>;
7160   defm m_Int : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7161                        (ins _.RC:$src1, _.ScalarMemOp:$src2), OpcodeStr,
7162                        "$src2, $src1", "$src1, $src2",
7163                        (OpNodeRnd (_.VT _.RC:$src1),
7164                                   (_.VT (scalar_to_vector
7165                                             (_.ScalarLdFrag addr:$src2))),
7166                                   (i32 FROUND_CURRENT))>;
7167
7168   defm rb_Int : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7169                          (ins _.RC:$src1, _.RC:$src2, AVX512RC:$rc), OpcodeStr,
7170                          "$rc, $src2, $src1", "$src1, $src2, $rc",
7171                          (OpNodeRnd (_.VT _.RC:$src1),
7172                                      (_.VT _.RC:$src2),
7173                                      (i32 imm:$rc))>,
7174                          EVEX_B, EVEX_RC;
7175
7176   let isCodeGenOnly = 1, hasSideEffects = 0 in {
7177     def r : I<opc, MRMSrcReg, (outs _.FRC:$dst),
7178                (ins _.FRC:$src1, _.FRC:$src2),
7179                OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
7180
7181     let mayLoad = 1 in
7182       def m : I<opc, MRMSrcMem, (outs _.FRC:$dst),
7183                  (ins _.FRC:$src1, _.ScalarMemOp:$src2),
7184                  OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>;
7185   }
7186   }
7187
7188   def : Pat<(_.EltVT (OpNode _.FRC:$src)),
7189             (!cast<Instruction>(NAME#SUFF#Zr)
7190                 (_.EltVT (IMPLICIT_DEF)), _.FRC:$src)>;
7191
7192   def : Pat<(_.EltVT (OpNode (load addr:$src))),
7193             (!cast<Instruction>(NAME#SUFF#Zm)
7194                 (_.EltVT (IMPLICIT_DEF)), addr:$src)>, Requires<[HasAVX512, OptForSize]>;
7195 }
7196
7197 multiclass avx512_sqrt_scalar_all<bits<8> opc, string OpcodeStr> {
7198   defm SSZ : avx512_sqrt_scalar<opc, OpcodeStr#"ss", f32x_info, "SS", fsqrt,
7199                         X86fsqrtRnds>, EVEX_CD8<32, CD8VT1>, EVEX_4V, XS;
7200   defm SDZ : avx512_sqrt_scalar<opc, OpcodeStr#"sd", f64x_info, "SD", fsqrt,
7201                         X86fsqrtRnds>, EVEX_CD8<64, CD8VT1>, EVEX_4V, XD, VEX_W;
7202 }
7203
7204 defm VSQRT   : avx512_sqrt_packed_all<0x51, "vsqrt", fsqrt>,
7205                avx512_sqrt_packed_all_round<0x51, "vsqrt", X86fsqrtRnd>;
7206
7207 defm VSQRT   : avx512_sqrt_scalar_all<0x51, "vsqrt">, VEX_LIG;
7208
7209 let Predicates = [HasAVX512] in {
7210   def : Pat<(f32 (X86frsqrt FR32X:$src)),
7211             (COPY_TO_REGCLASS (VRSQRT14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X)>;
7212   def : Pat<(f32 (X86frsqrt (load addr:$src))),
7213             (COPY_TO_REGCLASS (VRSQRT14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
7214             Requires<[OptForSize]>;
7215   def : Pat<(f32 (X86frcp FR32X:$src)),
7216             (COPY_TO_REGCLASS (VRCP14SSrr (v4f32 (IMPLICIT_DEF)), (COPY_TO_REGCLASS FR32X:$src, VR128X)), VR128X )>;
7217   def : Pat<(f32 (X86frcp (load addr:$src))),
7218             (COPY_TO_REGCLASS (VRCP14SSrm (v4f32 (IMPLICIT_DEF)), addr:$src), VR128X)>,
7219             Requires<[OptForSize]>;
7220 }
7221
7222 multiclass
7223 avx512_rndscale_scalar<bits<8> opc, string OpcodeStr, X86VectorVTInfo _> {
7224
7225   let ExeDomain = _.ExeDomain in {
7226   defm r : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7227                            (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
7228                            "$src3, $src2, $src1", "$src1, $src2, $src3",
7229                            (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7230                             (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
7231
7232   defm rb : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
7233                          (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3), OpcodeStr,
7234                          "$src3, {sae}, $src2, $src1", "$src1, $src2, {sae}, $src3",
7235                          (_.VT (X86RndScales (_.VT _.RC:$src1), (_.VT _.RC:$src2),
7236                          (i32 imm:$src3), (i32 FROUND_NO_EXC)))>, EVEX_B;
7237
7238   defm m : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
7239                          (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
7240                          OpcodeStr,
7241                          "$src3, $src2, $src1", "$src1, $src2, $src3",
7242                          (_.VT (X86RndScales (_.VT _.RC:$src1),
7243                           (_.VT (scalar_to_vector (_.ScalarLdFrag addr:$src2))),
7244                           (i32 imm:$src3), (i32 FROUND_CURRENT)))>;
7245   }
7246   let Predicates = [HasAVX512] in {
7247   def : Pat<(ffloor _.FRC:$src), (COPY_TO_REGCLASS
7248              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7249              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x1))), _.FRC)>;
7250   def : Pat<(fceil _.FRC:$src), (COPY_TO_REGCLASS
7251              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7252              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x2))), _.FRC)>;
7253   def : Pat<(ftrunc _.FRC:$src), (COPY_TO_REGCLASS
7254              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7255              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x3))), _.FRC)>;
7256   def : Pat<(frint _.FRC:$src), (COPY_TO_REGCLASS
7257              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7258              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0x4))), _.FRC)>;
7259   def : Pat<(fnearbyint _.FRC:$src), (COPY_TO_REGCLASS
7260              (_.VT (!cast<Instruction>(NAME##r) (_.VT (IMPLICIT_DEF)),
7261              (_.VT (COPY_TO_REGCLASS _.FRC:$src, _.RC)), (i32 0xc))), _.FRC)>;
7262
7263   def : Pat<(ffloor (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7264              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7265              addr:$src, (i32 0x1))), _.FRC)>;
7266   def : Pat<(fceil (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7267              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7268              addr:$src, (i32 0x2))), _.FRC)>;
7269   def : Pat<(ftrunc (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7270              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7271              addr:$src, (i32 0x3))), _.FRC)>;
7272   def : Pat<(frint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7273              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7274              addr:$src, (i32 0x4))), _.FRC)>;
7275   def : Pat<(fnearbyint (_.ScalarLdFrag addr:$src)), (COPY_TO_REGCLASS
7276              (_.VT (!cast<Instruction>(NAME##m) (_.VT (IMPLICIT_DEF)),
7277              addr:$src, (i32 0xc))), _.FRC)>;
7278   }
7279 }
7280
7281 defm VRNDSCALESS : avx512_rndscale_scalar<0x0A, "vrndscaless", f32x_info>,
7282                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VT1>;
7283
7284 defm VRNDSCALESD : avx512_rndscale_scalar<0x0B, "vrndscalesd", f64x_info>, VEX_W,
7285                                 AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VT1>;
7286
7287 //-------------------------------------------------
7288 // Integer truncate and extend operations
7289 //-------------------------------------------------
7290
7291 multiclass avx512_trunc_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
7292                               X86VectorVTInfo SrcInfo, X86VectorVTInfo DestInfo,
7293                               X86MemOperand x86memop> {
7294   let ExeDomain = DestInfo.ExeDomain in
7295   defm rr  : AVX512_maskable<opc, MRMDestReg, DestInfo, (outs DestInfo.RC:$dst),
7296                       (ins SrcInfo.RC:$src1), OpcodeStr ,"$src1", "$src1",
7297                       (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1)))>,
7298                        EVEX, T8XS;
7299
7300   // for intrinsic patter match
7301   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7302                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7303                            undef)),
7304             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
7305                                       SrcInfo.RC:$src1)>;
7306
7307   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7308                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7309                            DestInfo.ImmAllZerosV)),
7310             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrkz) DestInfo.KRCWM:$mask ,
7311                                       SrcInfo.RC:$src1)>;
7312
7313   def : Pat<(DestInfo.VT (X86select DestInfo.KRCWM:$mask,
7314                            (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1))),
7315                            DestInfo.RC:$src0)),
7316             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##rrk) DestInfo.RC:$src0,
7317                                       DestInfo.KRCWM:$mask ,
7318                                       SrcInfo.RC:$src1)>;
7319
7320   let mayStore = 1, mayLoad = 1, hasSideEffects = 0,
7321       ExeDomain = DestInfo.ExeDomain in {
7322     def mr : AVX512XS8I<opc, MRMDestMem, (outs),
7323                (ins x86memop:$dst, SrcInfo.RC:$src),
7324                OpcodeStr # "\t{$src, $dst|$dst, $src}",
7325                []>, EVEX;
7326
7327     def mrk : AVX512XS8I<opc, MRMDestMem, (outs),
7328                (ins x86memop:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src),
7329                OpcodeStr # "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}",
7330                []>, EVEX, EVEX_K;
7331   }//mayStore = 1, mayLoad = 1, hasSideEffects = 0
7332 }
7333
7334 multiclass avx512_trunc_mr_lowering<X86VectorVTInfo SrcInfo,
7335                                     X86VectorVTInfo DestInfo,
7336                                     PatFrag truncFrag, PatFrag mtruncFrag > {
7337
7338   def : Pat<(truncFrag (SrcInfo.VT SrcInfo.RC:$src), addr:$dst),
7339             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mr)
7340                                     addr:$dst, SrcInfo.RC:$src)>;
7341
7342   def : Pat<(mtruncFrag addr:$dst, SrcInfo.KRCWM:$mask,
7343                                                (SrcInfo.VT SrcInfo.RC:$src)),
7344             (!cast<Instruction>(NAME#SrcInfo.ZSuffix##mrk)
7345                             addr:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src)>;
7346 }
7347
7348 multiclass avx512_trunc<bits<8> opc, string OpcodeStr, SDNode OpNode,
7349          AVX512VLVectorVTInfo VTSrcInfo, X86VectorVTInfo DestInfoZ128,
7350          X86VectorVTInfo DestInfoZ256, X86VectorVTInfo DestInfoZ,
7351          X86MemOperand x86memopZ128, X86MemOperand x86memopZ256,
7352          X86MemOperand x86memopZ, PatFrag truncFrag, PatFrag mtruncFrag,
7353                                                      Predicate prd = HasAVX512>{
7354
7355   let Predicates = [HasVLX, prd] in {
7356     defm Z128:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info128,
7357                              DestInfoZ128, x86memopZ128>,
7358                 avx512_trunc_mr_lowering<VTSrcInfo.info128, DestInfoZ128,
7359                              truncFrag, mtruncFrag>, EVEX_V128;
7360
7361     defm Z256:  avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info256,
7362                              DestInfoZ256, x86memopZ256>,
7363                 avx512_trunc_mr_lowering<VTSrcInfo.info256, DestInfoZ256,
7364                              truncFrag, mtruncFrag>, EVEX_V256;
7365   }
7366   let Predicates = [prd] in
7367     defm Z:     avx512_trunc_common<opc, OpcodeStr, OpNode, VTSrcInfo.info512,
7368                              DestInfoZ, x86memopZ>,
7369                 avx512_trunc_mr_lowering<VTSrcInfo.info512, DestInfoZ,
7370                              truncFrag, mtruncFrag>, EVEX_V512;
7371 }
7372
7373 multiclass avx512_trunc_qb<bits<8> opc, string OpcodeStr, SDNode OpNode,
7374                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7375   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7376                v16i8x_info, v16i8x_info, v16i8x_info, i16mem, i32mem, i64mem,
7377                StoreNode, MaskedStoreNode>, EVEX_CD8<8, CD8VO>;
7378 }
7379
7380 multiclass avx512_trunc_qw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7381                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7382   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7383                v8i16x_info, v8i16x_info, v8i16x_info, i32mem, i64mem, i128mem,
7384                StoreNode, MaskedStoreNode>, EVEX_CD8<16, CD8VQ>;
7385 }
7386
7387 multiclass avx512_trunc_qd<bits<8> opc, string OpcodeStr, SDNode OpNode,
7388                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7389   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i64_info,
7390                v4i32x_info, v4i32x_info, v8i32x_info, i64mem, i128mem, i256mem,
7391                StoreNode, MaskedStoreNode>, EVEX_CD8<32, CD8VH>;
7392 }
7393
7394 multiclass avx512_trunc_db<bits<8> opc, string OpcodeStr, SDNode OpNode,
7395                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7396   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
7397                v16i8x_info, v16i8x_info, v16i8x_info, i32mem, i64mem, i128mem,
7398                StoreNode, MaskedStoreNode>, EVEX_CD8<8, CD8VQ>;
7399 }
7400
7401 multiclass avx512_trunc_dw<bits<8> opc, string OpcodeStr, SDNode OpNode,
7402                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7403   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i32_info,
7404               v8i16x_info, v8i16x_info, v16i16x_info, i64mem, i128mem, i256mem,
7405               StoreNode, MaskedStoreNode>, EVEX_CD8<16, CD8VH>;
7406 }
7407
7408 multiclass avx512_trunc_wb<bits<8> opc, string OpcodeStr, SDNode OpNode,
7409                            PatFrag StoreNode, PatFrag MaskedStoreNode> {
7410   defm NAME: avx512_trunc<opc, OpcodeStr, OpNode, avx512vl_i16_info,
7411               v16i8x_info, v16i8x_info, v32i8x_info, i64mem, i128mem, i256mem,
7412               StoreNode, MaskedStoreNode, HasBWI>, EVEX_CD8<16, CD8VH>;
7413 }
7414
7415 defm VPMOVQB    : avx512_trunc_qb<0x32, "vpmovqb",   X86vtrunc,
7416                                   truncstorevi8, masked_truncstorevi8>;
7417 defm VPMOVSQB   : avx512_trunc_qb<0x22, "vpmovsqb",  X86vtruncs,
7418                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7419 defm VPMOVUSQB  : avx512_trunc_qb<0x12, "vpmovusqb", X86vtruncus,
7420                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7421
7422 defm VPMOVQW    : avx512_trunc_qw<0x34, "vpmovqw",   X86vtrunc,
7423                                   truncstorevi16, masked_truncstorevi16>;
7424 defm VPMOVSQW   : avx512_trunc_qw<0x24, "vpmovsqw",  X86vtruncs,
7425                                   truncstore_s_vi16, masked_truncstore_s_vi16>;
7426 defm VPMOVUSQW  : avx512_trunc_qw<0x14, "vpmovusqw", X86vtruncus,
7427                                   truncstore_us_vi16, masked_truncstore_us_vi16>;
7428
7429 defm VPMOVQD    : avx512_trunc_qd<0x35, "vpmovqd",   X86vtrunc,
7430                                   truncstorevi32, masked_truncstorevi32>;
7431 defm VPMOVSQD   : avx512_trunc_qd<0x25, "vpmovsqd",  X86vtruncs,
7432                                   truncstore_s_vi32, masked_truncstore_s_vi32>;
7433 defm VPMOVUSQD  : avx512_trunc_qd<0x15, "vpmovusqd", X86vtruncus,
7434                                   truncstore_us_vi32, masked_truncstore_us_vi32>;
7435
7436 defm VPMOVDB    : avx512_trunc_db<0x31, "vpmovdb", X86vtrunc,
7437                                   truncstorevi8, masked_truncstorevi8>;
7438 defm VPMOVSDB   : avx512_trunc_db<0x21, "vpmovsdb",   X86vtruncs,
7439                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7440 defm VPMOVUSDB  : avx512_trunc_db<0x11, "vpmovusdb",  X86vtruncus,
7441                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7442
7443 defm VPMOVDW    : avx512_trunc_dw<0x33, "vpmovdw", X86vtrunc,
7444                                   truncstorevi16, masked_truncstorevi16>;
7445 defm VPMOVSDW   : avx512_trunc_dw<0x23, "vpmovsdw",   X86vtruncs,
7446                                   truncstore_s_vi16, masked_truncstore_s_vi16>;
7447 defm VPMOVUSDW  : avx512_trunc_dw<0x13, "vpmovusdw",  X86vtruncus,
7448                                   truncstore_us_vi16, masked_truncstore_us_vi16>;
7449
7450 defm VPMOVWB    : avx512_trunc_wb<0x30, "vpmovwb", X86vtrunc,
7451                                   truncstorevi8, masked_truncstorevi8>;
7452 defm VPMOVSWB   : avx512_trunc_wb<0x20, "vpmovswb",   X86vtruncs,
7453                                   truncstore_s_vi8, masked_truncstore_s_vi8>;
7454 defm VPMOVUSWB  : avx512_trunc_wb<0x10, "vpmovuswb",  X86vtruncus,
7455                                   truncstore_us_vi8, masked_truncstore_us_vi8>;
7456
7457 let Predicates = [HasAVX512, NoVLX] in {
7458 def: Pat<(v8i16 (X86vtrunc (v8i32 VR256X:$src))),
7459          (v8i16 (EXTRACT_SUBREG
7460                  (v16i16 (VPMOVDWZrr (v16i32 (INSERT_SUBREG (IMPLICIT_DEF),
7461                                           VR256X:$src, sub_ymm)))), sub_xmm))>;
7462 def: Pat<(v4i32 (X86vtrunc (v4i64 VR256X:$src))),
7463          (v4i32 (EXTRACT_SUBREG
7464                  (v8i32 (VPMOVQDZrr (v8i64 (INSERT_SUBREG (IMPLICIT_DEF),
7465                                            VR256X:$src, sub_ymm)))), sub_xmm))>;
7466 }
7467
7468 let Predicates = [HasBWI, NoVLX] in {
7469 def: Pat<(v16i8 (X86vtrunc (v16i16 VR256X:$src))),
7470          (v16i8 (EXTRACT_SUBREG (VPMOVWBZrr (v32i16 (INSERT_SUBREG (IMPLICIT_DEF),
7471                                             VR256X:$src, sub_ymm))), sub_xmm))>;
7472 }
7473
7474 multiclass avx512_extend_common<bits<8> opc, string OpcodeStr,
7475               X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo,
7476               X86MemOperand x86memop, PatFrag LdFrag, SDPatternOperator OpNode>{
7477   let ExeDomain = DestInfo.ExeDomain in {
7478   defm rr   : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
7479                     (ins SrcInfo.RC:$src), OpcodeStr ,"$src", "$src",
7480                     (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src)))>,
7481                   EVEX;
7482
7483   defm rm : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
7484                   (ins x86memop:$src), OpcodeStr ,"$src", "$src",
7485                   (DestInfo.VT (LdFrag addr:$src))>,
7486                 EVEX;
7487   }
7488 }
7489
7490 multiclass avx512_extend_BW<bits<8> opc, string OpcodeStr,
7491           SDPatternOperator OpNode, SDPatternOperator InVecNode,
7492           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7493   let Predicates = [HasVLX, HasBWI] in {
7494     defm Z128:  avx512_extend_common<opc, OpcodeStr, v8i16x_info,
7495                     v16i8x_info, i64mem, LdFrag, InVecNode>,
7496                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V128;
7497
7498     defm Z256:  avx512_extend_common<opc, OpcodeStr, v16i16x_info,
7499                     v16i8x_info, i128mem, LdFrag, OpNode>,
7500                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V256;
7501   }
7502   let Predicates = [HasBWI] in {
7503     defm Z   :  avx512_extend_common<opc, OpcodeStr, v32i16_info,
7504                     v32i8x_info, i256mem, LdFrag, OpNode>,
7505                      EVEX_CD8<8, CD8VH>, T8PD, EVEX_V512;
7506   }
7507 }
7508
7509 multiclass avx512_extend_BD<bits<8> opc, string OpcodeStr,
7510           SDPatternOperator OpNode, SDPatternOperator InVecNode,
7511           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7512   let Predicates = [HasVLX, HasAVX512] in {
7513     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
7514                    v16i8x_info, i32mem, LdFrag, InVecNode>,
7515                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V128;
7516
7517     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
7518                    v16i8x_info, i64mem, LdFrag, OpNode>,
7519                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V256;
7520   }
7521   let Predicates = [HasAVX512] in {
7522     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
7523                    v16i8x_info, i128mem, LdFrag, OpNode>,
7524                          EVEX_CD8<8, CD8VQ>, T8PD, EVEX_V512;
7525   }
7526 }
7527
7528 multiclass avx512_extend_BQ<bits<8> opc, string OpcodeStr,
7529           SDPatternOperator OpNode, SDPatternOperator InVecNode,
7530           string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi8")> {
7531   let Predicates = [HasVLX, HasAVX512] in {
7532     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7533                    v16i8x_info, i16mem, LdFrag, InVecNode>,
7534                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V128;
7535
7536     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7537                    v16i8x_info, i32mem, LdFrag, OpNode>,
7538                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V256;
7539   }
7540   let Predicates = [HasAVX512] in {
7541     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7542                    v16i8x_info, i64mem, LdFrag, OpNode>,
7543                      EVEX_CD8<8, CD8VO>, T8PD, EVEX_V512;
7544   }
7545 }
7546
7547 multiclass avx512_extend_WD<bits<8> opc, string OpcodeStr,
7548          SDPatternOperator OpNode, SDPatternOperator InVecNode,
7549          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
7550   let Predicates = [HasVLX, HasAVX512] in {
7551     defm Z128:  avx512_extend_common<opc, OpcodeStr, v4i32x_info,
7552                    v8i16x_info, i64mem, LdFrag, InVecNode>,
7553                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V128;
7554
7555     defm Z256:  avx512_extend_common<opc, OpcodeStr, v8i32x_info,
7556                    v8i16x_info, i128mem, LdFrag, OpNode>,
7557                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V256;
7558   }
7559   let Predicates = [HasAVX512] in {
7560     defm Z   :  avx512_extend_common<opc, OpcodeStr, v16i32_info,
7561                    v16i16x_info, i256mem, LdFrag, OpNode>,
7562                      EVEX_CD8<16, CD8VH>, T8PD, EVEX_V512;
7563   }
7564 }
7565
7566 multiclass avx512_extend_WQ<bits<8> opc, string OpcodeStr,
7567          SDPatternOperator OpNode, SDPatternOperator InVecNode,
7568          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi16")> {
7569   let Predicates = [HasVLX, HasAVX512] in {
7570     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7571                    v8i16x_info, i32mem, LdFrag, InVecNode>,
7572                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V128;
7573
7574     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7575                    v8i16x_info, i64mem, LdFrag, OpNode>,
7576                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V256;
7577   }
7578   let Predicates = [HasAVX512] in {
7579     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7580                    v8i16x_info, i128mem, LdFrag, OpNode>,
7581                      EVEX_CD8<16, CD8VQ>, T8PD, EVEX_V512;
7582   }
7583 }
7584
7585 multiclass avx512_extend_DQ<bits<8> opc, string OpcodeStr,
7586          SDPatternOperator OpNode, SDPatternOperator InVecNode,
7587          string ExtTy,PatFrag LdFrag = !cast<PatFrag>(ExtTy#"extloadvi32")> {
7588
7589   let Predicates = [HasVLX, HasAVX512] in {
7590     defm Z128:  avx512_extend_common<opc, OpcodeStr, v2i64x_info,
7591                    v4i32x_info, i64mem, LdFrag, InVecNode>,
7592                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V128;
7593
7594     defm Z256:  avx512_extend_common<opc, OpcodeStr, v4i64x_info,
7595                    v4i32x_info, i128mem, LdFrag, OpNode>,
7596                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V256;
7597   }
7598   let Predicates = [HasAVX512] in {
7599     defm Z   :  avx512_extend_common<opc, OpcodeStr, v8i64_info,
7600                    v8i32x_info, i256mem, LdFrag, OpNode>,
7601                      EVEX_CD8<32, CD8VH>, T8PD, EVEX_V512;
7602   }
7603 }
7604
7605 defm VPMOVZXBW : avx512_extend_BW<0x30, "vpmovzxbw", X86vzext, zext_invec, "z">;
7606 defm VPMOVZXBD : avx512_extend_BD<0x31, "vpmovzxbd", X86vzext, zext_invec, "z">;
7607 defm VPMOVZXBQ : avx512_extend_BQ<0x32, "vpmovzxbq", X86vzext, zext_invec, "z">;
7608 defm VPMOVZXWD : avx512_extend_WD<0x33, "vpmovzxwd", X86vzext, zext_invec, "z">;
7609 defm VPMOVZXWQ : avx512_extend_WQ<0x34, "vpmovzxwq", X86vzext, zext_invec, "z">;
7610 defm VPMOVZXDQ : avx512_extend_DQ<0x35, "vpmovzxdq", X86vzext, zext_invec, "z">;
7611
7612 defm VPMOVSXBW: avx512_extend_BW<0x20, "vpmovsxbw", X86vsext, sext_invec, "s">;
7613 defm VPMOVSXBD: avx512_extend_BD<0x21, "vpmovsxbd", X86vsext, sext_invec, "s">;
7614 defm VPMOVSXBQ: avx512_extend_BQ<0x22, "vpmovsxbq", X86vsext, sext_invec, "s">;
7615 defm VPMOVSXWD: avx512_extend_WD<0x23, "vpmovsxwd", X86vsext, sext_invec, "s">;
7616 defm VPMOVSXWQ: avx512_extend_WQ<0x24, "vpmovsxwq", X86vsext, sext_invec, "s">;
7617 defm VPMOVSXDQ: avx512_extend_DQ<0x25, "vpmovsxdq", X86vsext, sext_invec, "s">;
7618
7619 // EXTLOAD patterns, implemented using vpmovz
7620 multiclass avx512_ext_lowering<string InstrStr, X86VectorVTInfo To,
7621                                X86VectorVTInfo From, PatFrag LdFrag> {
7622   def : Pat<(To.VT (LdFrag addr:$src)),
7623             (!cast<Instruction>("VPMOVZX"#InstrStr#"rm") addr:$src)>;
7624   def : Pat<(To.VT (vselect To.KRCWM:$mask, (LdFrag addr:$src), To.RC:$src0)),
7625             (!cast<Instruction>("VPMOVZX"#InstrStr#"rmk") To.RC:$src0,
7626              To.KRC:$mask, addr:$src)>;
7627   def : Pat<(To.VT (vselect To.KRCWM:$mask, (LdFrag addr:$src),
7628                     To.ImmAllZerosV)),
7629             (!cast<Instruction>("VPMOVZX"#InstrStr#"rmkz") To.KRC:$mask,
7630              addr:$src)>;
7631 }
7632
7633 let Predicates = [HasVLX, HasBWI] in {
7634   defm : avx512_ext_lowering<"BWZ128", v8i16x_info,  v16i8x_info,  extloadvi8>;
7635   defm : avx512_ext_lowering<"BWZ256", v16i16x_info, v16i8x_info,  extloadvi8>;
7636 }
7637 let Predicates = [HasBWI] in {
7638   defm : avx512_ext_lowering<"BWZ",    v32i16_info,  v32i8x_info,  extloadvi8>;
7639 }
7640 let Predicates = [HasVLX, HasAVX512] in {
7641   defm : avx512_ext_lowering<"BDZ128", v4i32x_info,  v16i8x_info,  extloadvi8>;
7642   defm : avx512_ext_lowering<"BDZ256", v8i32x_info,  v16i8x_info,  extloadvi8>;
7643   defm : avx512_ext_lowering<"BQZ128", v2i64x_info,  v16i8x_info,  extloadvi8>;
7644   defm : avx512_ext_lowering<"BQZ256", v4i64x_info,  v16i8x_info,  extloadvi8>;
7645   defm : avx512_ext_lowering<"WDZ128", v4i32x_info,  v8i16x_info,  extloadvi16>;
7646   defm : avx512_ext_lowering<"WDZ256", v8i32x_info,  v8i16x_info,  extloadvi16>;
7647   defm : avx512_ext_lowering<"WQZ128", v2i64x_info,  v8i16x_info,  extloadvi16>;
7648   defm : avx512_ext_lowering<"WQZ256", v4i64x_info,  v8i16x_info,  extloadvi16>;
7649   defm : avx512_ext_lowering<"DQZ128", v2i64x_info,  v4i32x_info,  extloadvi32>;
7650   defm : avx512_ext_lowering<"DQZ256", v4i64x_info,  v4i32x_info,  extloadvi32>;
7651 }
7652 let Predicates = [HasAVX512] in {
7653   defm : avx512_ext_lowering<"BDZ",    v16i32_info,  v16i8x_info,  extloadvi8>;
7654   defm : avx512_ext_lowering<"BQZ",    v8i64_info,   v16i8x_info,  extloadvi8>;
7655   defm : avx512_ext_lowering<"WDZ",    v16i32_info,  v16i16x_info, extloadvi16>;
7656   defm : avx512_ext_lowering<"WQZ",    v8i64_info,   v8i16x_info,  extloadvi16>;
7657   defm : avx512_ext_lowering<"DQZ",    v8i64_info,   v8i32x_info,  extloadvi32>;
7658 }
7659
7660 multiclass AVX512_pmovx_patterns<string OpcPrefix, SDNode ExtOp,
7661                                  SDNode InVecOp, PatFrag ExtLoad16> {
7662   // 128-bit patterns
7663   let Predicates = [HasVLX, HasBWI] in {
7664   def : Pat<(v8i16 (InVecOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7665             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7666   def : Pat<(v8i16 (InVecOp (bc_v16i8 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7667             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7668   def : Pat<(v8i16 (InVecOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7669             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7670   def : Pat<(v8i16 (InVecOp (v16i8 (vzload_v2i64 addr:$src)))),
7671             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7672   def : Pat<(v8i16 (InVecOp (bc_v16i8 (loadv2i64 addr:$src)))),
7673             (!cast<I>(OpcPrefix#BWZ128rm) addr:$src)>;
7674   }
7675   let Predicates = [HasVLX] in {
7676   def : Pat<(v4i32 (InVecOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7677             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7678   def : Pat<(v4i32 (InVecOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7679             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7680   def : Pat<(v4i32 (InVecOp (v16i8 (vzload_v2i64 addr:$src)))),
7681             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7682   def : Pat<(v4i32 (InVecOp (bc_v16i8 (loadv2i64 addr:$src)))),
7683             (!cast<I>(OpcPrefix#BDZ128rm) addr:$src)>;
7684
7685   def : Pat<(v2i64 (InVecOp (bc_v16i8 (v4i32 (scalar_to_vector (ExtLoad16 addr:$src)))))),
7686             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7687   def : Pat<(v2i64 (InVecOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7688             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7689   def : Pat<(v2i64 (InVecOp (v16i8 (vzload_v2i64 addr:$src)))),
7690             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7691   def : Pat<(v2i64 (InVecOp (bc_v16i8 (loadv2i64 addr:$src)))),
7692             (!cast<I>(OpcPrefix#BQZ128rm) addr:$src)>;
7693
7694   def : Pat<(v4i32 (InVecOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7695             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7696   def : Pat<(v4i32 (InVecOp (bc_v8i16 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7697             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7698   def : Pat<(v4i32 (InVecOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7699             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7700   def : Pat<(v4i32 (InVecOp (v8i16 (vzload_v2i64 addr:$src)))),
7701             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7702   def : Pat<(v4i32 (InVecOp (bc_v8i16 (loadv2i64 addr:$src)))),
7703             (!cast<I>(OpcPrefix#WDZ128rm) addr:$src)>;
7704
7705   def : Pat<(v2i64 (InVecOp (bc_v8i16 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7706             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7707   def : Pat<(v2i64 (InVecOp (v8i16 (vzmovl_v4i32 addr:$src)))),
7708             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7709   def : Pat<(v2i64 (InVecOp (v8i16 (vzload_v2i64 addr:$src)))),
7710             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7711   def : Pat<(v2i64 (InVecOp (bc_v8i16 (loadv2i64 addr:$src)))),
7712             (!cast<I>(OpcPrefix#WQZ128rm) addr:$src)>;
7713
7714   def : Pat<(v2i64 (InVecOp (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7715             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7716   def : Pat<(v2i64 (InVecOp (bc_v4i32 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
7717             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7718   def : Pat<(v2i64 (InVecOp (v4i32 (vzmovl_v2i64 addr:$src)))),
7719             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7720   def : Pat<(v2i64 (InVecOp (v4i32 (vzload_v2i64 addr:$src)))),
7721             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7722   def : Pat<(v2i64 (InVecOp (bc_v4i32 (loadv2i64 addr:$src)))),
7723             (!cast<I>(OpcPrefix#DQZ128rm) addr:$src)>;
7724   }
7725   // 256-bit patterns
7726   let Predicates = [HasVLX, HasBWI] in {
7727   def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7728             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7729   def : Pat<(v16i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7730             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7731   def : Pat<(v16i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7732             (!cast<I>(OpcPrefix#BWZ256rm) addr:$src)>;
7733   }
7734   let Predicates = [HasVLX] in {
7735   def : Pat<(v8i32 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7736             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7737   def : Pat<(v8i32 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
7738             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7739   def : Pat<(v8i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7740             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7741   def : Pat<(v8i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7742             (!cast<I>(OpcPrefix#BDZ256rm) addr:$src)>;
7743
7744   def : Pat<(v4i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
7745             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7746   def : Pat<(v4i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
7747             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7748   def : Pat<(v4i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
7749             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7750   def : Pat<(v4i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7751             (!cast<I>(OpcPrefix#BQZ256rm) addr:$src)>;
7752
7753   def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7754             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7755   def : Pat<(v8i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7756             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7757   def : Pat<(v8i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7758             (!cast<I>(OpcPrefix#WDZ256rm) addr:$src)>;
7759
7760   def : Pat<(v4i64 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7761             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7762   def : Pat<(v4i64 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
7763             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7764   def : Pat<(v4i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
7765             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7766   def : Pat<(v4i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7767             (!cast<I>(OpcPrefix#WQZ256rm) addr:$src)>;
7768
7769   def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
7770             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7771   def : Pat<(v4i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
7772             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7773   def : Pat<(v4i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
7774             (!cast<I>(OpcPrefix#DQZ256rm) addr:$src)>;
7775   }
7776   // 512-bit patterns
7777   let Predicates = [HasBWI] in {
7778   def : Pat<(v32i16 (ExtOp (bc_v32i8 (loadv4i64 addr:$src)))),
7779             (!cast<I>(OpcPrefix#BWZrm) addr:$src)>;
7780   }
7781   let Predicates = [HasAVX512] in {
7782   def : Pat<(v16i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7783             (!cast<I>(OpcPrefix#BDZrm) addr:$src)>;
7784
7785   def : Pat<(v8i64 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
7786             (!cast<I>(OpcPrefix#BQZrm) addr:$src)>;
7787   def : Pat<(v8i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
7788             (!cast<I>(OpcPrefix#BQZrm) addr:$src)>;
7789
7790   def : Pat<(v16i32 (ExtOp (bc_v16i16 (loadv4i64 addr:$src)))),
7791             (!cast<I>(OpcPrefix#WDZrm) addr:$src)>;
7792
7793   def : Pat<(v8i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
7794             (!cast<I>(OpcPrefix#WQZrm) addr:$src)>;
7795
7796   def : Pat<(v8i64 (ExtOp (bc_v8i32 (loadv4i64 addr:$src)))),
7797             (!cast<I>(OpcPrefix#DQZrm) addr:$src)>;
7798   }
7799 }
7800
7801 defm : AVX512_pmovx_patterns<"VPMOVSX", X86vsext, sext_invec, extloadi32i16>;
7802 defm : AVX512_pmovx_patterns<"VPMOVZX", X86vzext, zext_invec, loadi16_anyext>;
7803
7804 //===----------------------------------------------------------------------===//
7805 // GATHER - SCATTER Operations
7806
7807 multiclass avx512_gather<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7808                          X86MemOperand memop, PatFrag GatherNode> {
7809   let Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb",
7810       ExeDomain = _.ExeDomain in
7811   def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst, _.KRCWM:$mask_wb),
7812             (ins _.RC:$src1, _.KRCWM:$mask, memop:$src2),
7813             !strconcat(OpcodeStr#_.Suffix,
7814             "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),
7815             [(set _.RC:$dst, _.KRCWM:$mask_wb,
7816               (GatherNode  (_.VT _.RC:$src1), _.KRCWM:$mask,
7817                      vectoraddr:$src2))]>, EVEX, EVEX_K,
7818              EVEX_CD8<_.EltSize, CD8VT1>;
7819 }
7820
7821 multiclass avx512_gather_q_pd<bits<8> dopc, bits<8> qopc,
7822                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7823   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512,
7824                                       vy512mem, mgatherv8i32>, EVEX_V512, VEX_W;
7825   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info512,
7826                                       vz512mem,  mgatherv8i64>, EVEX_V512, VEX_W;
7827 let Predicates = [HasVLX] in {
7828   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
7829                               vx256xmem, mgatherv4i32>, EVEX_V256, VEX_W;
7830   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info256,
7831                               vy256xmem, mgatherv4i64>, EVEX_V256, VEX_W;
7832   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
7833                               vx128xmem, mgatherv4i32>, EVEX_V128, VEX_W;
7834   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7835                               vx128xmem, mgatherv2i64>, EVEX_V128, VEX_W;
7836 }
7837 }
7838
7839 multiclass avx512_gather_d_ps<bits<8> dopc, bits<8> qopc,
7840                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7841   defm NAME##D##SUFF##Z: avx512_gather<dopc, OpcodeStr##"d", _.info512, vz512mem,
7842                                        mgatherv16i32>, EVEX_V512;
7843   defm NAME##Q##SUFF##Z: avx512_gather<qopc, OpcodeStr##"q", _.info256, vz256xmem,
7844                                        mgatherv8i64>, EVEX_V512;
7845 let Predicates = [HasVLX] in {
7846   defm NAME##D##SUFF##Z256: avx512_gather<dopc, OpcodeStr##"d", _.info256,
7847                                           vy256xmem, mgatherv8i32>, EVEX_V256;
7848   defm NAME##Q##SUFF##Z256: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7849                                           vy128xmem, mgatherv4i64>, EVEX_V256;
7850   defm NAME##D##SUFF##Z128: avx512_gather<dopc, OpcodeStr##"d", _.info128,
7851                                           vx128xmem, mgatherv4i32>, EVEX_V128;
7852   defm NAME##Q##SUFF##Z128: avx512_gather<qopc, OpcodeStr##"q", _.info128,
7853                                           vx64xmem, mgatherv2i64>, EVEX_V128;
7854 }
7855 }
7856
7857
7858 defm VGATHER : avx512_gather_q_pd<0x92, 0x93, avx512vl_f64_info, "vgather", "PD">,
7859                avx512_gather_d_ps<0x92, 0x93, avx512vl_f32_info, "vgather", "PS">;
7860
7861 defm VPGATHER : avx512_gather_q_pd<0x90, 0x91, avx512vl_i64_info, "vpgather", "Q">,
7862                 avx512_gather_d_ps<0x90, 0x91, avx512vl_i32_info, "vpgather", "D">;
7863
7864 multiclass avx512_scatter<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,
7865                           X86MemOperand memop, PatFrag ScatterNode> {
7866
7867 let mayStore = 1, Constraints = "$mask = $mask_wb", ExeDomain = _.ExeDomain in
7868
7869   def mr  : AVX5128I<opc, MRMDestMem, (outs _.KRCWM:$mask_wb),
7870             (ins memop:$dst, _.KRCWM:$mask, _.RC:$src),
7871             !strconcat(OpcodeStr#_.Suffix,
7872             "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),
7873             [(set _.KRCWM:$mask_wb, (ScatterNode (_.VT _.RC:$src),
7874                                      _.KRCWM:$mask,  vectoraddr:$dst))]>,
7875             EVEX, EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
7876 }
7877
7878 multiclass avx512_scatter_q_pd<bits<8> dopc, bits<8> qopc,
7879                         AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7880   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512,
7881                                       vy512mem, mscatterv8i32>, EVEX_V512, VEX_W;
7882   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info512,
7883                                       vz512mem,  mscatterv8i64>, EVEX_V512, VEX_W;
7884 let Predicates = [HasVLX] in {
7885   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
7886                               vx256xmem, mscatterv4i32>, EVEX_V256, VEX_W;
7887   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info256,
7888                               vy256xmem, mscatterv4i64>, EVEX_V256, VEX_W;
7889   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
7890                               vx128xmem, mscatterv4i32>, EVEX_V128, VEX_W;
7891   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7892                               vx128xmem, mscatterv2i64>, EVEX_V128, VEX_W;
7893 }
7894 }
7895
7896 multiclass avx512_scatter_d_ps<bits<8> dopc, bits<8> qopc,
7897                        AVX512VLVectorVTInfo _, string OpcodeStr, string SUFF> {
7898   defm NAME##D##SUFF##Z: avx512_scatter<dopc, OpcodeStr##"d", _.info512, vz512mem,
7899                                        mscatterv16i32>, EVEX_V512;
7900   defm NAME##Q##SUFF##Z: avx512_scatter<qopc, OpcodeStr##"q", _.info256, vz256xmem,
7901                                        mscatterv8i64>, EVEX_V512;
7902 let Predicates = [HasVLX] in {
7903   defm NAME##D##SUFF##Z256: avx512_scatter<dopc, OpcodeStr##"d", _.info256,
7904                                           vy256xmem, mscatterv8i32>, EVEX_V256;
7905   defm NAME##Q##SUFF##Z256: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7906                                           vy128xmem, mscatterv4i64>, EVEX_V256;
7907   defm NAME##D##SUFF##Z128: avx512_scatter<dopc, OpcodeStr##"d", _.info128,
7908                                           vx128xmem, mscatterv4i32>, EVEX_V128;
7909   defm NAME##Q##SUFF##Z128: avx512_scatter<qopc, OpcodeStr##"q", _.info128,
7910                                           vx64xmem, mscatterv2i64>, EVEX_V128;
7911 }
7912 }
7913
7914 defm VSCATTER : avx512_scatter_q_pd<0xA2, 0xA3, avx512vl_f64_info, "vscatter", "PD">,
7915                avx512_scatter_d_ps<0xA2, 0xA3, avx512vl_f32_info, "vscatter", "PS">;
7916
7917 defm VPSCATTER : avx512_scatter_q_pd<0xA0, 0xA1, avx512vl_i64_info, "vpscatter", "Q">,
7918                 avx512_scatter_d_ps<0xA0, 0xA1, avx512vl_i32_info, "vpscatter", "D">;
7919
7920 // prefetch
7921 multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,
7922                        RegisterClass KRC, X86MemOperand memop> {
7923   let Predicates = [HasPFI], hasSideEffects = 1 in
7924   def m  : AVX5128I<opc, F, (outs), (ins KRC:$mask, memop:$src),
7925             !strconcat(OpcodeStr, "\t{$src {${mask}}|{${mask}}, $src}"),
7926             []>, EVEX, EVEX_K;
7927 }
7928
7929 defm VGATHERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dps",
7930                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7931
7932 defm VGATHERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qps",
7933                      VK8WM, vz256xmem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7934
7935 defm VGATHERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM1m, "vgatherpf0dpd",
7936                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7937
7938 defm VGATHERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM1m, "vgatherpf0qpd",
7939                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7940
7941 defm VGATHERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dps",
7942                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7943
7944 defm VGATHERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qps",
7945                      VK8WM, vz256xmem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7946
7947 defm VGATHERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM2m, "vgatherpf1dpd",
7948                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7949
7950 defm VGATHERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM2m, "vgatherpf1qpd",
7951                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7952
7953 defm VSCATTERPF0DPS: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dps",
7954                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7955
7956 defm VSCATTERPF0QPS: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qps",
7957                      VK8WM, vz256xmem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7958
7959 defm VSCATTERPF0DPD: avx512_gather_scatter_prefetch<0xC6, MRM5m, "vscatterpf0dpd",
7960                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7961
7962 defm VSCATTERPF0QPD: avx512_gather_scatter_prefetch<0xC7, MRM5m, "vscatterpf0qpd",
7963                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7964
7965 defm VSCATTERPF1DPS: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dps",
7966                      VK16WM, vz512mem>, EVEX_V512, EVEX_CD8<32, CD8VT1>;
7967
7968 defm VSCATTERPF1QPS: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qps",
7969                      VK8WM, vz256xmem>, EVEX_V512, EVEX_CD8<64, CD8VT1>;
7970
7971 defm VSCATTERPF1DPD: avx512_gather_scatter_prefetch<0xC6, MRM6m, "vscatterpf1dpd",
7972                      VK8WM, vy512mem>, EVEX_V512, VEX_W, EVEX_CD8<32, CD8VT1>;
7973
7974 defm VSCATTERPF1QPD: avx512_gather_scatter_prefetch<0xC7, MRM6m, "vscatterpf1qpd",
7975                      VK8WM, vz512mem>, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;
7976
7977 // Helper fragments to match sext vXi1 to vXiY.
7978 def v64i1sextv64i8 : PatLeaf<(v64i8
7979                               (X86vsext
7980                                (v64i1 (X86pcmpgtm
7981                                 (bc_v64i8 (v16i32 immAllZerosV)),
7982                                 VR512:$src))))>;
7983 def v32i1sextv32i16 : PatLeaf<(v32i16 (X86vsrai VR512:$src, (i8 15)))>;
7984 def v16i1sextv16i32 : PatLeaf<(v16i32 (X86vsrai VR512:$src, (i8 31)))>;
7985 def v8i1sextv8i64   : PatLeaf<(v8i64 (X86vsrai VR512:$src, (i8 63)))>;
7986
7987 multiclass cvt_by_vec_width<bits<8> opc, X86VectorVTInfo Vec, string OpcodeStr > {
7988 def rr : AVX512XS8I<opc, MRMSrcReg, (outs Vec.RC:$dst), (ins Vec.KRC:$src),
7989                   !strconcat(OpcodeStr##Vec.Suffix, "\t{$src, $dst|$dst, $src}"),
7990                   [(set Vec.RC:$dst, (Vec.VT (X86vsext Vec.KRC:$src)))]>, EVEX;
7991 }
7992
7993 // Use 512bit version to implement 128/256 bit in case NoVLX.
7994 multiclass avx512_convert_mask_to_vector_lowering<X86VectorVTInfo X86Info,
7995                                                             X86VectorVTInfo _> {
7996
7997   def : Pat<(X86Info.VT (X86vsext (X86Info.KVT X86Info.KRC:$src))),
7998             (X86Info.VT (EXTRACT_SUBREG
7999                            (_.VT (!cast<Instruction>(NAME#"Zrr")
8000                              (_.KVT (COPY_TO_REGCLASS X86Info.KRC:$src,_.KRC)))),
8001                            X86Info.SubRegIdx))>;
8002 }
8003
8004 multiclass cvt_mask_by_elt_width<bits<8> opc, AVX512VLVectorVTInfo VTInfo,
8005                                  string OpcodeStr, Predicate prd> {
8006 let Predicates = [prd] in
8007   defm Z : cvt_by_vec_width<opc, VTInfo.info512, OpcodeStr>, EVEX_V512;
8008
8009   let Predicates = [prd, HasVLX] in {
8010     defm Z256 : cvt_by_vec_width<opc, VTInfo.info256, OpcodeStr>, EVEX_V256;
8011     defm Z128 : cvt_by_vec_width<opc, VTInfo.info128, OpcodeStr>, EVEX_V128;
8012   }
8013 let Predicates = [prd, NoVLX] in {
8014    defm Z256_Alt :   avx512_convert_mask_to_vector_lowering<VTInfo.info256,VTInfo.info512>;
8015    defm Z128_Alt :   avx512_convert_mask_to_vector_lowering<VTInfo.info128,VTInfo.info512>;
8016   }
8017
8018 }
8019
8020 defm VPMOVM2B : cvt_mask_by_elt_width<0x28, avx512vl_i8_info, "vpmovm2" , HasBWI>;
8021 defm VPMOVM2W : cvt_mask_by_elt_width<0x28, avx512vl_i16_info, "vpmovm2", HasBWI> , VEX_W;
8022 defm VPMOVM2D : cvt_mask_by_elt_width<0x38, avx512vl_i32_info, "vpmovm2", HasDQI>;
8023 defm VPMOVM2Q : cvt_mask_by_elt_width<0x38, avx512vl_i64_info, "vpmovm2", HasDQI> , VEX_W;
8024
8025 multiclass convert_vector_to_mask_common<bits<8> opc, X86VectorVTInfo _, string OpcodeStr > {
8026     def rr : AVX512XS8I<opc, MRMSrcReg, (outs _.KRC:$dst), (ins _.RC:$src),
8027                         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8028                         [(set _.KRC:$dst, (X86cvt2mask (_.VT _.RC:$src)))]>, EVEX;
8029 }
8030
8031 // Use 512bit version to implement 128/256 bit in case NoVLX.
8032 multiclass convert_vector_to_mask_lowering<X86VectorVTInfo ExtendInfo,
8033                                                             X86VectorVTInfo _> {
8034
8035   def : Pat<(_.KVT (X86cvt2mask (_.VT _.RC:$src))),
8036             (_.KVT (COPY_TO_REGCLASS
8037                      (!cast<Instruction>(NAME#"Zrr")
8038                        (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)),
8039                                       _.RC:$src, _.SubRegIdx)),
8040                    _.KRC))>;
8041 }
8042
8043 multiclass avx512_convert_vector_to_mask<bits<8> opc, string OpcodeStr,
8044                                    AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8045   let Predicates = [prd] in
8046     defm Z : convert_vector_to_mask_common <opc, VTInfo.info512, OpcodeStr>,
8047                                             EVEX_V512;
8048
8049   let Predicates = [prd, HasVLX] in {
8050     defm Z256 : convert_vector_to_mask_common<opc, VTInfo.info256, OpcodeStr>,
8051                                               EVEX_V256;
8052     defm Z128 : convert_vector_to_mask_common<opc, VTInfo.info128, OpcodeStr>,
8053                                                EVEX_V128;
8054   }
8055   let Predicates = [prd, NoVLX] in {
8056     defm Z256_Alt : convert_vector_to_mask_lowering<VTInfo.info512, VTInfo.info256>;
8057     defm Z128_Alt : convert_vector_to_mask_lowering<VTInfo.info512, VTInfo.info128>;
8058   }
8059 }
8060
8061 defm VPMOVB2M : avx512_convert_vector_to_mask<0x29, "vpmovb2m",
8062                                               avx512vl_i8_info, HasBWI>;
8063 defm VPMOVW2M : avx512_convert_vector_to_mask<0x29, "vpmovw2m",
8064                                               avx512vl_i16_info, HasBWI>, VEX_W;
8065 defm VPMOVD2M : avx512_convert_vector_to_mask<0x39, "vpmovd2m",
8066                                               avx512vl_i32_info, HasDQI>;
8067 defm VPMOVQ2M : avx512_convert_vector_to_mask<0x39, "vpmovq2m",
8068                                               avx512vl_i64_info, HasDQI>, VEX_W;
8069
8070 //===----------------------------------------------------------------------===//
8071 // AVX-512 - COMPRESS and EXPAND
8072 //
8073
8074 multiclass compress_by_vec_width_common<bits<8> opc, X86VectorVTInfo _,
8075                                  string OpcodeStr> {
8076   defm rr : AVX512_maskable<opc, MRMDestReg, _, (outs _.RC:$dst),
8077               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
8078               (_.VT (X86compress _.RC:$src1))>, AVX5128IBase;
8079
8080   let mayStore = 1, hasSideEffects = 0 in
8081   def mr : AVX5128I<opc, MRMDestMem, (outs),
8082               (ins _.MemOp:$dst, _.RC:$src),
8083               OpcodeStr # "\t{$src, $dst|$dst, $src}",
8084               []>, EVEX_CD8<_.EltSize, CD8VT1>;
8085
8086   def mrk : AVX5128I<opc, MRMDestMem, (outs),
8087               (ins _.MemOp:$dst, _.KRCWM:$mask, _.RC:$src),
8088               OpcodeStr # "\t{$src, $dst {${mask}}|$dst {${mask}}, $src}",
8089               []>,
8090               EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;
8091 }
8092
8093 multiclass compress_by_vec_width_lowering<X86VectorVTInfo _ > {
8094
8095   def : Pat<(X86mCompressingStore addr:$dst, _.KRCWM:$mask,
8096                                                (_.VT _.RC:$src)),
8097             (!cast<Instruction>(NAME#_.ZSuffix##mrk)
8098                             addr:$dst, _.KRCWM:$mask, _.RC:$src)>;
8099 }
8100
8101 multiclass compress_by_elt_width<bits<8> opc, string OpcodeStr,
8102                                  AVX512VLVectorVTInfo VTInfo> {
8103   defm Z : compress_by_vec_width_common<opc, VTInfo.info512, OpcodeStr>,
8104            compress_by_vec_width_lowering<VTInfo.info512>, EVEX_V512;
8105
8106   let Predicates = [HasVLX] in {
8107     defm Z256 : compress_by_vec_width_common<opc, VTInfo.info256, OpcodeStr>,
8108                 compress_by_vec_width_lowering<VTInfo.info256>, EVEX_V256;
8109     defm Z128 : compress_by_vec_width_common<opc, VTInfo.info128, OpcodeStr>,
8110                 compress_by_vec_width_lowering<VTInfo.info128>, EVEX_V128;
8111   }
8112 }
8113
8114 defm VPCOMPRESSD : compress_by_elt_width <0x8B, "vpcompressd", avx512vl_i32_info>,
8115                                          EVEX;
8116 defm VPCOMPRESSQ : compress_by_elt_width <0x8B, "vpcompressq", avx512vl_i64_info>,
8117                                          EVEX, VEX_W;
8118 defm VCOMPRESSPS : compress_by_elt_width <0x8A, "vcompressps", avx512vl_f32_info>,
8119                                          EVEX;
8120 defm VCOMPRESSPD : compress_by_elt_width <0x8A, "vcompresspd", avx512vl_f64_info>,
8121                                          EVEX, VEX_W;
8122
8123 // expand
8124 multiclass expand_by_vec_width<bits<8> opc, X86VectorVTInfo _,
8125                                  string OpcodeStr> {
8126   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8127               (ins _.RC:$src1), OpcodeStr, "$src1", "$src1",
8128               (_.VT (X86expand _.RC:$src1))>, AVX5128IBase;
8129
8130   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8131               (ins _.MemOp:$src1), OpcodeStr, "$src1", "$src1",
8132               (_.VT (X86expand (_.VT (bitconvert
8133                                       (_.LdFrag addr:$src1)))))>,
8134             AVX5128IBase, EVEX_CD8<_.EltSize, CD8VT1>;
8135 }
8136
8137 multiclass expand_by_vec_width_lowering<X86VectorVTInfo _ > {
8138
8139   def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask, undef)),
8140             (!cast<Instruction>(NAME#_.ZSuffix##rmkz)
8141                                         _.KRCWM:$mask, addr:$src)>;
8142
8143   def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask,
8144                                                (_.VT _.RC:$src0))),
8145             (!cast<Instruction>(NAME#_.ZSuffix##rmk)
8146                             _.RC:$src0, _.KRCWM:$mask, addr:$src)>;
8147 }
8148
8149 multiclass expand_by_elt_width<bits<8> opc, string OpcodeStr,
8150                                  AVX512VLVectorVTInfo VTInfo> {
8151   defm Z : expand_by_vec_width<opc, VTInfo.info512, OpcodeStr>,
8152            expand_by_vec_width_lowering<VTInfo.info512>, EVEX_V512;
8153
8154   let Predicates = [HasVLX] in {
8155     defm Z256 : expand_by_vec_width<opc, VTInfo.info256, OpcodeStr>,
8156                 expand_by_vec_width_lowering<VTInfo.info256>, EVEX_V256;
8157     defm Z128 : expand_by_vec_width<opc, VTInfo.info128, OpcodeStr>,
8158                 expand_by_vec_width_lowering<VTInfo.info128>, EVEX_V128;
8159   }
8160 }
8161
8162 defm VPEXPANDD : expand_by_elt_width <0x89, "vpexpandd", avx512vl_i32_info>,
8163                                          EVEX;
8164 defm VPEXPANDQ : expand_by_elt_width <0x89, "vpexpandq", avx512vl_i64_info>,
8165                                          EVEX, VEX_W;
8166 defm VEXPANDPS : expand_by_elt_width <0x88, "vexpandps", avx512vl_f32_info>,
8167                                          EVEX;
8168 defm VEXPANDPD : expand_by_elt_width <0x88, "vexpandpd", avx512vl_f64_info>,
8169                                          EVEX, VEX_W;
8170
8171 //handle instruction  reg_vec1 = op(reg_vec,imm)
8172 //                               op(mem_vec,imm)
8173 //                               op(broadcast(eltVt),imm)
8174 //all instruction created with FROUND_CURRENT
8175 multiclass avx512_unary_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8176                                       X86VectorVTInfo _>{
8177   let ExeDomain = _.ExeDomain in {
8178   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8179                       (ins _.RC:$src1, i32u8imm:$src2),
8180                       OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
8181                       (OpNode (_.VT _.RC:$src1),
8182                               (i32 imm:$src2),
8183                               (i32 FROUND_CURRENT))>;
8184   defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8185                     (ins _.MemOp:$src1, i32u8imm:$src2),
8186                     OpcodeStr##_.Suffix, "$src2, $src1", "$src1, $src2",
8187                     (OpNode (_.VT (bitconvert (_.LdFrag addr:$src1))),
8188                             (i32 imm:$src2),
8189                             (i32 FROUND_CURRENT))>;
8190   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8191                     (ins _.ScalarMemOp:$src1, i32u8imm:$src2),
8192                     OpcodeStr##_.Suffix, "$src2, ${src1}"##_.BroadcastStr,
8193                     "${src1}"##_.BroadcastStr##", $src2",
8194                     (OpNode (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src1))),
8195                             (i32 imm:$src2),
8196                             (i32 FROUND_CURRENT))>, EVEX_B;
8197   }
8198 }
8199
8200 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8201 multiclass avx512_unary_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
8202                                              SDNode OpNode, X86VectorVTInfo _>{
8203   let ExeDomain = _.ExeDomain in
8204   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8205                       (ins _.RC:$src1, i32u8imm:$src2),
8206                       OpcodeStr##_.Suffix, "$src2, {sae}, $src1",
8207                       "$src1, {sae}, $src2",
8208                       (OpNode (_.VT _.RC:$src1),
8209                               (i32 imm:$src2),
8210                               (i32 FROUND_NO_EXC))>, EVEX_B;
8211 }
8212
8213 multiclass avx512_common_unary_fp_sae_packed_imm<string OpcodeStr,
8214             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8215   let Predicates = [prd] in {
8216     defm Z    : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8217                 avx512_unary_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8218                                   EVEX_V512;
8219   }
8220   let Predicates = [prd, HasVLX] in {
8221     defm Z128 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
8222                                   EVEX_V128;
8223     defm Z256 : avx512_unary_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
8224                                   EVEX_V256;
8225   }
8226 }
8227
8228 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8229 //                               op(reg_vec2,mem_vec,imm)
8230 //                               op(reg_vec2,broadcast(eltVt),imm)
8231 //all instruction created with FROUND_CURRENT
8232 multiclass avx512_fp_packed_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8233                                 X86VectorVTInfo _>{
8234   let ExeDomain = _.ExeDomain in {
8235   defm rri : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8236                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8237                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8238                       (OpNode (_.VT _.RC:$src1),
8239                               (_.VT _.RC:$src2),
8240                               (i32 imm:$src3),
8241                               (i32 FROUND_CURRENT))>;
8242   defm rmi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8243                     (ins _.RC:$src1, _.MemOp:$src2, i32u8imm:$src3),
8244                     OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8245                     (OpNode (_.VT _.RC:$src1),
8246                             (_.VT (bitconvert (_.LdFrag addr:$src2))),
8247                             (i32 imm:$src3),
8248                             (i32 FROUND_CURRENT))>;
8249   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8250                     (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
8251                     OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
8252                     "$src1, ${src2}"##_.BroadcastStr##", $src3",
8253                     (OpNode (_.VT _.RC:$src1),
8254                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
8255                             (i32 imm:$src3),
8256                             (i32 FROUND_CURRENT))>, EVEX_B;
8257   }
8258 }
8259
8260 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8261 //                               op(reg_vec2,mem_vec,imm)
8262 multiclass avx512_3Op_rm_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
8263                              X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo>{
8264   let ExeDomain = DestInfo.ExeDomain in {
8265   defm rri : AVX512_maskable<opc, MRMSrcReg, DestInfo, (outs DestInfo.RC:$dst),
8266                   (ins SrcInfo.RC:$src1, SrcInfo.RC:$src2, u8imm:$src3),
8267                   OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8268                   (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
8269                                (SrcInfo.VT SrcInfo.RC:$src2),
8270                                (i8 imm:$src3)))>;
8271   defm rmi : AVX512_maskable<opc, MRMSrcMem, DestInfo, (outs DestInfo.RC:$dst),
8272                 (ins SrcInfo.RC:$src1, SrcInfo.MemOp:$src2, u8imm:$src3),
8273                 OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8274                 (DestInfo.VT (OpNode (SrcInfo.VT SrcInfo.RC:$src1),
8275                              (SrcInfo.VT (bitconvert
8276                                                 (SrcInfo.LdFrag addr:$src2))),
8277                              (i8 imm:$src3)))>;
8278   }
8279 }
8280
8281 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8282 //                               op(reg_vec2,mem_vec,imm)
8283 //                               op(reg_vec2,broadcast(eltVt),imm)
8284 multiclass avx512_3Op_imm8<bits<8> opc, string OpcodeStr, SDNode OpNode,
8285                            X86VectorVTInfo _>:
8286   avx512_3Op_rm_imm8<opc, OpcodeStr, OpNode, _, _>{
8287
8288   let ExeDomain = _.ExeDomain in
8289   defm rmbi : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8290                     (ins _.RC:$src1, _.ScalarMemOp:$src2, u8imm:$src3),
8291                     OpcodeStr, "$src3, ${src2}"##_.BroadcastStr##", $src1",
8292                     "$src1, ${src2}"##_.BroadcastStr##", $src3",
8293                     (OpNode (_.VT _.RC:$src1),
8294                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src2))),
8295                             (i8 imm:$src3))>, EVEX_B;
8296 }
8297
8298 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm)
8299 //                                      op(reg_vec2,mem_scalar,imm)
8300 //all instruction created with FROUND_CURRENT
8301 multiclass avx512_fp_scalar_imm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8302                                 X86VectorVTInfo _> {
8303   let ExeDomain = _.ExeDomain in {
8304   defm rri : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
8305                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8306                       OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8307                       (OpNode (_.VT _.RC:$src1),
8308                               (_.VT _.RC:$src2),
8309                               (i32 imm:$src3),
8310                               (i32 FROUND_CURRENT))>;
8311   defm rmi : AVX512_maskable_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
8312                     (ins _.RC:$src1, _.ScalarMemOp:$src2, i32u8imm:$src3),
8313                     OpcodeStr, "$src3, $src2, $src1", "$src1, $src2, $src3",
8314                     (OpNode (_.VT _.RC:$src1),
8315                             (_.VT (scalar_to_vector
8316                                       (_.ScalarLdFrag addr:$src2))),
8317                             (i32 imm:$src3),
8318                             (i32 FROUND_CURRENT))>;
8319   }
8320 }
8321
8322 //handle instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8323 multiclass avx512_fp_sae_packed_imm<bits<8> opc, string OpcodeStr,
8324                                              SDNode OpNode, X86VectorVTInfo _>{
8325   let ExeDomain = _.ExeDomain in
8326   defm rrib : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8327                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8328                       OpcodeStr, "$src3, {sae}, $src2, $src1",
8329                       "$src1, $src2, {sae}, $src3",
8330                       (OpNode (_.VT _.RC:$src1),
8331                               (_.VT _.RC:$src2),
8332                               (i32 imm:$src3),
8333                               (i32 FROUND_NO_EXC))>, EVEX_B;
8334 }
8335 //handle scalar instruction  reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae}
8336 multiclass avx512_fp_sae_scalar_imm<bits<8> opc, string OpcodeStr,
8337                                              SDNode OpNode, X86VectorVTInfo _> {
8338   let ExeDomain = _.ExeDomain in
8339   defm NAME#rrib : AVX512_maskable_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
8340                       (ins _.RC:$src1, _.RC:$src2, i32u8imm:$src3),
8341                       OpcodeStr, "$src3, {sae}, $src2, $src1",
8342                       "$src1, $src2, {sae}, $src3",
8343                       (OpNode (_.VT _.RC:$src1),
8344                               (_.VT _.RC:$src2),
8345                               (i32 imm:$src3),
8346                               (i32 FROUND_NO_EXC))>, EVEX_B;
8347 }
8348
8349 multiclass avx512_common_fp_sae_packed_imm<string OpcodeStr,
8350             AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8351   let Predicates = [prd] in {
8352     defm Z    : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8353                 avx512_fp_sae_packed_imm<opc, OpcodeStr, OpNode, _.info512>,
8354                                   EVEX_V512;
8355
8356   }
8357   let Predicates = [prd, HasVLX] in {
8358     defm Z128 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info128>,
8359                                   EVEX_V128;
8360     defm Z256 : avx512_fp_packed_imm<opc, OpcodeStr, OpNode, _.info256>,
8361                                   EVEX_V256;
8362   }
8363 }
8364
8365 multiclass avx512_common_3Op_rm_imm8<bits<8> opc, SDNode OpNode, string OpStr,
8366                    AVX512VLVectorVTInfo DestInfo, AVX512VLVectorVTInfo SrcInfo>{
8367   let Predicates = [HasBWI] in {
8368     defm Z    : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info512,
8369                            SrcInfo.info512>, EVEX_V512, AVX512AIi8Base, EVEX_4V;
8370   }
8371   let Predicates = [HasBWI, HasVLX] in {
8372     defm Z128 : avx512_3Op_rm_imm8<opc, OpStr, OpNode, DestInfo.info128,
8373                            SrcInfo.info128>, EVEX_V128, AVX512AIi8Base, EVEX_4V;
8374     defm Z256 : avx512_3Op_rm_imm8<opc, OpStr, OpNode,  DestInfo.info256,
8375                            SrcInfo.info256>, EVEX_V256, AVX512AIi8Base, EVEX_4V;
8376   }
8377 }
8378
8379 multiclass avx512_common_3Op_imm8<string OpcodeStr, AVX512VLVectorVTInfo _,
8380                                 bits<8> opc, SDNode OpNode>{
8381   let Predicates = [HasAVX512] in {
8382     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
8383   }
8384   let Predicates = [HasAVX512, HasVLX] in {
8385     defm Z128 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info128>, EVEX_V128;
8386     defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
8387   }
8388 }
8389
8390 multiclass avx512_common_fp_sae_scalar_imm<string OpcodeStr,
8391                   X86VectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{
8392   let Predicates = [prd] in {
8393      defm Z128 : avx512_fp_scalar_imm<opc, OpcodeStr, OpNode, _>,
8394                  avx512_fp_sae_scalar_imm<opc, OpcodeStr, OpNode, _>;
8395   }
8396 }
8397
8398 multiclass avx512_common_unary_fp_sae_packed_imm_all<string OpcodeStr,
8399                     bits<8> opcPs, bits<8> opcPd, SDNode OpNode, Predicate prd>{
8400   defm PS : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f32_info,
8401                             opcPs, OpNode, prd>, EVEX_CD8<32, CD8VF>;
8402   defm PD : avx512_common_unary_fp_sae_packed_imm<OpcodeStr, avx512vl_f64_info,
8403                             opcPd, OpNode, prd>, EVEX_CD8<64, CD8VF>, VEX_W;
8404 }
8405
8406
8407 defm VREDUCE   : avx512_common_unary_fp_sae_packed_imm_all<"vreduce", 0x56, 0x56,
8408                               X86VReduce, HasDQI>, AVX512AIi8Base, EVEX;
8409 defm VRNDSCALE : avx512_common_unary_fp_sae_packed_imm_all<"vrndscale", 0x08, 0x09,
8410                               X86VRndScale, HasAVX512>, AVX512AIi8Base, EVEX;
8411 defm VGETMANT : avx512_common_unary_fp_sae_packed_imm_all<"vgetmant", 0x26, 0x26,
8412                               X86VGetMant, HasAVX512>, AVX512AIi8Base, EVEX;
8413
8414
8415 defm VRANGEPD : avx512_common_fp_sae_packed_imm<"vrangepd", avx512vl_f64_info,
8416                                                        0x50, X86VRange, HasDQI>,
8417       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8418 defm VRANGEPS : avx512_common_fp_sae_packed_imm<"vrangeps", avx512vl_f32_info,
8419                                                        0x50, X86VRange, HasDQI>,
8420       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8421
8422 defm VRANGESD: avx512_common_fp_sae_scalar_imm<"vrangesd", f64x_info,
8423                                                  0x51, X86VRange, HasDQI>,
8424       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8425 defm VRANGESS: avx512_common_fp_sae_scalar_imm<"vrangess", f32x_info,
8426                                                  0x51, X86VRange, HasDQI>,
8427       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8428
8429 defm VREDUCESD: avx512_common_fp_sae_scalar_imm<"vreducesd", f64x_info,
8430                                                  0x57, X86Reduces, HasDQI>,
8431       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8432 defm VREDUCESS: avx512_common_fp_sae_scalar_imm<"vreducess", f32x_info,
8433                                                  0x57, X86Reduces, HasDQI>,
8434       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8435
8436 defm VGETMANTSD: avx512_common_fp_sae_scalar_imm<"vgetmantsd", f64x_info,
8437                                                  0x27, X86GetMants, HasAVX512>,
8438       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
8439 defm VGETMANTSS: avx512_common_fp_sae_scalar_imm<"vgetmantss", f32x_info,
8440                                                  0x27, X86GetMants, HasAVX512>,
8441       AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
8442
8443 multiclass avx512_shuff_packed_128<string OpcodeStr, AVX512VLVectorVTInfo _,
8444                                        bits<8> opc, SDNode OpNode = X86Shuf128>{
8445   let Predicates = [HasAVX512] in {
8446     defm Z    : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info512>, EVEX_V512;
8447
8448   }
8449   let Predicates = [HasAVX512, HasVLX] in {
8450      defm Z256 : avx512_3Op_imm8<opc, OpcodeStr, OpNode, _.info256>, EVEX_V256;
8451   }
8452 }
8453 let Predicates = [HasAVX512] in {
8454 def : Pat<(v16f32 (ffloor VR512:$src)),
8455           (VRNDSCALEPSZrri VR512:$src, (i32 0x1))>;
8456 def : Pat<(v16f32 (fnearbyint VR512:$src)),
8457           (VRNDSCALEPSZrri VR512:$src, (i32 0xC))>;
8458 def : Pat<(v16f32 (fceil VR512:$src)),
8459           (VRNDSCALEPSZrri VR512:$src, (i32 0x2))>;
8460 def : Pat<(v16f32 (frint VR512:$src)),
8461           (VRNDSCALEPSZrri VR512:$src, (i32 0x4))>;
8462 def : Pat<(v16f32 (ftrunc VR512:$src)),
8463           (VRNDSCALEPSZrri VR512:$src, (i32 0x3))>;
8464
8465 def : Pat<(v8f64 (ffloor VR512:$src)),
8466           (VRNDSCALEPDZrri VR512:$src, (i32 0x1))>;
8467 def : Pat<(v8f64 (fnearbyint VR512:$src)),
8468           (VRNDSCALEPDZrri VR512:$src, (i32 0xC))>;
8469 def : Pat<(v8f64 (fceil VR512:$src)),
8470           (VRNDSCALEPDZrri VR512:$src, (i32 0x2))>;
8471 def : Pat<(v8f64 (frint VR512:$src)),
8472           (VRNDSCALEPDZrri VR512:$src, (i32 0x4))>;
8473 def : Pat<(v8f64 (ftrunc VR512:$src)),
8474           (VRNDSCALEPDZrri VR512:$src, (i32 0x3))>;
8475 }
8476
8477 defm VSHUFF32X4 : avx512_shuff_packed_128<"vshuff32x4",avx512vl_f32_info, 0x23>,
8478       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8479 defm VSHUFF64X2 : avx512_shuff_packed_128<"vshuff64x2",avx512vl_f64_info, 0x23>,
8480       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8481 defm VSHUFI32X4 : avx512_shuff_packed_128<"vshufi32x4",avx512vl_i32_info, 0x43>,
8482       AVX512AIi8Base, EVEX_4V, EVEX_CD8<32, CD8VF>;
8483 defm VSHUFI64X2 : avx512_shuff_packed_128<"vshufi64x2",avx512vl_i64_info, 0x43>,
8484       AVX512AIi8Base, EVEX_4V, EVEX_CD8<64, CD8VF>, VEX_W;
8485
8486 let Predicates = [HasAVX512] in {
8487 // Provide fallback in case the load node that is used in the broadcast
8488 // patterns above is used by additional users, which prevents the pattern
8489 // selection.
8490 def : Pat<(v8f64 (X86SubVBroadcast (v2f64 VR128X:$src))),
8491           (VSHUFF64X2Zrri (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8492                           (INSERT_SUBREG (v8f64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8493                           0)>;
8494 def : Pat<(v8i64 (X86SubVBroadcast (v2i64 VR128X:$src))),
8495           (VSHUFI64X2Zrri (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8496                           (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8497                           0)>;
8498
8499 def : Pat<(v16f32 (X86SubVBroadcast (v4f32 VR128X:$src))),
8500           (VSHUFF32X4Zrri (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8501                           (INSERT_SUBREG (v16f32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8502                           0)>;
8503 def : Pat<(v16i32 (X86SubVBroadcast (v4i32 VR128X:$src))),
8504           (VSHUFI32X4Zrri (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8505                           (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8506                           0)>;
8507
8508 def : Pat<(v32i16 (X86SubVBroadcast (v8i16 VR128X:$src))),
8509           (VSHUFI32X4Zrri (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8510                           (INSERT_SUBREG (v32i16 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8511                           0)>;
8512
8513 def : Pat<(v64i8 (X86SubVBroadcast (v16i8 VR128X:$src))),
8514           (VSHUFI32X4Zrri (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8515                           (INSERT_SUBREG (v64i8 (IMPLICIT_DEF)), VR128X:$src, sub_xmm),
8516                           0)>;
8517 }
8518
8519 multiclass avx512_valign<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I> {
8520   defm NAME:       avx512_common_3Op_imm8<OpcodeStr, VTInfo_I, 0x03, X86VAlign>,
8521                            AVX512AIi8Base, EVEX_4V;
8522 }
8523
8524 defm VALIGND: avx512_valign<"valignd", avx512vl_i32_info>,
8525                                                   EVEX_CD8<32, CD8VF>;
8526 defm VALIGNQ: avx512_valign<"valignq", avx512vl_i64_info>,
8527                                                   EVEX_CD8<64, CD8VF>, VEX_W;
8528
8529 multiclass avx512_vpalignr_lowering<X86VectorVTInfo _ , list<Predicate> p>{
8530   let Predicates = p in
8531     def NAME#_.VTName#rri:
8532           Pat<(_.VT (X86PAlignr _.RC:$src1, _.RC:$src2, (i8 imm:$imm))),
8533               (!cast<Instruction>(NAME#_.ZSuffix#rri)
8534                     _.RC:$src1, _.RC:$src2, imm:$imm)>;
8535 }
8536
8537 multiclass avx512_vpalignr_lowering_common<AVX512VLVectorVTInfo _>:
8538       avx512_vpalignr_lowering<_.info512, [HasBWI]>,
8539       avx512_vpalignr_lowering<_.info128, [HasBWI, HasVLX]>,
8540       avx512_vpalignr_lowering<_.info256, [HasBWI, HasVLX]>;
8541
8542 defm VPALIGNR:   avx512_common_3Op_rm_imm8<0x0F, X86PAlignr, "vpalignr" ,
8543                                           avx512vl_i8_info, avx512vl_i8_info>,
8544                 avx512_vpalignr_lowering_common<avx512vl_i16_info>,
8545                 avx512_vpalignr_lowering_common<avx512vl_i32_info>,
8546                 avx512_vpalignr_lowering_common<avx512vl_f32_info>,
8547                 avx512_vpalignr_lowering_common<avx512vl_i64_info>,
8548                 avx512_vpalignr_lowering_common<avx512vl_f64_info>,
8549                 EVEX_CD8<8, CD8VF>;
8550
8551 defm VDBPSADBW: avx512_common_3Op_rm_imm8<0x42, X86dbpsadbw, "vdbpsadbw" ,
8552                     avx512vl_i16_info, avx512vl_i8_info>, EVEX_CD8<8, CD8VF>;
8553
8554 multiclass avx512_unary_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
8555                            X86VectorVTInfo _> {
8556   let ExeDomain = _.ExeDomain in {
8557   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8558                     (ins _.RC:$src1), OpcodeStr,
8559                     "$src1", "$src1",
8560                     (_.VT (OpNode _.RC:$src1))>, EVEX, AVX5128IBase;
8561
8562   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8563                   (ins _.MemOp:$src1), OpcodeStr,
8564                   "$src1", "$src1",
8565                   (_.VT (OpNode (bitconvert (_.LdFrag addr:$src1))))>,
8566             EVEX, AVX5128IBase, EVEX_CD8<_.EltSize, CD8VF>;
8567   }
8568 }
8569
8570 multiclass avx512_unary_rmb<bits<8> opc, string OpcodeStr, SDNode OpNode,
8571                             X86VectorVTInfo _> :
8572            avx512_unary_rm<opc, OpcodeStr, OpNode, _> {
8573   defm rmb : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8574                   (ins _.ScalarMemOp:$src1), OpcodeStr,
8575                   "${src1}"##_.BroadcastStr,
8576                   "${src1}"##_.BroadcastStr,
8577                   (_.VT (OpNode (X86VBroadcast
8578                                     (_.ScalarLdFrag addr:$src1))))>,
8579              EVEX, AVX5128IBase, EVEX_B, EVEX_CD8<_.EltSize, CD8VF>;
8580 }
8581
8582 multiclass avx512_unary_rm_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
8583                               AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8584   let Predicates = [prd] in
8585     defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
8586
8587   let Predicates = [prd, HasVLX] in {
8588     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
8589                               EVEX_V256;
8590     defm Z128 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info128>,
8591                               EVEX_V128;
8592   }
8593 }
8594
8595 multiclass avx512_unary_rmb_vl<bits<8> opc, string OpcodeStr, SDNode OpNode,
8596                                AVX512VLVectorVTInfo VTInfo, Predicate prd> {
8597   let Predicates = [prd] in
8598     defm Z : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info512>,
8599                               EVEX_V512;
8600
8601   let Predicates = [prd, HasVLX] in {
8602     defm Z256 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info256>,
8603                                  EVEX_V256;
8604     defm Z128 : avx512_unary_rmb<opc, OpcodeStr, OpNode, VTInfo.info128>,
8605                                  EVEX_V128;
8606   }
8607 }
8608
8609 multiclass avx512_unary_rm_vl_dq<bits<8> opc_d, bits<8> opc_q, string OpcodeStr,
8610                                  SDNode OpNode, Predicate prd> {
8611   defm Q : avx512_unary_rmb_vl<opc_q, OpcodeStr#"q", OpNode, avx512vl_i64_info,
8612                                prd>, VEX_W;
8613   defm D : avx512_unary_rmb_vl<opc_d, OpcodeStr#"d", OpNode, avx512vl_i32_info,
8614                                prd>;
8615 }
8616
8617 multiclass avx512_unary_rm_vl_bw<bits<8> opc_b, bits<8> opc_w, string OpcodeStr,
8618                                  SDNode OpNode, Predicate prd> {
8619   defm W : avx512_unary_rm_vl<opc_w, OpcodeStr#"w", OpNode, avx512vl_i16_info, prd>;
8620   defm B : avx512_unary_rm_vl<opc_b, OpcodeStr#"b", OpNode, avx512vl_i8_info, prd>;
8621 }
8622
8623 multiclass avx512_unary_rm_vl_all<bits<8> opc_b, bits<8> opc_w,
8624                                   bits<8> opc_d, bits<8> opc_q,
8625                                   string OpcodeStr, SDNode OpNode> {
8626   defm NAME : avx512_unary_rm_vl_dq<opc_d, opc_q, OpcodeStr, OpNode,
8627                                     HasAVX512>,
8628               avx512_unary_rm_vl_bw<opc_b, opc_w, OpcodeStr, OpNode,
8629                                     HasBWI>;
8630 }
8631
8632 defm VPABS : avx512_unary_rm_vl_all<0x1C, 0x1D, 0x1E, 0x1F, "vpabs", abs>;
8633
8634 // VPABS: Use 512bit version to implement 128/256 bit in case NoVLX.
8635 let Predicates = [HasAVX512, NoVLX] in {
8636   def : Pat<(v4i64 (abs VR256X:$src)),
8637             (EXTRACT_SUBREG
8638                 (VPABSQZrr
8639                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)),
8640              sub_ymm)>;
8641   def : Pat<(v2i64 (abs VR128X:$src)),
8642             (EXTRACT_SUBREG
8643                 (VPABSQZrr
8644                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)),
8645              sub_xmm)>;
8646 }
8647
8648 multiclass avx512_ctlz<bits<8> opc, string OpcodeStr, Predicate prd>{
8649
8650   defm NAME :          avx512_unary_rm_vl_dq<opc, opc, OpcodeStr, ctlz, prd>;
8651 }
8652
8653 defm VPLZCNT    : avx512_ctlz<0x44, "vplzcnt", HasCDI>;
8654 defm VPCONFLICT : avx512_unary_rm_vl_dq<0xC4, 0xC4, "vpconflict", X86Conflict, HasCDI>;
8655
8656 // VPLZCNT: Use 512bit version to implement 128/256 bit in case NoVLX.
8657 let Predicates = [HasCDI, NoVLX] in {
8658   def : Pat<(v4i64 (ctlz VR256X:$src)),
8659             (EXTRACT_SUBREG
8660                 (VPLZCNTQZrr
8661                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)),
8662              sub_ymm)>;
8663   def : Pat<(v2i64 (ctlz VR128X:$src)),
8664             (EXTRACT_SUBREG
8665                 (VPLZCNTQZrr
8666                     (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)),
8667              sub_xmm)>;
8668
8669   def : Pat<(v8i32 (ctlz VR256X:$src)),
8670             (EXTRACT_SUBREG
8671                 (VPLZCNTDZrr
8672                     (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR256X:$src, sub_ymm)),
8673              sub_ymm)>;
8674   def : Pat<(v4i32 (ctlz VR128X:$src)),
8675             (EXTRACT_SUBREG
8676                 (VPLZCNTDZrr
8677                     (INSERT_SUBREG (v16i32 (IMPLICIT_DEF)), VR128X:$src, sub_xmm)),
8678              sub_xmm)>;
8679 }
8680
8681 //===---------------------------------------------------------------------===//
8682 // Replicate Single FP - MOVSHDUP and MOVSLDUP
8683 //===---------------------------------------------------------------------===//
8684 multiclass avx512_replicate<bits<8> opc, string OpcodeStr, SDNode OpNode>{
8685   defm NAME:       avx512_unary_rm_vl<opc, OpcodeStr, OpNode, avx512vl_f32_info,
8686                                       HasAVX512>, XS;
8687 }
8688
8689 defm VMOVSHDUP : avx512_replicate<0x16, "vmovshdup", X86Movshdup>;
8690 defm VMOVSLDUP : avx512_replicate<0x12, "vmovsldup", X86Movsldup>;
8691
8692 //===----------------------------------------------------------------------===//
8693 // AVX-512 - MOVDDUP
8694 //===----------------------------------------------------------------------===//
8695
8696 multiclass avx512_movddup_128<bits<8> opc, string OpcodeStr, SDNode OpNode,
8697                                                             X86VectorVTInfo _> {
8698   let ExeDomain = _.ExeDomain in {
8699   defm rr : AVX512_maskable<opc, MRMSrcReg, _, (outs _.RC:$dst),
8700                    (ins _.RC:$src), OpcodeStr, "$src", "$src",
8701                    (_.VT (OpNode (_.VT _.RC:$src)))>, EVEX;
8702   defm rm : AVX512_maskable<opc, MRMSrcMem, _, (outs _.RC:$dst),
8703                  (ins _.ScalarMemOp:$src), OpcodeStr, "$src", "$src",
8704                  (_.VT (OpNode (_.VT (scalar_to_vector
8705                                        (_.ScalarLdFrag addr:$src)))))>,
8706                  EVEX, EVEX_CD8<_.EltSize, CD8VH>;
8707   }
8708 }
8709
8710 multiclass avx512_movddup_common<bits<8> opc, string OpcodeStr, SDNode OpNode,
8711                                                   AVX512VLVectorVTInfo VTInfo> {
8712
8713   defm Z : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info512>, EVEX_V512;
8714
8715   let Predicates = [HasAVX512, HasVLX] in {
8716     defm Z256 : avx512_unary_rm<opc, OpcodeStr, OpNode, VTInfo.info256>,
8717                                EVEX_V256;
8718     defm Z128 : avx512_movddup_128<opc, OpcodeStr, OpNode, VTInfo.info128>,
8719                                EVEX_V128;
8720   }
8721 }
8722
8723 multiclass avx512_movddup<bits<8> opc, string OpcodeStr, SDNode OpNode>{
8724   defm NAME:      avx512_movddup_common<opc, OpcodeStr, OpNode,
8725                                         avx512vl_f64_info>, XD, VEX_W;
8726 }
8727
8728 defm VMOVDDUP : avx512_movddup<0x12, "vmovddup", X86Movddup>;
8729
8730 let Predicates = [HasVLX] in {
8731 def : Pat<(X86Movddup (loadv2f64 addr:$src)),
8732           (VMOVDDUPZ128rm addr:$src)>;
8733 def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
8734           (VMOVDDUPZ128rm addr:$src)>;
8735 def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8736           (VMOVDDUPZ128rr (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8737
8738 def : Pat<(vselect (v2i1 VK2WM:$mask), (X86Movddup (loadv2f64 addr:$src)),
8739                    (v2f64 VR128X:$src0)),
8740           (VMOVDDUPZ128rmk VR128X:$src0, VK2WM:$mask, addr:$src)>;
8741 def : Pat<(vselect (v2i1 VK2WM:$mask), (X86Movddup (loadv2f64 addr:$src)),
8742                    (bitconvert (v4i32 immAllZerosV))),
8743           (VMOVDDUPZ128rmkz VK2WM:$mask, addr:$src)>;
8744
8745 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast f64:$src)),
8746                    (v2f64 VR128X:$src0)),
8747           (VMOVDDUPZ128rrk VR128X:$src0, VK2WM:$mask,
8748                            (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8749 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast f64:$src)),
8750                    (bitconvert (v4i32 immAllZerosV))),
8751           (VMOVDDUPZ128rrkz VK2WM:$mask, (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
8752
8753 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast (loadf64 addr:$src))),
8754                    (v2f64 VR128X:$src0)),
8755           (VMOVDDUPZ128rmk VR128X:$src0, VK2WM:$mask, addr:$src)>;
8756 def : Pat<(vselect (v2i1 VK2WM:$mask), (v2f64 (X86VBroadcast (loadf64 addr:$src))),
8757                    (bitconvert (v4i32 immAllZerosV))),
8758           (VMOVDDUPZ128rmkz VK2WM:$mask, addr:$src)>;
8759 }
8760
8761 //===----------------------------------------------------------------------===//
8762 // AVX-512 - Unpack Instructions
8763 //===----------------------------------------------------------------------===//
8764 defm VUNPCKH : avx512_fp_binop_p<0x15, "vunpckh", X86Unpckh, HasAVX512,
8765                                  SSE_ALU_ITINS_S>;
8766 defm VUNPCKL : avx512_fp_binop_p<0x14, "vunpckl", X86Unpckl, HasAVX512,
8767                                  SSE_ALU_ITINS_S>;
8768
8769 defm VPUNPCKLBW : avx512_binop_rm_vl_b<0x60, "vpunpcklbw", X86Unpckl,
8770                                        SSE_INTALU_ITINS_P, HasBWI>;
8771 defm VPUNPCKHBW : avx512_binop_rm_vl_b<0x68, "vpunpckhbw", X86Unpckh,
8772                                        SSE_INTALU_ITINS_P, HasBWI>;
8773 defm VPUNPCKLWD : avx512_binop_rm_vl_w<0x61, "vpunpcklwd", X86Unpckl,
8774                                        SSE_INTALU_ITINS_P, HasBWI>;
8775 defm VPUNPCKHWD : avx512_binop_rm_vl_w<0x69, "vpunpckhwd", X86Unpckh,
8776                                        SSE_INTALU_ITINS_P, HasBWI>;
8777
8778 defm VPUNPCKLDQ : avx512_binop_rm_vl_d<0x62, "vpunpckldq", X86Unpckl,
8779                                        SSE_INTALU_ITINS_P, HasAVX512>;
8780 defm VPUNPCKHDQ : avx512_binop_rm_vl_d<0x6A, "vpunpckhdq", X86Unpckh,
8781                                        SSE_INTALU_ITINS_P, HasAVX512>;
8782 defm VPUNPCKLQDQ : avx512_binop_rm_vl_q<0x6C, "vpunpcklqdq", X86Unpckl,
8783                                        SSE_INTALU_ITINS_P, HasAVX512>;
8784 defm VPUNPCKHQDQ : avx512_binop_rm_vl_q<0x6D, "vpunpckhqdq", X86Unpckh,
8785                                        SSE_INTALU_ITINS_P, HasAVX512>;
8786
8787 //===----------------------------------------------------------------------===//
8788 // AVX-512 - Extract & Insert Integer Instructions
8789 //===----------------------------------------------------------------------===//
8790
8791 multiclass avx512_extract_elt_bw_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
8792                                                             X86VectorVTInfo _> {
8793   def mr : AVX512Ii8<opc, MRMDestMem, (outs),
8794               (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
8795               OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8796               [(store (_.EltVT (trunc (assertzext (OpNode (_.VT _.RC:$src1),
8797                                                           imm:$src2)))),
8798                       addr:$dst)]>,
8799               EVEX, EVEX_CD8<_.EltSize, CD8VT1>;
8800 }
8801
8802 multiclass avx512_extract_elt_b<string OpcodeStr, X86VectorVTInfo _> {
8803   let Predicates = [HasBWI] in {
8804     def rr : AVX512Ii8<0x14, MRMDestReg, (outs GR32orGR64:$dst),
8805                   (ins _.RC:$src1, u8imm:$src2),
8806                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8807                   [(set GR32orGR64:$dst,
8808                         (X86pextrb (_.VT _.RC:$src1), imm:$src2))]>,
8809                   EVEX, TAPD;
8810
8811     defm NAME : avx512_extract_elt_bw_m<0x14, OpcodeStr, X86pextrb, _>, TAPD;
8812   }
8813 }
8814
8815 multiclass avx512_extract_elt_w<string OpcodeStr, X86VectorVTInfo _> {
8816   let Predicates = [HasBWI] in {
8817     def rr : AVX512Ii8<0xC5, MRMSrcReg, (outs GR32orGR64:$dst),
8818                   (ins _.RC:$src1, u8imm:$src2),
8819                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8820                   [(set GR32orGR64:$dst,
8821                         (X86pextrw (_.VT _.RC:$src1), imm:$src2))]>,
8822                   EVEX, PD;
8823
8824     let hasSideEffects = 0 in
8825     def rr_REV : AVX512Ii8<0x15, MRMDestReg, (outs GR32orGR64:$dst),
8826                    (ins _.RC:$src1, u8imm:$src2),
8827                    OpcodeStr#".s\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8828                    EVEX, TAPD;
8829
8830     defm NAME : avx512_extract_elt_bw_m<0x15, OpcodeStr, X86pextrw, _>, TAPD;
8831   }
8832 }
8833
8834 multiclass avx512_extract_elt_dq<string OpcodeStr, X86VectorVTInfo _,
8835                                                             RegisterClass GRC> {
8836   let Predicates = [HasDQI] in {
8837     def rr : AVX512Ii8<0x16, MRMDestReg, (outs GRC:$dst),
8838                   (ins _.RC:$src1, u8imm:$src2),
8839                   OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8840                   [(set GRC:$dst,
8841                       (extractelt (_.VT _.RC:$src1), imm:$src2))]>,
8842                   EVEX, TAPD;
8843
8844     def mr : AVX512Ii8<0x16, MRMDestMem, (outs),
8845                 (ins _.ScalarMemOp:$dst, _.RC:$src1, u8imm:$src2),
8846                 OpcodeStr#"\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8847                 [(store (extractelt (_.VT _.RC:$src1),
8848                                     imm:$src2),addr:$dst)]>,
8849                 EVEX, EVEX_CD8<_.EltSize, CD8VT1>, TAPD;
8850   }
8851 }
8852
8853 defm VPEXTRBZ : avx512_extract_elt_b<"vpextrb", v16i8x_info>;
8854 defm VPEXTRWZ : avx512_extract_elt_w<"vpextrw", v8i16x_info>;
8855 defm VPEXTRDZ : avx512_extract_elt_dq<"vpextrd", v4i32x_info, GR32>;
8856 defm VPEXTRQZ : avx512_extract_elt_dq<"vpextrq", v2i64x_info, GR64>, VEX_W;
8857
8858 multiclass avx512_insert_elt_m<bits<8> opc, string OpcodeStr, SDNode OpNode,
8859                                             X86VectorVTInfo _, PatFrag LdFrag> {
8860   def rm : AVX512Ii8<opc, MRMSrcMem, (outs _.RC:$dst),
8861       (ins _.RC:$src1,  _.ScalarMemOp:$src2, u8imm:$src3),
8862       OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8863       [(set _.RC:$dst,
8864           (_.VT (OpNode _.RC:$src1, (LdFrag addr:$src2), imm:$src3)))]>,
8865       EVEX_4V, EVEX_CD8<_.EltSize, CD8VT1>;
8866 }
8867
8868 multiclass avx512_insert_elt_bw<bits<8> opc, string OpcodeStr, SDNode OpNode,
8869                                             X86VectorVTInfo _, PatFrag LdFrag> {
8870   let Predicates = [HasBWI] in {
8871     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
8872         (ins _.RC:$src1, GR32orGR64:$src2, u8imm:$src3),
8873         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8874         [(set _.RC:$dst,
8875             (OpNode _.RC:$src1, GR32orGR64:$src2, imm:$src3))]>, EVEX_4V;
8876
8877     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, OpNode, _, LdFrag>;
8878   }
8879 }
8880
8881 multiclass avx512_insert_elt_dq<bits<8> opc, string OpcodeStr,
8882                                          X86VectorVTInfo _, RegisterClass GRC> {
8883   let Predicates = [HasDQI] in {
8884     def rr : AVX512Ii8<opc, MRMSrcReg, (outs _.RC:$dst),
8885         (ins _.RC:$src1, GRC:$src2, u8imm:$src3),
8886         OpcodeStr#"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8887         [(set _.RC:$dst,
8888             (_.VT (insertelt _.RC:$src1, GRC:$src2, imm:$src3)))]>,
8889         EVEX_4V, TAPD;
8890
8891     defm NAME : avx512_insert_elt_m<opc, OpcodeStr, insertelt, _,
8892                                     _.ScalarLdFrag>, TAPD;
8893   }
8894 }
8895
8896 defm VPINSRBZ : avx512_insert_elt_bw<0x20, "vpinsrb", X86pinsrb, v16i8x_info,
8897                                      extloadi8>, TAPD;
8898 defm VPINSRWZ : avx512_insert_elt_bw<0xC4, "vpinsrw", X86pinsrw, v8i16x_info,
8899                                      extloadi16>, PD;
8900 defm VPINSRDZ : avx512_insert_elt_dq<0x22, "vpinsrd", v4i32x_info, GR32>;
8901 defm VPINSRQZ : avx512_insert_elt_dq<0x22, "vpinsrq", v2i64x_info, GR64>, VEX_W;
8902 //===----------------------------------------------------------------------===//
8903 // VSHUFPS - VSHUFPD Operations
8904 //===----------------------------------------------------------------------===//
8905 multiclass avx512_shufp<string OpcodeStr, AVX512VLVectorVTInfo VTInfo_I,
8906                                                 AVX512VLVectorVTInfo VTInfo_FP>{
8907   defm NAME:     avx512_common_3Op_imm8<OpcodeStr, VTInfo_FP, 0xC6, X86Shufp>,
8908                                    EVEX_CD8<VTInfo_FP.info512.EltSize, CD8VF>,
8909                                    AVX512AIi8Base, EVEX_4V;
8910 }
8911
8912 defm VSHUFPS: avx512_shufp<"vshufps", avx512vl_i32_info, avx512vl_f32_info>, PS;
8913 defm VSHUFPD: avx512_shufp<"vshufpd", avx512vl_i64_info, avx512vl_f64_info>, PD, VEX_W;
8914 //===----------------------------------------------------------------------===//
8915 // AVX-512 - Byte shift Left/Right
8916 //===----------------------------------------------------------------------===//
8917
8918 multiclass avx512_shift_packed<bits<8> opc, SDNode OpNode, Format MRMr,
8919                              Format MRMm, string OpcodeStr, X86VectorVTInfo _>{
8920   def rr : AVX512<opc, MRMr,
8921              (outs _.RC:$dst), (ins _.RC:$src1, u8imm:$src2),
8922              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8923              [(set _.RC:$dst,(_.VT (OpNode _.RC:$src1, (i8 imm:$src2))))]>;
8924   def rm : AVX512<opc, MRMm,
8925            (outs _.RC:$dst), (ins _.MemOp:$src1, u8imm:$src2),
8926            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8927            [(set _.RC:$dst,(_.VT (OpNode
8928                                  (_.VT (bitconvert (_.LdFrag addr:$src1))),
8929                                  (i8 imm:$src2))))]>;
8930 }
8931
8932 multiclass avx512_shift_packed_all<bits<8> opc, SDNode OpNode, Format MRMr,
8933                                  Format MRMm, string OpcodeStr, Predicate prd>{
8934   let Predicates = [prd] in
8935     defm Z512 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8936                                     OpcodeStr, v64i8_info>, EVEX_V512;
8937   let Predicates = [prd, HasVLX] in {
8938     defm Z256 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8939                                     OpcodeStr, v32i8x_info>, EVEX_V256;
8940     defm Z128 : avx512_shift_packed<opc, OpNode, MRMr, MRMm,
8941                                     OpcodeStr, v16i8x_info>, EVEX_V128;
8942   }
8943 }
8944 defm VPSLLDQ : avx512_shift_packed_all<0x73, X86vshldq, MRM7r, MRM7m, "vpslldq",
8945                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
8946 defm VPSRLDQ : avx512_shift_packed_all<0x73, X86vshrdq, MRM3r, MRM3m, "vpsrldq",
8947                                        HasBWI>, AVX512PDIi8Base, EVEX_4V;
8948
8949
8950 multiclass avx512_psadbw_packed<bits<8> opc, SDNode OpNode,
8951                                 string OpcodeStr, X86VectorVTInfo _dst,
8952                                 X86VectorVTInfo _src>{
8953   def rr : AVX512BI<opc, MRMSrcReg,
8954              (outs _dst.RC:$dst), (ins _src.RC:$src1, _src.RC:$src2),
8955              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8956              [(set _dst.RC:$dst,(_dst.VT
8957                                 (OpNode (_src.VT _src.RC:$src1),
8958                                         (_src.VT _src.RC:$src2))))]>;
8959   def rm : AVX512BI<opc, MRMSrcMem,
8960            (outs _dst.RC:$dst), (ins _src.RC:$src1, _src.MemOp:$src2),
8961            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8962            [(set _dst.RC:$dst,(_dst.VT
8963                               (OpNode (_src.VT _src.RC:$src1),
8964                               (_src.VT (bitconvert
8965                                         (_src.LdFrag addr:$src2))))))]>;
8966 }
8967
8968 multiclass avx512_psadbw_packed_all<bits<8> opc, SDNode OpNode,
8969                                     string OpcodeStr, Predicate prd> {
8970   let Predicates = [prd] in
8971     defm Z512 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v8i64_info,
8972                                     v64i8_info>, EVEX_V512;
8973   let Predicates = [prd, HasVLX] in {
8974     defm Z256 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v4i64x_info,
8975                                     v32i8x_info>, EVEX_V256;
8976     defm Z128 : avx512_psadbw_packed<opc, OpNode, OpcodeStr, v2i64x_info,
8977                                     v16i8x_info>, EVEX_V128;
8978   }
8979 }
8980
8981 defm VPSADBW : avx512_psadbw_packed_all<0xf6, X86psadbw, "vpsadbw",
8982                                        HasBWI>, EVEX_4V;
8983
8984 // Transforms to swizzle an immediate to enable better matching when
8985 // memory operand isn't in the right place.
8986 def VPTERNLOG321_imm8 : SDNodeXForm<imm, [{
8987   // Convert a VPTERNLOG immediate by swapping operand 0 and operand 2.
8988   uint8_t Imm = N->getZExtValue();
8989   // Swap bits 1/4 and 3/6.
8990   uint8_t NewImm = Imm & 0xa5;
8991   if (Imm & 0x02) NewImm |= 0x10;
8992   if (Imm & 0x10) NewImm |= 0x02;
8993   if (Imm & 0x08) NewImm |= 0x40;
8994   if (Imm & 0x40) NewImm |= 0x08;
8995   return getI8Imm(NewImm, SDLoc(N));
8996 }]>;
8997 def VPTERNLOG213_imm8 : SDNodeXForm<imm, [{
8998   // Convert a VPTERNLOG immediate by swapping operand 1 and operand 2.
8999   uint8_t Imm = N->getZExtValue();
9000   // Swap bits 2/4 and 3/5.
9001   uint8_t NewImm = Imm & 0xc3;
9002   if (Imm & 0x04) NewImm |= 0x10;
9003   if (Imm & 0x10) NewImm |= 0x04;
9004   if (Imm & 0x08) NewImm |= 0x20;
9005   if (Imm & 0x20) NewImm |= 0x08;
9006   return getI8Imm(NewImm, SDLoc(N));
9007 }]>;
9008 def VPTERNLOG132_imm8 : SDNodeXForm<imm, [{
9009   // Convert a VPTERNLOG immediate by swapping operand 1 and operand 2.
9010   uint8_t Imm = N->getZExtValue();
9011   // Swap bits 1/2 and 5/6.
9012   uint8_t NewImm = Imm & 0x99;
9013   if (Imm & 0x02) NewImm |= 0x04;
9014   if (Imm & 0x04) NewImm |= 0x02;
9015   if (Imm & 0x20) NewImm |= 0x40;
9016   if (Imm & 0x40) NewImm |= 0x20;
9017   return getI8Imm(NewImm, SDLoc(N));
9018 }]>;
9019 def VPTERNLOG231_imm8 : SDNodeXForm<imm, [{
9020   // Convert a VPTERNLOG immediate by moving operand 1 to the end.
9021   uint8_t Imm = N->getZExtValue();
9022   // Move bits 1->2, 2->4, 3->6, 4->1, 5->3, 6->5
9023   uint8_t NewImm = Imm & 0x81;
9024   if (Imm & 0x02) NewImm |= 0x04;
9025   if (Imm & 0x04) NewImm |= 0x10;
9026   if (Imm & 0x08) NewImm |= 0x40;
9027   if (Imm & 0x10) NewImm |= 0x02;
9028   if (Imm & 0x20) NewImm |= 0x08;
9029   if (Imm & 0x40) NewImm |= 0x20;
9030   return getI8Imm(NewImm, SDLoc(N));
9031 }]>;
9032 def VPTERNLOG312_imm8 : SDNodeXForm<imm, [{
9033   // Convert a VPTERNLOG immediate by moving operand 2 to the beginning.
9034   uint8_t Imm = N->getZExtValue();
9035   // Move bits 1->4, 2->1, 3->5, 4->2, 5->6, 6->3
9036   uint8_t NewImm = Imm & 0x81;
9037   if (Imm & 0x02) NewImm |= 0x10;
9038   if (Imm & 0x04) NewImm |= 0x02;
9039   if (Imm & 0x08) NewImm |= 0x20;
9040   if (Imm & 0x10) NewImm |= 0x04;
9041   if (Imm & 0x20) NewImm |= 0x40;
9042   if (Imm & 0x40) NewImm |= 0x08;
9043   return getI8Imm(NewImm, SDLoc(N));
9044 }]>;
9045
9046 multiclass avx512_ternlog<bits<8> opc, string OpcodeStr, SDNode OpNode,
9047                           X86VectorVTInfo _>{
9048   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
9049   defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
9050                       (ins _.RC:$src2, _.RC:$src3, u8imm:$src4),
9051                       OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src4",
9052                       (OpNode (_.VT _.RC:$src1),
9053                               (_.VT _.RC:$src2),
9054                               (_.VT _.RC:$src3),
9055                               (i8 imm:$src4)), 1, 1>, AVX512AIi8Base, EVEX_4V;
9056   defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
9057                     (ins _.RC:$src2, _.MemOp:$src3, u8imm:$src4),
9058                     OpcodeStr, "$src4, $src3, $src2", "$src2, $src3, $src4",
9059                     (OpNode (_.VT _.RC:$src1),
9060                             (_.VT _.RC:$src2),
9061                             (_.VT (bitconvert (_.LdFrag addr:$src3))),
9062                             (i8 imm:$src4)), 1, 0>,
9063                     AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
9064   defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
9065                     (ins _.RC:$src2, _.ScalarMemOp:$src3, u8imm:$src4),
9066                     OpcodeStr, "$src4, ${src3}"##_.BroadcastStr##", $src2",
9067                     "$src2, ${src3}"##_.BroadcastStr##", $src4",
9068                     (OpNode (_.VT _.RC:$src1),
9069                             (_.VT _.RC:$src2),
9070                             (_.VT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
9071                             (i8 imm:$src4)), 1, 0>, EVEX_B,
9072                     AVX512AIi8Base, EVEX_4V, EVEX_CD8<_.EltSize, CD8VF>;
9073   }// Constraints = "$src1 = $dst"
9074
9075   // Additional patterns for matching passthru operand in other positions.
9076   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9077                    (OpNode _.RC:$src3, _.RC:$src2, _.RC:$src1, (i8 imm:$src4)),
9078                    _.RC:$src1)),
9079             (!cast<Instruction>(NAME#_.ZSuffix#rrik) _.RC:$src1, _.KRCWM:$mask,
9080              _.RC:$src2, _.RC:$src3, (VPTERNLOG321_imm8 imm:$src4))>;
9081   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9082                    (OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3, (i8 imm:$src4)),
9083                    _.RC:$src1)),
9084             (!cast<Instruction>(NAME#_.ZSuffix#rrik) _.RC:$src1, _.KRCWM:$mask,
9085              _.RC:$src2, _.RC:$src3, (VPTERNLOG213_imm8 imm:$src4))>;
9086
9087   // Additional patterns for matching loads in other positions.
9088   def : Pat<(_.VT (OpNode (bitconvert (_.LdFrag addr:$src3)),
9089                           _.RC:$src2, _.RC:$src1, (i8 imm:$src4))),
9090             (!cast<Instruction>(NAME#_.ZSuffix#rmi) _.RC:$src1, _.RC:$src2,
9091                                    addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>;
9092   def : Pat<(_.VT (OpNode _.RC:$src1,
9093                           (bitconvert (_.LdFrag addr:$src3)),
9094                           _.RC:$src2, (i8 imm:$src4))),
9095             (!cast<Instruction>(NAME#_.ZSuffix#rmi) _.RC:$src1, _.RC:$src2,
9096                                    addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>;
9097
9098   // Additional patterns for matching zero masking with loads in other
9099   // positions.
9100   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9101                    (OpNode (bitconvert (_.LdFrag addr:$src3)),
9102                     _.RC:$src2, _.RC:$src1, (i8 imm:$src4)),
9103                    _.ImmAllZerosV)),
9104             (!cast<Instruction>(NAME#_.ZSuffix#rmikz) _.RC:$src1, _.KRCWM:$mask,
9105              _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>;
9106   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9107                    (OpNode _.RC:$src1, (bitconvert (_.LdFrag addr:$src3)),
9108                     _.RC:$src2, (i8 imm:$src4)),
9109                    _.ImmAllZerosV)),
9110             (!cast<Instruction>(NAME#_.ZSuffix#rmikz) _.RC:$src1, _.KRCWM:$mask,
9111              _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>;
9112
9113   // Additional patterns for matching masked loads with different
9114   // operand orders.
9115   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9116                    (OpNode _.RC:$src1, (bitconvert (_.LdFrag addr:$src3)),
9117                     _.RC:$src2, (i8 imm:$src4)),
9118                    _.RC:$src1)),
9119             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9120              _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>;
9121   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9122                    (OpNode (bitconvert (_.LdFrag addr:$src3)),
9123                     _.RC:$src2, _.RC:$src1, (i8 imm:$src4)),
9124                    _.RC:$src1)),
9125             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9126              _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>;
9127   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9128                    (OpNode _.RC:$src2, _.RC:$src1,
9129                     (bitconvert (_.LdFrag addr:$src3)), (i8 imm:$src4)),
9130                    _.RC:$src1)),
9131             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9132              _.RC:$src2, addr:$src3, (VPTERNLOG213_imm8 imm:$src4))>;
9133   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9134                    (OpNode _.RC:$src2, (bitconvert (_.LdFrag addr:$src3)),
9135                     _.RC:$src1, (i8 imm:$src4)),
9136                    _.RC:$src1)),
9137             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9138              _.RC:$src2, addr:$src3, (VPTERNLOG231_imm8 imm:$src4))>;
9139   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9140                    (OpNode (bitconvert (_.LdFrag addr:$src3)),
9141                     _.RC:$src1, _.RC:$src2, (i8 imm:$src4)),
9142                    _.RC:$src1)),
9143             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9144              _.RC:$src2, addr:$src3, (VPTERNLOG312_imm8 imm:$src4))>;
9145
9146   // Additional patterns for matching broadcasts in other positions.
9147   def : Pat<(_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9148                           _.RC:$src2, _.RC:$src1, (i8 imm:$src4))),
9149             (!cast<Instruction>(NAME#_.ZSuffix#rmbi) _.RC:$src1, _.RC:$src2,
9150                                    addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>;
9151   def : Pat<(_.VT (OpNode _.RC:$src1,
9152                           (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9153                           _.RC:$src2, (i8 imm:$src4))),
9154             (!cast<Instruction>(NAME#_.ZSuffix#rmbi) _.RC:$src1, _.RC:$src2,
9155                                    addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>;
9156
9157   // Additional patterns for matching zero masking with broadcasts in other
9158   // positions.
9159   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9160                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9161                     _.RC:$src2, _.RC:$src1, (i8 imm:$src4)),
9162                    _.ImmAllZerosV)),
9163             (!cast<Instruction>(NAME#_.ZSuffix#rmbikz) _.RC:$src1,
9164              _.KRCWM:$mask, _.RC:$src2, addr:$src3,
9165              (VPTERNLOG321_imm8 imm:$src4))>;
9166   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9167                    (OpNode _.RC:$src1,
9168                     (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9169                     _.RC:$src2, (i8 imm:$src4)),
9170                    _.ImmAllZerosV)),
9171             (!cast<Instruction>(NAME#_.ZSuffix#rmbikz) _.RC:$src1,
9172              _.KRCWM:$mask, _.RC:$src2, addr:$src3,
9173              (VPTERNLOG132_imm8 imm:$src4))>;
9174
9175   // Additional patterns for matching masked broadcasts with different
9176   // operand orders.
9177   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9178                    (OpNode _.RC:$src1,
9179                     (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9180                     _.RC:$src2, (i8 imm:$src4)),
9181                    _.RC:$src1)),
9182             (!cast<Instruction>(NAME#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask,
9183              _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>;
9184   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9185                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9186                     _.RC:$src2, _.RC:$src1, (i8 imm:$src4)),
9187                    _.RC:$src1)),
9188             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9189              _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>;
9190   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9191                    (OpNode _.RC:$src2, _.RC:$src1,
9192                     (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9193                     (i8 imm:$src4)), _.RC:$src1)),
9194             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9195              _.RC:$src2, addr:$src3, (VPTERNLOG213_imm8 imm:$src4))>;
9196   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9197                    (OpNode _.RC:$src2,
9198                     (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9199                     _.RC:$src1, (i8 imm:$src4)),
9200                    _.RC:$src1)),
9201             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9202              _.RC:$src2, addr:$src3, (VPTERNLOG231_imm8 imm:$src4))>;
9203   def : Pat<(_.VT (vselect _.KRCWM:$mask,
9204                    (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)),
9205                     _.RC:$src1, _.RC:$src2, (i8 imm:$src4)),
9206                    _.RC:$src1)),
9207             (!cast<Instruction>(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask,
9208              _.RC:$src2, addr:$src3, (VPTERNLOG312_imm8 imm:$src4))>;
9209 }
9210
9211 multiclass avx512_common_ternlog<string OpcodeStr, AVX512VLVectorVTInfo _>{
9212   let Predicates = [HasAVX512] in
9213     defm Z    : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info512>, EVEX_V512;
9214   let Predicates = [HasAVX512, HasVLX] in {
9215     defm Z128 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info128>, EVEX_V128;
9216     defm Z256 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, _.info256>, EVEX_V256;
9217   }
9218 }
9219
9220 defm VPTERNLOGD : avx512_common_ternlog<"vpternlogd", avx512vl_i32_info>;
9221 defm VPTERNLOGQ : avx512_common_ternlog<"vpternlogq", avx512vl_i64_info>, VEX_W;
9222
9223 //===----------------------------------------------------------------------===//
9224 // AVX-512 - FixupImm
9225 //===----------------------------------------------------------------------===//
9226
9227 multiclass avx512_fixupimm_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
9228                                   X86VectorVTInfo _>{
9229   let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
9230     defm rri : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
9231                         (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9232                          OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9233                         (OpNode (_.VT _.RC:$src1),
9234                                 (_.VT _.RC:$src2),
9235                                 (_.IntVT _.RC:$src3),
9236                                 (i32 imm:$src4),
9237                                 (i32 FROUND_CURRENT))>;
9238     defm rmi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
9239                       (ins _.RC:$src2, _.MemOp:$src3, i32u8imm:$src4),
9240                       OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9241                       (OpNode (_.VT _.RC:$src1),
9242                               (_.VT _.RC:$src2),
9243                               (_.IntVT (bitconvert (_.LdFrag addr:$src3))),
9244                               (i32 imm:$src4),
9245                               (i32 FROUND_CURRENT))>;
9246     defm rmbi : AVX512_maskable_3src<opc, MRMSrcMem, _, (outs _.RC:$dst),
9247                       (ins _.RC:$src2, _.ScalarMemOp:$src3, i32u8imm:$src4),
9248                     OpcodeStr##_.Suffix, "$src4, ${src3}"##_.BroadcastStr##", $src2",
9249                     "$src2, ${src3}"##_.BroadcastStr##", $src4",
9250                       (OpNode (_.VT _.RC:$src1),
9251                               (_.VT _.RC:$src2),
9252                               (_.IntVT (X86VBroadcast(_.ScalarLdFrag addr:$src3))),
9253                               (i32 imm:$src4),
9254                               (i32 FROUND_CURRENT))>, EVEX_B;
9255   } // Constraints = "$src1 = $dst"
9256 }
9257
9258 multiclass avx512_fixupimm_packed_sae<bits<8> opc, string OpcodeStr,
9259                                       SDNode OpNode, X86VectorVTInfo _>{
9260 let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in {
9261   defm rrib : AVX512_maskable_3src<opc, MRMSrcReg, _, (outs _.RC:$dst),
9262                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9263                       OpcodeStr##_.Suffix, "$src4, {sae}, $src3, $src2",
9264                       "$src2, $src3, {sae}, $src4",
9265                       (OpNode (_.VT _.RC:$src1),
9266                                 (_.VT _.RC:$src2),
9267                                 (_.IntVT _.RC:$src3),
9268                                 (i32 imm:$src4),
9269                                 (i32 FROUND_NO_EXC))>, EVEX_B;
9270   }
9271 }
9272
9273 multiclass avx512_fixupimm_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
9274                                   X86VectorVTInfo _, X86VectorVTInfo _src3VT> {
9275   let Constraints = "$src1 = $dst" , Predicates = [HasAVX512],
9276       ExeDomain = _.ExeDomain in {
9277     defm rri : AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
9278                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9279                       OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9280                       (OpNode (_.VT _.RC:$src1),
9281                               (_.VT _.RC:$src2),
9282                               (_src3VT.VT _src3VT.RC:$src3),
9283                               (i32 imm:$src4),
9284                               (i32 FROUND_CURRENT))>;
9285
9286     defm rrib : AVX512_maskable_3src_scalar<opc, MRMSrcReg, _, (outs _.RC:$dst),
9287                       (ins _.RC:$src2, _.RC:$src3, i32u8imm:$src4),
9288                       OpcodeStr##_.Suffix, "$src4, {sae}, $src3, $src2",
9289                       "$src2, $src3, {sae}, $src4",
9290                       (OpNode (_.VT _.RC:$src1),
9291                               (_.VT _.RC:$src2),
9292                               (_src3VT.VT _src3VT.RC:$src3),
9293                               (i32 imm:$src4),
9294                               (i32 FROUND_NO_EXC))>, EVEX_B;
9295     defm rmi : AVX512_maskable_3src_scalar<opc, MRMSrcMem, _, (outs _.RC:$dst),
9296                      (ins _.RC:$src2, _.ScalarMemOp:$src3, i32u8imm:$src4),
9297                      OpcodeStr##_.Suffix, "$src4, $src3, $src2", "$src2, $src3, $src4",
9298                      (OpNode (_.VT _.RC:$src1),
9299                              (_.VT _.RC:$src2),
9300                              (_src3VT.VT (scalar_to_vector
9301                                        (_src3VT.ScalarLdFrag addr:$src3))),
9302                              (i32 imm:$src4),
9303                              (i32 FROUND_CURRENT))>;
9304   }
9305 }
9306
9307 multiclass avx512_fixupimm_packed_all<AVX512VLVectorVTInfo _Vec>{
9308   let Predicates = [HasAVX512] in
9309     defm Z    : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>,
9310                 avx512_fixupimm_packed_sae<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>,
9311                                   AVX512AIi8Base, EVEX_4V, EVEX_V512;
9312   let Predicates = [HasAVX512, HasVLX] in {
9313     defm Z128 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info128>,
9314                                   AVX512AIi8Base, EVEX_4V, EVEX_V128;
9315     defm Z256 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info256>,
9316                                   AVX512AIi8Base, EVEX_4V, EVEX_V256;
9317   }
9318 }
9319
9320 defm VFIXUPIMMSS : avx512_fixupimm_scalar<0x55, "vfixupimm", X86VFixupimmScalar,
9321                                           f32x_info, v4i32x_info>,
9322                          AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<32, CD8VT1>;
9323 defm VFIXUPIMMSD : avx512_fixupimm_scalar<0x55, "vfixupimm", X86VFixupimmScalar,
9324                                           f64x_info, v2i64x_info>,
9325                          AVX512AIi8Base, VEX_LIG, EVEX_4V, EVEX_CD8<64, CD8VT1>, VEX_W;
9326 defm VFIXUPIMMPS : avx512_fixupimm_packed_all<avx512vl_f32_info>,
9327                          EVEX_CD8<32, CD8VF>;
9328 defm VFIXUPIMMPD : avx512_fixupimm_packed_all<avx512vl_f64_info>,
9329                          EVEX_CD8<64, CD8VF>, VEX_W;
9330
9331
9332
9333 // Patterns used to select SSE scalar fp arithmetic instructions from
9334 // either:
9335 //
9336 // (1) a scalar fp operation followed by a blend
9337 //
9338 // The effect is that the backend no longer emits unnecessary vector
9339 // insert instructions immediately after SSE scalar fp instructions
9340 // like addss or mulss.
9341 //
9342 // For example, given the following code:
9343 //   __m128 foo(__m128 A, __m128 B) {
9344 //     A[0] += B[0];
9345 //     return A;
9346 //   }
9347 //
9348 // Previously we generated:
9349 //   addss %xmm0, %xmm1
9350 //   movss %xmm1, %xmm0
9351 //
9352 // We now generate:
9353 //   addss %xmm1, %xmm0
9354 //
9355 // (2) a vector packed single/double fp operation followed by a vector insert
9356 //
9357 // The effect is that the backend converts the packed fp instruction
9358 // followed by a vector insert into a single SSE scalar fp instruction.
9359 //
9360 // For example, given the following code:
9361 //   __m128 foo(__m128 A, __m128 B) {
9362 //     __m128 C = A + B;
9363 //     return (__m128) {c[0], a[1], a[2], a[3]};
9364 //   }
9365 //
9366 // Previously we generated:
9367 //   addps %xmm0, %xmm1
9368 //   movss %xmm1, %xmm0
9369 //
9370 // We now generate:
9371 //   addss %xmm1, %xmm0
9372
9373 // TODO: Some canonicalization in lowering would simplify the number of
9374 // patterns we have to try to match.
9375 multiclass AVX512_scalar_math_f32_patterns<SDNode Op, string OpcPrefix> {
9376   let Predicates = [HasAVX512] in {
9377     // extracted scalar math op with insert via movss
9378     def : Pat<(v4f32 (X86Movss (v4f32 VR128X:$dst), (v4f32 (scalar_to_vector
9379           (Op (f32 (extractelt (v4f32 VR128X:$dst), (iPTR 0))),
9380           FR32X:$src))))),
9381       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst,
9382           (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
9383
9384     // extracted scalar math op with insert via blend
9385     def : Pat<(v4f32 (X86Blendi (v4f32 VR128X:$dst), (v4f32 (scalar_to_vector
9386           (Op (f32 (extractelt (v4f32 VR128X:$dst), (iPTR 0))),
9387           FR32X:$src))), (i8 1))),
9388       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst,
9389           (COPY_TO_REGCLASS FR32X:$src, VR128X))>;
9390
9391     // vector math op with insert via movss
9392     def : Pat<(v4f32 (X86Movss (v4f32 VR128X:$dst),
9393           (Op (v4f32 VR128X:$dst), (v4f32 VR128X:$src)))),
9394       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst, v4f32:$src)>;
9395
9396     // vector math op with insert via blend
9397     def : Pat<(v4f32 (X86Blendi (v4f32 VR128X:$dst),
9398           (Op (v4f32 VR128X:$dst), (v4f32 VR128X:$src)), (i8 1))),
9399       (!cast<I>("V"#OpcPrefix#SSZrr_Int) v4f32:$dst, v4f32:$src)>;
9400
9401     // extracted masked scalar math op with insert via movss
9402     def : Pat<(X86Movss (v4f32 VR128X:$src1),
9403                (scalar_to_vector
9404                 (X86selects VK1WM:$mask,
9405                             (Op (f32 (extractelt (v4f32 VR128X:$src1), (iPTR 0))),
9406                                 FR32X:$src2),
9407                             FR32X:$src0))),
9408       (!cast<I>("V"#OpcPrefix#SSZrr_Intk) (COPY_TO_REGCLASS FR32X:$src0, VR128X),
9409           VK1WM:$mask, v4f32:$src1,
9410           (COPY_TO_REGCLASS FR32X:$src2, VR128X))>;
9411   }
9412 }
9413
9414 defm : AVX512_scalar_math_f32_patterns<fadd, "ADD">;
9415 defm : AVX512_scalar_math_f32_patterns<fsub, "SUB">;
9416 defm : AVX512_scalar_math_f32_patterns<fmul, "MUL">;
9417 defm : AVX512_scalar_math_f32_patterns<fdiv, "DIV">;
9418
9419 multiclass AVX512_scalar_math_f64_patterns<SDNode Op, string OpcPrefix> {
9420   let Predicates = [HasAVX512] in {
9421     // extracted scalar math op with insert via movsd
9422     def : Pat<(v2f64 (X86Movsd (v2f64 VR128X:$dst), (v2f64 (scalar_to_vector
9423           (Op (f64 (extractelt (v2f64 VR128X:$dst), (iPTR 0))),
9424           FR64X:$src))))),
9425       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst,
9426           (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
9427
9428     // extracted scalar math op with insert via blend
9429     def : Pat<(v2f64 (X86Blendi (v2f64 VR128X:$dst), (v2f64 (scalar_to_vector
9430           (Op (f64 (extractelt (v2f64 VR128X:$dst), (iPTR 0))),
9431           FR64X:$src))), (i8 1))),
9432       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst,
9433           (COPY_TO_REGCLASS FR64X:$src, VR128X))>;
9434
9435     // vector math op with insert via movsd
9436     def : Pat<(v2f64 (X86Movsd (v2f64 VR128X:$dst),
9437           (Op (v2f64 VR128X:$dst), (v2f64 VR128X:$src)))),
9438       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst, v2f64:$src)>;
9439
9440     // vector math op with insert via blend
9441     def : Pat<(v2f64 (X86Blendi (v2f64 VR128X:$dst),
9442           (Op (v2f64 VR128X:$dst), (v2f64 VR128X:$src)), (i8 1))),
9443       (!cast<I>("V"#OpcPrefix#SDZrr_Int) v2f64:$dst, v2f64:$src)>;
9444
9445     // extracted masked scalar math op with insert via movss
9446     def : Pat<(X86Movsd (v2f64 VR128X:$src1),
9447                (scalar_to_vector
9448                 (X86selects VK1WM:$mask,
9449                             (Op (f64 (extractelt (v2f64 VR128X:$src1), (iPTR 0))),
9450                                 FR64X:$src2),
9451                             FR64X:$src0))),
9452       (!cast<I>("V"#OpcPrefix#SDZrr_Intk) (COPY_TO_REGCLASS FR64X:$src0, VR128X),
9453           VK1WM:$mask, v2f64:$src1,
9454           (COPY_TO_REGCLASS FR64X:$src2, VR128X))>;
9455   }
9456 }
9457
9458 defm : AVX512_scalar_math_f64_patterns<fadd, "ADD">;
9459 defm : AVX512_scalar_math_f64_patterns<fsub, "SUB">;
9460 defm : AVX512_scalar_math_f64_patterns<fmul, "MUL">;
9461 defm : AVX512_scalar_math_f64_patterns<fdiv, "DIV">;