authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-03 14:37:42+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-04 14:17:57+01:00
logbd8ef0036d8d380a753bb88d426f58c059c97f61
tree4240e95673506e4b51fb255b6fd5c769e48a34a3
parent4a3611f7d6837da6a27df22e631838fd60819768

llvm: Use no-builtins attribute instead of nobuiltin.

The former prevents recognizing code patterns and turning them into libcalls, which is what we want for compiler-rt. The latter is meant to be used on call sites to prevent them from being turned into intrinsics. Context: https://github.com/ziglang/zig/issues/21833

1 files changed, 6 insertions(+), 9 deletions(-)

src/codegen/llvm.zig+6-9
...@@ -3242,19 +3242,22 @@ pub const Object = struct {...@@ -3242,19 +3242,22 @@ pub const Object = struct {
3242 if (owner_mod.unwind_tables) {3242 if (owner_mod.unwind_tables) {
3243 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);3243 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
3244 }3244 }
3245 if (comp.skip_linker_dependencies or comp.no_builtin) {3245 const target = owner_mod.resolved_target.result;
3246 if (comp.skip_linker_dependencies or comp.no_builtin or target.cpu.arch.isBpf()) {
3246 // The intent here is for compiler-rt and libc functions to not generate3247 // The intent here is for compiler-rt and libc functions to not generate
3247 // infinite recursion. For example, if we are compiling the memcpy function,3248 // infinite recursion. For example, if we are compiling the memcpy function,
3248 // and llvm detects that the body is equivalent to memcpy, it may replace the3249 // and llvm detects that the body is equivalent to memcpy, it may replace the
3249 // body of memcpy with a call to memcpy, which would then cause a stack3250 // body of memcpy with a call to memcpy, which would then cause a stack
3250 // overflow instead of performing memcpy.3251 // overflow instead of performing memcpy.
3251 try attributes.addFnAttr(.nobuiltin, &o.builder);3252 try attributes.addFnAttr(.{ .string = .{
3253 .kind = try o.builder.string("no-builtins"),
3254 .value = .empty,
3255 } }, &o.builder);
3252 }3256 }
3253 if (owner_mod.optimize_mode == .ReleaseSmall) {3257 if (owner_mod.optimize_mode == .ReleaseSmall) {
3254 try attributes.addFnAttr(.minsize, &o.builder);3258 try attributes.addFnAttr(.minsize, &o.builder);
3255 try attributes.addFnAttr(.optsize, &o.builder);3259 try attributes.addFnAttr(.optsize, &o.builder);
3256 }3260 }
3257 const target = owner_mod.resolved_target.result;
3258 if (target.cpu.model.llvm_name) |s| {3261 if (target.cpu.model.llvm_name) |s| {
3259 try attributes.addFnAttr(.{ .string = .{3262 try attributes.addFnAttr(.{ .string = .{
3260 .kind = try o.builder.string("target-cpu"),3263 .kind = try o.builder.string("target-cpu"),
...@@ -3267,12 +3270,6 @@ pub const Object = struct {...@@ -3267,12 +3270,6 @@ pub const Object = struct {
3267 .value = try o.builder.string(std.mem.span(s)),3270 .value = try o.builder.string(std.mem.span(s)),
3268 } }, &o.builder);3271 } }, &o.builder);
3269 }3272 }
3270 if (target.cpu.arch.isBpf()) {
3271 try attributes.addFnAttr(.{ .string = .{
3272 .kind = try o.builder.string("no-builtins"),
3273 .value = .empty,
3274 } }, &o.builder);
3275 }
3276 if (target.floatAbi() == .soft) {3273 if (target.floatAbi() == .soft) {
3277 // `use-soft-float` means "use software routines for floating point computations". In3274 // `use-soft-float` means "use software routines for floating point computations". In
3278 // other words, it configures how LLVM lowers basic float instructions like `fcmp`,3275 // other words, it configures how LLVM lowers basic float instructions like `fcmp`,