[SampleProfileLoader] Fix integer overflow in generateMDProfMetadata (#90217)
[llvm-project.git] / llvm / lib / Target / AArch64 / AArch64InstrGISel.td
blob58ca52f37b63b7a1f55cf6868a1c1289770d1bfa
1 //=----- AArch64InstrGISel.td - AArch64 GISel target pseudos -*- tablegen -*-=//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // AArch64 GlobalISel target pseudo instruction definitions. This is kept
10 // separately from the other tablegen files for organizational purposes, but
11 // share the same infrastructure.
13 //===----------------------------------------------------------------------===//
16 class AArch64GenericInstruction : GenericInstruction {
17   let Namespace = "AArch64";
20 // A pseudo to represent a relocatable add instruction as part of address
21 // computation.
22 def G_ADD_LOW : AArch64GenericInstruction {
23   let OutOperandList = (outs type0:$dst);
24   let InOperandList = (ins type1:$src, type2:$imm);
25   let hasSideEffects = 0;
28 // Pseudo for a rev16 instruction. Produced post-legalization from
29 // G_SHUFFLE_VECTORs with appropriate masks.
30 def G_REV16 : AArch64GenericInstruction {
31   let OutOperandList = (outs type0:$dst);
32   let InOperandList = (ins type0:$src);
33   let hasSideEffects = 0;
36 // Pseudo for a rev32 instruction. Produced post-legalization from
37 // G_SHUFFLE_VECTORs with appropriate masks.
38 def G_REV32 : AArch64GenericInstruction {
39   let OutOperandList = (outs type0:$dst);
40   let InOperandList = (ins type0:$src);
41   let hasSideEffects = 0;
44 // Pseudo for a rev64 instruction. Produced post-legalization from
45 // G_SHUFFLE_VECTORs with appropriate masks.
46 def G_REV64 : AArch64GenericInstruction {
47   let OutOperandList = (outs type0:$dst);
48   let InOperandList = (ins type0:$src);
49   let hasSideEffects = 0;
52 // Represents an uzp1 instruction. Produced post-legalization from
53 // G_SHUFFLE_VECTORs with appropriate masks.
54 def G_UZP1 : AArch64GenericInstruction {
55   let OutOperandList = (outs type0:$dst);
56   let InOperandList = (ins type0:$v1, type0:$v2);
57   let hasSideEffects = 0;
60 // Represents an uzp2 instruction. Produced post-legalization from
61 // G_SHUFFLE_VECTORs with appropriate masks.
62 def G_UZP2 : AArch64GenericInstruction {
63   let OutOperandList = (outs type0:$dst);
64   let InOperandList = (ins type0:$v1, type0:$v2);
65   let hasSideEffects = 0;
68 // Represents a zip1 instruction. Produced post-legalization from
69 // G_SHUFFLE_VECTORs with appropriate masks.
70 def G_ZIP1 : AArch64GenericInstruction {
71   let OutOperandList = (outs type0:$dst);
72   let InOperandList = (ins type0:$v1, type0:$v2);
73   let hasSideEffects = 0;
76 // Represents a zip2 instruction. Produced post-legalization from
77 // G_SHUFFLE_VECTORs with appropriate masks.
78 def G_ZIP2 : AArch64GenericInstruction {
79   let OutOperandList = (outs type0:$dst);
80   let InOperandList = (ins type0:$v1, type0:$v2);
81   let hasSideEffects = 0;
84 // Represents a dup instruction. Produced post-legalization from
85 // G_SHUFFLE_VECTORs with appropriate masks.
86 def G_DUP: AArch64GenericInstruction {
87   let OutOperandList = (outs type0:$dst);
88   let InOperandList = (ins type1:$lane);
89   let hasSideEffects = 0;
92 // Represents a lane duplicate operation.
93 def G_DUPLANE8 : AArch64GenericInstruction {
94   let OutOperandList = (outs type0:$dst);
95   let InOperandList = (ins type0:$src, type1:$lane);
96   let hasSideEffects = 0;
98 def G_DUPLANE16 : AArch64GenericInstruction {
99   let OutOperandList = (outs type0:$dst);
100   let InOperandList = (ins type0:$src, type1:$lane);
101   let hasSideEffects = 0;
103 def G_DUPLANE32 : AArch64GenericInstruction {
104   let OutOperandList = (outs type0:$dst);
105   let InOperandList = (ins type0:$src, type1:$lane);
106   let hasSideEffects = 0;
108 def G_DUPLANE64 : AArch64GenericInstruction {
109   let OutOperandList = (outs type0:$dst);
110   let InOperandList = (ins type0:$src, type1:$lane);
111   let hasSideEffects = 0;
114 // Represents a trn1 instruction. Produced post-legalization from
115 // G_SHUFFLE_VECTORs with appropriate masks.
116 def G_TRN1 : AArch64GenericInstruction {
117   let OutOperandList = (outs type0:$dst);
118   let InOperandList = (ins type0:$v1, type0:$v2);
119   let hasSideEffects = 0;
122 // Represents a trn2 instruction. Produced post-legalization from
123 // G_SHUFFLE_VECTORs with appropriate masks.
124 def G_TRN2 : AArch64GenericInstruction {
125   let OutOperandList = (outs type0:$dst);
126   let InOperandList = (ins type0:$v1, type0:$v2);
127   let hasSideEffects = 0;
130 // Represents an ext instruction. Produced post-legalization from
131 // G_SHUFFLE_VECTORs with appropriate masks.
132 def G_EXT: AArch64GenericInstruction {
133   let OutOperandList = (outs type0:$dst);
134   let InOperandList = (ins type0:$v1, type0:$v2, untyped_imm_0:$imm);
135   let hasSideEffects = 0;
138 // Represents a vector G_ASHR with an immediate.
139 def G_VASHR : AArch64GenericInstruction {
140   let OutOperandList = (outs type0:$dst);
141   let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
142   let hasSideEffects = 0;
145 // Represents a vector G_LSHR with an immediate.
146 def G_VLSHR : AArch64GenericInstruction {
147   let OutOperandList = (outs type0:$dst);
148   let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
149   let hasSideEffects = 0;
152 // Represents an integer to FP conversion on the FPR bank.
153 def G_SITOF : AArch64GenericInstruction {
154   let OutOperandList = (outs type0:$dst);
155   let InOperandList = (ins type0:$src);
156   let hasSideEffects = 0;
158 def G_UITOF : AArch64GenericInstruction {
159   let OutOperandList = (outs type0:$dst);
160   let InOperandList = (ins type0:$src);
161   let hasSideEffects = 0;
164 def G_FCMEQ : AArch64GenericInstruction {
165   let OutOperandList = (outs type0:$dst);
166   let InOperandList = (ins type0:$src1, type1:$src2);
167   let hasSideEffects = 0;
170 def G_FCMGE : AArch64GenericInstruction {
171   let OutOperandList = (outs type0:$dst);
172   let InOperandList = (ins type0:$src1, type1:$src2);
173   let hasSideEffects = 0;
176 def G_FCMGT : AArch64GenericInstruction {
177   let OutOperandList = (outs type0:$dst);
178   let InOperandList = (ins type0:$src1, type1:$src2);
179   let hasSideEffects = 0;
182 def G_FCMEQZ : AArch64GenericInstruction {
183   let OutOperandList = (outs type0:$dst);
184   let InOperandList = (ins type0:$src);
185   let hasSideEffects = 0;
188 def G_FCMGEZ : AArch64GenericInstruction {
189   let OutOperandList = (outs type0:$dst);
190   let InOperandList = (ins type0:$src);
191   let hasSideEffects = 0;
194 def G_FCMGTZ : AArch64GenericInstruction {
195   let OutOperandList = (outs type0:$dst);
196   let InOperandList = (ins type0:$src);
197   let hasSideEffects = 0;
200 def G_FCMLEZ : AArch64GenericInstruction {
201   let OutOperandList = (outs type0:$dst);
202   let InOperandList = (ins type0:$src);
203   let hasSideEffects = 0;
206 def G_FCMLTZ : AArch64GenericInstruction {
207   let OutOperandList = (outs type0:$dst);
208   let InOperandList = (ins type0:$src);
209   let hasSideEffects = 0;
212 def G_AARCH64_PREFETCH : AArch64GenericInstruction {
213   let OutOperandList = (outs);
214   let InOperandList = (ins type0:$imm, ptype0:$src1);
215   let hasSideEffects = 1;
218 def G_UMULL : AArch64GenericInstruction {
219   let OutOperandList = (outs type0:$dst);
220   let InOperandList = (ins type0:$src1, type0:$src2);
221   let hasSideEffects = 0;
224 def G_SMULL : AArch64GenericInstruction {
225   let OutOperandList = (outs type0:$dst);
226   let InOperandList = (ins type0:$src1, type0:$src2);
227   let hasSideEffects = 0;
230 def G_UADDLP : AArch64GenericInstruction {
231   let OutOperandList = (outs type0:$dst);
232   let InOperandList = (ins type0:$src1);
233   let hasSideEffects = 0;
236 def G_SADDLP : AArch64GenericInstruction {
237   let OutOperandList = (outs type0:$dst);
238   let InOperandList = (ins type0:$src1);
239   let hasSideEffects = 0;
242 def G_UADDLV : AArch64GenericInstruction {
243   let OutOperandList = (outs type0:$dst);
244   let InOperandList = (ins type0:$src1);
245   let hasSideEffects = 0;
248 def G_SADDLV : AArch64GenericInstruction {
249   let OutOperandList = (outs type0:$dst);
250   let InOperandList = (ins type0:$src1);
251   let hasSideEffects = 0;
254 def G_UDOT : AArch64GenericInstruction {
255   let OutOperandList = (outs type0:$dst);
256   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
257   let hasSideEffects = 0;
260 def G_SDOT : AArch64GenericInstruction {
261   let OutOperandList = (outs type0:$dst);
262   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
263   let hasSideEffects = 0;
266 // Generic instruction for the BSP pseudo. It is expanded into BSP, which
267 // expands into BSL/BIT/BIF after register allocation.
268 def G_BSP : AArch64GenericInstruction {
269   let OutOperandList = (outs type0:$dst);
270   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
271   let hasSideEffects = 0;
274 def : GINodeEquiv<G_REV16, AArch64rev16>;
275 def : GINodeEquiv<G_REV32, AArch64rev32>;
276 def : GINodeEquiv<G_REV64, AArch64rev64>;
277 def : GINodeEquiv<G_UZP1, AArch64uzp1>;
278 def : GINodeEquiv<G_UZP2, AArch64uzp2>;
279 def : GINodeEquiv<G_ZIP1, AArch64zip1>;
280 def : GINodeEquiv<G_ZIP2, AArch64zip2>;
281 def : GINodeEquiv<G_DUP, AArch64dup>;
282 def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
283 def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
284 def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
285 def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
286 def : GINodeEquiv<G_TRN1, AArch64trn1>;
287 def : GINodeEquiv<G_TRN2, AArch64trn2>;
288 def : GINodeEquiv<G_EXT, AArch64ext>;
289 def : GINodeEquiv<G_VASHR, AArch64vashr>;
290 def : GINodeEquiv<G_VLSHR, AArch64vlshr>;
291 def : GINodeEquiv<G_SITOF, AArch64sitof>;
292 def : GINodeEquiv<G_UITOF, AArch64uitof>;
294 def : GINodeEquiv<G_FCMEQ, AArch64fcmeq>;
295 def : GINodeEquiv<G_FCMGE, AArch64fcmge>;
296 def : GINodeEquiv<G_FCMGT, AArch64fcmgt>;
298 def : GINodeEquiv<G_FCMEQZ, AArch64fcmeqz>;
299 def : GINodeEquiv<G_FCMGEZ, AArch64fcmgez>;
300 def : GINodeEquiv<G_FCMGTZ, AArch64fcmgtz>;
301 def : GINodeEquiv<G_FCMLEZ, AArch64fcmlez>;
302 def : GINodeEquiv<G_FCMLTZ, AArch64fcmltz>;
304 def : GINodeEquiv<G_BSP, AArch64bsp>;
306 def : GINodeEquiv<G_UMULL, AArch64umull>;
307 def : GINodeEquiv<G_SMULL, AArch64smull>;
309 def : GINodeEquiv<G_SADDLP, AArch64saddlp_n>;
310 def : GINodeEquiv<G_UADDLP, AArch64uaddlp_n>;
312 def : GINodeEquiv<G_SADDLV, AArch64saddlv>;
313 def : GINodeEquiv<G_UADDLV, AArch64uaddlv>;
315 def : GINodeEquiv<G_UDOT, AArch64udot>;
316 def : GINodeEquiv<G_SDOT, AArch64sdot>;
318 def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
320 def : GINodeEquiv<G_AARCH64_PREFETCH, AArch64Prefetch>;
322 // These are patterns that we only use for GlobalISel via the importer.
323 def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
324                      (vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
325            (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>;
327 let Predicates = [HasNEON] in {
328   def : Pat<(v2f64 (sint_to_fp v2i32:$src)),
329             (SCVTFv2f64 (SSHLLv2i32_shift V64:$src, 0))>;
330   def : Pat<(v2f64 (uint_to_fp v2i32:$src)),
331             (UCVTFv2f64 (USHLLv2i32_shift V64:$src, 0))>;
332   def : Pat<(v2f32 (sint_to_fp v2i64:$src)),
333             (FCVTNv2i32 (SCVTFv2f64 V128:$src))>;
334   def : Pat<(v2f32 (uint_to_fp v2i64:$src)),
335             (FCVTNv2i32 (UCVTFv2f64 V128:$src))>;
337   def : Pat<(v2i64 (fp_to_sint v2f32:$src)),
338             (FCVTZSv2f64 (FCVTLv2i32 V64:$src))>;
339   def : Pat<(v2i64 (fp_to_uint v2f32:$src)),
340             (FCVTZUv2f64 (FCVTLv2i32 V64:$src))>;
341   def : Pat<(v2i32 (fp_to_sint v2f64:$src)),
342             (XTNv2i32 (FCVTZSv2f64 V128:$src))>;
343   def : Pat<(v2i32 (fp_to_uint v2f64:$src)),
344             (XTNv2i32 (FCVTZUv2f64 V128:$src))>;
348 let Predicates = [HasNoLSE] in {
349 def : Pat<(atomic_cmp_swap_8 GPR64:$addr, GPR32:$desired, GPR32:$new),
350           (CMP_SWAP_8 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
352 def : Pat<(atomic_cmp_swap_16 GPR64:$addr, GPR32:$desired, GPR32:$new),
353           (CMP_SWAP_16 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
355 def : Pat<(atomic_cmp_swap_32 GPR64:$addr, GPR32:$desired, GPR32:$new),
356           (CMP_SWAP_32 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
358 def : Pat<(atomic_cmp_swap_64 GPR64:$addr, GPR64:$desired, GPR64:$new),
359           (CMP_SWAP_64 GPR64:$addr, GPR64:$desired, GPR64:$new)>;
362 def : Pat<(int_aarch64_stlxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
363           (STLXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
364 def : Pat<(int_aarch64_stxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
365           (STXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
367 let GIIgnoreCopies = 1 in
368 class PatIgnoreCopies<dag pattern, dag result> : Pat<pattern, result>, GISelFlags;
370 multiclass SIMDAcrossLanesSignedIntrinsicBHS<string baseOpc, Intrinsic intOp> {
371   def : PatIgnoreCopies<(i32 (sext (i8 (intOp (v8i8 V64:$Rn))))),
372         (i32 (SMOVvi8to32
373           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
374            (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn), bsub),
375           (i64 0)))>;
376   def : Pat<(i8 (intOp (v8i8 V64:$Rn))),
377         (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn)>;
379   def : PatIgnoreCopies<(i32 (sext (i8 (intOp (v16i8 V128:$Rn))))),
380         (i32 (SMOVvi8to32
381           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
382            (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn), bsub),
383           (i64 0)))>;
384   def : Pat<(i8 (intOp (v16i8 V128:$Rn))),
385         (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn)>;
387   def : PatIgnoreCopies<(i32 (sext (i16 (intOp (v4i16 V64:$Rn))))),
388         (i32 (SMOVvi16to32
389           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
390            (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn), hsub),
391           (i64 0)))>;
392   def : Pat<(i16 (intOp (v4i16 V64:$Rn))),
393         (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn)>;
395   def : PatIgnoreCopies<(i32 (sext (i16 (intOp (v8i16 V128:$Rn))))),
396         (i32 (SMOVvi16to32
397           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
398            (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn), hsub),
399           (i64 0)))>;
400   def : Pat<(i16 (intOp (v8i16 V128:$Rn))),
401         (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn)>;
403   def : PatIgnoreCopies<(i32 (intOp (v4i32 V128:$Rn))),
404         (i32 (EXTRACT_SUBREG
405           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
406            (!cast<Instruction>(!strconcat(baseOpc, "v4i32v")) V128:$Rn), ssub),
407           ssub))>;
410 multiclass SIMDAcrossLanesUnsignedIntrinsicBHS<string baseOpc,
411                                                 Intrinsic intOp> {
412   def : PatIgnoreCopies<(i32 (zext (i8 (intOp (v8i8 V64:$Rn))))),
413         (COPY_TO_REGCLASS
414           (i32 (EXTRACT_SUBREG
415             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
416               (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn), bsub),
417             ssub)),
418           GPR32)>;
419   def : Pat<(i8 (intOp (v8i8 V64:$Rn))),
420         (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn)>;
422   def : PatIgnoreCopies<(i32 (zext (i8 (intOp (v16i8 V128:$Rn))))),
423         (COPY_TO_REGCLASS
424           (i32 (EXTRACT_SUBREG
425             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
426               (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn), bsub),
427             ssub)),
428         GPR32)>;
429   def : Pat<(i8 (intOp (v16i8 V128:$Rn))),
430         (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn)>;
433   def : PatIgnoreCopies<(i32 (zext (i16 (intOp (v4i16 V64:$Rn))))),
434         (COPY_TO_REGCLASS
435           (i32 (EXTRACT_SUBREG
436             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
437               (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn), hsub),
438             ssub)),
439           GPR32)>;
440   def : Pat<(i16 (intOp (v4i16 V64:$Rn))),
441         (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn)>;
443   def : PatIgnoreCopies<(i32 (zext (i16 (intOp (v8i16 V128:$Rn))))),
444         (COPY_TO_REGCLASS
445           (i32 (EXTRACT_SUBREG
446             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
447               (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn), hsub),
448             ssub)),
449         GPR32)>;
450   def : Pat<(i16 (intOp (v8i16 V128:$Rn))),
451         (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn)>;
453   def : PatIgnoreCopies<(i32 (intOp (v4i32 V128:$Rn))),
454         (i32 (EXTRACT_SUBREG
455           (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
456             (!cast<Instruction>(!strconcat(baseOpc, "v4i32v")) V128:$Rn), ssub),
457           ssub))>;
461 defm : SIMDAcrossLanesSignedIntrinsicBHS<"ADDV", int_aarch64_neon_saddv>;
462 // vaddv_[su]32 is special; -> ADDP Vd.2S,Vn.2S,Vm.2S; return Vd.s[0];Vn==Vm
463 def : Pat<(i32 (int_aarch64_neon_saddv (v2i32 V64:$Rn))),
464           (i32 (EXTRACT_SUBREG
465             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
466               (ADDPv2i32 V64:$Rn, V64:$Rn), dsub),
467             ssub))>;
469 def : Pat<(i64 (int_aarch64_neon_saddv (v2i64 V128:$Rn))),
470           (i64 (EXTRACT_SUBREG
471           (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
472               (ADDPv2i64p V128:$Rn), dsub),
473             dsub))>;
475 defm : SIMDAcrossLanesUnsignedIntrinsicBHS<"ADDV", int_aarch64_neon_uaddv>;
476 def : Pat<(i32 (int_aarch64_neon_uaddv (v2i32 V64:$Rn))),
477           (i32 (EXTRACT_SUBREG
478             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
479               (ADDPv2i32 V64:$Rn, V64:$Rn), dsub),
480             ssub))>;
481 def : Pat<(i64 (int_aarch64_neon_uaddv (v2i64 V128:$Rn))),
482           (i64 (EXTRACT_SUBREG
483           (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
484               (ADDPv2i64p V128:$Rn), dsub),
485             dsub))>;
487 defm : SIMDAcrossLanesSignedIntrinsicBHS<"SMAXV", int_aarch64_neon_smaxv>;
488 def : Pat<(i32 (int_aarch64_neon_smaxv (v2i32 V64:$Rn))),
489           (i32 (EXTRACT_SUBREG
490             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
491               (SMAXPv2i32 V64:$Rn, V64:$Rn), dsub),
492             ssub))>;
494 defm : SIMDAcrossLanesSignedIntrinsicBHS<"SMINV", int_aarch64_neon_sminv>;
495 def : Pat<(i32 (int_aarch64_neon_sminv (v2i32 V64:$Rn))),
496           (i32 (EXTRACT_SUBREG
497             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
498               (SMINPv2i32 V64:$Rn, V64:$Rn), dsub),
499             ssub))>;
501 defm : SIMDAcrossLanesUnsignedIntrinsicBHS<"UMAXV", int_aarch64_neon_umaxv>;
502 def : Pat<(i32 (int_aarch64_neon_umaxv (v2i32 V64:$Rn))),
503           (i32 (EXTRACT_SUBREG
504             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
505               (UMAXPv2i32 V64:$Rn, V64:$Rn), dsub),
506             ssub))>;
508 defm : SIMDAcrossLanesUnsignedIntrinsicBHS<"UMINV", int_aarch64_neon_uminv>;
509 def : Pat<(i32 (int_aarch64_neon_uminv (v2i32 V64:$Rn))),
510           (i32 (EXTRACT_SUBREG
511             (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
512               (UMINPv2i32 V64:$Rn, V64:$Rn), dsub),
513             ssub))>;
515 // Match stores from lane 0 to the appropriate subreg's store.
516 multiclass VecStoreLane64_0Pat<ComplexPattern UIAddrMode, SDPatternOperator storeop,
517                             ValueType VTy, ValueType STy,
518                             SubRegIndex SubRegIdx, Operand IndexType,
519                             Instruction STR> {
520   def : Pat<(storeop (STy (vector_extract (VTy VecListOne64:$Vt), (i64 0))),
521                      (UIAddrMode GPR64sp:$Rn, IndexType:$offset)),
522             (STR (EXTRACT_SUBREG VecListOne64:$Vt, SubRegIdx),
523                  GPR64sp:$Rn, IndexType:$offset)>;
525 multiclass VecStoreULane64_0Pat<SDPatternOperator StoreOp,
526                              ValueType VTy, ValueType STy,
527                              SubRegIndex SubRegIdx, Instruction STR> {
528   defm : VecStoreLane64_0Pat<am_unscaled64, StoreOp, VTy, STy, SubRegIdx, simm9, STR>;
531 multiclass VecROStoreLane64_0Pat<ROAddrMode ro, SDPatternOperator storeop,
532                               ValueType VecTy, ValueType STy,
533                               SubRegIndex SubRegIdx,
534                               Instruction STRW, Instruction STRX> {
536   def : Pat<(storeop (STy (vector_extract (VecTy VecListOne64:$Vt), (i64 0))),
537                      (ro.Wpat GPR64sp:$Rn, GPR32:$Rm, ro.Wext:$extend)),
538             (STRW (EXTRACT_SUBREG VecListOne64:$Vt, SubRegIdx),
539                   GPR64sp:$Rn, GPR32:$Rm, ro.Wext:$extend)>;
541   def : Pat<(storeop (STy (vector_extract (VecTy VecListOne64:$Vt), (i64 0))),
542                      (ro.Xpat GPR64sp:$Rn, GPR64:$Rm, ro.Xext:$extend)),
543             (STRX (EXTRACT_SUBREG VecListOne64:$Vt, SubRegIdx),
544                   GPR64sp:$Rn, GPR64:$Rm, ro.Xext:$extend)>;
547 let AddedComplexity = 19 in {
548   def : St1Lane128Pat<store, VectorIndexB, v16i8, i8,  ST1i8>;
549   def : St1Lane64Pat<store, VectorIndexB, v8i8,  i8,  ST1i8>;
551   defm : VecStoreLane64_0Pat<am_indexed16, store, v4i16, i16, hsub, uimm12s2, STRHui>;
552   defm : VecStoreLane64_0Pat<am_indexed32, store, v2i32, i32, ssub, uimm12s4, STRSui>;
554   defm : VecStoreULane64_0Pat<store, v4i16, i16, hsub, STURHi>;
555   defm : VecStoreULane64_0Pat<store, v2i32, i32, ssub, STURSi>;
556   defm : VecROStoreLane64_0Pat<ro16, store, v4i16, i16, hsub, STRHroW, STRHroX>;
557   defm : VecROStoreLane64_0Pat<ro32, store, v2i32, i32, ssub, STRSroW, STRSroX>;
560 def : Pat<(v8i8 (AArch64dup (i8 (load (am_indexed8 GPR64sp:$Rn))))),
561           (LD1Rv8b GPR64sp:$Rn)>;
562 def : Pat<(v16i8 (AArch64dup (i8 (load GPR64sp:$Rn)))),
563           (LD1Rv16b GPR64sp:$Rn)>;
564 def : Pat<(v4i16 (AArch64dup (i16 (load GPR64sp:$Rn)))),
565           (LD1Rv4h GPR64sp:$Rn)>;
566 def : Pat<(v8i16 (AArch64dup (i16 (load GPR64sp:$Rn)))),
567           (LD1Rv8h GPR64sp:$Rn)>;
568 def : Pat<(v2i32 (AArch64dup (i32 (load GPR64sp:$Rn)))),
569           (LD1Rv2s GPR64sp:$Rn)>;
570 def : Pat<(v4i32 (AArch64dup (i32 (load GPR64sp:$Rn)))),
571           (LD1Rv4s GPR64sp:$Rn)>;
572 def : Pat<(v2i64 (AArch64dup (i64 (load GPR64sp:$Rn)))),
573           (LD1Rv2d GPR64sp:$Rn)>;
574 def : Pat<(v1i64 (AArch64dup (i64 (load GPR64sp:$Rn)))),
575           (LD1Rv1d GPR64sp:$Rn)>;