complex_control_flow.js (4074B)
1 // Test branch hinting with nested if. 2 3 var imports = { "":{inc() { counter++ }} }; 4 counter = 0; 5 6 let module = new WebAssembly.Module(wasmTextToBinary(`(module 7 (import "" "inc" (func (result i32))) 8 (func 9 (result i32) 10 (@metadata.code.branch_hint "\\00") (if (result i32) 11 (i32.const 1) 12 (then 13 (@metadata.code.branch_hint "\\00") (if (result i32) 14 (i32.const 2) 15 (then 16 (@metadata.code.branch_hint "\\00") (if (result i32) 17 (i32.const 3) 18 (then 19 (@metadata.code.branch_hint "\\00") (if (result i32) 20 (i32.const 0) 21 (then (call 0)) 22 (else (i32.const 42)) 23 ) 24 ) 25 (else (call 0)) 26 ) 27 ) 28 (else (call 0)) 29 ) 30 ) 31 (else (call 0)) 32 ) 33 ) 34 (export "run" (func 1)) 35 )`, 42, imports)); 36 37 assertEq(counter, 0); 38 assertEq(wasmParsedBranchHints(module), true); 39 let instance = new WebAssembly.Instance(module, imports); 40 instance.exports.run(42); 41 42 module = new WebAssembly.Module(wasmTextToBinary(` 43 (module 44 (func $dummy) 45 (func (export "nested") (param i32 i32) (result i32) 46 (if (result i32) (local.get 0) 47 (then 48 (if (local.get 1) (then (call $dummy) (block) (nop))) 49 (if (local.get 1) (then) (else (call $dummy) (block) (nop))) 50 (@metadata.code.branch_hint "\\01") 51 (if (result i32) (local.get 1) 52 (then (call $dummy) (i32.const 9)) 53 (else (call $dummy) (i32.const 10)) 54 ) 55 ) 56 (else 57 (if (local.get 1) (then (call $dummy) (block) (nop))) 58 (if (local.get 1) (then) (else (call $dummy) (block) (nop))) 59 (@metadata.code.branch_hint "\\00") 60 (if (result i32) (local.get 1) 61 (then (call $dummy) (i32.const 10)) 62 (else (call $dummy) (i32.const 11)) 63 ) 64 ) 65 ) 66 ) 67 )`)); 68 69 assertEq(wasmParsedBranchHints(module), true); 70 instance = new WebAssembly.Instance(module, imports); 71 instance.exports.nested(2, 5); 72 73 // Test that branch hinting can propagate to successor blocks. 74 module = new WebAssembly.Module(wasmTextToBinary(` 75 (module 76 (func (export "main") (param $x i32) (result i32) 77 (if (result i32) 78 (i32.gt_s (local.get $x) (i32.const 0)) 79 (then 80 (@metadata.code.branch_hint "\\00") 81 (if (result i32) 82 (i32.eq (local.get $x) (i32.const 1)) 83 (then 84 (i32.const 10) 85 ) 86 (else 87 (if (result i32) 88 (i32.eq (local.get $x) (i32.const 2)) 89 (then 90 (i32.const 20) 91 ) 92 (else 93 (i32.const 99) 94 ) 95 ) 96 ) 97 ) 98 ) 99 (else 100 (i32.const 0) 101 ) 102 ) 103 ) 104 )`)); 105 106 assertEq(wasmParsedBranchHints(module), true); 107 instance = new WebAssembly.Instance(module, imports); 108 instance.exports.main(2); 109 110 // Test that the nested if branch has the correct branch hinting likelyness. 111 module = new WebAssembly.Module(wasmTextToBinary(` 112 (module 113 (func (export "main") (param $x i32) (result i32) 114 (if (result i32) 115 (i32.gt_s (local.get $x) (i32.const 0)) 116 (then 117 (@metadata.code.branch_hint "\\01") 118 (if (result i32) 119 (i32.eq (local.get $x) (i32.const 1)) 120 (then 121 (i32.const 10) 122 ) 123 (else 124 (@metadata.code.branch_hint "\\00") 125 (if (result i32) 126 (i32.eq (local.get $x) (i32.const 2)) 127 (then 128 (i32.const 20) 129 ) 130 (else 131 (i32.const 99) 132 ) 133 ) 134 ) 135 ) 136 ) 137 (else 138 (i32.const 0) 139 ) 140 ) 141 ) 142 )`)); 143 144 assertEq(wasmParsedBranchHints(module), true); 145 instance = new WebAssembly.Instance(module, imports); 146 instance.exports.main(5);