From 8145cb9eca7d1cfb4e88f5278aab59ba94255f31 Mon Sep 17 00:00:00 2001 From: Afonso Bordado Date: Thu, 20 Jun 2024 20:15:23 +0100 Subject: [PATCH] riscv64: Add support for `bitcast.i128` This was accidentally broken in #8692. It turns out bitcasts from i128 to i128 are legal, that PR accidentally reverted that use case. This is now added to a runtest to ensure it works on all platforms. --- cranelift/codegen/src/isa/riscv64/lower.isle | 9 +++++++-- .../filetests/runtests/i128-bitcast.clif | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 cranelift/filetests/filetests/runtests/i128-bitcast.clif diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle index d287e0c7b877..04de11d1f16c 100644 --- a/cranelift/codegen/src/isa/riscv64/lower.isle +++ b/cranelift/codegen/src/isa/riscv64/lower.isle @@ -2465,20 +2465,25 @@ ;; These rules should probably be handled in `gen_bitcast`, but it's convenient to have that return ;; a single register, instead of a `ValueRegs` -(rule 2 (lower (has_type $I128 (bitcast _ v @ (value_type (ty_vec_fits_in_register _))))) +(rule 3 (lower (has_type $I128 (bitcast _ v @ (value_type (ty_vec_fits_in_register _))))) (value_regs (gen_extractlane $I64X2 v 0) (gen_extractlane $I64X2 v 1))) ;; Move the high half into a vector register, and then use vslide1up to move it up and ;; insert the lower half in one instruction. -(rule 1 (lower (has_type (ty_vec_fits_in_register _) (bitcast _ v @ (value_type $I128)))) +(rule 2 (lower (has_type (ty_vec_fits_in_register _) (bitcast _ v @ (value_type $I128)))) (let ((lo XReg (value_regs_get v 0)) (hi XReg (value_regs_get v 1)) (vstate VState (vstate_from_type $I64X2)) (vec VReg (rv_vmv_sx hi vstate))) (rv_vslide1up_vx vec vec lo (unmasked) vstate))) +;; `gen_bitcast` below only works with single register values, so handle I128 +;; specially here. +(rule 1 (lower (has_type $I128 (bitcast _ v @ (value_type $I128)))) + v) + (rule 0 (lower (has_type out_ty (bitcast _ v @ (value_type in_ty)))) (gen_bitcast v in_ty out_ty)) diff --git a/cranelift/filetests/filetests/runtests/i128-bitcast.clif b/cranelift/filetests/filetests/runtests/i128-bitcast.clif new file mode 100644 index 000000000000..2b4cf930c6c6 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-bitcast.clif @@ -0,0 +1,15 @@ +test interpret +test run +set enable_llvm_abi_extensions=true +target aarch64 +target x86_64 +target s390x +target riscv64 +target riscv64 has_c has_zcb + +function %bitcast_i128_i128(i128) -> i128 { +block0(v0: i128): + v1 = bitcast.i128 v0 + return v1 +} +; run: %bitcast_i128_i128(0) == 0