diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index b8cef6a7e250e..b800cd792ae31 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1565,9 +1565,17 @@ extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned SrcAlign, LLVMValueRef Size, bool IsVolatile) { - return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), MaybeAlign(DstAlign), - unwrap(Src), MaybeAlign(SrcAlign), - unwrap(Size), IsVolatile)); + if (unwrap(B)->GetInsertBlock()->getParent()->hasFnAttribute("no-builtins") || + unwrap(B)->GetInsertBlock()->getParent()->hasFnAttribute( + "no-builtin-memcpy")) { + return wrap(unwrap(B)->CreateMemCpyInline(unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Src), MaybeAlign(SrcAlign), + unwrap(Size), IsVolatile)); + } else { + return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Src), MaybeAlign(SrcAlign), + unwrap(Size), IsVolatile)); + } } extern "C" LLVMValueRef @@ -1583,8 +1591,16 @@ extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Val, LLVMValueRef Size, bool IsVolatile) { - return wrap(unwrap(B)->CreateMemSet(unwrap(Dst), unwrap(Val), unwrap(Size), - MaybeAlign(DstAlign), IsVolatile)); + if (unwrap(B)->GetInsertBlock()->getParent()->hasFnAttribute("no-builtins") || + unwrap(B)->GetInsertBlock()->getParent()->hasFnAttribute( + "no-builtin-memset")) { + return wrap(unwrap(B)->CreateMemSetInline(unwrap(Dst), MaybeAlign(DstAlign), + unwrap(Val), unwrap(Size), + IsVolatile)); + } else { + return wrap(unwrap(B)->CreateMemSet(unwrap(Dst), unwrap(Val), unwrap(Size), + MaybeAlign(DstAlign), IsVolatile)); + } } // Polyfill for `LLVMBuildCallBr`, which was added in LLVM 19. diff --git a/tests/codegen/no_builtin-mem.rs b/tests/codegen/no_builtin-mem.rs new file mode 100644 index 0000000000000..8b81dcb6fdaf0 --- /dev/null +++ b/tests/codegen/no_builtin-mem.rs @@ -0,0 +1,16 @@ +#![crate_type = "lib"] +#![no_builtins] + +type T = [u8; 256]; + +#[no_mangle] +pub fn f() -> [i32; 1000] { + // CHECK: call void @llvm.memset.inline.{{.*}}(ptr nonnull align 4 %{{.*}}, i8 0, i64 4000, i1 false) + [0; 1000] +} + +#[no_mangle] +pub fn g(x: &[i32; 1000], y: &mut [i32; 1000]) { + // CHECK: call void @llvm.memcpy.inline.{{.*}}(ptr nonnull align 4 %{{.*}}, ptr nonnull align 4 %{{.*}}, i64 4000, i1 false) + *y = *x; +}