Skip to content

Commit 910ab3f

Browse files
authored
Cranelift: ((x > 0) ? x : -x) => (iabs x) (#10850)
* add rules * add tests * fix rules
1 parent e261738 commit 910ab3f

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed

cranelift/codegen/src/opts/selects.isle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,8 @@
8686
(sextend ty a @ (value_type small))
8787
(sextend ty b @ (value_type small))))
8888
(sextend ty (select small cond a b)))
89+
90+
(rule (simplify (select ty (sgt _ x (iconst_u ty 0)) x (ineg ty x))) (subsume (iabs ty x)))
91+
(rule (simplify (select ty (sge _ x (iconst_u ty 0)) x (ineg ty x))) (subsume (iabs ty x)))
92+
(rule (simplify (select ty (sle _ x (iconst_u ty 0)) (ineg ty x) x)) (subsume (iabs ty x)))
93+
(rule (simplify (select ty (slt _ x (iconst_u ty 0)) (ineg ty x) x)) (subsume (iabs ty x)))
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
test optimize precise-output
2+
set opt_level=speed
3+
target x86_64
4+
5+
;; (x > 0) ? x : neg(x) => abs(x)
6+
7+
function %abs_sgt_x_negx_i64(i64) -> i64 {
8+
block0(v0: i64): ;; x
9+
v1 = iconst.i64 0 ;; 0 for icmp
10+
v2 = icmp sgt v0, v1 ;; x > 0
11+
v3 = iconst.i64 0 ;; 0 for isub (ineg)
12+
v4 = isub v3, v0 ;; 0 - x (represents ineg x)
13+
v5 = select v2, v0, v4 ;; (x > 0) ? x : (0-x)
14+
return v5
15+
}
16+
; function %abs_sgt_x_negx_i64(i64) -> i64 fast {
17+
; block0(v0: i64):
18+
; v9 = iabs v0
19+
; return v9
20+
; }
21+
22+
function %abs_sgt_x_negx_i32(i32) -> i32 {
23+
block0(v0: i32):
24+
v1 = iconst.i32 0
25+
v2 = icmp sgt v0, v1
26+
v3 = iconst.i32 0
27+
v4 = isub v3, v0
28+
v5 = select v2, v0, v4
29+
return v5
30+
}
31+
; function %abs_sgt_x_negx_i32(i32) -> i32 fast {
32+
; block0(v0: i32):
33+
; v9 = iabs v0
34+
; return v9
35+
; }
36+
37+
function %abs_sgt_x_negx_i16(i16) -> i16 {
38+
block0(v0: i16):
39+
v1 = iconst.i16 0
40+
v2 = icmp sgt v0, v1
41+
v3 = iconst.i16 0
42+
v4 = isub v3, v0
43+
v5 = select v2, v0, v4
44+
return v5
45+
}
46+
; function %abs_sgt_x_negx_i16(i16) -> i16 fast {
47+
; block0(v0: i16):
48+
; v9 = iabs v0
49+
; return v9
50+
; }
51+
52+
function %abs_sgt_x_negx_i8(i8) -> i8 {
53+
block0(v0: i8):
54+
v1 = iconst.i8 0
55+
v2 = icmp sgt v0, v1
56+
v3 = iconst.i8 0
57+
v4 = isub v3, v0
58+
v5 = select v2, v0, v4
59+
return v5
60+
}
61+
; function %abs_sgt_x_negx_i8(i8) -> i8 fast {
62+
; block0(v0: i8):
63+
; v9 = iabs v0
64+
; return v9
65+
; }
66+
67+
;; (x >= 0) ? x : neg(x) => abs(x)
68+
69+
function %abs_sge_x_negx_i64(i64) -> i64 {
70+
block0(v0: i64):
71+
v1 = iconst.i64 0
72+
v2 = icmp sge v0, v1 ;; x >= 0
73+
v3 = iconst.i64 0
74+
v4 = isub v3, v0
75+
v5 = select v2, v0, v4
76+
return v5
77+
}
78+
; function %abs_sge_x_negx_i64(i64) -> i64 fast {
79+
; block0(v0: i64):
80+
; v9 = iabs v0
81+
; return v9
82+
; }
83+
84+
function %abs_sge_x_negx_i32(i32) -> i32 {
85+
block0(v0: i32):
86+
v1 = iconst.i32 0
87+
v2 = icmp sge v0, v1
88+
v3 = iconst.i32 0
89+
v4 = isub v3, v0
90+
v5 = select v2, v0, v4
91+
return v5
92+
}
93+
; function %abs_sge_x_negx_i32(i32) -> i32 fast {
94+
; block0(v0: i32):
95+
; v9 = iabs v0
96+
; return v9
97+
; }
98+
99+
function %abs_sge_x_negx_i16(i16) -> i16 {
100+
block0(v0: i16):
101+
v1 = iconst.i16 0
102+
v2 = icmp sge v0, v1
103+
v3 = iconst.i16 0
104+
v4 = isub v3, v0
105+
v5 = select v2, v0, v4
106+
return v5
107+
}
108+
; function %abs_sge_x_negx_i16(i16) -> i16 fast {
109+
; block0(v0: i16):
110+
; v9 = iabs v0
111+
; return v9
112+
; }
113+
114+
function %abs_sge_x_negx_i8(i8) -> i8 {
115+
block0(v0: i8):
116+
v1 = iconst.i8 0
117+
v2 = icmp sge v0, v1
118+
v3 = iconst.i8 0
119+
v4 = isub v3, v0
120+
v5 = select v2, v0, v4
121+
return v5
122+
}
123+
; function %abs_sge_x_negx_i8(i8) -> i8 fast {
124+
; block0(v0: i8):
125+
; v9 = iabs v0
126+
; return v9
127+
; }
128+
129+
130+
;; (x <= 0) ? neg(x) : x => abs(x)
131+
132+
function %abs_sle_negx_x_i64(i64) -> i64 {
133+
block0(v0: i64):
134+
v1 = iconst.i64 0
135+
v2 = icmp sle v0, v1 ;; x <= 0
136+
v3 = iconst.i64 0
137+
v4 = isub v3, v0 ;; 0 - x
138+
v5 = select v2, v4, v0 ;; (x <= 0) ? (0-x) : x
139+
return v5
140+
}
141+
; function %abs_sle_negx_x_i64(i64) -> i64 fast {
142+
; block0(v0: i64):
143+
; v9 = iabs v0
144+
; return v9
145+
; }
146+
147+
function %abs_sle_negx_x_i32(i32) -> i32 {
148+
block0(v0: i32):
149+
v1 = iconst.i32 0
150+
v2 = icmp sle v0, v1
151+
v3 = iconst.i32 0
152+
v4 = isub v3, v0
153+
v5 = select v2, v4, v0
154+
return v5
155+
}
156+
; function %abs_sle_negx_x_i32(i32) -> i32 fast {
157+
; block0(v0: i32):
158+
; v9 = iabs v0
159+
; return v9
160+
; }
161+
162+
function %abs_sle_negx_x_i16(i16) -> i16 {
163+
block0(v0: i16):
164+
v1 = iconst.i16 0
165+
v2 = icmp sle v0, v1
166+
v3 = iconst.i16 0
167+
v4 = isub v3, v0
168+
v5 = select v2, v4, v0
169+
return v5
170+
}
171+
; function %abs_sle_negx_x_i16(i16) -> i16 fast {
172+
; block0(v0: i16):
173+
; v9 = iabs v0
174+
; return v9
175+
; }
176+
177+
function %abs_sle_negx_x_i8(i8) -> i8 {
178+
block0(v0: i8):
179+
v1 = iconst.i8 0
180+
v2 = icmp sle v0, v1
181+
v3 = iconst.i8 0
182+
v4 = isub v3, v0
183+
v5 = select v2, v4, v0
184+
return v5
185+
}
186+
; function %abs_sle_negx_x_i8(i8) -> i8 fast {
187+
; block0(v0: i8):
188+
; v9 = iabs v0
189+
; return v9
190+
; }
191+
192+
;; (x < 0) ? neg(x) : x => abs(x)
193+
function %abs_slt_negx_x_i64(i64) -> i64 {
194+
block0(v0: i64):
195+
v1 = iconst.i64 0
196+
v2 = icmp slt v0, v1 ;; x < 0
197+
v3 = iconst.i64 0
198+
v4 = isub v3, v0
199+
v5 = select v2, v4, v0
200+
return v5
201+
}
202+
; function %abs_slt_negx_x_i64(i64) -> i64 fast {
203+
; block0(v0: i64):
204+
; v9 = iabs v0
205+
; return v9
206+
; }
207+
208+
function %abs_slt_negx_x_i32(i32) -> i32 {
209+
block0(v0: i32):
210+
v1 = iconst.i32 0
211+
v2 = icmp slt v0, v1
212+
v3 = iconst.i32 0
213+
v4 = isub v3, v0
214+
v5 = select v2, v4, v0
215+
return v5
216+
}
217+
218+
; function %abs_slt_negx_x_i32(i32) -> i32 fast {
219+
; block0(v0: i32):
220+
; v9 = iabs v0
221+
; return v9
222+
; }
223+
224+
function %abs_slt_negx_x_i16(i16) -> i16 {
225+
block0(v0: i16):
226+
v1 = iconst.i16 0
227+
v2 = icmp slt v0, v1
228+
v3 = iconst.i16 0
229+
v4 = isub v3, v0
230+
v5 = select v2, v4, v0
231+
return v5
232+
}
233+
234+
; function %abs_slt_negx_x_i16(i16) -> i16 fast {
235+
; block0(v0: i16):
236+
; v9 = iabs v0
237+
; return v9
238+
; }
239+
240+
function %abs_slt_negx_x_i8(i8) -> i8 {
241+
block0(v0: i8):
242+
v1 = iconst.i8 0
243+
v2 = icmp slt v0, v1
244+
v3 = iconst.i8 0
245+
v4 = isub v3, v0
246+
v5 = select v2, v4, v0
247+
return v5
248+
}
249+
250+
; function %abs_slt_negx_x_i8(i8) -> i8 fast {
251+
; block0(v0: i8):
252+
; v9 = iabs v0
253+
; return v9
254+
; }

0 commit comments

Comments
 (0)