Skip to content

Commit 4fd715d

Browse files
committed
riscv64: Add sextend+Arithmetic rules
1 parent a047f3c commit 4fd715d

File tree

3 files changed

+278
-1
lines changed

3 files changed

+278
-1
lines changed

cranelift/codegen/src/isa/riscv64/lower.isle

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,38 @@
399399
(rule (lower (has_type out_ty (sextend val @ (value_type in_ty))))
400400
(sext val in_ty out_ty))
401401

402+
;; The instructions below are present in RV64I and sign-extend the result to 64 bits.
403+
404+
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (iadd x y)))))
405+
(alu_rrr (AluOPRRR.Addw) x y))
406+
407+
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (isub x y)))))
408+
(alu_rrr (AluOPRRR.Subw) x y))
409+
410+
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (ishl x y)))))
411+
(alu_rrr (AluOPRRR.Sllw) x y))
412+
413+
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (ushr x y)))))
414+
(alu_rrr (AluOPRRR.Srlw) x y))
415+
416+
(rule 1 (lower (has_type $I64 (sextend (has_type $I32 (sshr x y)))))
417+
(alu_rrr (AluOPRRR.Sraw) x y))
418+
419+
420+
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (iadd x (imm12_from_value y))))))
421+
(alu_rr_imm12 (AluOPRRI.Addiw) x y))
422+
423+
(rule 3 (lower (has_type $I64 (sextend (has_type $I32 (iadd (imm12_from_value x) y)))))
424+
(alu_rr_imm12 (AluOPRRI.Addiw) y x))
425+
426+
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (ishl x (imm12_from_value y))))))
427+
(alu_rr_imm12 (AluOPRRI.Slliw) x y))
428+
429+
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (ushr x (imm12_from_value y))))))
430+
(alu_rr_imm12 (AluOPRRI.SrliW) x y))
431+
432+
(rule 2 (lower (has_type $I64 (sextend (has_type $I32 (sshr x (imm12_from_value y))))))
433+
(alu_rr_imm12 (AluOPRRI.Sraiw) x y))
402434

403435
;;;; Rules for `popcnt` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
404436
(rule (lower (has_type (fits_in_64 ty) (popcnt x)))
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
test compile precise-output
2+
set unwind_info=false
3+
target riscv64
4+
5+
function %sext_add_i32(i32, i32) -> i64 {
6+
block0(v0: i32, v1: i32):
7+
v2 = iadd.i32 v0, v1
8+
v3 = sextend.i64 v2
9+
return v3
10+
}
11+
12+
; VCode:
13+
; block0:
14+
; addw a0,a0,a1
15+
; ret
16+
;
17+
; Disassembled:
18+
; block0: ; offset 0x0
19+
; addw a0, a0, a1
20+
; ret
21+
22+
function %sext_sub_i32(i32, i32) -> i64 {
23+
block0(v0: i32, v1: i32):
24+
v2 = isub.i32 v0, v1
25+
v3 = sextend.i64 v2
26+
return v3
27+
}
28+
29+
; VCode:
30+
; block0:
31+
; subw a0,a0,a1
32+
; ret
33+
;
34+
; Disassembled:
35+
; block0: ; offset 0x0
36+
; subw a0, a0, a1
37+
; ret
38+
39+
function %sext_ishl_i32(i32, i32) -> i64 {
40+
block0(v0: i32, v1: i32):
41+
v2 = ishl.i32 v0, v1
42+
v3 = sextend.i64 v2
43+
return v3
44+
}
45+
46+
; VCode:
47+
; block0:
48+
; sllw a0,a0,a1
49+
; ret
50+
;
51+
; Disassembled:
52+
; block0: ; offset 0x0
53+
; sllw a0, a0, a1
54+
; ret
55+
56+
function %sext_ushr_i32(i32, i32) -> i64 {
57+
block0(v0: i32, v1: i32):
58+
v2 = ushr.i32 v0, v1
59+
v3 = sextend.i64 v2
60+
return v3
61+
}
62+
63+
; VCode:
64+
; block0:
65+
; srlw a0,a0,a1
66+
; ret
67+
;
68+
; Disassembled:
69+
; block0: ; offset 0x0
70+
; srlw a0, a0, a1
71+
; ret
72+
73+
function %sext_sshr_i32(i32, i32) -> i64 {
74+
block0(v0: i32, v1: i32):
75+
v2 = sshr.i32 v0, v1
76+
v3 = sextend.i64 v2
77+
return v3
78+
}
79+
80+
; VCode:
81+
; block0:
82+
; sraw a0,a0,a1
83+
; ret
84+
;
85+
; Disassembled:
86+
; block0: ; offset 0x0
87+
; sraw a0, a0, a1
88+
; ret
89+
90+
function %sext_add_const_i32(i32) -> i64 {
91+
block0(v0: i32):
92+
v1 = iconst.i32 -1
93+
v2 = iadd.i32 v0, v1
94+
v3 = sextend.i64 v2
95+
return v3
96+
}
97+
98+
; VCode:
99+
; block0:
100+
; addiw a0,a0,-1
101+
; ret
102+
;
103+
; Disassembled:
104+
; block0: ; offset 0x0
105+
; addiw a0, a0, -1
106+
; ret
107+
108+
function %sext_ishl_const_i32(i32) -> i64 {
109+
block0(v0: i32):
110+
v1 = iconst.i32 31
111+
v2 = ishl.i32 v0, v1
112+
v3 = sextend.i64 v2
113+
return v3
114+
}
115+
116+
; VCode:
117+
; block0:
118+
; slliw a0,a0,31
119+
; ret
120+
;
121+
; Disassembled:
122+
; block0: ; offset 0x0
123+
; slliw a0, a0, 0x1f
124+
; ret
125+
126+
function %sext_ushr_const_i32(i32) -> i64 {
127+
block0(v0: i32):
128+
v1 = iconst.i32 31
129+
v2 = ushr.i32 v0, v1
130+
v3 = sextend.i64 v2
131+
return v3
132+
}
133+
134+
; VCode:
135+
; block0:
136+
; srliw a0,a0,31
137+
; ret
138+
;
139+
; Disassembled:
140+
; block0: ; offset 0x0
141+
; srliw a0, a0, 0x1f
142+
; ret
143+
144+
function %sext_sshr_const_i32(i32) -> i64 {
145+
block0(v0: i32):
146+
v1 = iconst.i32 31
147+
v2 = sshr.i32 v0, v1
148+
v3 = sextend.i64 v2
149+
return v3
150+
}
151+
152+
; VCode:
153+
; block0:
154+
; sraiw a0,a0,31
155+
; ret
156+
;
157+
; Disassembled:
158+
; block0: ; offset 0x0
159+
; sraiw a0, a0, 0x1f
160+
; ret
161+

cranelift/filetests/filetests/runtests/arithmetic-extends.clif

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,88 @@ block0(v0: i64, v1: i32):
148148
}
149149
; run: %add_uext_ishl_3(0x0123_4567, 0x8000_0000) == 0x0123_4567
150150
; run: %add_uext_ishl_3(0x0123_4567, 0xC000_0000) == 0x0123_4567
151-
; run: %add_uext_ishl_3(0x0123_4567, 0xE000_0000) == 0x0123_4567
151+
; run: %add_uext_ishl_3(0x0123_4567, 0xE000_0000) == 0x0123_4567
152+
153+
154+
;; These tests perform the operations in 32bits but then sign extend the results to 64bits
155+
function %sext_add_i32(i32, i32) -> i64 {
156+
block0(v0: i32, v1: i32):
157+
v2 = iadd.i32 v0, v1
158+
v3 = sextend.i64 v2
159+
return v3
160+
}
161+
; run: %sext_add_i32(1, 0) == 1
162+
; run: %sext_add_i32(0, -1) == -1
163+
164+
165+
function %sext_sub_i32(i32, i32) -> i64 {
166+
block0(v0: i32, v1: i32):
167+
v2 = isub.i32 v0, v1
168+
v3 = sextend.i64 v2
169+
return v3
170+
}
171+
; run: %sext_sub_i32(1, 0) == 1
172+
; run: %sext_sub_i32(0, 1) == -1
173+
174+
175+
function %sext_ishl_i32(i32, i32) -> i64 {
176+
block0(v0: i32, v1: i32):
177+
v2 = ishl.i32 v0, v1
178+
v3 = sextend.i64 v2
179+
return v3
180+
}
181+
; run: %sext_ishl_i32(1, 31) == 0xFFFFFFFF80000000
182+
183+
function %sext_ushr_i32(i32, i32) -> i64 {
184+
block0(v0: i32, v1: i32):
185+
v2 = ushr.i32 v0, v1
186+
v3 = sextend.i64 v2
187+
return v3
188+
}
189+
; run: %sext_ushr_i32(0x8000_0000, 0) == 0xFFFFFFFF80000000
190+
; run: %sext_ushr_i32(0x8000_0000, 32) == 0xFFFFFFFF80000000
191+
192+
function %sext_sshr_i32(i32, i32) -> i64 {
193+
block0(v0: i32, v1: i32):
194+
v2 = sshr.i32 v0, v1
195+
v3 = sextend.i64 v2
196+
return v3
197+
}
198+
; run: %sext_sshr_i32(0x8000_0000, 0) == 0xFFFFFFFF80000000
199+
; run: %sext_sshr_i32(0x8000_0000, 32) == 0xFFFFFFFF80000000
200+
201+
function %sext_add_const_i32(i32) -> i64 {
202+
block0(v0: i32):
203+
v1 = iconst.i32 -1
204+
v2 = iadd.i32 v0, v1
205+
v3 = sextend.i64 v2
206+
return v3
207+
}
208+
; run: %sext_add_const_i32(0) == -1
209+
210+
function %sext_ishl_const_i32(i32) -> i64 {
211+
block0(v0: i32):
212+
v1 = iconst.i32 31
213+
v2 = ishl.i32 v0, v1
214+
v3 = sextend.i64 v2
215+
return v3
216+
}
217+
; run: %sext_ishl_const_i32(1) == 0xFFFFFFFF80000000
218+
219+
function %sext_ushr_const_i32(i32) -> i64 {
220+
block0(v0: i32):
221+
v1 = iconst.i32 32
222+
v2 = ushr.i32 v0, v1
223+
v3 = sextend.i64 v2
224+
return v3
225+
}
226+
; run: %sext_ushr_const_i32(0x8000_0000) == 0xFFFFFFFF80000000
227+
228+
function %sext_sshr_const_i32(i32) -> i64 {
229+
block0(v0: i32):
230+
v1 = iconst.i32 32
231+
v2 = sshr.i32 v0, v1
232+
v3 = sextend.i64 v2
233+
return v3
234+
}
235+
; run: %sext_sshr_const_i32(0x8000_0000) == 0xFFFFFFFF80000000

0 commit comments

Comments
 (0)