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
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.
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_prefetcht0(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(.SysV) [*]u8;

View file

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

View file

@ -1,7 +1,7 @@
use inkwell::{
attributes::{Attribute, AttributeLoc},
module::Linkage,
types::{BasicType, IntType},
types::{BasicType, BasicTypeEnum, IntType},
values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, InstructionOpcode, IntValue,
PointerValue, StructValue,
@ -287,19 +287,37 @@ pub(crate) fn run_low_level<'a, 'ctx>(
}
}
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)) => {
(int_width.stack_size() as usize > env.target_info.ptr_size())
.then_some(int_width.type_name())
(int_width.type_name(), int_width.stack_size())
}
LayoutRepr::Builtin(Builtin::Decimal) => {
// 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);
call_bitcode_fn_fixing_for_convention(
@ -495,12 +513,18 @@ pub(crate) fn run_low_level<'a, 'ctx>(
use roc_target::OperatingSystem::*;
match env.target_info.operating_system {
Windows => {
let return_type = env.context.struct_type(
&[env.ptr_int().into(), env.context.i32_type().into()],
false,
);
let zig_return_type = env
.module
.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(
env,
@ -508,19 +532,19 @@ pub(crate) fn run_low_level<'a, 'ctx>(
bitcode::STR_GET_SCALAR_UNSAFE,
);
let return_type = basic_type_from_layout(
let roc_return_type = basic_type_from_layout(
env,
layout_interner,
layout_interner.get_repr(layout),
);
let cast_result = env.builder.build_pointer_cast(
result,
return_type.ptr_type(AddressSpace::default()),
roc_return_type.ptr_type(AddressSpace::default()),
"cast",
);
env.builder
.new_build_load(return_type, cast_result, "load_result")
.new_build_load(roc_return_type, cast_result, "load_result")
}
Unix => {
let result = call_str_bitcode_fn(