From 68f05aabaf91d5b16c12c2ef8cf8c21927721075 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 15 Jun 2025 09:39:33 -0700 Subject: [PATCH 1/3] riscv64: Consider vstate clobbered on calls This commit fixes an issue in the riscv64 backend where the tracking for the vector state register was only considered clobbered on the entry to basic blocks as opposed to also after call instructions. This updates the vector state upon encountering these instructions to ensure that after a call the vector state is re-updated in case it was changed by the callee. Closes #10951 --- .../codegen/src/isa/riscv64/inst/emit.rs | 10 ++++- .../filetests/runtests/riscv64-vstate.clif | 42 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 cranelift/filetests/filetests/runtests/riscv64-vstate.clif diff --git a/cranelift/codegen/src/isa/riscv64/inst/emit.rs b/cranelift/codegen/src/isa/riscv64/inst/emit.rs index 105334c8c679..2273d6dab971 100644 --- a/cranelift/codegen/src/isa/riscv64/inst/emit.rs +++ b/cranelift/codegen/src/isa/riscv64/inst/emit.rs @@ -64,6 +64,10 @@ impl EmitState { fn take_stack_map(&mut self) -> Option { self.user_stack_map.take() } + + fn clobber_vstate(&mut self) { + self.vstate = EmitVState::Unknown; + } } impl MachInstEmitState for EmitState { @@ -93,7 +97,7 @@ impl MachInstEmitState for EmitState { fn on_new_block(&mut self) { // Reset the vector state. - self.vstate = EmitVState::Unknown; + self.clobber_vstate(); } fn frame_layout(&self) -> &FrameLayout { @@ -395,6 +399,7 @@ impl Inst { if rd.to_reg() == zero_reg() && base != zero_reg() && offset.as_i16() == 0 => { sink.put2(encode_cr2_type(CrOp::CJr, base)); + state.clobber_vstate(); } // c.jalr @@ -402,6 +407,7 @@ impl Inst { if rd.to_reg() == link_reg() && base != zero_reg() && offset.as_i16() == 0 => { sink.put2(encode_cr2_type(CrOp::CJalr, base)); + state.clobber_vstate(); } // c.ebreak @@ -1294,6 +1300,7 @@ impl Inst { sink.use_label_at_offset(*start_off, label, LabelUse::Jal20); sink.add_uncond_branch(*start_off, *start_off + 4, label); sink.put4(0b1101111); + state.clobber_vstate(); } &Inst::CondBr { taken, @@ -1683,6 +1690,7 @@ impl Inst { } &Inst::Jalr { rd, base, offset } => { sink.put4(enc_jalr(rd, base, offset)); + state.clobber_vstate(); } &Inst::EBreak => { sink.put4(0x00100073); diff --git a/cranelift/filetests/filetests/runtests/riscv64-vstate.clif b/cranelift/filetests/filetests/runtests/riscv64-vstate.clif new file mode 100644 index 000000000000..47fc78dd9b29 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/riscv64-vstate.clif @@ -0,0 +1,42 @@ +test interpret +test run +set opt_level=none +set preserve_frame_pointers=true +set enable_multi_ret_implicit_sret=true +target x86_64 +target riscv64 +target s390x +target aarch64 + +function u1:1(i64) -> i64 fast { + ss0 = explicit_slot 32 + ss1 = explicit_slot 32 + const0 = 0xbdea39e5631c0104d92f26de921e6dbf + +block0(v2: i64): + v1 = iconst.i64 -5608073308517523622 + v3 = vconst.f32x4 const0 + stack_store v1, ss0 + stack_store v1, ss0+8 + stack_store v1, ss0+16 + stack_store v1, ss0+24 + stack_store v3, ss1 + stack_store v3, ss1+16 + return v2 +} + +function %main() -> i16x8, f64x2 fast { + sig0 = (i64) -> i64 fast + fn0 = u1:1 sig0 + const0 = 0x00110022003300440055006600770088 + +block0: + v1 = iconst.i64 0x1f96_3ea8_4eb6_5f81 + v11 = vconst.i16x8 const0 + v13 = vconst.f32x4 const0 + v26 = fvpromote_low v13 + v45 = call fn0(v1) + return v11, v26 +} + +; run: %main() == [0x00110022003300440055006600770088, 0x3805401980000000380dc02200000000] From 7c901281e4e8ad46f25f31b5e4ce9cccd36889cd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 15 Jun 2025 09:45:33 -0700 Subject: [PATCH 2/3] Fix some runtests --- cranelift/filetests/filetests/runtests/riscv64-vstate.clif | 3 ++- .../filetests/runtests/scalar-to-vector-upper-bits-zero.clif | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cranelift/filetests/filetests/runtests/riscv64-vstate.clif b/cranelift/filetests/filetests/runtests/riscv64-vstate.clif index 47fc78dd9b29..39a68ab66998 100644 --- a/cranelift/filetests/filetests/runtests/riscv64-vstate.clif +++ b/cranelift/filetests/filetests/runtests/riscv64-vstate.clif @@ -4,9 +4,10 @@ set opt_level=none set preserve_frame_pointers=true set enable_multi_ret_implicit_sret=true target x86_64 -target riscv64 target s390x target aarch64 +target riscv64 has_v +target riscv64 has_v has_c has_zcb function u1:1(i64) -> i64 fast { ss0 = explicit_slot 32 diff --git a/cranelift/filetests/filetests/runtests/scalar-to-vector-upper-bits-zero.clif b/cranelift/filetests/filetests/runtests/scalar-to-vector-upper-bits-zero.clif index 2d431b892368..5e96852e9ad8 100644 --- a/cranelift/filetests/filetests/runtests/scalar-to-vector-upper-bits-zero.clif +++ b/cranelift/filetests/filetests/runtests/scalar-to-vector-upper-bits-zero.clif @@ -10,9 +10,8 @@ target s390x target x86_64 target x86_64 sse42 target x86_64 sse42 has_avx -;; FIXME(#11011 maybe?) this test doesn't work on risc-v -;:target riscv64 has_v -;;target riscv64 has_v has_c has_zcb +target riscv64 has_v +target riscv64 has_v has_c has_zcb function u1:1() -> f64 fast { ss0 = explicit_slot 32 From f403109e980894e37c27ff340cb5a6cfde2ef930 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 15 Jun 2025 09:57:19 -0700 Subject: [PATCH 3/3] Update test expectations --- .../filetests/isa/riscv64/simd-abi-large-spill.clif | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cranelift/filetests/filetests/isa/riscv64/simd-abi-large-spill.clif b/cranelift/filetests/filetests/isa/riscv64/simd-abi-large-spill.clif index bb313c7f166b..d4278ce21732 100644 --- a/cranelift/filetests/filetests/isa/riscv64/simd-abi-large-spill.clif +++ b/cranelift/filetests/filetests/isa/riscv64/simd-abi-large-spill.clif @@ -50,13 +50,14 @@ block0: ; mv s1, a0 ; .byte 0x57, 0x70, 0x84, 0xcc ; auipc t6, 0 -; addi t6, t6, 0x40 +; addi t6, t6, 0x50 ; .byte 0x87, 0xd5, 0x0f, 0x02 ; .byte 0x57, 0x70, 0x08, 0xcc ; .byte 0xa7, 0x05, 0x01, 0x02 ; auipc ra, 0 ; reloc_external RiscvCallPlt u2:0 0 ; jalr ra ; mv a0, s1 +; .byte 0x57, 0x70, 0x08, 0xcc ; .byte 0x87, 0x05, 0x01, 0x02 ; .byte 0xa7, 0x05, 0x05, 0x02 ; ld s1, 0x408(sp) @@ -65,6 +66,9 @@ block0: ; ld s0, 0(sp) ; addi sp, sp, 0x10 ; ret +; .byte 0x00, 0x00, 0x00, 0x00 +; .byte 0x00, 0x00, 0x00, 0x00 +; .byte 0x00, 0x00, 0x00, 0x00 ; .byte 0x02, 0x04, 0x0a, 0x02 ; .byte 0x00, 0x00, 0x00, 0x00 ; .byte 0x00, 0x00, 0x00, 0x00