authorgravatar for iknacx@noreply.codeberg.orgIgnacio Ibarra <iknacx@noreply.codeberg.org> 2026-07-29 22:33:30-04:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-02 13:14:27+02:00
log1b7b856a810708ecfc8f78298cdd0a76315e8578
tree5b3109be76fc9b999a52edce09822f9685af9a6b
parent79dc16a0ee9f10b80966611f12fcb56f993778fc

llvm: workaround NVPTX alias restriction on kernel exports

Solves the LLVM error "NVPTX aliasee must be a non-kernel function definition." on nvptx(64) targets, by renaming the llvm global directly to the first export.

1 files changed, 13 insertions(+), 1 deletions(-)

src/codegen/llvm.zig+13-1
...@@ -1506,6 +1506,9 @@ pub const Object = struct {...@@ -1506,6 +1506,9 @@ pub const Object = struct {
1506 variable.setSection(try o.builder.string(section_slice), &o.builder);1506 variable.setSection(try o.builder.string(section_slice), &o.builder);
1507 }1507 }
15081508
1509 const arch = comp.root_mod.resolved_target.result.cpu.arch;
1510 const is_nvptx = arch == .nvptx or arch == .nvptx64;
1511
1509 const llvm_global_ty = llvm_global.typeOf(&o.builder);1512 const llvm_global_ty = llvm_global.typeOf(&o.builder);
15101513
1511 // All exports are represented as aliases to the original global.1514 // All exports are represented as aliases to the original global.
...@@ -1513,7 +1516,7 @@ pub const Object = struct {...@@ -1513,7 +1516,7 @@ pub const Object = struct {
1513 // TODO: we currently do not delete old exports. To do that we'll need to track which1516 // TODO: we currently do not delete old exports. To do that we'll need to track which
1514 // globals actually *are* exports.1517 // globals actually *are* exports.
15151518
1516 for (export_indices) |export_idx| {1519 for (export_indices, 0..) |export_idx, export_i| {
1517 const exp = export_idx.ptr(zcu);1520 const exp = export_idx.ptr(zcu);
1518 const exp_name = try o.builder.strtabString(exp.opts.name.toSlice(ip));1521 const exp_name = try o.builder.strtabString(exp.opts.name.toSlice(ip));
15191522
...@@ -1524,6 +1527,15 @@ pub const Object = struct {...@@ -1524,6 +1527,15 @@ pub const Object = struct {
1524 // The name, aliasee, and type will be set within this block. Other properties of the1527 // The name, aliasee, and type will be set within this block. Other properties of the
1525 // alias will be set below.1528 // alias will be set below.
1526 const alias_global: Builder.Global.Index = global: {1529 const alias_global: Builder.Global.Index = global: {
1530
1531 // WORKAROUND (see https://github.com/llvm/llvm-project/issues/213504)
1532 // LLVM throws "NVPTX aliasee must be a non-kernel function definition"
1533 // if we try to alias a kernel, so we just rename the global directly.
1534 if (is_nvptx and export_i == 0) {
1535 try llvm_global.rename(exp_name, &o.builder);
1536 break :global llvm_global;
1537 }
1538
1527 const existing_global = o.builder.getGlobal(exp_name) orelse {1539 const existing_global = o.builder.getGlobal(exp_name) orelse {
1528 // There is no existing global with this name, so make a new alias.1540 // There is no existing global with this name, so make a new alias.
1529 const alias = try o.builder.addAlias(1541 const alias = try o.builder.addAlias(