about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbeetrees <b@beetr.ee>2025-05-23 15:51:51 +0100
committerbeetrees <b@beetr.ee>2025-05-23 15:51:51 +0100
commitdcd3168c97c6024b24f80abbb2407c81d9b0a25a (patch)
tree54feeb0fe1c19cf9a301f4b115900e5c0ef4cc55
parent3ab6af049bb84a6e107851ecf333512b0d4562eb (diff)
downloadrust-dcd3168c97c6024b24f80abbb2407c81d9b0a25a.tar.gz
rust-dcd3168c97c6024b24f80abbb2407c81d9b0a25a.zip
Use correct sign extension on `__powi*f2` arguments
-rw-r--r--src/abi/mod.rs28
-rw-r--r--src/intrinsics/mod.rs3
2 files changed, 30 insertions, 1 deletions
diff --git a/src/abi/mod.rs b/src/abi/mod.rs
index 70d29596e22..5f7bf3821d7 100644
--- a/src/abi/mod.rs
+++ b/src/abi/mod.rs
@@ -828,3 +828,31 @@ pub(crate) fn codegen_drop<'tcx>(
         }
     }
 }
+
+pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam {
+    let param = AbiParam::new(ty);
+    if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size.bits() {
+        match (&*tcx.sess.target.arch, &*tcx.sess.target.vendor) {
+            ("x86_64", _) | ("aarch64", "apple") => match (ty, is_signed) {
+                (types::I8 | types::I16, true) => param.sext(),
+                (types::I8 | types::I16, false) => param.uext(),
+                _ => param,
+            },
+            ("aarch64", _) => param,
+            ("riscv64", _) => match (ty, is_signed) {
+                (types::I32, _) | (_, true) => param.sext(),
+                _ => param.uext(),
+            },
+            ("s390x", _) => {
+                if is_signed {
+                    param.sext()
+                } else {
+                    param.uext()
+                }
+            }
+            _ => unimplemented!("{:?}", tcx.sess.target.arch),
+        }
+    } else {
+        param
+    }
+}
diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs
index 25e224ebfe2..7c18922d93c 100644
--- a/src/intrinsics/mod.rs
+++ b/src/intrinsics/mod.rs
@@ -416,7 +416,8 @@ fn codegen_float_intrinsic_call<'tcx>(
         // These intrinsics aren't supported natively by Cranelift.
         // Lower them to a libcall.
         sym::powif32 | sym::powif64 => {
-            let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), AbiParam::new(types::I32)];
+            let input_tys: Vec<_> =
+                vec![AbiParam::new(clif_ty), lib_call_arg_param(fx.tcx, types::I32, true)];
             let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0];
             CValue::by_val(ret_val, fx.layout_of(ty))
         }