riscv64: Add masking for small types when lowering select (#5504)
When lowering `select+icmp` we have an optimization that allows us to avoid materializing the icmp result. We were accidentally not masking the high bits for i8 and i16 in this case. Issue #5498 reported this as an illegal instruction but what was happening there was that the invalid select caused a division by zero.
This commit is contained in:
@@ -615,8 +615,10 @@
|
|||||||
(gen_select ty (truthy_to_reg cty (normalize_cmp_value cty c)) x y))
|
(gen_select ty (truthy_to_reg cty (normalize_cmp_value cty c)) x y))
|
||||||
|
|
||||||
(rule 1
|
(rule 1
|
||||||
(lower (has_type ty (select (icmp cc a b) x y)))
|
(lower (has_type ty (select (icmp cc a b @ (value_type in_ty)) x y)))
|
||||||
(gen_select_reg cc a b x y))
|
(let ((a Reg (normalize_cmp_value in_ty a))
|
||||||
|
(b Reg (normalize_cmp_value in_ty b)))
|
||||||
|
(gen_select_reg cc a b x y)))
|
||||||
|
|
||||||
;;;;; Rules for `bitselect`;;;;;;;;;
|
;;;;; Rules for `bitselect`;;;;;;;;;
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ block0(v0: i8, v1: i64, v2: i64):
|
|||||||
}
|
}
|
||||||
|
|
||||||
; block0:
|
; block0:
|
||||||
; li a3,42
|
; andi a3,a0,255
|
||||||
; select_reg a0,a1,a2##condition=(a0 eq a3)
|
; li a4,42
|
||||||
|
; andi a5,a4,255
|
||||||
|
; select_reg a0,a1,a2##condition=(a3 eq a5)
|
||||||
; ret
|
; ret
|
||||||
|
|
||||||
function %g(i8) -> i8 {
|
function %g(i8) -> i8 {
|
||||||
@@ -62,8 +64,10 @@ block0(v0: i32, v1: i8, v2: i8):
|
|||||||
}
|
}
|
||||||
|
|
||||||
; block0:
|
; block0:
|
||||||
; li a3,42
|
; addiw a3,a0,0
|
||||||
; select_reg a0,a1,a2##condition=(a0 eq a3)
|
; li a4,42
|
||||||
|
; addiw a5,a4,0
|
||||||
|
; select_reg a0,a1,a2##condition=(a3 eq a5)
|
||||||
; ret
|
; ret
|
||||||
|
|
||||||
function %i128_select(i8, i128, i128) -> i128 {
|
function %i128_select(i8, i128, i128) -> i128 {
|
||||||
|
|||||||
18
cranelift/filetests/filetests/runtests/issue-5498.clif
Normal file
18
cranelift/filetests/filetests/runtests/issue-5498.clif
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
test interpret
|
||||||
|
test run
|
||||||
|
target aarch64
|
||||||
|
target s390x
|
||||||
|
target x86_64
|
||||||
|
target riscv64
|
||||||
|
|
||||||
|
function %a(i16, i8) -> i16 {
|
||||||
|
block0(v0: i16, v1: i8):
|
||||||
|
v2 = iconst.i16 0
|
||||||
|
v3 = iconst.i16 1
|
||||||
|
|
||||||
|
v4 = ishl v0, v1
|
||||||
|
v5 = icmp eq v4, v2
|
||||||
|
v6 = select v5, v3, v4
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %a(514, -1) == 1
|
||||||
Reference in New Issue
Block a user