@@ -4802,7 +4802,7 @@ pub const FuncGen = struct {
48024802 const operand_bits = @intCast (u16 , operand_scalar_ty .bitSize (target ));
48034803 const rt_int_bits = compilerRtIntBits (operand_bits );
48044804 const rt_int_ty = self .context .intType (rt_int_bits );
4805- const extended = e : {
4805+ var extended = e : {
48064806 if (operand_scalar_ty .isSignedInt ()) {
48074807 break :e self .builder .buildSExtOrBitCast (operand , rt_int_ty , "" );
48084808 } else {
@@ -4819,7 +4819,16 @@ pub const FuncGen = struct {
48194819 compiler_rt_operand_abbrev ,
48204820 compiler_rt_dest_abbrev ,
48214821 }) catch unreachable ;
4822- const param_types = [1 ]* const llvm.Type {rt_int_ty };
4822+
4823+ var param_types = [1 ]* const llvm.Type {rt_int_ty };
4824+ if (rt_int_bits == 128 and (target .os .tag == .windows and target .cpu .arch == .x86_64 )) {
4825+ // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
4826+ // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.
4827+ const v2i64 = self .context .intType (64 ).vectorType (2 );
4828+ extended = self .builder .buildBitCast (extended , v2i64 , "" );
4829+ param_types = [1 ]* const llvm.Type {v2i64 };
4830+ }
4831+
48234832 const libc_fn = self .getLibcFunction (fn_name , & param_types , dest_llvm_ty );
48244833 const params = [1 ]* const llvm.Value {extended };
48254834
@@ -4851,7 +4860,12 @@ pub const FuncGen = struct {
48514860 }
48524861
48534862 const rt_int_bits = compilerRtIntBits (@intCast (u16 , dest_scalar_ty .bitSize (target )));
4854- const libc_ret_ty = self .context .intType (rt_int_bits );
4863+ const ret_ty = self .context .intType (rt_int_bits );
4864+ const libc_ret_ty = if (rt_int_bits == 128 and (target .os .tag == .windows and target .cpu .arch == .x86_64 )) b : {
4865+ // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
4866+ // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.
4867+ break :b self .context .intType (64 ).vectorType (2 );
4868+ } else ret_ty ;
48554869
48564870 const operand_bits = operand_scalar_ty .floatBits (target );
48574871 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev (operand_bits );
@@ -4871,13 +4885,11 @@ pub const FuncGen = struct {
48714885 const libc_fn = self .getLibcFunction (fn_name , & param_types , libc_ret_ty );
48724886 const params = [1 ]* const llvm.Value {operand };
48734887
4874- const result = self .builder .buildCall (libc_fn , & params , params .len , .C , .Auto , "" );
4875-
4876- if (libc_ret_ty == dest_llvm_ty ) {
4877- return result ;
4878- }
4888+ var result = self .builder .buildCall (libc_fn , & params , params .len , .C , .Auto , "" );
48794889
4880- return self .builder .buildTrunc (result , dest_llvm_ty , "" );
4890+ if (libc_ret_ty != ret_ty ) result = self .builder .buildBitCast (result , ret_ty , "" );
4891+ if (ret_ty != dest_llvm_ty ) result = self .builder .buildTrunc (result , dest_llvm_ty , "" );
4892+ return result ;
48814893 }
48824894
48834895 fn airSliceField (self : * FuncGen , inst : Air.Inst.Index , index : c_uint ) ! ? * const llvm.Value {
@@ -6490,8 +6502,15 @@ pub const FuncGen = struct {
64906502 const one = int_llvm_ty .constInt (1 , .False );
64916503 const shift_amt = int_llvm_ty .constInt (float_bits - 1 , .False );
64926504 const sign_mask = one .constShl (shift_amt );
6493- const bitcasted_operand = self .builder .buildBitCast (params [0 ], int_llvm_ty , "" );
6494- const result = self .builder .buildXor (bitcasted_operand , sign_mask , "" );
6505+ const result = if (ty .zigTypeTag () == .Vector ) blk : {
6506+ const splat_sign_mask = self .builder .buildVectorSplat (ty .vectorLen (), sign_mask , "" );
6507+ const cast_ty = int_llvm_ty .vectorType (ty .vectorLen ());
6508+ const bitcasted_operand = self .builder .buildBitCast (params [0 ], cast_ty , "" );
6509+ break :blk self .builder .buildXor (bitcasted_operand , splat_sign_mask , "" );
6510+ } else blk : {
6511+ const bitcasted_operand = self .builder .buildBitCast (params [0 ], int_llvm_ty , "" );
6512+ break :blk self .builder .buildXor (bitcasted_operand , sign_mask , "" );
6513+ };
64956514 return self .builder .buildBitCast (result , llvm_ty , "" );
64966515 },
64976516 .add , .sub , .div , .mul = > FloatOpStrat {
0 commit comments