xref: /llvm-project/llvm/test/CodeGen/LoongArch/intrinsic.ll (revision 240512c43234f58b3924cd90fe0781445d97e98d)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc --mtriple=loongarch32 --mattr=+f --verify-machineinstrs < %s | FileCheck %s
3; RUN: llc --mtriple=loongarch64 --mattr=+f --verify-machineinstrs < %s | FileCheck %s
4
5declare void @llvm.loongarch.dbar(i32)
6declare void @llvm.loongarch.ibar(i32)
7declare void @llvm.loongarch.break(i32)
8declare void @llvm.loongarch.movgr2fcsr(i32, i32)
9declare i32 @llvm.loongarch.movfcsr2gr(i32)
10declare void @llvm.loongarch.syscall(i32)
11declare i32 @llvm.loongarch.csrrd.w(i32 immarg)
12declare i32 @llvm.loongarch.csrwr.w(i32, i32 immarg)
13declare i32 @llvm.loongarch.csrxchg.w(i32, i32, i32 immarg)
14declare i32 @llvm.loongarch.iocsrrd.b(i32)
15declare i32 @llvm.loongarch.iocsrrd.h(i32)
16declare i32 @llvm.loongarch.iocsrrd.w(i32)
17declare void @llvm.loongarch.iocsrwr.b(i32, i32)
18declare void @llvm.loongarch.iocsrwr.h(i32, i32)
19declare void @llvm.loongarch.iocsrwr.w(i32, i32)
20declare i32 @llvm.loongarch.cpucfg(i32)
21
22define void @foo() nounwind {
23; CHECK-LABEL: foo:
24; CHECK:       # %bb.0: # %entry
25; CHECK-NEXT:    dbar 0
26; CHECK-NEXT:    ret
27entry:
28  call void @llvm.loongarch.dbar(i32 0)
29  ret void
30}
31
32define void @ibar() nounwind {
33; CHECK-LABEL: ibar:
34; CHECK:       # %bb.0: # %entry
35; CHECK-NEXT:    ibar 0
36; CHECK-NEXT:    ret
37entry:
38  call void @llvm.loongarch.ibar(i32 0)
39  ret void
40}
41
42define void @break() nounwind {
43; CHECK-LABEL: break:
44; CHECK:       # %bb.0: # %entry
45; CHECK-NEXT:    break 1
46; CHECK-NEXT:    ret
47entry:
48  call void @llvm.loongarch.break(i32 1)
49  ret void
50}
51
52define void @movgr2fcsr(i32 %a) nounwind {
53; CHECK-LABEL: movgr2fcsr:
54; CHECK:       # %bb.0: # %entry
55; CHECK-NEXT:    movgr2fcsr $fcsr1, $a0
56; CHECK-NEXT:    ret
57entry:
58  call void @llvm.loongarch.movgr2fcsr(i32 1, i32 %a)
59  ret void
60}
61
62define i32 @movfcsr2gr() nounwind {
63; CHECK-LABEL: movfcsr2gr:
64; CHECK:       # %bb.0: # %entry
65; CHECK-NEXT:    movfcsr2gr $a0, $fcsr1
66; CHECK-NEXT:    ret
67entry:
68  %res = call i32 @llvm.loongarch.movfcsr2gr(i32 1)
69  ret i32 %res
70}
71
72;; TODO: Optimize out `movfcsr2gr` without data-dependency.
73define void @movfcsr2gr_noret() nounwind {
74; CHECK-LABEL: movfcsr2gr_noret:
75; CHECK:       # %bb.0: # %entry
76; CHECK-NEXT:    movfcsr2gr $zero, $fcsr1
77; CHECK-NEXT:    ret
78entry:
79  %res = call i32 @llvm.loongarch.movfcsr2gr(i32 1)
80  ret void
81}
82
83define void @syscall() nounwind {
84; CHECK-LABEL: syscall:
85; CHECK:       # %bb.0: # %entry
86; CHECK-NEXT:    syscall 1
87; CHECK-NEXT:    ret
88entry:
89  call void @llvm.loongarch.syscall(i32 1)
90  ret void
91}
92
93define i32 @csrrd_w() {
94; CHECK-LABEL: csrrd_w:
95; CHECK:       # %bb.0: # %entry
96; CHECK-NEXT:    csrrd $a0, 1
97; CHECK-NEXT:    ret
98entry:
99  %0 = tail call i32 @llvm.loongarch.csrrd.w(i32 1)
100  ret i32 %0
101}
102
103define void @csrrd_w_noret() {
104; CHECK-LABEL: csrrd_w_noret:
105; CHECK:       # %bb.0: # %entry
106; CHECK-NEXT:    csrrd $zero, 1
107; CHECK-NEXT:    ret
108entry:
109  %0 = tail call i32 @llvm.loongarch.csrrd.w(i32 1)
110  ret void
111}
112
113define i32 @csrwr_w(i32 signext %a) {
114; CHECK-LABEL: csrwr_w:
115; CHECK:       # %bb.0: # %entry
116; CHECK-NEXT:    csrwr $a0, 1
117; CHECK-NEXT:    ret
118entry:
119  %0 = tail call i32 @llvm.loongarch.csrwr.w(i32 %a, i32 1)
120  ret i32 %0
121}
122
123;; Check that csrwr is emitted even if the return value of the intrinsic is not used.
124define void @csrwr_w_noret(i32 signext %a) {
125; CHECK-LABEL: csrwr_w_noret:
126; CHECK:       # %bb.0: # %entry
127; CHECK-NEXT:    csrwr $a0, 1
128; CHECK-NEXT:    ret
129entry:
130  %0 = tail call i32 @llvm.loongarch.csrwr.w(i32 %a, i32 1)
131  ret void
132}
133
134define i32 @csrxchg_w(i32 signext %a, i32 signext %b) {
135; CHECK-LABEL: csrxchg_w:
136; CHECK:       # %bb.0: # %entry
137; CHECK-NEXT:    csrxchg $a0, $a1, 1
138; CHECK-NEXT:    ret
139entry:
140  %0 = tail call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 %b, i32 1)
141  ret i32 %0
142}
143
144;; Check that csrxchg is emitted even if the return value of the intrinsic is not used.
145define void @csrxchg_w_noret(i32 signext %a, i32 signext %b) {
146; CHECK-LABEL: csrxchg_w_noret:
147; CHECK:       # %bb.0: # %entry
148; CHECK-NEXT:    csrxchg $a0, $a1, 1
149; CHECK-NEXT:    ret
150entry:
151  %0 = tail call i32 @llvm.loongarch.csrxchg.w(i32 %a, i32 %b, i32 1)
152  ret void
153}
154
155define i32 @iocsrrd_b(i32 %a) {
156; CHECK-LABEL: iocsrrd_b:
157; CHECK:       # %bb.0: # %entry
158; CHECK-NEXT:    iocsrrd.b $a0, $a0
159; CHECK-NEXT:    ret
160entry:
161  %0 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 %a)
162  ret i32 %0
163}
164
165define i32 @iocsrrd_h(i32 %a) {
166; CHECK-LABEL: iocsrrd_h:
167; CHECK:       # %bb.0: # %entry
168; CHECK-NEXT:    iocsrrd.h $a0, $a0
169; CHECK-NEXT:    ret
170entry:
171  %0 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 %a)
172  ret i32 %0
173}
174
175define i32 @iocsrrd_w(i32 %a) {
176; CHECK-LABEL: iocsrrd_w:
177; CHECK:       # %bb.0: # %entry
178; CHECK-NEXT:    iocsrrd.w $a0, $a0
179; CHECK-NEXT:    ret
180entry:
181  %0 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 %a)
182  ret i32 %0
183}
184
185define void @iocsrrd_b_noret(i32 %a) {
186; CHECK-LABEL: iocsrrd_b_noret:
187; CHECK:       # %bb.0: # %entry
188; CHECK-NEXT:    iocsrrd.b $zero, $a0
189; CHECK-NEXT:    ret
190entry:
191  %0 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 %a)
192  ret void
193}
194
195define void @iocsrrd_h_noret(i32 %a) {
196; CHECK-LABEL: iocsrrd_h_noret:
197; CHECK:       # %bb.0: # %entry
198; CHECK-NEXT:    iocsrrd.h $zero, $a0
199; CHECK-NEXT:    ret
200entry:
201  %0 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 %a)
202  ret void
203}
204
205define void @iocsrrd_w_noret(i32 %a) {
206; CHECK-LABEL: iocsrrd_w_noret:
207; CHECK:       # %bb.0: # %entry
208; CHECK-NEXT:    iocsrrd.w $zero, $a0
209; CHECK-NEXT:    ret
210entry:
211  %0 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 %a)
212  ret void
213}
214
215define void @iocsrwr_b(i32 %a, i32 %b) {
216; CHECK-LABEL: iocsrwr_b:
217; CHECK:       # %bb.0: # %entry
218; CHECK-NEXT:    iocsrwr.b $a0, $a1
219; CHECK-NEXT:    ret
220entry:
221  tail call void @llvm.loongarch.iocsrwr.b(i32 %a, i32 %b)
222  ret void
223}
224
225define void @iocsrwr_h(i32 %a, i32 %b) {
226; CHECK-LABEL: iocsrwr_h:
227; CHECK:       # %bb.0: # %entry
228; CHECK-NEXT:    iocsrwr.h $a0, $a1
229; CHECK-NEXT:    ret
230entry:
231  tail call void @llvm.loongarch.iocsrwr.h(i32 %a, i32 %b)
232  ret void
233}
234
235define void @iocsrwr_w(i32 %a, i32 %b) {
236; CHECK-LABEL: iocsrwr_w:
237; CHECK:       # %bb.0: # %entry
238; CHECK-NEXT:    iocsrwr.w $a0, $a1
239; CHECK-NEXT:    ret
240entry:
241  tail call void @llvm.loongarch.iocsrwr.w(i32 %a, i32 %b)
242  ret void
243}
244
245define i32 @cpucfg(i32 %a) {
246; CHECK-LABEL: cpucfg:
247; CHECK:       # %bb.0: # %entry
248; CHECK-NEXT:    cpucfg $a0, $a0
249; CHECK-NEXT:    ret
250entry:
251  %0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a)
252  ret i32 %0
253}
254
255define void @cpucfg_noret(i32 %a) {
256; CHECK-LABEL: cpucfg_noret:
257; CHECK:       # %bb.0: # %entry
258; CHECK-NEXT:    ret
259entry:
260  %0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a)
261  ret void
262}
263