WebAssembly / WebAssembly/binaryen

local-cse in O3 introduces side-effecting across structurally isolated sub-trees thus prevent const prop & DCE

Open
#7,470 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
WebAssembly
Stars
8.6k
Forks
885
Avg merge
1d 19h
Merged PRs (30d)
69

Description

Given the following code:

(module
  (import "External" "external_function" (func $external_function))
  (func $_start (param $0 i64) (param $1 i32) (param $2 i32) (param $3 i32)
    (local $4 i32) (local $5 i32)
    i32.const 0
    call $foo
    drop
  )
  (func $foo (param $0 i32) (result i32)
    (local $1 i32) (local $2 i32) (local $4 i32) (local $5 i32) (local $scratch i32) (local $3 i64) (local $6 i64)
      i32.const 77986
      i32.load16_u
      i32.const 16
      local.tee $2
      i32.shl
      local.get $2
      i32.shr_s
      i32.const 65533
      i32.eq
      i32.const 77986
      i32.load16_u
      i32.const 16
      i32.shl
      i32.and
      if (result i32)  ;; label = @4
        call $external_function
        i32.const 0
      else
        i32.const 1
      end
    )
  (memory $0 258 258)
  (export "_start" (func $_start)))

wasm-opt (d0d970cb5) eliminates the dead br_if body by -all -O2 but can not do that by -all -O3.

Analysis

Similar but different to #7440, this time wasm-opt in O3 introduces side-effect in more complex structure by local-cse:

The figure below depicts how the local.cse transforms the input:

Image

It introduces the local.tee for less code size, however, it also affects the constant propagation and further blocks the dead code elimination.

Different from #7440, whose solution is simply enhancing the optimization of the binaryOp regardless that the side effects of its children, this issues is more complex because the local-cse does CSE in different depth and sub-tree, is there any code logic which can check or deal with this issue?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the provided WebAssembly module with wasm-opt d0d970cb5 using -all -O2 and -all -O3, then inspect the local-cse transformation and its interaction with constant propagation and dead-code elimination. Compare the resulting optimization trees, focusing on the introduced local.tee across structurally isolated sub-trees. Done means O3 can eliminate the dead branch without introducing an invalid side-effect dependency.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.