// #target: macos-x64 module test; struct Foo { int[] x; } macro int Foo.@operator_element_at(&foo, usz index) @operator([]) { return foo.x[index]; } macro usz Foo.@operator_len(&foo) @operator(len) { return foo.x.len; } fn void main() { int[*] i = { 1, 3, 10 }; Foo x = { &i }; foreach_r FOO: (int f : x) { printf("%d\n", f); while (1) { break FOO; } } } extern fn int printf(char *fmt, ...); /* #expect: test.ll define void @test.main() #0 { entry: %i = alloca [3 x i32], align 4 %x = alloca %Foo, align 8 %.anon = alloca i64, align 8 %f = alloca i32, align 4 %index = alloca i64, align 8 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %i, ptr align 4 @.__const, i32 12, i1 false) %0 = insertvalue %"int[]" undef, ptr %i, 0 %1 = insertvalue %"int[]" %0, i64 3, 1 store %"int[]" %1, ptr %x, align 8 %neq = icmp ne ptr %x, null call void @llvm.assume(i1 %neq) %ptradd = getelementptr inbounds i8, ptr %x, i64 8 %2 = load i64, ptr %ptradd, align 8 store i64 %2, ptr %.anon, align 8 br label %loop.cond loop.cond: ; preds = %entry %3 = load i64, ptr %.anon, align 8 %gt = icmp ugt i64 %3, 0 br i1 %gt, label %loop.body, label %loop.exit loop.body: ; preds = %loop.cond %4 = load i64, ptr %.anon, align 8 %subnuw = sub nuw i64 %4, 1 store i64 %subnuw, ptr %.anon, align 8 %5 = load i64, ptr %.anon, align 8 store i64 %5, ptr %index, align 8 %neq1 = icmp ne ptr %x, null call void @llvm.assume(i1 %neq1) %6 = load ptr, ptr %x, align 8 %7 = load i64, ptr %index, align 8 %ptroffset = getelementptr inbounds [4 x i8], ptr %6, i64 %7 %8 = load i32, ptr %ptroffset, align 4 store i32 %8, ptr %f, align 4 %9 = load i32, ptr %f, align 4 %10 = call i32 (ptr, ...) @printf(ptr @.str, i32 %9) br label %loop.body2 loop.body2: ; preds = %loop.body br label %loop.exit loop.exit: ; preds = %loop.body2, %loop.cond ret void }