Stream: git-wasmtime

Topic: wasmtime / issue #14716 Cranelift: x64: branch on flags f...


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

vamsi3 opened issue #14716:

Feature

On x64, a brif on the overflow result of uadd_overflow jumps straight on the flags set by the add. The other three overflow ops don't get this: the overflow bit goes through setcc and test first.

function %f(i32, i32) -> i32 {
block0(v0: i32, v1: i32):
  v2, v3 = usub_overflow v0, v1
  brif v3, block1, block2
block1:
  v4 = iadd v2, v0
  return v4
block2:
  v5 = iconst.i32 2
  return v5
}

Currently:

subl    %esi, %r8d
setb    %r9b
testb   %r9b, %r9b
jne     ...

Could be:

subl    %esi, %r8d
jb      ...

Benefit

Two fewer instructions and one less register for every checked subtraction or signed add that branches on overflow, which is the usual pattern for languages with checked arithmetic.

Implementation

Same shape as the existing uadd_overflow rules: an is_nonzero rule in inst.isle that reuses the flags (CC.B for usub_overflow, CC.O for the signed ops), and a lower rule so the setcc isn't emitted when nothing else uses the overflow result. Up to 64 bits only, like uadd_overflow.

I'll open a PR for this shortly and link it here.

Alternatives

The setcc/test pair only appears after lowering, so the mid-end can't remove it.

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

alexcrichton added the cranelift:goal:optimize-speed label to Issue #14716.

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

alexcrichton added the cranelift:area:x64 label to Issue #14716.

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

alexcrichton removed the cranelift:goal:optimize-speed label from Issue #14716.

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

alexcrichton added the cranelift label to Issue #14716.

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

alexcrichton added the cranelift:goal:optimize-speed label to Issue #14716.

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

alexcrichton removed the cranelift:area:x64 label from Issue #14716.

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

alexcrichton removed the cranelift label from Issue #14716.

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

alexcrichton added the cranelift:area:x64 label to Issue #14716.

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

alexcrichton added the cranelift label to Issue #14716.

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

cfallin closed issue #14716:

Feature

On x64, a brif on the overflow result of uadd_overflow jumps straight on the flags set by the add. The other three overflow ops don't get this: the overflow bit goes through setcc and test first.

function %f(i32, i32) -> i32 {
block0(v0: i32, v1: i32):
  v2, v3 = usub_overflow v0, v1
  brif v3, block1, block2
block1:
  v4 = iadd v2, v0
  return v4
block2:
  v5 = iconst.i32 2
  return v5
}

Currently:

subl    %esi, %r8d
setb    %r9b
testb   %r9b, %r9b
jne     ...

Could be:

subl    %esi, %r8d
jb      ...

Benefit

Two fewer instructions and one less register for every checked subtraction or signed add that branches on overflow, which is the usual pattern for languages with checked arithmetic.

Implementation

Same shape as the existing uadd_overflow rules: an is_nonzero rule in inst.isle that reuses the flags (CC.B for usub_overflow, CC.O for the signed ops), and a lower rule so the setcc isn't emitted when nothing else uses the overflow result. Up to 64 bits only, like uadd_overflow.

I'll open a PR for this shortly and link it here.

Alternatives

The setcc/test pair only appears after lowering, so the mid-end can't remove it.


Last updated: Oct 31 2026 at 23:03 UTC