Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

OptimizeInstructions: `--tnh` makes `ref.cast` non-nullable before a possibly infinite loop

Aperta
#9,246 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
cpp, wasm
Ambito
compilers

Direzione di ricerca

The check is in src/passes/OptimizeInstructions.cpp around lines 1843-1853, where a ref.cast is made non-nullable when a later sibling transfersControlFlow(). Read the effects code for mayNotReturn and how loops are marked after #5711. Run the reproducer with --traps-never-happen to see the cast turn into ref.cast (ref $S). Done when a sibling that may not return keeps the nullable cast, and the existing tests still pass.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Reproducer

(module
 (type $S (struct (field (mut i32))))
 (func (export "f") (param $a anyref) (param $n i32)
  (struct.set $S 0
   (ref.cast (ref null $S) (local.get $a))
   (loop $l (result i32) (br_if $l (local.get $n)) (i32.const 0)))))

wasm-opt -all in.wat --optimize-instructions --traps-never-happen (also -O3) turns the cast into (ref.cast (ref $S) ...). In pseudocode:

// input
x = cast_or_null<S>(a)
while (n != 0) {}
x.field0 = 0              // traps if x is null

// output
x = cast_nonnull<S>(a)    // traps if a is null
while (n != 0) {}
x.field0 = 0

With a = null and n = 1, the input loops forever without reaching the struct.set, so nothing traps; the output traps before the loop.

Cause

https://github.com/WebAssembly/binaryen/blob/1d7748aa4ef48ac93f90712c2437ef88c6441389/src/passes/OptimizeInstructions.cpp#L1843-L1853

This check excludes a later sibling that transfersControlFlow(), since then "we might not reach the parent". A sibling that may not return (an infinite loop) also means we might not reach the parent, but transfersControlFlow() does not include mayNotReturn, so the check misses it. The same applies to array.get, array.set and array.copy.

This check predates #5711. Before #5711 a loop had the effect "may trap (timeout)", which traps-never-happen ignores, so assuming the loop terminates was consistent. #5711 changed loops to mayNotReturn so that traps-never-happen keeps infinite loops, but this check was not updated.

Possible fix

Add || effects(child).mayNotReturn to that check.

If traps-never-happen is meant to allow this, please let us know.

Lingua principale
WebAssembly
Stelle
8.7k
Fork
895
Merge medio
1g 22h
PR unite (30g)
97

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di WebAssembly/binaryen

Tutte le issue di WebAssembly/binaryen

Issue simili

Altre issue su Compilers

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.