llvm: fix atomic widening of packed structs

Additionally, disable failing big-endian atomic test

also improve test paramaters to catch this when condition is removed

also some other cleanups
This commit is contained in:
Kendall Condon 2025-06-27 13:38:54 -04:00 committed by Matthew Lugg
parent 4a1594fbde
commit f7dc9b50ab
2 changed files with 14 additions and 6 deletions

View file

@ -4339,9 +4339,11 @@ pub const Object = struct {
/// types to work around a LLVM deficiency when targeting ARM/AArch64. /// types to work around a LLVM deficiency when targeting ARM/AArch64.
fn getAtomicAbiType(o: *Object, pt: Zcu.PerThread, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type { fn getAtomicAbiType(o: *Object, pt: Zcu.PerThread, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {
const zcu = pt.zcu; const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const int_ty = switch (ty.zigTypeTag(zcu)) { const int_ty = switch (ty.zigTypeTag(zcu)) {
.int => ty, .int => ty,
.@"enum" => ty.intTagType(zcu), .@"enum" => ty.intTagType(zcu),
.@"struct" => Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntTypeUnordered(ip)),
.float => { .float => {
if (!is_rmw_xchg) return .none; if (!is_rmw_xchg) return .none;
return o.builder.intType(@intCast(ty.abiSize(zcu) * 8)); return o.builder.intType(@intCast(ty.abiSize(zcu) * 8));
@ -11424,7 +11426,7 @@ pub const FuncGen = struct {
if (workaround_disable_truncate) { if (workaround_disable_truncate) {
// see https://github.com/llvm/llvm-project/issues/64222 // see https://github.com/llvm/llvm-project/issues/64222
// disable the truncation codepath for larger that 32bits value - with this heuristic, the backend passes the test suite. // disable the truncation codepath for larger than 32bits value - with this heuristic, the backend passes the test suite.
return try fg.wip.load(access_kind, payload_llvm_ty, payload_ptr, payload_alignment, ""); return try fg.wip.load(access_kind, payload_llvm_ty, payload_ptr, payload_alignment, "");
} }

View file

@ -1,7 +1,6 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const expect = std.testing.expect; const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const supports_128_bit_atomics = switch (builtin.cpu.arch) { const supports_128_bit_atomics = switch (builtin.cpu.arch) {
// TODO: Ideally this could be sync'd with the logic in Sema. // TODO: Ideally this could be sync'd with the logic in Sema.
@ -364,25 +363,32 @@ test "atomics with different types" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // #24282
try testAtomicsWithType(bool, true, false); try testAtomicsWithType(bool, true, false);
try testAtomicsWithType(u1, 0, 1); try testAtomicsWithType(u1, 0, 1);
try testAtomicsWithType(i4, 0, 1); try testAtomicsWithType(i4, 2, 1);
try testAtomicsWithType(u5, 0, 1); try testAtomicsWithType(u5, 2, 1);
try testAtomicsWithType(i15, 0, 1); try testAtomicsWithType(i15, 2, 1);
try testAtomicsWithType(u24, 0, 1); try testAtomicsWithType(u24, 2, 1);
try testAtomicsWithType(u0, 0, 0); try testAtomicsWithType(u0, 0, 0);
try testAtomicsWithType(i0, 0, 0); try testAtomicsWithType(i0, 0, 0);
try testAtomicsWithType(enum(u32) { x = 1234, y = 5678 }, .x, .y); try testAtomicsWithType(enum(u32) { x = 1234, y = 5678 }, .x, .y);
try testAtomicsWithType(enum(u19) { x = 1234, y = 5678 }, .x, .y);
try testAtomicsWithPackedStruct( try testAtomicsWithPackedStruct(
packed struct { x: u7, y: u24, z: bool }, packed struct { x: u7, y: u24, z: bool },
.{ .x = 1, .y = 2, .z = true }, .{ .x = 1, .y = 2, .z = true },
.{ .x = 3, .y = 4, .z = false }, .{ .x = 3, .y = 4, .z = false },
); );
try testAtomicsWithPackedStruct(
packed struct { x: u19, y: bool },
.{ .x = 1, .y = true },
.{ .x = 3, .y = false },
);
} }
fn testAtomicsWithType(comptime T: type, a: T, b: T) !void { fn testAtomicsWithType(comptime T: type, a: T, b: T) !void {