Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

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

Geschlossen
#9,246 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Ein zugehöriger Pull Request wurde bereits gemerged.

  • #9256 von @tamaroning — gemerged

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
45/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
cpp, wasm
Bereich
compilers

Rechercherichtung

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.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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.

Vorherrschende Sprache
WebAssembly
Sterne
8.7k
Forks
897
Ø Merge
2 T. 1 Std.
Gemergte PRs (30 T.)
103

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus WebAssembly/binaryen

Alle Issues in WebAssembly/binaryen

Ähnliche Issues

Weitere Issues zu Compilers

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.