From 4e875f33a70cf21e9562e81083ced52771869b5c Mon Sep 17 00:00:00 2001 From: yuyang <96557710+yuyang-ok@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:29:55 +0800 Subject: [PATCH] Codegen fix `fcvt_from_sint.f32 ` with small types on riscv64. (#5964) * fix issue5952 * We should only extend i8 and i16 * remove extra space * move some code --- cranelift/codegen/src/isa/riscv64/inst.isle | 6 ++++ cranelift/codegen/src/isa/riscv64/lower.isle | 4 +-- .../filetests/isa/riscv64/fcvt-small.clif | 28 +++++++++++++------ .../filetests/runtests/issue5952.clif | 14 ++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 cranelift/filetests/filetests/runtests/issue5952.clif diff --git a/cranelift/codegen/src/isa/riscv64/inst.isle b/cranelift/codegen/src/isa/riscv64/inst.isle index 4cee85ed5d..66a0d942af 100644 --- a/cranelift/codegen/src/isa/riscv64/inst.isle +++ b/cranelift/codegen/src/isa/riscv64/inst.isle @@ -1925,6 +1925,12 @@ (rule (normalize_cmp_value $I64 r _) r) (rule (normalize_cmp_value $I128 r _) r) +(decl normalize_fcvt_from_int (ValueRegs Type ExtendOp) ValueRegs) +(rule 2 (normalize_fcvt_from_int r (fits_in_16 ty) op) + (extend r op ty $I64)) +(rule 1 (normalize_fcvt_from_int r _ _) + r) + ;; Convert a truthy value, possibly of more than one register (an ;; I128), to one register. If narrower than 64 bits, must have already ;; been masked (e.g. by `normalize_cmp_value`). diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle index 0a15865e72..163d0cb63a 100644 --- a/cranelift/codegen/src/isa/riscv64/lower.isle +++ b/cranelift/codegen/src/isa/riscv64/lower.isle @@ -802,12 +802,12 @@ ;;;;; Rules for `fcvt_from_sint`;;;;;;;;; (rule (lower (has_type to (fcvt_from_sint v @ (value_type from)))) - (fpu_rr (int_convert_2_float_op from $true to) to v)) + (fpu_rr (int_convert_2_float_op from $true to) to (normalize_fcvt_from_int v from (ExtendOp.Signed)))) ;;;;; Rules for `fcvt_from_uint`;;;;;;;;; (rule (lower (has_type to (fcvt_from_uint v @ (value_type from)))) - (fpu_rr (int_convert_2_float_op from $false to) to v)) + (fpu_rr (int_convert_2_float_op from $false to) to (normalize_fcvt_from_int v from (ExtendOp.Zero)))) ;;;;; Rules for `symbol_value`;;;;;;;;; (rule diff --git a/cranelift/filetests/filetests/isa/riscv64/fcvt-small.clif b/cranelift/filetests/filetests/isa/riscv64/fcvt-small.clif index eb1be56123..e821e120f0 100644 --- a/cranelift/filetests/filetests/isa/riscv64/fcvt-small.clif +++ b/cranelift/filetests/filetests/isa/riscv64/fcvt-small.clif @@ -10,12 +10,14 @@ block0(v0: i8): ; VCode: ; block0: -; fcvt.s.lu fa0,a0 +; andi t2,a0,255 +; fcvt.s.lu fa0,t2 ; ret ; ; Disassembled: ; block0: ; offset 0x0 -; fcvt.s.lu fa0, a0 +; andi t2, a0, 0xff +; fcvt.s.lu fa0, t2 ; ret function u0:0(i8) -> f64 { @@ -26,12 +28,14 @@ block0(v0: i8): ; VCode: ; block0: -; fcvt.d.lu fa0,a0 +; andi t2,a0,255 +; fcvt.d.lu fa0,t2 ; ret ; ; Disassembled: ; block0: ; offset 0x0 -; fcvt.d.lu fa0, a0 +; andi t2, a0, 0xff +; fcvt.d.lu fa0, t2 ; ret function u0:0(i16) -> f32 { @@ -42,12 +46,16 @@ block0(v0: i16): ; VCode: ; block0: -; fcvt.s.lu fa0,a0 +; slli t2,a0,48 +; srli a1,t2,48 +; fcvt.s.lu fa0,a1 ; ret ; ; Disassembled: ; block0: ; offset 0x0 -; fcvt.s.lu fa0, a0 +; slli t2, a0, 0x30 +; srli a1, t2, 0x30 +; fcvt.s.lu fa0, a1 ; ret function u0:0(i16) -> f64 { @@ -58,12 +66,16 @@ block0(v0: i16): ; VCode: ; block0: -; fcvt.d.lu fa0,a0 +; slli t2,a0,48 +; srli a1,t2,48 +; fcvt.d.lu fa0,a1 ; ret ; ; Disassembled: ; block0: ; offset 0x0 -; fcvt.d.lu fa0, a0 +; slli t2, a0, 0x30 +; srli a1, t2, 0x30 +; fcvt.d.lu fa0, a1 ; ret function u0:0(f32) -> i8 { diff --git a/cranelift/filetests/filetests/runtests/issue5952.clif b/cranelift/filetests/filetests/runtests/issue5952.clif new file mode 100644 index 0000000000..64a4a8f399 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/issue5952.clif @@ -0,0 +1,14 @@ +test interpret +test run +target aarch64 +target x86_64 +target s390x +target riscv64 + +function %a(i16 uext) -> f32 { +block0(v0: i16): + v1 = fcvt_from_sint.f32 v0 + return v1 +} + +; run: %a(-12800) == -0x1.900000p13 \ No newline at end of file