diff --git a/src/abi/mod.rs b/src/abi/mod.rs
index 64bc9ab6aab..4f8ede9cfbc 100644
--- a/src/abi/mod.rs
+++ b/src/abi/mod.rs
@@ -117,6 +117,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
         returns: Vec<AbiParam>,
         args: &[Value],
     ) -> &[Value] {
+        if self.tcx.sess.target.is_like_windows
+            && params.iter().any(|param| param.value_type == types::I128)
+        {
+            let (params, args): (Vec<_>, Vec<_>) =
+                params
+                    .into_iter()
+                    .zip(args)
+                    .map(|(param, &arg)| {
+                        if param.value_type == types::I128 {
+                            let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot(
+                                StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 },
+                            ));
+                            arg_ptr.store(self, arg, MemFlags::trusted());
+                            (AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
+                        } else {
+                            (param, arg)
+                        }
+                    })
+                    .unzip();
+            return self.lib_call(name, params, returns, &args);
+        }
+
         let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
         let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
         let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
diff --git a/src/cast.rs b/src/cast.rs
index a474acedcb0..8c23152cda7 100644
--- a/src/cast.rs
+++ b/src/cast.rs
@@ -64,29 +64,12 @@ pub(crate) fn clif_int_or_float_cast(
                 },
             );
 
-            if fx.tcx.sess.target.is_like_windows {
-                // FIXME move this logic into lib_call
-                let arg_place = CPlace::new_stack_slot(
-                    fx,
-                    fx.layout_of(if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }),
-                );
-                let arg_ptr = arg_place.to_ptr();
-                arg_ptr.store(fx, from, MemFlags::trusted());
-                let args = [arg_ptr.get_addr(fx)];
-                return fx.lib_call(
-                    &name,
-                    vec![AbiParam::new(fx.pointer_type)],
-                    vec![AbiParam::new(to_ty)],
-                    &args,
-                )[0];
-            } else {
-                return fx.lib_call(
-                    &name,
-                    vec![AbiParam::new(types::I128)],
-                    vec![AbiParam::new(to_ty)],
-                    &[from],
-                )[0];
-            }
+            return fx.lib_call(
+                &name,
+                vec![AbiParam::new(types::I128)],
+                vec![AbiParam::new(to_ty)],
+                &[from],
+            )[0];
         }
 
         // int-like -> float
diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs
index af3356e8213..c2a2ce8ad6a 100644
--- a/src/codegen_i128.rs
+++ b/src/codegen_i128.rs
@@ -32,21 +32,14 @@ pub(crate) fn maybe_codegen<'tcx>(
                 let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
                 if fx.tcx.sess.target.is_like_windows {
                     let ret_place = CPlace::new_stack_slot(fx, lhs.layout());
-                    let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
-                    let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
-                    assert!(lhs_extra.is_none());
-                    assert!(rhs_extra.is_none());
-                    let args = [
-                        ret_place.to_ptr().get_addr(fx),
-                        lhs_ptr.get_addr(fx),
-                        rhs_ptr.get_addr(fx),
-                    ];
+                    let args =
+                        [ret_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
                     fx.lib_call(
                         "__multi3",
                         vec![
                             AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
-                            AbiParam::new(fx.pointer_type),
-                            AbiParam::new(fx.pointer_type),
+                            AbiParam::new(types::I128),
+                            AbiParam::new(types::I128),
                         ],
                         vec![],
                         &args,
@@ -87,29 +80,12 @@ pub(crate) fn maybe_codegen<'tcx>(
             assert!(checked);
             let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
             let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
-            let (param_types, args) = if fx.tcx.sess.target.is_like_windows {
-                let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
-                let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
-                assert!(lhs_extra.is_none());
-                assert!(rhs_extra.is_none());
-                (
-                    vec![
-                        AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
-                        AbiParam::new(fx.pointer_type),
-                        AbiParam::new(fx.pointer_type),
-                    ],
-                    [out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)],
-                )
-            } else {
-                (
-                    vec![
-                        AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
-                        AbiParam::new(types::I128),
-                        AbiParam::new(types::I128),
-                    ],
-                    [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)],
-                )
-            };
+            let param_types = vec![
+                AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
+                AbiParam::new(types::I128),
+                AbiParam::new(types::I128),
+            ];
+            let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
             let name = match (bin_op, is_signed) {
                 (BinOp::Add, false) => "__rust_u128_addo",
                 (BinOp::Add, true) => "__rust_i128_addo",
@@ -132,14 +108,10 @@ pub(crate) fn maybe_codegen<'tcx>(
                 _ => unreachable!(),
             };
             if fx.tcx.sess.target.is_like_windows {
-                let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
-                let (rhs_ptr, rhs_extra) = rhs.force_stack(fx);
-                assert!(lhs_extra.is_none());
-                assert!(rhs_extra.is_none());
-                let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)];
+                let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)];
                 let ret = fx.lib_call(
                     name,
-                    vec![AbiParam::new(fx.pointer_type), AbiParam::new(fx.pointer_type)],
+                    vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
                     vec![AbiParam::new(types::I64X2)],
                     &args,
                 )[0];