Skip to content
This repository was archived by the owner on Jul 7, 2022. It is now read-only.

Commit 10cb064

Browse files
committed
fix panic when encountering memcpy, memset, memove intrinsics
when encountering the example below we rewrote the intrinsics name to e.g. "memcpy" but because this string was likely not yet in string table get_extname() asserted. Instead of manually creating the string table entries I decided to start moving to the ExternalName::LibCall functionality. I did not want to introduce an new dependency on cranelift-module (and also didn't want to add the `Box<dyn Fn(ir::LibCall)>` everywhere) so instead I hardcoded the name of the three functions for now. ```llvm define dso_local void @foo(i8* nocapture readonly, i8* nocapture, i8* nocapture, i8* nocapture) local_unnamed_addr { tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %1, i8* align 1 %0, i64 42, i1 false) tail call void @llvm.memmove.p0i8.p0i8.i64(i8* align 1 %2, i8* align 1 %0, i64 42, i1 false) tail call void @llvm.memset.p0i8.i64(i8* align 1 %3, i8 0, i64 42, i1 false) ret void } declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1) ```
1 parent b41c30e commit 10cb064

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

lib/llvm/src/operations.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,13 @@ fn translate_mem_intrinsic(
858858
// start optimizing these libcalls.
859859
let args = [dst_arg, src_arg, len_arg];
860860

861-
let funcname = strings.get_extname(name);
861+
let libcall = match name {
862+
"memcpy" => ir::LibCall::Memcpy,
863+
"memmove" => ir::LibCall::Memmove,
864+
"memset" => ir::LibCall::Memset,
865+
_ => panic!("not handled {}", name)
866+
};
867+
862868
// TODO: Translate the calling convention.
863869
let mut sig = ir::Signature::new(CallConv::SystemV);
864870
sig.params.resize(3, ir::AbiParam::new(pointer_type));
@@ -868,7 +874,7 @@ fn translate_mem_intrinsic(
868874
sig.returns.resize(1, ir::AbiParam::new(pointer_type));
869875
let signature = ctx.builder.import_signature(sig);
870876
let data = ir::ExtFuncData {
871-
name: funcname,
877+
name: ir::ExternalName::LibCall(libcall),
872878
signature,
873879
colocated: false, // TODO: Set the colocated flag based on the visibility.
874880
};

lib/llvm/src/string_table.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ impl StringTable {
2626
.0
2727
.as_str()
2828
}
29+
ir::ExternalName::LibCall(libcall) => {
30+
match libcall {
31+
ir::LibCall::Memcpy => "memcpy",
32+
ir::LibCall::Memmove => "memmove",
33+
ir::LibCall::Memset => "memset",
34+
_ => panic!("unhandled LibCall {}", libcall),
35+
}
36+
}
2937
_ => panic!("non-user names not yet implemented"),
3038
}
3139
}

lib/llvm/src/translate.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,22 @@ pub fn translate_module(
103103
// Collect externally referenced symbols for the module.
104104
for func_ref in func.il.dfg.ext_funcs.keys() {
105105
let name = &func.il.dfg.ext_funcs[func_ref].name;
106-
// If this function is defined inside the module, don't list it
107-
// as an import.
108-
let c_str = ffi::CString::new(result.strings.get_str(name))
109-
.map_err(|err| err.description().to_string())?;
110-
let llvm_str = c_str.as_ptr();
111-
let llvm_func = unsafe { LLVMGetNamedFunction(llvm_mod, llvm_str) };
112-
if llvm_func.is_null() || unsafe { LLVMIsDeclaration(llvm_func) } != 0 {
113-
result.imports.push((name.clone(), SymbolKind::Function));
106+
match name {
107+
ir::ExternalName::User{..} => {
108+
// If this function is defined inside the module, don't list it
109+
// as an import.
110+
let c_str = ffi::CString::new(result.strings.get_str(name))
111+
.map_err(|err| err.description().to_string())?;
112+
let llvm_str = c_str.as_ptr();
113+
let llvm_func = unsafe { LLVMGetNamedFunction(llvm_mod, llvm_str) };
114+
if llvm_func.is_null() || unsafe { LLVMIsDeclaration(llvm_func) } != 0 {
115+
result.imports.push((name.clone(), SymbolKind::Function));
116+
}
117+
}
118+
ir::ExternalName::LibCall{..} => {
119+
result.imports.push((name.clone(), SymbolKind::Function));
120+
}
121+
_ => panic!("unhandled: {}", name)
114122
}
115123
}
116124
for global_var in func.il.global_values.keys() {

0 commit comments

Comments
 (0)