diff --git a/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts b/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts index 3d21a8f82..f33aefbf6 100644 --- a/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts +++ b/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts @@ -258,3 +258,21 @@ test("Float16Array accesses version in elements and share the element tag", () = // The checked copy keeps its per-element tests. expect(body.slice(0, body.indexOf(fast))).toContain("bytes.index.invalid"); }); + +test("bodies compiled without optimization keep one checked loop", () => { + const loop = counted([set(ref("out", f64s), ref("i"), get(ref("src", f64s), ref("i")))]); + const boxes = Array.from({ length: 512 }, (_, k) => local(`box${k}`, F64, true, { boxed: true })); + const mod: IrModule = { + irVersion: 16, + sourceFile: loc.file, + entry: "__main", + functions: [ + { name: "__main", params: [], returnType: VOID, locals: [], body: [], loc }, + fn([loop], boxes), + ], + }; + const body = /^define internal [^\n]*@sc_bf_kernel[^]*?^}/m.exec(emitLlvmModule(mod))![0]; + expect(body.split("\n", 1)[0]).toContain("optnone"); + expect(body).not.toContain("bytes.version"); + expect(body).toContain("bytes.index.invalid"); +}); diff --git a/packages/compiler/src/backend/llvm/emitter.ts b/packages/compiler/src/backend/llvm/emitter.ts index a567a23b3..ad179bde4 100644 --- a/packages/compiler/src/backend/llvm/emitter.ts +++ b/packages/compiler/src/backend/llvm/emitter.ts @@ -6995,6 +6995,8 @@ export class LlEmitter { for (const local of this.currentLocals.values()) if (local.boxed || this.captureIds.has(local.id)) slots.add(`%${mangleLocal(local.id)}`); B.volatileSlots = slots; + // Without optimization a versioned copy only adds code. + this.bytesLoopVersionsEnabled = false; } // Captured bindings come in through the environment — borrowed for the // whole call (the closure owns them): bound here, never released here.