authorgravatar for mattnite@proton.meMatthew Knight <mattnite@proton.me> 2026-07-22 20:23:36+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-07-22 20:23:36+02:00
logcad234174ae7ae990ebc526b6fcd92d18516e3c1
tree5d9d734257766db53e38094feff90c50e9f28898
parentaad9870a284410b9b7fa4d5c5d84f4a4d697c71b

llvm: fix address space of global aliases

#32108 contains my process for root causing this issue. In short, while the LLVM language does not associate aliases with address spaces, the address space does get serialized alongside the alias, and that value was hardcoded to `.default`, and the error observed was from a failed sanity check. I added an assertion on the serialization side and observed it get hit, showing the difference in address space. I followed that up with a patch to grab the address space from the aliasee instead of hardcoding it. The AVR repro now compiles: ```zig export fn anything() void {} ``` Fixes: https://codeberg.org/ziglang/zig/issues/32108 Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36146

2 files changed, 10 insertions(+), 3 deletions(-)

lib/std/zig/llvm/Builder.zig+4-1
...@@ -13955,8 +13955,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco...@@ -13955,8 +13955,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
13955 }13955 }
1395613956
13957 const strtab = alias.global.strtab(self);13957 const strtab = alias.global.strtab(self);
13958
13959 const global = alias.global.ptrConst(self);13958 const global = alias.global.ptrConst(self);
13959
13960 // LLVM requires the types to match
13961 assert(global.addr_space == alias.aliasee.typeOf(self).pointerAddrSpace(self));
13962
13960 try module_block.writeAbbrev(ModuleBlock.Alias{13963 try module_block.writeAbbrev(ModuleBlock.Alias{
13961 .strtab_offset = strtab.offset,13964 .strtab_offset = strtab.offset,
13962 .strtab_size = strtab.size,13965 .strtab_size = strtab.size,
src/codegen/llvm.zig+6-2
...@@ -1661,7 +1661,7 @@ pub const Object = struct {...@@ -1661,7 +1661,7 @@ pub const Object = struct {
1661 const alias = try o.builder.addAlias(1661 const alias = try o.builder.addAlias(
1662 exp_name,1662 exp_name,
1663 llvm_global_ty,1663 llvm_global_ty,
1664 .default,1664 global_index.ptrConst(&o.builder).addr_space,
1665 global_index.toConst(),1665 global_index.toConst(),
1666 );1666 );
1667 break :global alias.ptrConst(&o.builder).global;1667 break :global alias.ptrConst(&o.builder).global;
...@@ -1673,6 +1673,10 @@ pub const Object = struct {...@@ -1673,6 +1673,10 @@ pub const Object = struct {
1673 // We can just repurpose the existing alias.1673 // We can just repurpose the existing alias.
1674 alias.setAliasee(global_index.toConst(), &o.builder);1674 alias.setAliasee(global_index.toConst(), &o.builder);
1675 alias.ptrConst(&o.builder).global.ptr(&o.builder).type = global_index.typeOf(&o.builder);1675 alias.ptrConst(&o.builder).global.ptr(&o.builder).type = global_index.typeOf(&o.builder);
1676 // If the type the alias is pointing to can change, then
1677 // it makes sense that we should update the address
1678 // space too.
1679 alias.ptrConst(&o.builder).global.ptr(&o.builder).addr_space = global_index.ptrConst(&o.builder).addr_space;
1676 break :global existing_global;1680 break :global existing_global;
1677 },1681 },
1678 .variable, .function => {1682 .variable, .function => {
...@@ -1687,7 +1691,7 @@ pub const Object = struct {...@@ -1687,7 +1691,7 @@ pub const Object = struct {
1687 const alias = try o.builder.addAlias(1691 const alias = try o.builder.addAlias(
1688 exp_name,1692 exp_name,
1689 llvm_global_ty,1693 llvm_global_ty,
1690 .default,1694 global_index.ptrConst(&o.builder).addr_space,
1691 global_index.toConst(),1695 global_index.toConst(),
1692 );1696 );
1693 break :global alias.ptrConst(&o.builder).global;1697 break :global alias.ptrConst(&o.builder).global;