Stream: git-wasmtime

Topic: wasmtime / issue #12911 How should CLIF `*_imm` instructi...


view this post on Zulip Wasmtime GitHub notifications bot (Mar 31 2026 at 17:29):

alexcrichton opened issue #12911:

Currently CLIF allows instructions such as iadd_imm.i128 v0, 100. The immediate is limited to 64-bits, however. During legalization the *_imm instructions are replaced with constant+op, and there's a list of whether i128 immediates are sign or zero extended. Currently though it's a bit arbitrary as to which instructions are sign-extended (iadd, irsub, imul, sdiv, srem) and which aren't (bor, band, ...).

Personally I'd say that in both situations the desired 128-bit immediate could be either zero or sign extended so it's not necessarily always correct to infer from the instruction itself.

Should CLIF always sign extend? Always zero extend? Disallow the 128-bit type with these instructions?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 31 2026 at 17:29):

alexcrichton added the cranelift:area:clif label to Issue #12911.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 31 2026 at 19:21):

cfallin commented on issue #12911:

Wow, that's interesting -- first let's talk about sign extension in the linked code in general. It looks like the sign-extension behavior goes back to #4602, which I even reviewed+approved at the time. In hindsight with the additional discussions we've had about constants and signedness I think it would be good to simplify this and remove as much magic/surprising behavior as possible.

In particular it seems that the *_imm instructions (e.g. iadd_imm) take an imm64 immediate, which is defined so that the InstructionData directly contains an ir::immediates::Imm64. I would expect legalization to directly split apart the opcode/arg and immediate and carry that Imm64 through blindly to an iconst, no more, no less -- anything else is a surprising and out-of-place behavior for a mechanical substitution.

So if we take that approach, where op_imm is mechanically equivalent to op + iconst, then I'd expect the defined/allowable types for op_imm to follow those of iconst. The latter is defined to operate on NarrowInt, or in other words, only up to 64 bits. So the simple answer to this question (IMHO) is "inapplicable: iadd_imm and friends should not operate on i128".

Whether this affects any embedders is a separate question (cc @bjorn3?) but IMHO, clarity in IR definition is the high-order bit here.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 01 2026 at 09:09):

bjorn3 commented on issue #12911:

I believe the only places in cg_clif where I use an *_imm instruction with an i128 are icmp_imm eq val, 0 where sign doesn't matter.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 01 2026 at 16:13):

alexcrichton commented on issue #12911:

Conclusion from today's Cranelift meeting: it's probably best to go ahead and just jettison the *_imm instructions entirely and to delegate these helpers to frontend helpers which would sidestep this question entirely.


Last updated: Apr 12 2026 at 23:10 UTC