diff --git a/packages/compiler/src/backend/llvm/emitter.ts b/packages/compiler/src/backend/llvm/emitter.ts index 8ce49a03d..a15782b31 100644 --- a/packages/compiler/src/backend/llvm/emitter.ts +++ b/packages/compiler/src/backend/llvm/emitter.ts @@ -811,7 +811,14 @@ export class LlEmitter { this.ffiExtendNarrowIntegers = options.wasi === true || ffiExtendsNarrowIntegers(options.targetTriple); this.wasi = options.wasi === true; - this.inlineTrunc = /^(x86_64|amd64)\b/i.test(options.targetTriple ?? ""); + // An empty triple targets the host, as for executableTls below: the + // Node-hosted CLI passes none, the native CLI passes its toolchain's, and + // both must emit the same module for the same target. + this.inlineTrunc = + !this.wasi && + (options.targetTriple + ? /^(x86_64|amd64)\b/i.test(options.targetTriple) + : process.arch === "x64"); this.executableTls = mod.workers === true && mod.lib === undefined && diff --git a/packages/compiler/test/byte-number-emission.test.ts b/packages/compiler/test/byte-number-emission.test.ts index 18c41814e..fc36fd23d 100644 --- a/packages/compiler/test/byte-number-emission.test.ts +++ b/packages/compiler/test/byte-number-emission.test.ts @@ -45,7 +45,8 @@ test("numeric byte pipelines retain checked fallbacks and use field widths on bo expect(wide).toContain("phi i64"); expect(wide).toContain("@llvm.bswap.i64"); const offsets = body(ll, "offsets"); - expect(offsets).toContain("@llvm.trunc.f64"); + // Truncation is the intrinsic, or inline on an x86-64 host (trunc.ts). + expect(offsets).toMatch(/@llvm\.trunc\.f64|@llvm\.copysign\.f64/); expect(offsets).toContain("@scr_dataview_set"); expect(offsets).toContain("@scr_dataview_get"); expect(offsets).toMatch(/icmp ule i(?:32|64)/);