Skip to content

Optimize comparisons of adjusted values #5008

Open

Description

@kripken

E.g.

  (i32.gt_u
   (i32.shr_u
    (local.get $0)
    (i32.const 1)
   )
   (i32.const 100)
  )
 =->
  (i32.gt_u
   (local.get $0)
   (i32.const 201)
  )

Instead of dividing by 2 and then comparing, we can compare the original value.

More variations: add a constant, or both add and multiply/divide.

Found by the superoptimizer #4994 (for comparison to other findings: rule #8, benefit 30492).

Activity

  1. kripken commented on Sep 2, 2022

    @kripken
    MemberAuthor

    Another example from rule #10:

    (i32.lt_s
     (i32.shr_s
      (local.get $0)
      (i32.const 1)
     )
     (i32.const 12)
    )
     =->
    (i32.lt_s
     (local.get $0)
     (i32.const 24)
    )
  2. kripken commented on Sep 2, 2022

    @kripken
    MemberAuthor

    This also happens with floats, though there we may need fast-math, e.g.

    (f32.ge
     (f32.add
      (local.get $0)
      (f32.const -9.99999993922529e-09)
     )
     (f32.const 0)
    )
     =->
    (f32.gt
     (local.get $0)
     (f32.const 9.99999905104687e-09)
    )

    (rule #21)

  3. kripken commented on Sep 6, 2022

    @kripken
    MemberAuthor

    Another example:

     (i32.gt_u
      (i32.add
       (i32.shr_u
        (local.get $0)
        (i32.const 1)
       )
       (i32.const 8)
      )
      (i32.const 65535)
     )

    The add's left operand is less than 32 bits, so it cannot overflow even with an added 8, and so x + 8 >= 65535 can be turned into x >= 65527.

    edit: This and related things seem to be the top superoptimizer finding for Java and Dart, followed by #5008 (comment)

  4. self-assigned this
    on Sep 9, 2022
  5. kripken commented on Sep 13, 2022

    @kripken
    MemberAuthor

    All comparisons <, >=, etc should be handled with +. That leaves things like shifts, and float operations, as mentioned above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions