xref: /llvm-project/llvm/test/CodeGen/AArch64/sve-vscale.ll (revision f1ec0d12bb0843f0deab83ef2b5cf1339cbc4f0b)
1; RUN: llc -mtriple aarch64 -mattr=+sve -asm-verbose=0 < %s | FileCheck %s
2; RUN: opt -mtriple=aarch64 -passes='require<profile-summary>,function(codegenprepare)' -S < %s | llc -mtriple=aarch64 -mattr=+sve -asm-verbose=0 | FileCheck %s
3
4;
5; RDVL
6;
7
8; CHECK-LABEL: rdvl_i8:
9; CHECK:       rdvl x0, #1
10; CHECK-NEXT:  ret
11define i8 @rdvl_i8() nounwind {
12  %vscale = call i8 @llvm.vscale.i8()
13  %1 = mul nsw i8 %vscale, 16
14  ret i8 %1
15}
16
17; CHECK-LABEL: rdvl_i16:
18; CHECK:       rdvl x0, #1
19; CHECK-NEXT:  ret
20define i16 @rdvl_i16() nounwind {
21  %vscale = call i16 @llvm.vscale.i16()
22  %1 = mul nsw i16 %vscale, 16
23  ret i16 %1
24}
25
26; CHECK-LABEL: rdvl_i32:
27; CHECK:       rdvl x0, #1
28; CHECK-NEXT:  ret
29define i32 @rdvl_i32() nounwind {
30  %vscale = call i32 @llvm.vscale.i32()
31  %1 = mul nsw i32 %vscale, 16
32  ret i32 %1
33}
34
35; CHECK-LABEL: rdvl_i64:
36; CHECK:       rdvl x0, #1
37; CHECK-NEXT:  ret
38define i64 @rdvl_i64() nounwind {
39  %vscale = call i64 @llvm.vscale.i64()
40  %1 = mul nsw i64 %vscale, 16
41  ret i64 %1
42}
43
44; CHECK-LABEL: rdvl_const:
45; CHECK:       rdvl x0, #1
46; CHECK-NEXT:  ret
47define i32 @rdvl_const() nounwind {
48  %vscale.ptr = getelementptr <vscale x 1 x i8>, ptr null, i64 1
49  %vscale.int = ptrtoint ptr %vscale.ptr to i32
50  %vscale.scaled = mul nsw i32 %vscale.int, 16
51  ret i32 %vscale.scaled
52}
53
54define i32 @vscale_1() nounwind {
55; CHECK-LABEL: vscale_1:
56; CHECK:       rdvl [[TMP:x[0-9]+]], #1
57; CHECK-NEXT:  lsr  x0, [[TMP]], #4
58; CHECK-NEXT:  ret
59  %vscale = call i32 @llvm.vscale.i32()
60  ret i32 %vscale
61}
62
63define i32 @vscale_neg1() nounwind {
64; CHECK-LABEL: vscale_neg1:
65; CHECK:       rdvl [[TMP:x[0-9]+]], #-1
66; CHECK-NEXT:  asr  x0, [[TMP]], #4
67; CHECK-NEXT:  ret
68  %vscale = call i32 @llvm.vscale.i32()
69  %neg = mul nsw i32 -1, %vscale
70  ret i32 %neg
71}
72
73; CHECK-LABEL: rdvl_3:
74; CHECK:       rdvl [[VL_B:x[0-9]+]], #1
75; CHECK-NEXT:  mov  w[[MUL:[0-9]+]], #3
76; CHECK-NEXT:  lsr  [[VL_Q:x[0-9]+]], [[VL_B]], #4
77; CHECK-NEXT:  mul  x0, [[VL_Q]], x[[MUL]]
78; CHECK-NEXT:  ret
79define i32 @rdvl_3() nounwind {
80  %vscale = call i32 @llvm.vscale.i32()
81  %1 = mul nsw i32 %vscale, 3
82  ret i32 %1
83}
84
85
86; CHECK-LABEL: rdvl_min:
87; CHECK:       rdvl x0, #-32
88; CHECK-NEXT:  ret
89define i32 @rdvl_min() nounwind {
90  %vscale = call i32 @llvm.vscale.i32()
91  %1 = mul nsw i32 %vscale, -512
92  ret i32 %1
93}
94
95; CHECK-LABEL: rdvl_max:
96; CHECK:       rdvl x0, #31
97; CHECK-NEXT:  ret
98define i32 @rdvl_max() nounwind {
99  %vscale = call i32 @llvm.vscale.i32()
100  %1 = mul nsw i32 %vscale, 496
101  ret i32 %1
102}
103
104define i1 @rdvl_i1() {
105; CHECK-LABEL: rdvl_i1:
106; CHECK:         rdvl x8, #-1
107; CHECK-NEXT:    asr x8, x8, #4
108; CHECK-NEXT:    and w0, w8, #0x1
109; CHECK-NEXT:    ret
110  %a = tail call i64 @llvm.vscale.i64()
111  %b = trunc i64 %a to i1
112  ret i1 %b
113}
114
115;
116; CNTH
117;
118
119; CHECK-LABEL: cnth:
120; CHECK:       cnth x0{{$}}
121; CHECK-NEXT:  ret
122define i32 @cnth() nounwind {
123  %vscale = call i32 @llvm.vscale.i32()
124  %1 = shl nsw i32 %vscale, 3
125  ret i32 %1
126}
127
128; CHECK-LABEL: cnth_max:
129; CHECK:       cnth x0, all, mul #15
130; CHECK-NEXT:  ret
131define i32 @cnth_max() nounwind {
132  %vscale = call i32 @llvm.vscale.i32()
133  %1 = mul nsw i32 %vscale, 120
134  ret i32 %1
135}
136
137; CHECK-LABEL: cnth_neg:
138; CHECK:       cnth [[CNT:x[0-9]+]]
139; CHECK:       neg x0, [[CNT]]
140; CHECK-NEXT:  ret
141define i32 @cnth_neg() nounwind {
142  %vscale = call i32 @llvm.vscale.i32()
143  %1 = mul nsw i32 %vscale, -8
144  ret i32 %1
145}
146
147;
148; CNTW
149;
150
151; CHECK-LABEL: cntw:
152; CHECK:       cntw x0{{$}}
153; CHECK-NEXT:  ret
154define i32 @cntw() nounwind {
155  %vscale = call i32 @llvm.vscale.i32()
156  %1 = shl nsw i32 %vscale, 2
157  ret i32 %1
158}
159
160; CHECK-LABEL: cntw_max:
161; CHECK:       cntw x0, all, mul #15
162; CHECK-NEXT:  ret
163define i32 @cntw_max() nounwind {
164  %vscale = call i32 @llvm.vscale.i32()
165  %1 = mul nsw i32 %vscale, 60
166  ret i32 %1
167}
168
169; CHECK-LABEL: cntw_neg:
170; CHECK:       cntw [[CNT:x[0-9]+]]
171; CHECK:       neg x0, [[CNT]]
172; CHECK-NEXT:  ret
173define i32 @cntw_neg() nounwind {
174  %vscale = call i32 @llvm.vscale.i32()
175  %1 = mul nsw i32 %vscale, -4
176  ret i32 %1
177}
178
179;
180; CNTD
181;
182
183; CHECK-LABEL: cntd:
184; CHECK:       cntd x0{{$}}
185; CHECK-NEXT:  ret
186define i32 @cntd() nounwind {
187  %vscale = call i32 @llvm.vscale.i32()
188  %1 = shl nsw i32 %vscale, 1
189  ret i32 %1
190}
191
192; CHECK-LABEL: cntd_max:
193; CHECK:       cntd x0, all, mul #15
194; CHECK-NEXT:  ret
195define i32 @cntd_max() nounwind {
196  %vscale = call i32 @llvm.vscale.i32()
197  %1 = mul nsw i32 %vscale, 30
198  ret i32 %1
199}
200
201; CHECK-LABEL: cntd_neg:
202; CHECK:       cntd [[CNT:x[0-9]+]]
203; CHECK:       neg x0, [[CNT]]
204; CHECK-NEXT:  ret
205define i32 @cntd_neg() nounwind {
206  %vscale = call i32 @llvm.vscale.i32()
207  %1 = mul nsw i32 %vscale, -2
208  ret i32 %1
209}
210
211declare i8 @llvm.vscale.i8()
212declare i16 @llvm.vscale.i16()
213declare i32 @llvm.vscale.i32()
214declare i64 @llvm.vscale.i64()
215