;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: wasm-opt %s -all --optimize-level=3 --generate-stack-ir --optimize-stack-ir --print-stack-ir | filecheck %s (module ;; CHECK: (type $FUNCSIG$v (func)) (type $FUNCSIG$v (func)) ;; CHECK: (type $5 (func (result i32))) ;; CHECK: (type $6 (func (param i32) (result i32))) ;; CHECK: (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vf (func (param f32))) ;; CHECK: (type $4 (func (result f64))) ;; CHECK: (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) ;; CHECK: (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $4 (func (result f64))) (type $5 (func (result i32))) (type $6 (func (param i32) (result i32))) ;; CHECK: (type $7 (func (param f64) (result f64))) (type $7 (func (param f64) (result f64))) ;; CHECK: (type $8 (func (result i64))) (type $8 (func (result i64))) ;; CHECK: (type $9 (func (param i32 i64))) (type $9 (func (param i32 i64))) ;; CHECK: (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi (type $FUNCSIG$v))) (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) ;; CHECK: (import "asm2wasm" "f64-to-int" (func $f64-to-int (type $FUNCSIG$id) (param f64) (result i32))) (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) ;; CHECK: (import "asm2wasm" "f64-rem" (func $f64-rem (type $FUNCSIG$ddd) (param f64 f64) (result f64))) (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) ;; CHECK: (memory $mem 4096 4096) ;; CHECK: (data $data (i32.const 1026) "\14\00") ;; CHECK: (table $table 10 funcref) (table $table 10 funcref) ;; CHECK: (elem $elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) (elem $elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) (memory $mem 4096 4096) (data $data (i32.const 1026) "\14\00") ;; CHECK: (export "big_negative" (func $big_negative)) (export "big_negative" (func $big_negative)) ;; CHECK: (func $big_negative (type $FUNCSIG$v) ;; CHECK-NEXT: (local $temp f64) ;; CHECK-NEXT: f64.const -2147483648 ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: f64.const -2147483648 ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: f64.const -21474836480 ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: f64.const 0.039625 ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: f64.const -0.039625 ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: ) (func $big_negative (type $FUNCSIG$v) (local $temp f64) (block $block0 (local.set $temp (f64.const -2147483648) ) (local.set $temp (f64.const -2147483648) ) (local.set $temp (f64.const -21474836480) ) (local.set $temp (f64.const 0.039625) ) (local.set $temp (f64.const -0.039625) ) ) ) ;; CHECK: (func $importedDoubles (type $4) (result f64) ;; CHECK-NEXT: (local $temp f64) ;; CHECK-NEXT: block $topmost (result f64) ;; CHECK-NEXT: i32.const 8 ;; CHECK-NEXT: f64.load ;; CHECK-NEXT: i32.const 16 ;; CHECK-NEXT: f64.load ;; CHECK-NEXT: f64.add ;; CHECK-NEXT: i32.const 16 ;; CHECK-NEXT: f64.load ;; CHECK-NEXT: f64.neg ;; CHECK-NEXT: f64.add ;; CHECK-NEXT: i32.const 8 ;; CHECK-NEXT: f64.load ;; CHECK-NEXT: f64.neg ;; CHECK-NEXT: f64.add ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: i32.const 24 ;; CHECK-NEXT: i32.load ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.gt_s ;; CHECK-NEXT: if ;; CHECK-NEXT: f64.const -3.4 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 32 ;; CHECK-NEXT: f64.load ;; CHECK-NEXT: f64.const 0 ;; CHECK-NEXT: f64.gt ;; CHECK-NEXT: if ;; CHECK-NEXT: f64.const 5.6 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: f64.const 1.2 ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $importedDoubles (type $4) (result f64) (local $temp f64) (block $topmost (result f64) (local.set $temp (f64.add (f64.add (f64.add (f64.load (i32.const 8) ) (f64.load (i32.const 16) ) ) (f64.neg (f64.load (i32.const 16) ) ) ) (f64.neg (f64.load (i32.const 8) ) ) ) ) (if (i32.gt_s (i32.load (i32.const 24) ) (i32.const 0) ) (then (br $topmost (f64.const -3.4) ) ) ) (if (f64.gt (f64.load (i32.const 32) ) (f64.const 0) ) (then (br $topmost (f64.const 5.6) ) ) ) (f64.const 1.2) ) ) ;; CHECK: (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) ;; CHECK-NEXT: (local $t f64) ;; CHECK-NEXT: (local $Int f64) ;; CHECK-NEXT: (local $Double i32) ;; CHECK-NEXT: block $topmost (result f64) ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: f64.const 0 ;; CHECK-NEXT: f64.gt ;; CHECK-NEXT: if ;; CHECK-NEXT: f64.const 1.2 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: local.get $Int ;; CHECK-NEXT: f64.const 0 ;; CHECK-NEXT: f64.gt ;; CHECK-NEXT: if ;; CHECK-NEXT: f64.const -3.4 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: local.get $Double ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.gt_s ;; CHECK-NEXT: if ;; CHECK-NEXT: f64.const 5.6 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: local.get $y ;; CHECK-NEXT: f64.lt ;; CHECK-NEXT: if ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: local.get $y ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) (local $t f64) (local $Int f64) (local $Double i32) (block $topmost (result f64) (if (f64.gt (local.get $x) (f64.const 0) ) (then (br $topmost (f64.const 1.2) ) ) ) (if (f64.gt (local.get $Int) (f64.const 0) ) (then (br $topmost (f64.const -3.4) ) ) ) (if (i32.gt_s (local.get $Double) (i32.const 0) ) (then (br $topmost (f64.const 5.6) ) ) ) (if (f64.lt (local.get $x) (local.get $y) ) (then (br $topmost (local.get $x) ) ) ) (local.get $y) ) ) ;; CHECK: (func $intOps (type $5) (result i32) ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.eq ;; CHECK-NEXT: ) (func $intOps (type $5) (result i32) (local $x i32) (i32.eq (local.get $x) (i32.const 0) ) ) ;; CHECK: (func $hexLiterals (type $FUNCSIG$v) ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.const 313249263 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: i32.const -19088752 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $hexLiterals (type $FUNCSIG$v) (drop (i32.add (i32.add (i32.const 0) (i32.const 313249263) ) (i32.const -19088752) ) ) ) ;; CHECK: (func $conversions (type $FUNCSIG$v) ;; CHECK-NEXT: (local $i i32) ;; CHECK-NEXT: (local $d f64) ;; CHECK-NEXT: local.get $d ;; CHECK-NEXT: call $f64-to-int ;; CHECK-NEXT: local.set $i ;; CHECK-NEXT: local.get $i ;; CHECK-NEXT: f64.convert_i32_s ;; CHECK-NEXT: local.set $d ;; CHECK-NEXT: local.get $i ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.shr_u ;; CHECK-NEXT: f64.convert_i32_u ;; CHECK-NEXT: local.set $d ;; CHECK-NEXT: ) (func $conversions (type $FUNCSIG$v) (local $i i32) (local $d f64) (block $block0 (local.set $i (call $f64-to-int (local.get $d) ) ) (local.set $d (f64.convert_i32_s (local.get $i) ) ) (local.set $d (f64.convert_i32_u (i32.shr_u (local.get $i) (i32.const 0) ) ) ) ) ) ;; CHECK: (func $seq (type $FUNCSIG$v) ;; CHECK-NEXT: (local $J f64) ;; CHECK-NEXT: f64.const 0.1 ;; CHECK-NEXT: drop ;; CHECK-NEXT: f64.const 5.1 ;; CHECK-NEXT: f64.const 3.2 ;; CHECK-NEXT: drop ;; CHECK-NEXT: f64.const 4.2 ;; CHECK-NEXT: f64.sub ;; CHECK-NEXT: local.set $J ;; CHECK-NEXT: ) (func $seq (type $FUNCSIG$v) (local $J f64) (local.set $J (f64.sub (block $block0 (result f64) (drop (f64.const 0.1) ) (f64.const 5.1) ) (block $block1 (result f64) (drop (f64.const 3.2) ) (f64.const 4.2) ) ) ) ) ;; CHECK: (func $switcher (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: block $topmost (result i32) ;; CHECK-NEXT: block $switch-default$3 ;; CHECK-NEXT: block $switch-case$2 ;; CHECK-NEXT: block $switch-case$1 ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: i32.sub ;; CHECK-NEXT: br_table $switch-case$1 $switch-case$2 $switch-default$3 ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: block $switch-default$7 ;; CHECK-NEXT: block $switch-case$6 ;; CHECK-NEXT: block $switch-case$5 ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: i32.const 5 ;; CHECK-NEXT: i32.sub ;; CHECK-NEXT: br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 121 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 51 ;; CHECK-NEXT: br $topmost ;; CHECK-NEXT: end ;; CHECK-NEXT: block $label$break$Lout ;; CHECK-NEXT: block $switch-default$16 ;; CHECK-NEXT: block $switch-case$15 ;; CHECK-NEXT: block $switch-case$12 ;; CHECK-NEXT: block $switch-case$9 ;; CHECK-NEXT: block $switch-case$8 ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: i32.sub ;; CHECK-NEXT: br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 ;; CHECK-NEXT: end ;; CHECK-NEXT: br $label$break$Lout ;; CHECK-NEXT: end ;; CHECK-NEXT: br $label$break$Lout ;; CHECK-NEXT: end ;; CHECK-NEXT: block $while-out$10 ;; CHECK-NEXT: loop $while-in$11 ;; CHECK-NEXT: br $while-out$10 ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: end ;; CHECK-NEXT: end ;; CHECK-NEXT: loop $while-in$14 ;; CHECK-NEXT: br $label$break$Lout ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: end ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $switcher (type $6) (param $x i32) (result i32) (block $topmost (result i32) (block $switch$0 (block $switch-default$3 (block $switch-case$2 (block $switch-case$1 (br_table $switch-case$1 $switch-case$2 $switch-default$3 (i32.sub (local.get $x) (i32.const 1) ) ) ) (br $topmost (i32.const 1) ) ) (br $topmost (i32.const 2) ) ) (nop) ) (block $switch$4 (block $switch-default$7 (block $switch-case$6 (block $switch-case$5 (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 (i32.sub (local.get $x) (i32.const 5) ) ) ) (br $topmost (i32.const 121) ) ) (br $topmost (i32.const 51) ) ) (nop) ) (block $label$break$Lout (block $switch-default$16 (block $switch-case$15 (block $switch-case$12 (block $switch-case$9 (block $switch-case$8 (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 (i32.sub (local.get $x) (i32.const 2) ) ) ) (br $label$break$Lout) ) (br $label$break$Lout) ) (block $while-out$10 (loop $while-in$11 (block $block1 (br $while-out$10) (br $while-in$11) ) ) (br $label$break$Lout) ) ) (block $while-out$13 (loop $while-in$14 (block $block3 (br $label$break$Lout) (br $while-in$14) ) ) (br $label$break$Lout) ) ) (nop) ) (i32.const 0) ) ) ;; CHECK: (func $blocker (type $FUNCSIG$v) ;; CHECK-NEXT: block $label$break$L ;; CHECK-NEXT: br $label$break$L ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $blocker (type $FUNCSIG$v) (block $label$break$L (br $label$break$L) ) ) ;; CHECK: (func $frem (type $4) (result f64) ;; CHECK-NEXT: f64.const 5.5 ;; CHECK-NEXT: f64.const 1.2 ;; CHECK-NEXT: call $f64-rem ;; CHECK-NEXT: ) (func $frem (type $4) (result f64) (call $f64-rem (f64.const 5.5) (f64.const 1.2) ) ) ;; CHECK: (func $big_uint_div_u (type $5) (result i32) ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: i32.const -1 ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: i32.div_u ;; CHECK-NEXT: i32.const -1 ;; CHECK-NEXT: i32.and ;; CHECK-NEXT: ) (func $big_uint_div_u (type $5) (result i32) (local $x i32) (block $topmost (result i32) (local.set $x (i32.and (i32.div_u (i32.const -1) (i32.const 2) ) (i32.const -1) ) ) (local.get $x) ) ) ;; CHECK: (func $fr (type $FUNCSIG$vf) (param $x f32) ;; CHECK-NEXT: (local $y f32) ;; CHECK-NEXT: (local $z f64) ;; CHECK-NEXT: local.get $z ;; CHECK-NEXT: f32.demote_f64 ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $y ;; CHECK-NEXT: drop ;; CHECK-NEXT: f32.const 5 ;; CHECK-NEXT: drop ;; CHECK-NEXT: f32.const 0 ;; CHECK-NEXT: drop ;; CHECK-NEXT: f32.const 5 ;; CHECK-NEXT: drop ;; CHECK-NEXT: f32.const 0 ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $fr (type $FUNCSIG$vf) (param $x f32) (local $y f32) (local $z f64) (block $block0 (drop (f32.demote_f64 (local.get $z) ) ) (drop (local.get $y) ) (drop (f32.const 5) ) (drop (f32.const 0) ) (drop (f32.const 5) ) (drop (f32.const 0) ) ) ) ;; CHECK: (func $negZero (type $4) (result f64) ;; CHECK-NEXT: f64.const -0 ;; CHECK-NEXT: ) (func $negZero (type $4) (result f64) (f64.const -0) ) ;; CHECK: (func $abs (type $FUNCSIG$v) ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: (local $y f64) ;; CHECK-NEXT: (local $z f32) ;; CHECK-NEXT: (local $asm2wasm_i32_temp i32) ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: local.set $asm2wasm_i32_temp ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: local.get $asm2wasm_i32_temp ;; CHECK-NEXT: i32.sub ;; CHECK-NEXT: local.get $asm2wasm_i32_temp ;; CHECK-NEXT: local.get $asm2wasm_i32_temp ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.lt_s ;; CHECK-NEXT: select ;; CHECK-NEXT: local.set $x ;; CHECK-NEXT: f64.const 0 ;; CHECK-NEXT: f64.abs ;; CHECK-NEXT: local.set $y ;; CHECK-NEXT: f32.const 0 ;; CHECK-NEXT: f32.abs ;; CHECK-NEXT: local.set $z ;; CHECK-NEXT: ) (func $abs (type $FUNCSIG$v) (local $x i32) (local $y f64) (local $z f32) (local $asm2wasm_i32_temp i32) (block $block0 (local.set $x (block $block1 (result i32) (local.set $asm2wasm_i32_temp (i32.const 0) ) (select (i32.sub (i32.const 0) (local.get $asm2wasm_i32_temp) ) (local.get $asm2wasm_i32_temp) (i32.lt_s (local.get $asm2wasm_i32_temp) (i32.const 0) ) ) ) ) (local.set $y (f64.abs (f64.const 0) ) ) (local.set $z (f32.abs (f32.const 0) ) ) ) ) ;; CHECK: (func $neg (type $FUNCSIG$v) ;; CHECK-NEXT: (local $x f32) ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: f32.neg ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: i32.const 7 ;; CHECK-NEXT: i32.and ;; CHECK-NEXT: i32.const 8 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: call_indirect $table (type $FUNCSIG$vf) ;; CHECK-NEXT: ) (func $neg (type $FUNCSIG$v) (local $x f32) (block $block0 (local.set $x (f32.neg (local.get $x) ) ) (call_indirect (type $FUNCSIG$vf) (local.get $x) (i32.add (i32.and (i32.const 1) (i32.const 7) ) (i32.const 8) ) ) ) ) ;; CHECK: (func $cneg (type $FUNCSIG$vf) (param $x f32) ;; CHECK-NEXT: local.get $x ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: i32.const 7 ;; CHECK-NEXT: i32.and ;; CHECK-NEXT: i32.const 8 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: call_indirect $table (type $FUNCSIG$vf) ;; CHECK-NEXT: ) (func $cneg (type $FUNCSIG$vf) (param $x f32) (call_indirect (type $FUNCSIG$vf) (local.get $x) (i32.add (i32.and (i32.const 1) (i32.const 7) ) (i32.const 8) ) ) ) ;; CHECK: (func $___syscall_ret (type $FUNCSIG$v) ;; CHECK-NEXT: (local $$0 i32) ;; CHECK-NEXT: local.get $$0 ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: i32.shr_u ;; CHECK-NEXT: i32.const -4096 ;; CHECK-NEXT: i32.gt_u ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $___syscall_ret (type $FUNCSIG$v) (local $$0 i32) (drop (i32.gt_u (i32.shr_u (local.get $$0) (i32.const 0) ) (i32.const -4096) ) ) ) ;; CHECK: (func $z (type $FUNCSIG$v) ;; CHECK-NEXT: ) (func $z (type $FUNCSIG$v) (nop) ) ;; CHECK: (func $w (type $FUNCSIG$v) ;; CHECK-NEXT: ) (func $w (type $FUNCSIG$v) (nop) ) ;; CHECK: (func $block_and_after (type $5) (result i32) ;; CHECK-NEXT: block $waka ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: drop ;; CHECK-NEXT: br $waka ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: ) (func $block_and_after (type $5) (result i32) (block $waka (drop (i32.const 1) ) (br $waka) ) (i32.const 0) ) ;; CHECK: (func $loop-roundtrip (type $7) (param $0 f64) (result f64) ;; CHECK-NEXT: loop $loop-in1 (result f64) ;; CHECK-NEXT: local.get $0 ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $0 ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $loop-roundtrip (type $7) (param $0 f64) (result f64) (loop $loop-in1 (result f64) (drop (local.get $0) ) (local.get $0) ) ) ;; CHECK: (func $big-i64 (type $8) (result i64) ;; CHECK-NEXT: i64.const -9218868437227405313 ;; CHECK-NEXT: ) (func $big-i64 (type $8) (result i64) (i64.const -9218868437227405313) ) ;; CHECK: (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: local.get $0 ;; CHECK-NEXT: local.get $1 ;; CHECK-NEXT: i64.store32 ;; CHECK-NEXT: ) (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) (i64.store32 (local.get $0) (local.get $1) ) ) ;; CHECK: (func $return-unreachable (type $5) (result i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: ) (func $return-unreachable (result i32) (return (i32.const 1)) ) ;; CHECK: (func $unreachable-block (type $5) (result i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: return ;; CHECK-NEXT: ) (func $unreachable-block (result i32) (f64.abs (block ;; note no type - valid in binaryen IR, in wasm must be i32 (drop (i32.const 1)) (return (i32.const 2)) ) ) ) ;; CHECK: (func $unreachable-block-toplevel (type $5) (result i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: return ;; CHECK-NEXT: ) (func $unreachable-block-toplevel (result i32) (block ;; note no type - valid in binaryen IR, in wasm must be i32 (drop (i32.const 1)) (return (i32.const 2)) ) ) ;; CHECK: (func $unreachable-block0 (type $5) (result i32) ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: return ;; CHECK-NEXT: ) (func $unreachable-block0 (result i32) (f64.abs (block ;; note no type - valid in binaryen IR, in wasm must be i32 (return (i32.const 2)) ) ) ) ;; CHECK: (func $unreachable-block0-toplevel (type $5) (result i32) ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: return ;; CHECK-NEXT: ) (func $unreachable-block0-toplevel (result i32) (block ;; note no type - valid in binaryen IR, in wasm must be i32 (return (i32.const 2)) ) ) ;; CHECK: (func $unreachable-block-with-br (type $5) (result i32) ;; CHECK-NEXT: block $block ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: drop ;; CHECK-NEXT: br $block ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: ) (func $unreachable-block-with-br (result i32) (block $block ;; unreachable type due to last element having that type, but the block is exitable (drop (i32.const 1)) (br $block) ) (i32.const 1) ) ;; CHECK: (func $unreachable-if (type $5) (result i32) ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: if ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: return ;; CHECK-NEXT: else ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-if (result i32) (f64.abs (if ;; note no type - valid in binaryen IR, in wasm must be i32 (i32.const 3) (then (return (i32.const 2)) ) (else (return (i32.const 1)) ) ) ) ) ;; CHECK: (func $unreachable-if-toplevel (type $5) (result i32) ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: if ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: return ;; CHECK-NEXT: else ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-if-toplevel (result i32) (if ;; note no type - valid in binaryen IR, in wasm must be i32 (i32.const 3) (then (return (i32.const 2)) ) (else (return (i32.const 1)) ) ) ) ;; CHECK: (func $unreachable-loop (type $5) (result i32) ;; CHECK-NEXT: loop $loop-in ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-loop (result i32) (f64.abs (loop ;; note no type - valid in binaryen IR, in wasm must be i32 (nop) (return (i32.const 1)) ) ) ) ;; CHECK: (func $unreachable-loop0 (type $5) (result i32) ;; CHECK-NEXT: loop $loop-in ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-loop0 (result i32) (f64.abs (loop ;; note no type - valid in binaryen IR, in wasm must be i32 (return (i32.const 1)) ) ) ) ;; CHECK: (func $unreachable-loop-toplevel (type $5) (result i32) ;; CHECK-NEXT: loop $loop-in ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-loop-toplevel (result i32) (loop ;; note no type - valid in binaryen IR, in wasm must be i32 (nop) (return (i32.const 1)) ) ) ;; CHECK: (func $unreachable-loop0-toplevel (type $5) (result i32) ;; CHECK-NEXT: loop $loop-in ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: return ;; CHECK-NEXT: end ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-loop0-toplevel (result i32) (loop ;; note no type - valid in binaryen IR, in wasm must be i32 (return (i32.const 1)) ) ) ;; CHECK: (func $unreachable-ifs (type $FUNCSIG$v) ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-ifs (if (unreachable) (then (nop))) (if (unreachable) (then (unreachable))) (if (unreachable) (then (nop) )(else (nop))) (if (unreachable) (then (unreachable) )(else (nop))) (if (unreachable) (then (nop) )(else (unreachable))) (if (unreachable) (then (unreachable) )(else (unreachable))) ;; (if (i32.const 1) (then (unreachable) )(else (nop))) (if (i32.const 1) (then (nop) )(else (unreachable))) (if (i32.const 1) (then (unreachable) )(else (unreachable))) ) ;; CHECK: (func $unreachable-if-arm (type $FUNCSIG$v) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: if ;; CHECK-NEXT: else ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $unreachable-if-arm (if (i32.const 1) (then (block (nop) ) ) (else (block (unreachable) (drop (i32.const 1) ) ) ) ) ) ;; CHECK: (func $local-to-stack (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $local-to-stack (param $x i32) (result i32) (local $temp i32) (local.set $temp (call $local-to-stack (i32.const 1))) ;; this set could just be on the stack (drop (call $local-to-stack (i32.const 2))) (local.get $temp) ) ;; CHECK: (func $local-to-stack-1 (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.eqz ;; CHECK-NEXT: ) (func $local-to-stack-1 (param $x i32) (result i32) (local $temp i32) (local.set $temp (call $local-to-stack (i32.const 1))) (drop (call $local-to-stack (i32.const 2))) (i32.eqz (local.get $temp) ) ) ;; CHECK: (func $local-to-stack-1b (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $local-to-stack-1b (param $x i32) (result i32) (local $temp i32) (local.set $temp (call $local-to-stack (i32.const 1))) (drop (call $local-to-stack (i32.const 2))) (i32.add (local.get $temp) (i32.const 3) ) ) ;; CHECK: (func $local-to-stack-1c-no (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: local.get $temp ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $local-to-stack-1c-no (param $x i32) (result i32) (local $temp i32) (local.set $temp (call $local-to-stack (i32.const 1))) (drop (call $local-to-stack (i32.const 2))) (i32.add (i32.const 3) ;; this is in the way (local.get $temp) ) ) ;; CHECK: (func $local-to-stack-2-no (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $temp ;; CHECK-NEXT: local.get $temp ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $local-to-stack-2-no (param $x i32) (result i32) (local $temp i32) (local.set $temp (call $local-to-stack (i32.const 1))) (drop (call $local-to-stack (i32.const 2))) (i32.add (local.get $temp) (local.get $temp) ;; a second use - so cannot stack it ) ) ;; CHECK: (func $local-to-stack-3-no (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: if ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: else ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: local.set $temp ;; CHECK-NEXT: end ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $temp ;; CHECK-NEXT: ) (func $local-to-stack-3-no (param $x i32) (result i32) (local $temp i32) (if (i32.const 1) (then (local.set $temp (call $local-to-stack (i32.const 1))) ) (else (local.set $temp (call $local-to-stack (i32.const 2))) ;; two sets for that get ) ) (drop (call $local-to-stack (i32.const 3))) (local.get $temp) ) ;; CHECK: (func $local-to-stack-multi-4 (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 4 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $local-to-stack-multi-4 (param $x i32) (result i32) (local $temp1 i32) (local $temp2 i32) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (drop (call $local-to-stack-multi-4 (i32.const 2))) (drop (local.get $temp1)) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 3))) ;; same local, used later (drop (call $local-to-stack-multi-4 (i32.const 4))) (local.get $temp1) ) ;; CHECK: (func $local-to-stack-multi-5 (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 4 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $local-to-stack-multi-5 (param $x i32) (result i32) (local $temp1 i32) (local $temp2 i32) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (drop (call $local-to-stack-multi-4 (i32.const 2))) (drop (local.get $temp1)) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 3))) ;; different local, used later (drop (call $local-to-stack-multi-4 (i32.const 4))) (local.get $temp2) ) ;; CHECK: (func $local-to-stack-multi-6-justone (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: local.set $temp2 ;; CHECK-NEXT: i32.const 4 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $temp2 ;; CHECK-NEXT: local.get $temp2 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $local-to-stack-multi-6-justone (param $x i32) (result i32) (local $temp1 i32) (local $temp2 i32) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (drop (call $local-to-stack-multi-4 (i32.const 2))) (drop (local.get $temp1)) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 3))) ;; different local, used later (drop (call $local-to-stack-multi-4 (i32.const 4))) (i32.add (local.get $temp2) (local.get $temp2) ) ) ;; CHECK: (func $local-to-stack-multi-7-justone (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: local.set $temp1 ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $temp1 ;; CHECK-NEXT: local.get $temp1 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 4 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $local-to-stack-multi-7-justone (param $x i32) (result i32) (local $temp1 i32) (local $temp2 i32) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (drop (call $local-to-stack-multi-4 (i32.const 2))) (drop (i32.add (local.get $temp1) (local.get $temp1) ) ) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 3))) ;; different local, used later (drop (call $local-to-stack-multi-4 (i32.const 4))) (local.get $temp2) ) ;; CHECK: (func $local-to-stack-overlapping-multi-8-no (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: local.set $temp1 ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: local.get $temp1 ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $local-to-stack-overlapping-multi-8-no (param $x i32) (result i32) (local $temp1 i32) (local $temp2 i32) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 1))) (drop (call $local-to-stack-multi-4 (i32.const 3))) (i32.add (local.get $temp2) ;; the timing (local.get $temp1) ;; it sucks ) ) ;; CHECK: (func $local-to-stack-overlapping-multi-9-yes (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 3 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $local-to-stack-overlapping-multi-9-yes (param $x i32) (result i32) (local $temp1 i32) (local $temp2 i32) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 1))) (drop (call $local-to-stack-multi-4 (i32.const 3))) (i32.add (local.get $temp1) ;; the stars align (local.get $temp2) ;; and a time presents itself ) ) ;; CHECK: (func $local-to-stack-through-control-flow (type $FUNCSIG$v) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: (local $temp2 i32) ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: if ;; CHECK-NEXT: end ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: block $block ;; CHECK-NEXT: br $block ;; CHECK-NEXT: end ;; CHECK-NEXT: drop ;; CHECK-NEXT: drop ;; CHECK-NEXT: ) (func $local-to-stack-through-control-flow (local $temp1 i32) (local $temp2 i32) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 0))) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (if (i32.const 0) (then (nop))) (drop (local.get $temp1)) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 2))) (block $block (br $block)) (drop (local.get $temp1)) (drop (local.get $temp2)) ) ;; CHECK: (func $local-to-stack-in-control-flow (type $FUNCSIG$v) ;; CHECK-NEXT: (local $temp1 i32) ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: if ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: else ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $local-to-stack-multi-4 ;; CHECK-NEXT: drop ;; CHECK-NEXT: end ;; CHECK-NEXT: ) (func $local-to-stack-in-control-flow (local $temp1 i32) (if (i32.const 0) (then (block (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 0))) (drop (local.get $temp1)) ) ) (else (block (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) (drop (local.get $temp1)) ) ) ) ) ;; CHECK: (func $remove-block (type $6) (param $x i32) (result i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: call $remove-block ;; CHECK-NEXT: i32.const 1 ;; CHECK-NEXT: call $remove-block ;; CHECK-NEXT: i32.const 2 ;; CHECK-NEXT: call $remove-block ;; CHECK-NEXT: drop ;; CHECK-NEXT: i32.eqz ;; CHECK-NEXT: i32.add ;; CHECK-NEXT: ) (func $remove-block (param $x i32) (result i32) (local $temp i32) (i32.add (call $remove-block (i32.const 0)) (i32.eqz (block (result i32) ;; after we use the stack instead of the local, we can remove this block (local.set $temp (call $remove-block (i32.const 1))) (drop (call $remove-block (i32.const 2))) (local.get $temp) ) ) ) ) ;; CHECK: (func $tuple-local2stack (type $FUNCSIG$v) ;; CHECK-NEXT: (local $pair (tuple f32 i32)) ;; CHECK-NEXT: (local $f32 f32) ;; CHECK-NEXT: f32.const 0 ;; CHECK-NEXT: i32.const 0 ;; CHECK-NEXT: tuple.make 2 ;; CHECK-NEXT: local.set $pair ;; CHECK-NEXT: local.get $pair ;; CHECK-NEXT: tuple.extract 2 0 ;; CHECK-NEXT: local.set $f32 ;; CHECK-NEXT: ) (func $tuple-local2stack (local $pair (tuple f32 i32)) (local $f32 f32) ;; We should not optimize out this get-set pair in Stack IR since we can do ;; better in the binary writer. (local.set $pair (tuple.make 2 (f32.const 0) (i32.const 0) ) ) (local.set $f32 (tuple.extract 2 0 (local.get $pair) ) ) ) )