Stream: git-wasmtime

Topic: wasmtime / PR #14896 Cranelift: add mid-end opt rules


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

myunbin opened PR #14896 from myunbin:add-rules-261021 to bytecodealliance:main:

Add mid-end optimization rules:

Thanks!

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

myunbin removed the review request for wasmtime-compiler-reviewers from PR #14896.

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

myunbin requested cfallin for a review on PR #14896.

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

myunbin requested wasmtime-compiler-reviewers for a review on PR #14896.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 21 2026 at 03:50):

github-actions[bot] added the label cranelift on PR #14896.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 21 2026 at 03:50):

github-actions[bot] added the label isle on PR #14896.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 21 2026 at 04:51):

github-actions[bot] commented on PR #14896:

Subscribe to Label Action

cc @avanhatt, @cfallin, @fitzgen, @mmcloughlin

<details>
This issue or pull request has been labeled: "cranelift", "isle"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 18:34):

:thumbs_up: cfallin submitted PR review:

Thanks! The new rules look good generally. Just one question below about a possible pessimization.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 18:34):

:speech_balloon: cfallin created PR review comment:

This seems like a regression -- we won't use the native negation instruction anymore but instead will load a zero-constant and do a subtract. Could you look into what's going on here (cost function discrepancies or something else)?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 19:15):

:memo: myunbin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 19:15):

:speech_balloon: myunbin created PR review comment:

@cfallin

I believe it's because of the rule ~x + C → (C - 1) - x.

When C=1, both rules match:

The cost model assigns both candidates as 4: ineg(4) and iconst(1) - isub(3), therefore tie.
Maybe the tie breaker chooses 0 - x afterward.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 19:16):

:speech_balloon: myunbin edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 19:17):

:speech_balloon: myunbin edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 23 2026 at 19:17):

:speech_balloon: myunbin edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 26 2026 at 20:17):

:memo: cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 26 2026 at 20:17):

:speech_balloon: cfallin created PR review comment:

Interesting. Probably we should adjust the cost of ineg: on all CPUs I'm aware of, a unary integer negation operator has the same cost as other ALU ops (1 cycle) so it should win against a const materialization plus an ALU op. Can you bundle that change in here and see if it fixes this regression?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 27 2026 at 02:33):

myunbin updated PR #14896.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 27 2026 at 02:37):

:memo: myunbin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 27 2026 at 02:37):

:speech_balloon: myunbin created PR review comment:

I adjusted ineg to have same cost with other ALU ops. I guess all affected test cases now produce ineg.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 27 2026 at 02:39):

:speech_balloon: myunbin edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 28 2026 at 21:05):

cfallin commented on PR #14896:

@myunbin it looks like there is a verifier failure now -- could you take a look?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 29 2026 at 02:02):

myunbin commented on PR #14896:

@cfallin I found two issues while investigating this failure.

  1. iconst_u spec seems to treat the result as a single integer rather than a splat. For example, the verifier reports: iconst_u({bits: 32, lanes: 4}, 1) -> [1, 0, 0, 0]. A splat would produce [1, 1, 1, 1]. The spec seems to be missing the per-lane semantics for supported vector types. I can investigate more and open a separate PR.

<details>
<summary>log</summary>

isub({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00], [#xff #xff #xff #xff]) -> [#x01 #x01 #x01
#x01]
ineg({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#x00 #x00 #x00 #x00]
bnot({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#xff #xff #xff #xff]
iconst_u({bits: 32, lanes: 4}, #x0000000000000001) -> [#x01 #x00 #x00 #x00]
simplify([#x01 #x01 #x01 #x01]) -> [#x01 #x00 #x00 #x00]
violated: cranelift/codegen/src/spec/opt.isle line 71: e123
violated: cranelift/codegen/src/spec/opt.isle line 20: e167

</details>

  1. I guess rule (rule (simplify (isub ty (ineg ty x) (bnot ty x))) (iconst_u ty 1)) crashes. Currently iconst_u only supports scalar and vec128, but this rule can also match other vector widths, causing a panic. I'll restrict the rule to the supported types for now. Is there a reason the helper's vector support is limited to 128 bits?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 29 2026 at 02:04):

myunbin edited a comment on PR #14896:

@cfallin I found two issues.

  1. iconst_u spec seems to treat the result as a single integer rather than a splat. For example, the verifier reports: iconst_u({bits: 32, lanes: 4}, 1) -> [1, 0, 0, 0]. A splat would produce [1, 1, 1, 1]. The spec seems to be missing the per-lane semantics for supported vector types. I can investigate more and open a separate PR.

<details>
<summary>log</summary>

isub({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00], [#xff #xff #xff #xff]) -> [#x01 #x01 #x01
#x01]
ineg({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#x00 #x00 #x00 #x00]
bnot({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#xff #xff #xff #xff]
iconst_u({bits: 32, lanes: 4}, #x0000000000000001) -> [#x01 #x00 #x00 #x00]
simplify([#x01 #x01 #x01 #x01]) -> [#x01 #x00 #x00 #x00]
violated: cranelift/codegen/src/spec/opt.isle line 71: e123
violated: cranelift/codegen/src/spec/opt.isle line 20: e167

</details>

  1. I guess rule (rule (simplify (isub ty (ineg ty x) (bnot ty x))) (iconst_u ty 1)) crashes. Currently iconst_u only supports scalar and vec128, but this rule can also match other vector widths, causing a panic. I'll restrict the rule to the supported types for now. Is there a reason the helper's vector support is limited to 128 bits?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 29 2026 at 02:04):

myunbin edited a comment on PR #14896:

@cfallin I found two issues.

  1. iconst_u spec seems to treat the result as a single integer rather than a splat. For example, the verifier reports: iconst_u({bits: 32, lanes: 4}, 1) -> [1, 0, 0, 0]. A splat would produce [1, 1, 1, 1]. The spec seems to be missing the per-lane semantics for supported vector types. I can investigate more and open a separate PR.

<details>
<summary>log</summary>

isub({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00], [#xff #xff #xff #xff]) -> [#x01 #x01 #x01
#x01]
ineg({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#x00 #x00 #x00 #x00]
bnot({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#xff #xff #xff #xff]
iconst_u({bits: 32, lanes: 4}, #x0000000000000001) -> [#x01 #x00 #x00 #x00]
simplify([#x01 #x01 #x01 #x01]) -> [#x01 #x00 #x00 #x00]
violated: cranelift/codegen/src/spec/opt.isle line 71: e123
violated: cranelift/codegen/src/spec/opt.isle line 20: e167

</details>

  1. I guess rule (rule (simplify (isub ty (ineg ty x) (bnot ty x))) (iconst_u ty 1)) crashes. Currently iconst_u only supports scalar and vec128, but this rule can also match other vector widths, causing a panic. I'll restrict the rule to the supported types for now. Is there a reason the helper's vector support is limited to 128 bits?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 29 2026 at 02:05):

myunbin edited a comment on PR #14896:

@cfallin I found two issues.

  1. iconst_u spec seems to treat the result as a single integer rather than a splat. For example, the verifier reports: iconst_u({bits: 32, lanes: 4}, 1) -> [1, 0, 0, 0]. A splat would produce [1, 1, 1, 1]. The spec seems to be missing the per-lane semantics for supported vector types. I can investigate more and open a separate PR.

<details>
<summary>log</summary>

isub({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00], [#xff #xff #xff #xff]) -> [#x01 #x01 #x01
#x01]
ineg({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#x00 #x00 #x00 #x00]
bnot({bits: 32, lanes: 4}, [#x00 #x00 #x00 #x00]) -> [#xff #xff #xff #xff]
iconst_u({bits: 32, lanes: 4}, #x0000000000000001) -> [#x01 #x00 #x00 #x00]
simplify([#x01 #x01 #x01 #x01]) -> [#x01 #x00 #x00 #x00]
violated: cranelift/codegen/src/spec/opt.isle line 71: e123
violated: cranelift/codegen/src/spec/opt.isle line 20: e167

</details>

  1. (rule (simplify (isub ty (ineg ty x) (bnot ty x))) (iconst_u ty 1)) crashes. Currently iconst_u only supports scalar and vec128, but this rule can also match other vector widths, causing a panic. I'll restrict the rule to the supported types for now. Is there a reason the helper's vector support is limited to 128 bits?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 29 2026 at 02:14):

myunbin updated PR #14896.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 29 2026 at 02:51):

myunbin updated PR #14896.


Last updated: Oct 31 2026 at 23:03 UTC