Similar to an earlier issue for ordinary branches (fixed in PR #1833), the cranelift-wasm crate did not previously correctly translate a br_table instruction's default-target branch when the branch target was a loop with loop parameters. The mistranslated CLIF resulted in a validation error. This one-line fix simply fills in the correct parameter count, generating a jump instruction with the appropriate parameters from the stack. This issue was found by :decoder in the SpiderMonkey embedding of Cranelift, in https://bugzilla.mozilla.org/show_bug.cgi?id=1657062. The test case is from that bug report.
641 lines
11 KiB
Plaintext
641 lines
11 KiB
Plaintext
;; From https://bugzilla.mozilla.org/show_bug.cgi?id=1657062.
|
|
;;
|
|
;; This just tests that Cranelift can compile this function; it previously
|
|
;; triggered a validator error on the CLIF that is generated by the wasm crate.
|
|
|
|
(module
|
|
(type (;0;) (func (param i32 i32 i32) (result i32)))
|
|
(func $main (type 0) (param i32 i32 i32) (result i32)
|
|
local.get 1
|
|
i32.const 6150
|
|
local.get 2
|
|
i32.const -63
|
|
br_if 0 (;@0;)
|
|
loop (param i32 i32 i32) (result i32) ;; label = @1
|
|
i32.const -59
|
|
local.get 1
|
|
i32.const -49
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.const 0
|
|
i32.const 0
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.const 27
|
|
select
|
|
i32.const 24
|
|
select
|
|
local.get 0
|
|
i32.const 27
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 452672
|
|
i32.const 32
|
|
br_if 1 (;@0;)
|
|
i32.const -23
|
|
i32.div_s
|
|
local.get 1
|
|
if ;; label = @2
|
|
nop
|
|
i32.const -52
|
|
if ;; label = @3
|
|
nop
|
|
i32.const -52
|
|
local.tee 1
|
|
br_table 1 (;@2;) 0 (;@3;)
|
|
end
|
|
local.get 2
|
|
br_table 0 (;@2;) 0 (;@2;)
|
|
end
|
|
local.get 1
|
|
nop
|
|
i32.const -23
|
|
i32.div_s
|
|
nop
|
|
i32.const -25
|
|
i32.popcnt
|
|
select
|
|
select
|
|
i32.const 139
|
|
select
|
|
drop
|
|
i32.const -8051
|
|
nop
|
|
drop
|
|
i32.const 27
|
|
i32.const -63
|
|
local.get 1
|
|
i32.const 1
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const -6145
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
select
|
|
local.get 1
|
|
i32.const -7937
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.eqz
|
|
i32.const -49
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 32
|
|
call $main
|
|
i32.const -1
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const -49
|
|
i32.const 0
|
|
i32.const 0
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
call $main
|
|
i32.const -1
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 3
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
nop
|
|
i32.const -59
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.const 32
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 4
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.const -19
|
|
nop
|
|
nop
|
|
i32.const -23
|
|
i32.div_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.div_s
|
|
local.get 1
|
|
i32.const 1
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 1
|
|
drop
|
|
i32.const -63
|
|
i32.const 27
|
|
select
|
|
i32.const 27
|
|
select
|
|
local.tee 0
|
|
i32.const 27
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 452672
|
|
i32.const 32
|
|
br_if 1 (;@0;)
|
|
i32.const -23
|
|
i32.div_s
|
|
local.get 1
|
|
if ;; label = @2
|
|
nop
|
|
i32.const -52
|
|
if ;; label = @3
|
|
nop
|
|
i32.const -52
|
|
local.tee 1
|
|
br_table 1 (;@2;) 0 (;@3;)
|
|
end
|
|
local.get 2
|
|
br_table 0 (;@2;) 0 (;@2;)
|
|
end
|
|
local.get 1
|
|
nop
|
|
i32.const -23
|
|
i32.div_s
|
|
nop
|
|
i32.const -25
|
|
i32.popcnt
|
|
select
|
|
select
|
|
i32.const 139
|
|
select
|
|
drop
|
|
i32.const -64
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
nop
|
|
i32.const -59
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.const 32
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 4
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.const -19
|
|
nop
|
|
nop
|
|
i32.const -23
|
|
i32.div_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.div_s
|
|
local.get 1
|
|
i32.const 1
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 1
|
|
drop
|
|
nop
|
|
i32.const -49
|
|
br_if 0 (;@1;)
|
|
local.set 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.const 0
|
|
i32.const 0
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
call $main
|
|
i32.const -1
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
nop
|
|
i32.const -59
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.const 32
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 4
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.div_s
|
|
local.get 1
|
|
i32.const 1
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 1
|
|
drop
|
|
i32.const -63
|
|
i32.const 27
|
|
select
|
|
i32.const 27
|
|
select
|
|
local.tee 0
|
|
i32.const 27
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 452672
|
|
i32.const 32
|
|
br_if 1 (;@0;)
|
|
i32.const -23
|
|
i32.div_s
|
|
local.get 1
|
|
if ;; label = @2
|
|
nop
|
|
i32.const -52
|
|
if ;; label = @3
|
|
nop
|
|
i32.const -52
|
|
local.tee 1
|
|
br_table 1 (;@2;) 0 (;@3;)
|
|
end
|
|
local.get 2
|
|
br_table 0 (;@2;) 0 (;@2;)
|
|
end
|
|
local.get 1
|
|
nop
|
|
i32.const -23
|
|
i32.div_s
|
|
nop
|
|
i32.const -25
|
|
i32.popcnt
|
|
select
|
|
select
|
|
i32.const 139
|
|
select
|
|
drop
|
|
i32.const -64
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
nop
|
|
i32.const -59
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.const 32
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
br_if 0 (;@1;)
|
|
i32.const 4
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
br_table 0 (;@1;)
|
|
unreachable
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.const -19
|
|
nop
|
|
nop
|
|
i32.const -23
|
|
i32.div_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.div_s
|
|
local.get 1
|
|
i32.const 1
|
|
i32.const -63
|
|
i32.const 2
|
|
i32.const 1
|
|
drop
|
|
nop
|
|
i32.const -49
|
|
br_if 0 (;@1;)
|
|
local.set 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.const 0
|
|
i32.const 0
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 32
|
|
call $main
|
|
i32.const -1
|
|
i32.rem_s
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
local.get 1
|
|
select
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const -64
|
|
i32.ge_u
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.ge_u
|
|
i32.ge_u
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.ge_u
|
|
nop
|
|
i32.const -59
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.eqz
|
|
i32.const 32
|
|
select
|
|
br_if 0 (;@1;)
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const 0
|
|
i32.const 2
|
|
i32.const -63
|
|
i32.const 27
|
|
i32.const -63
|
|
i32.eqz
|
|
i32.eqz
|
|
br 0 (;@1;)
|
|
end
|
|
unreachable
|
|
i32.div_s
|
|
unreachable
|
|
i32.rem_s
|
|
i32.div_s
|
|
return
|
|
br_if 0 (;@0;)
|
|
i32.const 0
|
|
i32.extend8_s
|
|
unreachable
|
|
unreachable
|
|
unreachable
|
|
unreachable
|
|
i32.ctz
|
|
unreachable
|
|
i32.ge_u
|
|
unreachable
|
|
unreachable
|
|
i32.popcnt
|
|
unreachable
|
|
unreachable
|
|
i32.popcnt)
|
|
(export "main" (func $main)))
|