1; RUN: llc -aarch64-sve-vector-bits-min=128  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefix=NO_SVE
2; RUN: llc -aarch64-sve-vector-bits-min=256  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK
3; RUN: llc -aarch64-sve-vector-bits-min=384  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK
4; RUN: llc -aarch64-sve-vector-bits-min=512  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
5; RUN: llc -aarch64-sve-vector-bits-min=640  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
6; RUN: llc -aarch64-sve-vector-bits-min=768  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
7; RUN: llc -aarch64-sve-vector-bits-min=896  -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
8; RUN: llc -aarch64-sve-vector-bits-min=1024 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
9; RUN: llc -aarch64-sve-vector-bits-min=1152 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
10; RUN: llc -aarch64-sve-vector-bits-min=1280 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
11; RUN: llc -aarch64-sve-vector-bits-min=1408 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
12; RUN: llc -aarch64-sve-vector-bits-min=1536 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
13; RUN: llc -aarch64-sve-vector-bits-min=1664 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
14; RUN: llc -aarch64-sve-vector-bits-min=1792 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
15; RUN: llc -aarch64-sve-vector-bits-min=1920 -aarch64-enable-atomic-cfg-tidy=false < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
16; RUN: llc -aarch64-sve-vector-bits-min=2048 -aarch64-enable-atomic-cfg-tidy=false < %s 2>%t | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024,VBITS_GE_2048
17; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
18
19; WARN-NOT: warning
20
21; Test we can code generater patterns of the form:
22;   fixed_length_vector = ISD::EXTRACT_SUBVECTOR scalable_vector, 0
23;   scalable_vector = ISD::INSERT_SUBVECTOR scalable_vector, fixed_length_vector, 0
24;
25; NOTE: Currently shufflevector does not support scalable vectors so it cannot
26; be used to model the above operations.  Instead these tests rely on knowing
27; how fixed length operation are lowered to scalable ones, with multiple blocks
28; ensuring insert/extract sequences are not folded away.
29
30target triple = "aarch64-unknown-linux-gnu"
31
32; Don't use SVE when its registers are no bigger than NEON.
33; NO_SVE-NOT: ptrue
34
35define void @subvector_v8i32(<8 x i32> *%in, <8 x i32>* %out) #0 {
36; CHECK-LABEL: subvector_v8i32:
37; CHECK: ptrue [[PG:p[0-9]+]].s, vl8
38; CHECK: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
39; CHECK: st1w { [[DATA]] }, [[PG]], [x1]
40; CHECK: ret
41  %a = load <8 x i32>, <8 x i32>* %in
42  br label %bb1
43
44bb1:
45  store <8 x i32> %a, <8 x i32>* %out
46  ret void
47}
48
49define void @subvector_v16i32(<16 x i32> *%in, <16 x i32>* %out) #0 {
50; CHECK-LABEL: subvector_v16i32:
51; VBITS_GE_512: ptrue [[PG:p[0-9]+]].s, vl16
52; VBITS_GE_512: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
53; VBITS_GE_512: st1w { [[DATA]] }, [[PG]], [x1]
54; CHECKT: ret
55  %a = load <16 x i32>, <16 x i32>* %in
56  br label %bb1
57
58bb1:
59  store <16 x i32> %a, <16 x i32>* %out
60  ret void
61}
62
63define void @subvector_v32i32(<32 x i32> *%in, <32 x i32>* %out) #0 {
64; CHECK-LABEL: subvector_v32i32:
65; VBITS_GE_1024: ptrue [[PG:p[0-9]+]].s, vl32
66; VBITS_GE_1024: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
67; VBITS_GE_1024: st1w { [[DATA]] }, [[PG]], [x1]
68; CHECK: ret
69  %a = load <32 x i32>, <32 x i32>* %in
70  br label %bb1
71
72bb1:
73  store <32 x i32> %a, <32 x i32>* %out
74  ret void
75}
76
77define void @subvector_v64i32(<64 x i32> *%in, <64 x i32>* %out) #0 {
78; CHECK-LABEL: subvector_v64i32:
79; VBITS_GE_2048: ptrue [[PG:p[0-9]+]].s, vl64
80; VBITS_GE_2048: ld1w { [[DATA:z[0-9]+.s]] }, [[PG]]/z, [x0]
81; VBITS_GE_2048: st1w { [[DATA]] }, [[PG]], [x1]
82; CHECK: ret
83  %a = load <64 x i32>, <64 x i32>* %in
84  br label %bb1
85
86bb1:
87  store <64 x i32> %a, <64 x i32>* %out
88  ret void
89}
90
91define <8 x i1> @no_warn_dropped_scalable(<8 x i32>* %in) #0 {
92; CHECK-LABEL: no_warn_dropped_scalable:
93; CHECK: ptrue [[PG:p[0-9]+]].s, vl8
94; CHECK: ld1w { [[A:z[0-9]+]].s }, [[PG]]/z, [x0]
95; CHECK: cmpgt p{{[0-9]}}.s, [[PG]]/z, [[A]].s, #0
96; CHECK: ret
97  %a = load <8 x i32>, <8 x i32>* %in
98  br label %bb1
99
100bb1:
101  %cond = icmp sgt <8 x i32> %a, zeroinitializer
102  ret <8 x i1> %cond
103}
104
105; binop(insert_subvec(a), insert_subvec(b)) -> insert_subvec(binop(a,b)) like
106; combines remove redundant subvector operations. This test ensures it's not
107; performed when the input idiom is the result of operation legalisation. When
108; not prevented the test triggers infinite combine->legalise->combine->...
109define void @no_subvector_binop_hang(<8 x i32>* %in, <8 x i32>* %out, i1 %cond) #0 {
110; CHECK-LABEL: no_subvector_binop_hang:
111; CHECK:       // %bb.0:
112; CHECK-NEXT:    ptrue [[PG:p[0-9]+]].s, vl8
113; CHECK-NEXT:    ld1w { [[A:z[0-9]+]].s }, [[PG]]/z, [x0]
114; CHECK-NEXT:    ld1w { [[B:z[0-9]+]].s }, [[PG]]/z, [x1]
115; CHECK-NEXT:    tbz w2, #0, .LBB5_2
116; CHECK-NEXT:  // %bb.1: // %bb.1
117; CHECK-NEXT:    orr [[OR:z[0-9]+]].d, [[A]].d, [[B]].d
118; CHECK-NEXT:    st1w { [[OR]].s }, [[PG]], [x1]
119; CHECK-NEXT:  .LBB5_2: // %bb.2
120; CHECK-NEXT:    ret
121  %a = load <8 x i32>, <8 x i32>* %in
122  %b = load <8 x i32>, <8 x i32>* %out
123  br i1 %cond, label %bb.1, label %bb.2
124
125bb.1:
126  %or = or <8 x i32> %a, %b
127  store <8 x i32> %or, <8 x i32>* %out
128  br label %bb.2
129
130bb.2:
131  ret void
132}
133
134attributes #0 = { "target-features"="+sve" }
135