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:
Afonso Bordado
2023-01-03 19:59:14 +00:00
committed by GitHub
parent f911855612
commit 7e94704264
3 changed files with 30 additions and 6 deletions

View File

@@ -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`;;;;;;;;;

View File

@@ -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 {

View 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