atomics A.0b: real seq_cst load/store emission (green)

Replace the A.0a emit bail with real LLVM atomic codegen:
- emitAtomicLoad: LLVMBuildLoad2 + LLVMSetOrdering + LLVMSetAlignment
- emitAtomicStore: LLVMBuildStore + LLVMSetOrdering + LLVMSetAlignment (value
  coerced to the pointee type, mirroring emitStore)
- llvmOrdering: explicit sx AtomicOrdering -> LLVMAtomicOrdering map (LLVM's enum
  is non-contiguous; never an identity cast)

examples/1700 now prints 7/42/43; IR is 'load atomic i64, ptr .. seq_cst, align 8'
+ 'store atomic ..'. Unit test 'emit: atomic load/store (seq_cst, aligned)' locks
the emission shape (load atomic/store atomic/seq_cst/align 8) without a fragile
full-module .ir snapshot. Suite green (710 examples + units).
This commit is contained in:
agra
2026-06-20 09:08:05 +03:00
parent 22af40413d
commit 64c7db5eb1
6 changed files with 98 additions and 22 deletions

View File

@@ -214,6 +214,40 @@ test "emit: alloca, store, load" {
try std.testing.expect(std.mem.indexOf(u8, ir_str, "ret i64") != null);
}
test "emit: atomic load/store (seq_cst, aligned)" {
const alloc = std.testing.allocator;
var module = Module.init(alloc);
defer module.deinit();
var b = Builder.init(&module);
// func f() -> i64 { var x: i64; atomic_store(&x, 10, seq_cst);
// return atomic_load(&x, seq_cst); }
_ = b.beginFunction(str(&module, "f"), &.{}, .i64);
const entry = b.appendBlock(str(&module, "entry"), &.{});
b.switchToBlock(entry);
const x_ptr = b.alloca(.i64);
const ten = b.constInt(10, .i64);
b.emitVoid(.{ .atomic_store = .{ .ptr = x_ptr, .val = ten, .val_ty = .i64, .ordering = .seq_cst } }, .void);
const loaded = b.emit(.{ .atomic_load = .{ .ptr = x_ptr, .ordering = .seq_cst } }, .i64);
b.ret(loaded, .i64);
b.finalize();
var emitter = LLVMEmitter.init(alloc, &module, "test_atomic", .{});
defer emitter.deinit();
emitter.emit();
try std.testing.expect(emitter.verify());
const ir_str = emitter.dumpToString();
// Atomic load/store with seq_cst ordering AND a mandatory alignment.
try std.testing.expect(std.mem.indexOf(u8, ir_str, "load atomic") != null);
try std.testing.expect(std.mem.indexOf(u8, ir_str, "store atomic") != null);
try std.testing.expect(std.mem.indexOf(u8, ir_str, "seq_cst") != null);
try std.testing.expect(std.mem.indexOf(u8, ir_str, "align 8") != null);
}
test "emit: comparison and branch" {
const alloc = std.testing.allocator;
var module = Module.init(alloc);