x64: Fill out more AVX instructions (#5849)

* x64: Fill out more AVX instructions

This commit fills out more AVX instructions for SSE counterparts
currently used. Many of these instructions do not benefit from the
3-operand form that AVX uses but instead benefit from being able to use
`XmmMem` instead of `XmmMemAligned` which may be able to avoid some
extra temporary registers in some cases.

* Review comments
This commit is contained in:
Alex Crichton
2023-02-23 16:31:31 -06:00
committed by GitHub
parent 8abfe928d6
commit 3fc3bc9ec8
7 changed files with 1114 additions and 13 deletions

View File

@@ -0,0 +1,598 @@
test compile precise-output
set enable_simd
target x86_64 has_avx
function %f32_add(f32, f32) -> f32 {
block0(v0: f32, v1: f32):
v2 = fadd v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vaddss %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vaddss %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64_add(f64, f64) -> f64 {
block0(v0: f64, v1: f64):
v2 = fadd v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vaddsd %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vaddsd %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32_sub(f32, f32) -> f32 {
block0(v0: f32, v1: f32):
v2 = fsub v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vsubss %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vsubss %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64_sub(f64, f64) -> f64 {
block0(v0: f64, v1: f64):
v2 = fsub v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vsubsd %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vsubsd %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32_mul(f32, f32) -> f32 {
block0(v0: f32, v1: f32):
v2 = fmul v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vmulss %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vmulss %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64_mul(f64, f64) -> f64 {
block0(v0: f64, v1: f64):
v2 = fmul v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vmulsd %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vmulsd %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32_div(f32, f32) -> f32 {
block0(v0: f32, v1: f32):
v2 = fdiv v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vdivss %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vdivss %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64_div(f64, f64) -> f64 {
block0(v0: f64, v1: f64):
v2 = fdiv v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vdivsd %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vdivsd %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32_min(f32, f32) -> f32 {
block0(v0: f32, v1: f32):
v2 = fmin_pseudo v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vminss %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vminss %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64_min(f64, f64) -> f64 {
block0(v0: f64, v1: f64):
v2 = fmin_pseudo v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vminsd %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vminsd %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32_max(f32, f32) -> f32 {
block0(v0: f32, v1: f32):
v2 = fmax_pseudo v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vmaxss %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vmaxss %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64_max(f64, f64) -> f64 {
block0(v0: f64, v1: f64):
v2 = fmax_pseudo v0, v1
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vmaxsd %xmm1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vmaxsd %xmm0, %xmm1, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32x4_sqrt(f32x4) -> f32x4 {
block0(v0: f32x4):
v1 = sqrt v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vsqrtps %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vsqrtps %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64x2_sqrt(f64x2) -> f64x2 {
block0(v0: f64x2):
v1 = sqrt v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vsqrtpd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vsqrtpd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f32x4_floor(f32x4) -> f32x4 {
block0(v0: f32x4):
v1 = floor v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vroundps $1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vroundps $1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %f64x2_floor(f64x2) -> f64x2 {
block0(v0: f64x2):
v1 = floor v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vroundpd $1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vroundpd $1, %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %fcvt_low_from_sint(i32x4) -> f64x2 {
block0(v0: i32x4):
v1 = fcvt_low_from_sint.f64x2 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vcvtdq2pd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vcvtdq2pd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %fcvt_from_uint(i32x4) -> f32x4 {
block0(v0: i32x4):
v1 = fcvt_from_uint.f32x4 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpslld %xmm0, $16, %xmm2
; vpsrld %xmm2, $16, %xmm4
; vpsubd %xmm0, %xmm4, %xmm6
; vcvtdq2ps %xmm4, %xmm8
; vpsrld %xmm6, $1, %xmm10
; vcvtdq2ps %xmm10, %xmm12
; vaddps %xmm12, %xmm12, %xmm14
; vaddps %xmm14, %xmm8, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpslld $0x10, %xmm0, %xmm2
; vpsrld $0x10, %xmm2, %xmm4
; vpsubd %xmm4, %xmm0, %xmm6
; vcvtdq2ps %xmm4, %xmm8
; vpsrld $1, %xmm6, %xmm10
; vcvtdq2ps %xmm10, %xmm12
; vaddps %xmm12, %xmm12, %xmm14
; vaddps %xmm8, %xmm14, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %fvdemote(f64x2) -> f32x4 {
block0(v0: f64x2):
v1 = fvdemote v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vcvtpd2ps %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vcvtpd2ps %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %fvpromote_low(f32x4) -> f64x2 {
block0(v0: f32x4):
v1 = fvpromote_low v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vcvtps2pd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vcvtps2pd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %fcvt_to_sint_sat(f32x4) -> i32x4 {
block0(v0: f32x4):
v1 = fcvt_to_sint_sat.i32x4 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vcmpps $0 %xmm0, %xmm0, %xmm2
; vandps %xmm0, %xmm2, %xmm4
; vpxor %xmm2, %xmm4, %xmm6
; vcvttps2dq %xmm4, %xmm8
; vpand %xmm8, %xmm6, %xmm10
; vpsrad %xmm10, $31, %xmm12
; vpxor %xmm12, %xmm8, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vcmpeqps %xmm0, %xmm0, %xmm2
; vandps %xmm2, %xmm0, %xmm4
; vpxor %xmm4, %xmm2, %xmm6
; vcvttps2dq %xmm4, %xmm8
; vpand %xmm6, %xmm8, %xmm10
; vpsrad $0x1f, %xmm10, %xmm12
; vpxor %xmm8, %xmm12, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %fcvt_to_sint_sat_snarrow(f64x2) -> i32x4 {
block0(v0: f64x2):
v1 = fcvt_to_sint_sat.i64x2 v0
v2 = vconst.i64x2 0x00
v3 = snarrow v1, v2
return v3
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vcmppd $0 %xmm0, %xmm0, %xmm2
; movupd const(0), %xmm4
; vandps %xmm2, %xmm4, %xmm6
; vminpd %xmm0, %xmm6, %xmm8
; vcvttpd2dq %xmm8, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vcmpeqpd %xmm0, %xmm0, %xmm2
; movupd 0x1f(%rip), %xmm4
; vandps %xmm4, %xmm2, %xmm6
; vminpd %xmm6, %xmm0, %xmm8
; vcvttpd2dq %xmm8, %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, %al

View File

@@ -1213,7 +1213,7 @@ block0(v0: i8x16):
; movq %rsp, %rbp
; block0:
; vpalignr $8 %xmm0, %xmm0, %xmm2
; pmovzxbw %xmm2, %xmm0
; vpmovzxbw %xmm2, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
@@ -1224,7 +1224,7 @@ block0(v0: i8x16):
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpalignr $8, %xmm0, %xmm0, %xmm2
; pmovzxbw %xmm2, %xmm0
; vpmovzxbw %xmm2, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
@@ -1359,7 +1359,7 @@ block0(v0: f64x2):
; vmaxpd %xmm0, %xmm2, %xmm4
; movupd const(0), %xmm6
; vminpd %xmm4, %xmm6, %xmm8
; roundpd $3, %xmm8, %xmm10
; vroundpd $3, %xmm8, %xmm10
; movupd const(1), %xmm12
; vaddpd %xmm10, %xmm12, %xmm14
; vshufps $136 %xmm14, %xmm2, %xmm0
@@ -1376,8 +1376,8 @@ block0(v0: f64x2):
; vmaxpd %xmm2, %xmm0, %xmm4
; movupd 0x2c(%rip), %xmm6
; vminpd %xmm6, %xmm4, %xmm8
; roundpd $3, %xmm8, %xmm10
; movupd 0x28(%rip), %xmm12
; vroundpd $3, %xmm8, %xmm10
; movupd 0x29(%rip), %xmm12
; vaddpd %xmm12, %xmm10, %xmm14
; vshufps $0x88, %xmm2, %xmm14, %xmm0
; movq %rbp, %rsp
@@ -1388,7 +1388,8 @@ block0(v0: f64x2):
; addb %al, (%rax)
; addb %al, (%rax)
; addb %al, (%rax)
; addb %ah, %al
; addb %al, (%rax)
; loopne 0x43
function %i8x16_shl(i8x16, i32) -> i8x16 {
block0(v0: i8x16, v1: i32):
@@ -1884,3 +1885,78 @@ block0(v0: i64x2):
; popq %rbp
; retq
function %i8x16_abs(i8x16) -> i8x16 {
block0(v0: i8x16):
v1 = iabs v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpabsb %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpabsb %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %i16x8_abs(i16x8) -> i16x8 {
block0(v0: i16x8):
v1 = iabs v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpabsw %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpabsw %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq
function %i32x4_abs(i32x4) -> i32x4 {
block0(v0: i32x4):
v1 = iabs v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpabsd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpabsd %xmm0, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq

View File

@@ -0,0 +1,154 @@
test compile precise-output
set enable_simd
target x86_64 has_avx
function %sload8x8(i64) -> i16x8 {
block0(v0: i64):
v1 = sload8x8 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpmovsxbw 0(%rdi), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpmovsxbw (%rdi), %xmm0 ; trap: heap_oob
; movq %rbp, %rsp
; popq %rbp
; retq
function %uload8x8(i64) -> i16x8 {
block0(v0: i64):
v1 = uload8x8 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpmovzxbw 0(%rdi), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpmovzxbw (%rdi), %xmm0 ; trap: heap_oob
; movq %rbp, %rsp
; popq %rbp
; retq
function %sload16x4(i64) -> i32x4 {
block0(v0: i64):
v1 = sload16x4 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpmovsxwd 0(%rdi), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpmovsxwd (%rdi), %xmm0 ; trap: heap_oob
; movq %rbp, %rsp
; popq %rbp
; retq
function %uload16x4(i64) -> i32x4 {
block0(v0: i64):
v1 = uload16x4 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpmovzxwd 0(%rdi), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpmovzxwd (%rdi), %xmm0 ; trap: heap_oob
; movq %rbp, %rsp
; popq %rbp
; retq
function %sload32x2(i64) -> i64x2 {
block0(v0: i64):
v1 = sload32x2 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpmovsxdq 0(%rdi), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpmovsxdq (%rdi), %xmm0 ; trap: heap_oob
; movq %rbp, %rsp
; popq %rbp
; retq
function %uload32x2(i64) -> i64x2 {
block0(v0: i64):
v1 = uload32x2 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; vpmovzxdq 0(%rdi), %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; vpmovzxdq (%rdi), %xmm0 ; trap: heap_oob
; movq %rbp, %rsp
; popq %rbp
; retq