Merge pull request #5799 from roc-lang/luke-windows-changes

fix  memcpy on windows
This commit is contained in:
Luke Boswell 2023-09-13 05:31:58 +10:00 committed by GitHub
commit 9507c527c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 21 deletions

View file

@ -59,6 +59,11 @@ jobs:
- name: Test setjmp/longjmp logic - name: Test setjmp/longjmp logic
run: cargo test-gen-dev --locked --release nat_alias && cargo test-gen-dev --locked --release a_crash run: cargo test-gen-dev --locked --release nat_alias && cargo test-gen-dev --locked --release a_crash
- name: Run gen tests
run: cargo test-gen-llvm --locked --release gen_str
- name: Actually run the tests. - name: Actually run the tests.
run: cargo test --locked --release -p roc_ident -p roc_region -p roc_collections -p roc_can -p roc_types -p roc_solve -p roc_mono -p roc_gen_dev -p roc_gen_wasm -p roc_serialize -p roc_linker -p roc_cli run: cargo test --locked --release -p roc_ident -p roc_region -p roc_collections -p roc_can -p roc_types -p roc_solve -p roc_mono -p roc_gen_dev -p roc_gen_wasm -p roc_serialize -p roc_linker -p roc_cli

View file

@ -14,5 +14,5 @@ comptime {
} }
} }
pub extern fn __folly_memcpy_prefetchw(noalias dest: [*]u8, noalias src: [*]const u8, len: usize) callconv(.C) [*]u8; pub extern fn __folly_memcpy_prefetchw(noalias dest: [*]u8, noalias src: [*]const u8, len: usize) callconv(.SysV) [*]u8;
pub extern fn __folly_memcpy_prefetcht0(noalias dest: [*]u8, noalias src: [*]const u8, len: usize) callconv(.C) [*]u8; pub extern fn __folly_memcpy_prefetcht0(noalias dest: [*]u8, noalias src: [*]const u8, len: usize) callconv(.SysV) [*]u8;

View file

@ -61,6 +61,13 @@ impl FloatWidth {
_ => None, _ => None,
} }
} }
pub const fn type_name(&self) -> &'static str {
match self {
Self::F32 => "f32",
Self::F64 => "f64",
}
}
} }
#[repr(u8)] #[repr(u8)]

View file

@ -1,7 +1,7 @@
use inkwell::{ use inkwell::{
attributes::{Attribute, AttributeLoc}, attributes::{Attribute, AttributeLoc},
module::Linkage, module::Linkage,
types::{BasicType, IntType}, types::{BasicType, BasicTypeEnum, IntType},
values::{ values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionOpcode, IntValue, BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionOpcode, IntValue,
PointerValue, StructValue, PointerValue, StructValue,
@ -287,19 +287,37 @@ pub(crate) fn run_low_level<'a, 'ctx>(
} }
} }
PtrWidth::Bytes8 => { PtrWidth::Bytes8 => {
let cc_return_by_pointer = match layout_interner.get_repr(number_layout) { let (type_name, width) = {
match layout_interner.get_repr(number_layout) {
LayoutRepr::Builtin(Builtin::Int(int_width)) => { LayoutRepr::Builtin(Builtin::Int(int_width)) => {
(int_width.stack_size() as usize > env.target_info.ptr_size()) (int_width.type_name(), int_width.stack_size())
.then_some(int_width.type_name())
} }
LayoutRepr::Builtin(Builtin::Decimal) => { LayoutRepr::Builtin(Builtin::Decimal) => {
// zig picks 128 for dec.RocDec // zig picks 128 for dec.RocDec
Some("i128") ("i128", 16)
}
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
(float_width.type_name(), float_width.stack_size())
}
_ => {
unreachable!("other layout types are non-numeric")
}
} }
_ => None,
}; };
if let Some(type_name) = cc_return_by_pointer { use roc_target::OperatingSystem::*;
let cc_return_by_pointer = match env.target_info.operating_system {
Windows => {
// there is just one return register on Windows
(width + 1) as usize > env.target_info.ptr_size()
}
_ => {
// on other systems we have two return registers
(width + 1) as usize > 2 * env.target_info.ptr_size()
}
};
if cc_return_by_pointer {
let bitcode_return_type = zig_num_parse_result_type(env, type_name); let bitcode_return_type = zig_num_parse_result_type(env, type_name);
call_bitcode_fn_fixing_for_convention( call_bitcode_fn_fixing_for_convention(
@ -495,12 +513,18 @@ pub(crate) fn run_low_level<'a, 'ctx>(
use roc_target::OperatingSystem::*; use roc_target::OperatingSystem::*;
match env.target_info.operating_system { match env.target_info.operating_system {
Windows => { Windows => {
let return_type = env.context.struct_type( let zig_return_type = env
&[env.ptr_int().into(), env.context.i32_type().into()], .module
false, .get_function(bitcode::STR_GET_SCALAR_UNSAFE)
); .unwrap()
.get_type()
.get_param_types()[0]
.into_pointer_type()
.get_element_type();
let result = env.builder.build_alloca(return_type, "result"); let result = env
.builder
.build_alloca(BasicTypeEnum::try_from(zig_return_type).unwrap(), "result");
call_void_bitcode_fn( call_void_bitcode_fn(
env, env,
@ -508,19 +532,19 @@ pub(crate) fn run_low_level<'a, 'ctx>(
bitcode::STR_GET_SCALAR_UNSAFE, bitcode::STR_GET_SCALAR_UNSAFE,
); );
let return_type = basic_type_from_layout( let roc_return_type = basic_type_from_layout(
env, env,
layout_interner, layout_interner,
layout_interner.get_repr(layout), layout_interner.get_repr(layout),
); );
let cast_result = env.builder.build_pointer_cast( let cast_result = env.builder.build_pointer_cast(
result, result,
return_type.ptr_type(AddressSpace::default()), roc_return_type.ptr_type(AddressSpace::default()),
"cast", "cast",
); );
env.builder env.builder
.new_build_load(return_type, cast_result, "load_result") .new_build_load(roc_return_type, cast_result, "load_result")
} }
Unix => { Unix => {
let result = call_str_bitcode_fn( let result = call_str_bitcode_fn(