Skip to content

Optimize combined integer compare #2126

Open
@lexaknyazev

Description

@lexaknyazev

Generic case

This function

export function foo(x: i32, a: i32, b: i32): boolean {
  return (x < a) || (x > b);
}

currently yields

  i32.const 1
  local.get $0
  local.get $2
  i32.gt_s
  local.get $0
  local.get $1
  i32.lt_s
  select

A better option with fewer instructions and a shorter stack would probably be:

  local.get $0
  local.get $2
  i32.gt_s
  local.get $0
  local.get $1
  i32.lt_s
  i32.or

Const bounds case

When bounds are const values, the compiler may exploit the integer wrapping to reduce the number of compare instructions.

Outer range check

export function bar(x: i32): boolean {
  return (x < 10) || (x > 100);
}

could be

  local.get $0
  i32.const 10
  i32.sub
  i32.const 90
  i32.gt_u

Inner range check

export function baz(x: i32): boolean {
  return (x > 10) && (x < 100);
}

could be

  local.get $0
  i32.const 11
  i32.sub
  i32.const 89
  i32.lt_u

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions