x64: Improve codegen for splats (#6025)
This commit goes through the lowerings for the CLIF `splat` instruction
and improves the support for each operator. Many of these lowerings are
mirrored from v8/SpiderMonkey and there are a number of improvements:
* AVX2 `v{p,}broadcast*` instructions are added and used when available.
* Float-based splats are much simpler and always a single-instruction
* Integer-based splats don't insert into an uninit xmm value and instead
start out with a `movd` to move into an `xmm` register. This
thoeretically breaks dependencies with prior instructions since `movd`
creates a fresh new value in the destination register.
* Loads are now sunk into all of the instructions. A new extractor,
`sinkable_load_exact`, was added to sink the i8/i16 loads.
This commit is contained in:
@@ -1315,11 +1315,10 @@ block0(v0: i8):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm2
|
||||
; vpinsrb $0, %xmm2, %rdi, %xmm4
|
||||
; uninit %xmm6
|
||||
; vpxor %xmm6, %xmm6, %xmm8
|
||||
; vpshufb %xmm4, %xmm8, %xmm0
|
||||
; movd %edi, %xmm2
|
||||
; uninit %xmm4
|
||||
; vpxor %xmm4, %xmm4, %xmm6
|
||||
; vpshufb %xmm2, %xmm6, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
@@ -1329,9 +1328,9 @@ block0(v0: i8):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vpinsrb $0, %edi, %xmm2, %xmm4
|
||||
; vpxor %xmm6, %xmm6, %xmm8
|
||||
; vpshufb %xmm8, %xmm4, %xmm0
|
||||
; movd %edi, %xmm2
|
||||
; vpxor %xmm4, %xmm4, %xmm6
|
||||
; vpshufb %xmm6, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
@@ -170,11 +170,10 @@ block0(v0: i8):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm0
|
||||
; pinsrb $0, %xmm0, %rdi, %xmm0
|
||||
; uninit %xmm7
|
||||
; pxor %xmm7, %xmm7, %xmm7
|
||||
; pshufb %xmm0, %xmm7, %xmm0
|
||||
; movd %edi, %xmm0
|
||||
; uninit %xmm5
|
||||
; pxor %xmm5, %xmm5, %xmm5
|
||||
; pshufb %xmm0, %xmm5, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
@@ -184,9 +183,9 @@ block0(v0: i8):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; pinsrb $0, %edi, %xmm0
|
||||
; pxor %xmm7, %xmm7
|
||||
; pshufb %xmm7, %xmm0
|
||||
; movd %edi, %xmm0
|
||||
; pxor %xmm5, %xmm5
|
||||
; pshufb %xmm5, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
@@ -203,9 +202,8 @@ block0:
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movl $-1, %esi
|
||||
; uninit %xmm4
|
||||
; pinsrw $0, %xmm4, %rsi, %xmm4
|
||||
; pinsrw $1, %xmm4, %rsi, %xmm4
|
||||
; movd %esi, %xmm2
|
||||
; pshuflw $0, %xmm2, %xmm4
|
||||
; pshufd $0, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
@@ -217,8 +215,8 @@ block0:
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movl $0xffffffff, %esi
|
||||
; pinsrw $0, %esi, %xmm4
|
||||
; pinsrw $1, %esi, %xmm4
|
||||
; movd %esi, %xmm2
|
||||
; pshuflw $0, %xmm2, %xmm4
|
||||
; pshufd $0, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
@@ -234,9 +232,8 @@ block0(v0: i32):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm3
|
||||
; pinsrd $0, %xmm3, %rdi, %xmm3
|
||||
; pshufd $0, %xmm3, %xmm0
|
||||
; movd %edi, %xmm2
|
||||
; pshufd $0, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
@@ -246,8 +243,8 @@ block0(v0: i32):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; pinsrd $0, %edi, %xmm3
|
||||
; pshufd $0, %xmm3, %xmm0
|
||||
; movd %edi, %xmm2
|
||||
; pshufd $0, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
@@ -262,11 +259,7 @@ block0(v0: f64):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movdqa %xmm0, %xmm5
|
||||
; uninit %xmm0
|
||||
; movdqa %xmm5, %xmm6
|
||||
; movsd %xmm0, %xmm6, %xmm0
|
||||
; movlhps %xmm0, %xmm6, %xmm0
|
||||
; movddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
@@ -276,10 +269,7 @@ block0(v0: f64):
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movdqa %xmm0, %xmm5
|
||||
; movdqa %xmm5, %xmm6
|
||||
; movsd %xmm6, %xmm0
|
||||
; movlhps %xmm6, %xmm0
|
||||
; movddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
334
cranelift/filetests/filetests/isa/x64/simd-splat-avx.clif
Normal file
334
cranelift/filetests/filetests/isa/x64/simd-splat-avx.clif
Normal file
@@ -0,0 +1,334 @@
|
||||
test compile precise-output
|
||||
set enable_simd
|
||||
target x86_64 has_avx
|
||||
|
||||
function %splat_i8(i8) -> i8x16 {
|
||||
block0(v0: i8):
|
||||
v1 = splat.i8x16 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; uninit %xmm4
|
||||
; vpxor %xmm4, %xmm4, %xmm6
|
||||
; vpshufb %xmm2, %xmm6, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; vpxor %xmm4, %xmm4, %xmm6
|
||||
; vpshufb %xmm6, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i16(i16) -> i16x8 {
|
||||
block0(v0: i16):
|
||||
v1 = splat.i16x8 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; vpshuflw $0, %xmm2, %xmm4
|
||||
; vpshufd $0, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; vpshuflw $0, %xmm2, %xmm4
|
||||
; vpshufd $0, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i32(i32) -> i32x4 {
|
||||
block0(v0: i32):
|
||||
v1 = splat.i32x4 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; vpshufd $0, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; vpshufd $0, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i64(i64) -> i64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = splat.i64x2 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movq %rdi, %xmm2
|
||||
; vmovddup %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movq %rdi, %xmm2
|
||||
; vmovddup %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_f32(f32) -> f32x4 {
|
||||
block0(v0: f32):
|
||||
v1 = splat.f32x4 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vshufps $0, %xmm0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vshufps $0, %xmm0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_f64(f64) -> f64x2 {
|
||||
block0(v0: f64):
|
||||
v1 = splat.f64x2 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vmovddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vmovddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i8(i64) -> i8x16 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i8 v0
|
||||
v2 = splat.i8x16 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm2
|
||||
; vpinsrb $0, %xmm2, 0(%rdi), %xmm4
|
||||
; uninit %xmm6
|
||||
; vpxor %xmm6, %xmm6, %xmm8
|
||||
; vpshufb %xmm4, %xmm8, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vpinsrb $0, (%rdi), %xmm2, %xmm4 ; trap: heap_oob
|
||||
; vpxor %xmm6, %xmm6, %xmm8
|
||||
; vpshufb %xmm8, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i16(i64) -> i16x8 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i16 v0
|
||||
v2 = splat.i16x8 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm2
|
||||
; vpinsrw $0, %xmm2, 0(%rdi), %xmm4
|
||||
; vpshuflw $0, %xmm4, %xmm6
|
||||
; vpshufd $0, %xmm6, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vpinsrw $0, (%rdi), %xmm2, %xmm4 ; trap: heap_oob
|
||||
; vpshuflw $0, %xmm4, %xmm6
|
||||
; vpshufd $0, %xmm6, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i32(i64) -> i32x4 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i32 v0
|
||||
v2 = splat.i32x4 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vbroadcastss 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vbroadcastss (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i64(i64) -> i64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i64 v0
|
||||
v2 = splat.i64x2 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vmovddup 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vmovddup (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_f32(i64) -> f32x4 {
|
||||
block0(v0: i64):
|
||||
v1 = load.f32 v0
|
||||
v2 = splat.f32x4 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vbroadcastss 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vbroadcastss (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_f64(i64) -> f64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = load.f64 v0
|
||||
v2 = splat.f64x2 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vmovddup 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vmovddup (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
318
cranelift/filetests/filetests/isa/x64/simd-splat-avx2.clif
Normal file
318
cranelift/filetests/filetests/isa/x64/simd-splat-avx2.clif
Normal file
@@ -0,0 +1,318 @@
|
||||
test compile precise-output
|
||||
set enable_simd
|
||||
target x86_64 has_avx has_avx2
|
||||
|
||||
function %splat_i8(i8) -> i8x16 {
|
||||
block0(v0: i8):
|
||||
v1 = splat.i8x16 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; vpbroadcastb %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; vpbroadcastb %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i16(i16) -> i16x8 {
|
||||
block0(v0: i16):
|
||||
v1 = splat.i16x8 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; vpbroadcastw %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; vpbroadcastw %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i32(i32) -> i32x4 {
|
||||
block0(v0: i32):
|
||||
v1 = splat.i32x4 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; vpbroadcastd %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; vpbroadcastd %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i64(i64) -> i64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = splat.i64x2 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movq %rdi, %xmm2
|
||||
; vmovddup %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movq %rdi, %xmm2
|
||||
; vmovddup %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_f32(f32) -> f32x4 {
|
||||
block0(v0: f32):
|
||||
v1 = splat.f32x4 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vbroadcastss %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vbroadcastss %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_f64(f64) -> f64x2 {
|
||||
block0(v0: f64):
|
||||
v1 = splat.f64x2 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vmovddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vmovddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i8(i64) -> i8x16 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i8 v0
|
||||
v2 = splat.i8x16 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vpbroadcastb 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vpbroadcastb (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i16(i64) -> i16x8 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i16 v0
|
||||
v2 = splat.i16x8 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vpbroadcastw 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vpbroadcastw (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i32(i64) -> i32x4 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i32 v0
|
||||
v2 = splat.i32x4 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vbroadcastss 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vbroadcastss (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i64(i64) -> i64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i64 v0
|
||||
v2 = splat.i64x2 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vmovddup 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vmovddup (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_f32(i64) -> f32x4 {
|
||||
block0(v0: i64):
|
||||
v1 = load.f32 v0
|
||||
v2 = splat.f32x4 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vbroadcastss 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vbroadcastss (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_f64(i64) -> f64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = load.f64 v0
|
||||
v2 = splat.f64x2 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; vmovddup 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; vmovddup (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
338
cranelift/filetests/filetests/isa/x64/simd-splat.clif
Normal file
338
cranelift/filetests/filetests/isa/x64/simd-splat.clif
Normal file
@@ -0,0 +1,338 @@
|
||||
test compile precise-output
|
||||
set enable_simd
|
||||
target x86_64
|
||||
|
||||
function %splat_i8(i8) -> i8x16 {
|
||||
block0(v0: i8):
|
||||
v1 = splat.i8x16 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm0
|
||||
; uninit %xmm5
|
||||
; pxor %xmm5, %xmm5, %xmm5
|
||||
; pshufb %xmm0, %xmm5, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm0
|
||||
; pxor %xmm5, %xmm5
|
||||
; pshufb %xmm5, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i16(i16) -> i16x8 {
|
||||
block0(v0: i16):
|
||||
v1 = splat.i16x8 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; pshuflw $0, %xmm2, %xmm4
|
||||
; pshufd $0, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; pshuflw $0, %xmm2, %xmm4
|
||||
; pshufd $0, %xmm4, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i32(i32) -> i32x4 {
|
||||
block0(v0: i32):
|
||||
v1 = splat.i32x4 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movd %edi, %xmm2
|
||||
; pshufd $0, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movd %edi, %xmm2
|
||||
; pshufd $0, %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_i64(i64) -> i64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = splat.i64x2 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movq %rdi, %xmm2
|
||||
; movddup %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movq %rdi, %xmm2
|
||||
; movddup %xmm2, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_f32(f32) -> f32x4 {
|
||||
block0(v0: f32):
|
||||
v1 = splat.f32x4 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; shufps $0, %xmm0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; shufps $0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %splat_f64(f64) -> f64x2 {
|
||||
block0(v0: f64):
|
||||
v1 = splat.f64x2 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movddup %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i8(i64) -> i8x16 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i8 v0
|
||||
v2 = splat.i8x16 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm0
|
||||
; pinsrb $0, %xmm0, 0(%rdi), %xmm0
|
||||
; uninit %xmm7
|
||||
; pxor %xmm7, %xmm7, %xmm7
|
||||
; pshufb %xmm0, %xmm7, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; pinsrb $0, (%rdi), %xmm0 ; trap: heap_oob
|
||||
; pxor %xmm7, %xmm7
|
||||
; pshufb %xmm7, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i16(i64) -> i16x8 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i16 v0
|
||||
v2 = splat.i16x8 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; uninit %xmm3
|
||||
; pinsrw $0, %xmm3, 0(%rdi), %xmm3
|
||||
; pshuflw $0, %xmm3, %xmm6
|
||||
; pshufd $0, %xmm6, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; pinsrw $0, (%rdi), %xmm3 ; trap: heap_oob
|
||||
; pshuflw $0, %xmm3, %xmm6
|
||||
; pshufd $0, %xmm6, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i32(i64) -> i32x4 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i32 v0
|
||||
v2 = splat.i32x4 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movss 0(%rdi), %xmm0
|
||||
; shufps $0, %xmm0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movss (%rdi), %xmm0 ; trap: heap_oob
|
||||
; shufps $0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_i64(i64) -> i64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = load.i64 v0
|
||||
v2 = splat.i64x2 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movddup 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movddup (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_f32(i64) -> f32x4 {
|
||||
block0(v0: i64):
|
||||
v1 = load.f32 v0
|
||||
v2 = splat.f32x4 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movss 0(%rdi), %xmm0
|
||||
; shufps $0, %xmm0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movss (%rdi), %xmm0 ; trap: heap_oob
|
||||
; shufps $0, %xmm0, %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
function %load_splat_f64(i64) -> f64x2 {
|
||||
block0(v0: i64):
|
||||
v1 = load.f64 v0
|
||||
v2 = splat.f64x2 v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; VCode:
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movddup 0(%rdi), %xmm0
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
;
|
||||
; Disassembled:
|
||||
; block0: ; offset 0x0
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block1: ; offset 0x4
|
||||
; movddup (%rdi), %xmm0 ; trap: heap_oob
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; retq
|
||||
|
||||
@@ -4,6 +4,8 @@ target aarch64
|
||||
target s390x
|
||||
set enable_simd
|
||||
target x86_64 has_sse3 has_ssse3 has_sse41
|
||||
target x86_64 has_sse3 has_ssse3 has_sse41 has_avx
|
||||
target x86_64 has_sse3 has_ssse3 has_sse41 has_avx has_avx2
|
||||
|
||||
function %splat_i8x16(i8) -> i8x16 {
|
||||
block0(v0: i8):
|
||||
|
||||
Reference in New Issue
Block a user