Skip to content

Commit 153efb8

Browse files
TerryGuolialan
authored andcommitted
[EraVM] Add pre-commit test for optimizing branch with overflow
Add tests that contain branch instruction whose condition comes from whether there is an overflow in calling overflow arithmetic intrinsic. Co-authored-by: Alan Li <[email protected]> PR: #581, Issue: #491.
1 parent d7124ce commit 153efb8

File tree

1 file changed

+352
-0
lines changed

1 file changed

+352
-0
lines changed
Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2+
; RUN: llc -O3 --disable-eravm-scalar-opt-passes < %s | FileCheck %s
3+
4+
target datalayout = "E-p:256:256-i256:256:256-S32-a:256:256"
5+
target triple = "eravm"
6+
7+
declare { i256, i1 } @llvm.uadd.with.overflow.i256(i256, i256)
8+
declare { i256, i1 } @llvm.usub.with.overflow.i256(i256, i256)
9+
declare { i256, i1 } @llvm.umul.with.overflow.i256(i256, i256)
10+
declare void @has_overflow()
11+
declare void @has_no_overflow()
12+
13+
define void @uaddo_branch_1(i256 %x, i256 %y) {
14+
; CHECK-LABEL: uaddo_branch_1:
15+
; CHECK: ; %bb.0: ; %entry
16+
; CHECK-NEXT: add r1, r2, r2
17+
; CHECK-NEXT: sub! r2, r1, r1
18+
; CHECK-NEXT: add 0, r0, r1
19+
; CHECK-NEXT: add.lt 1, r0, r1
20+
; CHECK-NEXT: sub.s! 1, r1, r1
21+
; CHECK-NEXT: jump.ne @.BB0_2
22+
; CHECK-NEXT: ; %bb.1: ; %overflow_detected
23+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
24+
; CHECK-NEXT: ret
25+
; CHECK-NEXT: .BB0_2: ; %no_overflow_detected
26+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
27+
; CHECK-NEXT: ret
28+
entry:
29+
%res1 = call {i256, i1} @llvm.uadd.with.overflow.i256(i256 %x, i256 %y)
30+
%overflow = extractvalue {i256, i1} %res1, 1
31+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
32+
33+
overflow_detected:
34+
call void @has_overflow()
35+
br label %exit
36+
37+
no_overflow_detected:
38+
call void @has_no_overflow()
39+
br label %exit
40+
41+
exit:
42+
ret void
43+
}
44+
45+
define void @uadd_branch_2(i256 %x, i256 %y) {
46+
; CHECK-LABEL: uadd_branch_2:
47+
; CHECK: ; %bb.0: ; %entry
48+
; CHECK-NEXT: add r1, r2, r2
49+
; CHECK-NEXT: sub! r2, r1, r1
50+
; CHECK-NEXT: add 0, r0, r1
51+
; CHECK-NEXT: add.lt 1, r0, r1
52+
; CHECK-NEXT: and! 1, r1, r1
53+
; CHECK-NEXT: jump.eq @.BB1_1
54+
; CHECK-NEXT: ; %bb.2: ; %overflow_detected
55+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
56+
; CHECK-NEXT: ret
57+
; CHECK-NEXT: .BB1_1: ; %no_overflow_detected
58+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
59+
; CHECK-NEXT: ret
60+
entry:
61+
%res1 = call {i256, i1} @llvm.uadd.with.overflow.i256(i256 %x, i256 %y)
62+
%overflow = extractvalue {i256, i1} %res1, 1
63+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
64+
65+
no_overflow_detected:
66+
call void @has_no_overflow()
67+
br label %exit
68+
69+
overflow_detected:
70+
call void @has_overflow()
71+
br label %exit
72+
73+
exit:
74+
ret void
75+
}
76+
77+
define i256 @uadd_branch_3(i256 %x, i256 %y) {
78+
; CHECK-LABEL: uadd_branch_3:
79+
; CHECK: ; %bb.0: ; %entry
80+
; CHECK-NEXT: nop stack+=[1 + r0]
81+
; CHECK-NEXT: add r1, r2, stack-[1]
82+
; CHECK-NEXT: sub! stack-[1], r1, r1
83+
; CHECK-NEXT: add 0, r0, r1
84+
; CHECK-NEXT: add.lt 1, r0, r1
85+
; CHECK-NEXT: sub.s! 1, r1, r1
86+
; CHECK-NEXT: jump.ne @.BB2_2
87+
; CHECK-NEXT: ; %bb.1: ; %overflow_detected
88+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
89+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
90+
; CHECK-NEXT: ret
91+
; CHECK-NEXT: .BB2_2: ; %no_overflow_detected
92+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
93+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
94+
; CHECK-NEXT: ret
95+
entry:
96+
%res1 = call {i256, i1} @llvm.uadd.with.overflow.i256(i256 %x, i256 %y)
97+
%sum = extractvalue {i256, i1} %res1, 0
98+
%overflow = extractvalue {i256, i1} %res1, 1
99+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
100+
101+
overflow_detected:
102+
call void @has_overflow()
103+
br label %exit
104+
105+
no_overflow_detected:
106+
call void @has_no_overflow()
107+
br label %exit
108+
109+
exit:
110+
ret i256 %sum
111+
}
112+
113+
define i256 @uadd_branch_complicated(i256 %a, i256 %b, i256 %c, i256 %x, i256 %y) {
114+
; CHECK-LABEL: uadd_branch_complicated:
115+
; CHECK: ; %bb.0: ; %entry
116+
; CHECK-NEXT: nop stack+=[1 + r0]
117+
; CHECK-NEXT: add r4, r5, r5
118+
; CHECK-NEXT: sub! r1, r2, r1
119+
; CHECK-NEXT: add.ge r5, r0, r3
120+
; CHECK-NEXT: add r3, r0, stack-[1] ; 32-byte Folded Spill
121+
; CHECK-NEXT: sub! r5, r4, r1
122+
; CHECK-NEXT: add 0, r0, r1
123+
; CHECK-NEXT: add.lt 1, r0, r1
124+
; CHECK-NEXT: and! 1, r1, r1
125+
; CHECK-NEXT: jump.eq @.BB3_1
126+
; CHECK-NEXT: ; %bb.2: ; %overflow_detected
127+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
128+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
129+
; CHECK-NEXT: ret
130+
; CHECK-NEXT: .BB3_1: ; %no_overflow_detected
131+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
132+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
133+
; CHECK-NEXT: ret
134+
entry:
135+
%res1 = call {i256, i1} @llvm.uadd.with.overflow.i256(i256 %x, i256 %y)
136+
%sum = extractvalue {i256, i1} %res1, 0
137+
%cmp = icmp uge i256 %a, %b
138+
%val = select i1 %cmp, i256 %sum, i256 %c
139+
%overflow = extractvalue {i256, i1} %res1, 1
140+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
141+
142+
no_overflow_detected:
143+
call void @has_no_overflow()
144+
br label %exit
145+
146+
overflow_detected:
147+
call void @has_overflow()
148+
br label %exit
149+
150+
exit:
151+
ret i256 %val
152+
}
153+
154+
define void @usub_branch_1(i256 %x, i256 %y) {
155+
; CHECK-LABEL: usub_branch_1:
156+
; CHECK: ; %bb.0: ; %entry
157+
; CHECK-NEXT: sub r1, r2, r2
158+
; CHECK-NEXT: sub! r2, r1, r1
159+
; CHECK-NEXT: add 0, r0, r1
160+
; CHECK-NEXT: add.gt 1, r0, r1
161+
; CHECK-NEXT: sub.s! 1, r1, r1
162+
; CHECK-NEXT: jump.ne @.BB4_2
163+
; CHECK-NEXT: ; %bb.1: ; %overflow_detected
164+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
165+
; CHECK-NEXT: ret
166+
; CHECK-NEXT: .BB4_2: ; %no_overflow_detected
167+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
168+
; CHECK-NEXT: ret
169+
entry:
170+
%res1 = call {i256, i1} @llvm.usub.with.overflow.i256(i256 %x, i256 %y)
171+
%overflow = extractvalue {i256, i1} %res1, 1
172+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
173+
174+
overflow_detected:
175+
call void @has_overflow()
176+
br label %exit
177+
178+
no_overflow_detected:
179+
call void @has_no_overflow()
180+
br label %exit
181+
182+
exit:
183+
ret void
184+
}
185+
186+
define void @usub_branch_2(i256 %x, i256 %y) {
187+
; CHECK-LABEL: usub_branch_2:
188+
; CHECK: ; %bb.0: ; %entry
189+
; CHECK-NEXT: sub r1, r2, r2
190+
; CHECK-NEXT: sub! r2, r1, r1
191+
; CHECK-NEXT: add 0, r0, r1
192+
; CHECK-NEXT: add.gt 1, r0, r1
193+
; CHECK-NEXT: and! 1, r1, r1
194+
; CHECK-NEXT: jump.eq @.BB5_1
195+
; CHECK-NEXT: ; %bb.2: ; %overflow_detected
196+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
197+
; CHECK-NEXT: ret
198+
; CHECK-NEXT: .BB5_1: ; %no_overflow_detected
199+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
200+
; CHECK-NEXT: ret
201+
entry:
202+
%res1 = call {i256, i1} @llvm.usub.with.overflow.i256(i256 %x, i256 %y)
203+
%overflow = extractvalue {i256, i1} %res1, 1
204+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
205+
206+
no_overflow_detected:
207+
call void @has_no_overflow()
208+
br label %exit
209+
210+
overflow_detected:
211+
call void @has_overflow()
212+
br label %exit
213+
214+
exit:
215+
ret void
216+
}
217+
218+
define i256 @usub_branch_3(i256 %x, i256 %y) {
219+
; CHECK-LABEL: usub_branch_3:
220+
; CHECK: ; %bb.0: ; %entry
221+
; CHECK-NEXT: nop stack+=[1 + r0]
222+
; CHECK-NEXT: sub r1, r2, stack-[1]
223+
; CHECK-NEXT: sub! stack-[1], r1, r1
224+
; CHECK-NEXT: add 0, r0, r1
225+
; CHECK-NEXT: add.gt 1, r0, r1
226+
; CHECK-NEXT: sub.s! 1, r1, r1
227+
; CHECK-NEXT: jump.ne @.BB6_2
228+
; CHECK-NEXT: ; %bb.1: ; %overflow_detected
229+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
230+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
231+
; CHECK-NEXT: ret
232+
; CHECK-NEXT: .BB6_2: ; %no_overflow_detected
233+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
234+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
235+
; CHECK-NEXT: ret
236+
entry:
237+
%res1 = call {i256, i1} @llvm.usub.with.overflow.i256(i256 %x, i256 %y)
238+
%sum = extractvalue {i256, i1} %res1, 0
239+
%overflow = extractvalue {i256, i1} %res1, 1
240+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
241+
242+
overflow_detected:
243+
call void @has_overflow()
244+
br label %exit
245+
246+
no_overflow_detected:
247+
call void @has_no_overflow()
248+
br label %exit
249+
250+
exit:
251+
ret i256 %sum
252+
}
253+
254+
define void @umul_branch_1(i256 %x, i256 %y) {
255+
; CHECK-LABEL: umul_branch_1:
256+
; CHECK: ; %bb.0: ; %entry
257+
; CHECK-NEXT: mul r1, r2, r1, r2
258+
; CHECK-NEXT: sub! r2, r0, r1
259+
; CHECK-NEXT: add 0, r0, r1
260+
; CHECK-NEXT: add.ne 1, r0, r1
261+
; CHECK-NEXT: sub.s! 1, r1, r1
262+
; CHECK-NEXT: jump.ne @.BB7_2
263+
; CHECK-NEXT: ; %bb.1: ; %overflow_detected
264+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
265+
; CHECK-NEXT: ret
266+
; CHECK-NEXT: .BB7_2: ; %no_overflow_detected
267+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
268+
; CHECK-NEXT: ret
269+
entry:
270+
%res1 = call {i256, i1} @llvm.umul.with.overflow.i256(i256 %x, i256 %y)
271+
%overflow = extractvalue {i256, i1} %res1, 1
272+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
273+
274+
overflow_detected:
275+
call void @has_overflow()
276+
br label %exit
277+
278+
no_overflow_detected:
279+
call void @has_no_overflow()
280+
br label %exit
281+
282+
exit:
283+
ret void
284+
}
285+
286+
define void @umul_branch_2(i256 %x, i256 %y) {
287+
; CHECK-LABEL: umul_branch_2:
288+
; CHECK: ; %bb.0: ; %entry
289+
; CHECK-NEXT: mul r1, r2, r1, r2
290+
; CHECK-NEXT: sub! r2, r0, r1
291+
; CHECK-NEXT: add 0, r0, r1
292+
; CHECK-NEXT: add.ne 1, r0, r1
293+
; CHECK-NEXT: and! 1, r1, r1
294+
; CHECK-NEXT: jump.eq @.BB8_1
295+
; CHECK-NEXT: ; %bb.2: ; %overflow_detected
296+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
297+
; CHECK-NEXT: ret
298+
; CHECK-NEXT: .BB8_1: ; %no_overflow_detected
299+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
300+
; CHECK-NEXT: ret
301+
entry:
302+
%res1 = call {i256, i1} @llvm.umul.with.overflow.i256(i256 %x, i256 %y)
303+
%overflow = extractvalue {i256, i1} %res1, 1
304+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
305+
306+
no_overflow_detected:
307+
call void @has_no_overflow()
308+
br label %exit
309+
310+
overflow_detected:
311+
call void @has_overflow()
312+
br label %exit
313+
314+
exit:
315+
ret void
316+
}
317+
318+
define i256 @umul_branch_3(i256 %x, i256 %y) {
319+
; CHECK-LABEL: umul_branch_3:
320+
; CHECK: ; %bb.0: ; %entry
321+
; CHECK-NEXT: nop stack+=[1 + r0]
322+
; CHECK-NEXT: mul r1, r2, stack-[1], r1
323+
; CHECK-NEXT: sub! r1, r0, r1
324+
; CHECK-NEXT: add 0, r0, r1
325+
; CHECK-NEXT: add.ne 1, r0, r1
326+
; CHECK-NEXT: sub.s! 1, r1, r1
327+
; CHECK-NEXT: jump.ne @.BB9_2
328+
; CHECK-NEXT: ; %bb.1: ; %overflow_detected
329+
; CHECK-NEXT: near_call r0, @has_overflow, @DEFAULT_UNWIND
330+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
331+
; CHECK-NEXT: ret
332+
; CHECK-NEXT: .BB9_2: ; %no_overflow_detected
333+
; CHECK-NEXT: near_call r0, @has_no_overflow, @DEFAULT_UNWIND
334+
; CHECK-NEXT: add stack-[1], r0, r1 ; 32-byte Folded Reload
335+
; CHECK-NEXT: ret
336+
entry:
337+
%res1 = call {i256, i1} @llvm.umul.with.overflow.i256(i256 %x, i256 %y)
338+
%sum = extractvalue {i256, i1} %res1, 0
339+
%overflow = extractvalue {i256, i1} %res1, 1
340+
br i1 %overflow, label %overflow_detected, label %no_overflow_detected
341+
342+
overflow_detected:
343+
call void @has_overflow()
344+
br label %exit
345+
346+
no_overflow_detected:
347+
call void @has_no_overflow()
348+
br label %exit
349+
350+
exit:
351+
ret i256 %sum
352+
}

0 commit comments

Comments
 (0)