Skip to content

Commit 063ddbe

Browse files
committed
Add the no-builtins attribute to functions when no_builtins is applied at the crate level.
When `no_builtins` is applied at the crate level, we should add the `no-builtins` attribute to each function to ensure it takes effect in LTO.
1 parent 00a39cc commit 063ddbe

File tree

8 files changed

+67
-1
lines changed

8 files changed

+67
-1
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+4
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ pub fn from_fn_attrs<'ll, 'tcx>(
335335
to_add.extend(probestack_attr(cx));
336336
to_add.extend(stackprotector_attr(cx));
337337

338+
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_BUILTINS) {
339+
to_add.push(llvm::CreateAttrString(cx.llcx, "no-builtins"));
340+
}
341+
338342
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
339343
to_add.push(AttributeKind::Cold.create_attr(cx.llcx));
340344
}

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_ast::{ast, MetaItemKind, NestedMetaItem};
1+
use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
22
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
33
use rustc_errors::struct_span_err;
44
use rustc_hir as hir;
@@ -60,6 +60,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
6060
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
6161
}
6262

63+
// When `no_builtins` is applied at the crate level, we should add the
64+
// `no-builtins` attribute to each function to ensure it takes effect in LTO.
65+
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
66+
let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins);
67+
if no_builtins {
68+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS;
69+
}
70+
6371
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
6472

6573
let mut inline_span = None;

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ bitflags! {
100100
const REALLOCATOR = 1 << 18;
101101
/// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory.
102102
const ALLOCATOR_ZEROED = 1 << 19;
103+
/// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function.
104+
const NO_BUILTINS = 1 << 20;
103105
}
104106
}
105107

tests/codegen/no_builtins-at-crate.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// compile-flags: -C opt-level=1
2+
3+
#![no_builtins]
4+
#![crate_type = "lib"]
5+
6+
// CHECK: define void @__aeabi_memcpy
7+
// CHECK-SAME: #0
8+
#[no_mangle]
9+
pub unsafe extern "C" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, size: usize) {
10+
// CHECK: call
11+
// CHECK-SAME: @memcpy(
12+
memcpy(dest, src, size);
13+
}
14+
15+
// CHECK: declare
16+
// CHECK-SAME: @memcpy
17+
// CHECK-SAME: #0
18+
extern "C" {
19+
pub fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
20+
}
21+
22+
// CHECK: attributes #0
23+
// CHECK-SAME: "no-builtins"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
include ../tools.mk
2+
3+
# We want to check if `no-builtins` is also added to the function declarations in the used crate.
4+
5+
all:
6+
$(RUSTC) no_builtins.rs --emit=link
7+
$(RUSTC) main.rs --emit=llvm-ir
8+
9+
cat "$(TMPDIR)"/main.ll | "$(LLVM_FILECHECK)" filecheck.main.txt
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CHECK: declare void @foo()
2+
CHECK-SAME: #[[ATTR_3:[0-9]+]]
3+
4+
CHECK: attributes #[[ATTR_3]]
5+
CHECK-SAME: no-builtins
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extern crate no_builtins;
2+
3+
#[no_mangle]
4+
fn call_foo() {
5+
no_builtins::foo();
6+
}
7+
8+
fn main() {
9+
call_foo();
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![crate_type = "lib"]
2+
#![no_builtins]
3+
4+
#[no_mangle]
5+
pub fn foo() {}

0 commit comments

Comments
 (0)