Change CLIF shuffle to validate lane indices (#5995)

* Change CLIF `shuffle` to validate lane indices

Previously the CLIF `shuffle` instruction did not perform any validation
on the lane shuffle mask and specified that out-of-bounds lanes always
returned 0 as the value. This behavior though is not required by
WebAssembly which validates that lane indices are always in-bounds.
Additionally since these are static immediates even other code
generators should be able to verify that the immediates are in-bounds.

As a result this commit updates the definition of the `shuffle`
instruction to specify that all byte immediates must be in-bounds in the
range of [0, 32). The verifier has been updated and some test cases have
been removed that were testing this functionality.

Closes #5989

* Only generate valid shuffle immediates in fuzzer
This commit is contained in:
Alex Crichton
2023-03-13 09:24:11 -05:00
committed by GitHub
parent 2386eee56b
commit 7956dc6ba2
8 changed files with 33 additions and 120 deletions

View File

@@ -70,37 +70,6 @@ block0(v0: i8x16, v1: i8x16):
; vperm %v24, %v24, %v25, %v3
; br %r14
function %shuffle_2(i8x16, i8x16) -> i8x16 wasmtime_system_v {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [0 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47]
return v2
}
; VCode:
; block0:
; vgbm %v3, 1
; bras %r1, 20 ; data.u128 0x8080808080808080808080808080800f ; vl %v5, 0(%r1)
; vperm %v7, %v24, %v25, %v5
; vn %v24, %v3, %v7
; br %r14
;
; Disassembled:
; block0: ; offset 0x0
; vgbm %v3, 1
; bras %r1, 0x1a
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x0f
; vl %v5, 0(%r1)
; vperm %v7, %v24, %v25, %v5
; vn %v24, %v3, %v7
; br %r14
function %shuffle_vmrhg_xy(i8x16, i8x16) -> i8x16 wasmtime_system_v {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [24 25 26 27 28 29 30 31 8 9 10 11 12 13 14 15]

View File

@@ -68,37 +68,6 @@ block0(v0: i8x16, v1: i8x16):
; vperm %v24, %v24, %v25, %v3
; br %r14
function %shuffle_2(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [0 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47]
return v2
}
; VCode:
; block0:
; vgbm %v3, 32768
; bras %r1, 20 ; data.u128 0x00808080808080808080808080808080 ; vl %v5, 0(%r1)
; vperm %v7, %v24, %v25, %v5
; vn %v24, %v3, %v7
; br %r14
;
; Disassembled:
; block0: ; offset 0x0
; vgbm %v3, 0x8000
; bras %r1, 0x1a
; .byte 0x00, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; .byte 0x80, 0x80
; vl %v5, 0(%r1)
; vperm %v7, %v24, %v25, %v5
; vn %v24, %v3, %v7
; br %r14
function %shuffle_vmrhg_xy(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23]

View File

@@ -42,55 +42,6 @@ block0(v0: i8x16, v1: i8x16):
; addb %al, (%rax)
; addb %al, (%rax)
function %shuffle_out_of_bounds(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):
;; pick zero for the first lane, the rest use first lane of v0
;; This should introduce two constants, one for the permutation and one to
;; mask the non-zero values for lanes 1-15
v2 = shuffle v0, v1, 0x80000000000000000000000000000000
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; movdqa %xmm0, %xmm6
; movdqu const(0), %xmm0
; movdqa %xmm6, %xmm7
; vpermi2b %xmm1, %xmm7, %xmm0, %xmm0
; andps %xmm0, const(1), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; movdqa %xmm0, %xmm6
; movdqu 0x20(%rip), %xmm0
; movdqa %xmm6, %xmm7
; vpermi2b %xmm1, %xmm7, %xmm0
; andps 0x1f(%rip), %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, -1(%rax)
function %f3(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [3 0 31 26 4 6 12 11 23 13 24 4 2 15 17 5]

View File

@@ -14,13 +14,6 @@ block0(v0: i8x16, v1: i8x16):
}
; run: %shuffle_i8x16([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32]) == [4 1 32 27 5 7 13 12 24 14 25 5 3 16 18 6]
function %shuffle_zeros(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [3 0 32 255 4 6 12 11 23 13 24 4 2 97 17 5]
return v2
}
; run: %shuffle_zeros([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32]) == [4 1 0 0 5 7 13 12 24 14 25 5 3 0 18 6]
function %shuffle1(i8x16) -> i8x16 {
block0(v0: i8x16):
v1 = shuffle v0, v0, [8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

View File

@@ -123,3 +123,9 @@ block0:
v1 = ireduce.i64 v0 ; error: input i32 must be larger than output i64
return
}
function %bad_shuffle(i8x16, i8x16) {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 32] ; error: shuffle immediate index 32 is larger than the maximum 31
return
}