| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2 | |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE42 | |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,AVX,AVX2 | |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,AVX,AVX512 | |
| define i16 @smulh_i16(i16 %x, i16 %y) nounwind { | |
| ; CHECK-LABEL: smulh_i16: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movswl %si, %ecx | |
| ; CHECK-NEXT: movswl %di, %eax | |
| ; CHECK-NEXT: imull %ecx, %eax | |
| ; CHECK-NEXT: shrl $16, %eax | |
| ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax | |
| ; CHECK-NEXT: retq | |
| %r = call i16 @llvm.smulh(i16 %x, i16 %y) | |
| ret i16 %r | |
| } | |
| define i32 @smulh_i32(i32 %x, i32 %y) nounwind { | |
| ; CHECK-LABEL: smulh_i32: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movslq %esi, %rcx | |
| ; CHECK-NEXT: movslq %edi, %rax | |
| ; CHECK-NEXT: imulq %rcx, %rax | |
| ; CHECK-NEXT: shrq $32, %rax | |
| ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax | |
| ; CHECK-NEXT: retq | |
| %r = call i32 @llvm.smulh(i32 %x, i32 %y) | |
| ret i32 %r | |
| } | |
| define i64 @smulh_i64(i64 %x, i64 %y) nounwind { | |
| ; CHECK-LABEL: smulh_i64: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: imulq %rsi | |
| ; CHECK-NEXT: movq %rdx, %rax | |
| ; CHECK-NEXT: retq | |
| %r = call i64 @llvm.smulh(i64 %x, i64 %y) | |
| ret i64 %r | |
| } | |
| define i96 @smulh_i96(i96 %x, i96 %y) nounwind { | |
| ; SSE-LABEL: smulh_i96: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: movq %rdx, %r8 | |
| ; SSE-NEXT: movslq %ecx, %r10 | |
| ; SSE-NEXT: shldq $32, %rdi, %rsi | |
| ; SSE-NEXT: movq %rsi, %r11 | |
| ; SSE-NEXT: sarq $63, %r11 | |
| ; SSE-NEXT: shlq $32, %rdi | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %rdx | |
| ; SSE-NEXT: movq %rdx, %rcx | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r8 | |
| ; SSE-NEXT: movq %rax, %r9 | |
| ; SSE-NEXT: imulq %r8, %r11 | |
| ; SSE-NEXT: addq %rcx, %r9 | |
| ; SSE-NEXT: adcq %rdx, %r11 | |
| ; SSE-NEXT: movq %r11, %rcx | |
| ; SSE-NEXT: sarq $63, %rcx | |
| ; SSE-NEXT: movq %r10, %r8 | |
| ; SSE-NEXT: sarq $63, %r8 | |
| ; SSE-NEXT: imulq %rdi, %r8 | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %r10 | |
| ; SSE-NEXT: addq %r9, %rax | |
| ; SSE-NEXT: adcq %rdx, %r8 | |
| ; SSE-NEXT: movq %r8, %rdi | |
| ; SSE-NEXT: sarq $63, %rdi | |
| ; SSE-NEXT: addq %r11, %r8 | |
| ; SSE-NEXT: adcq %rcx, %rdi | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: imulq %r10 | |
| ; SSE-NEXT: addq %r8, %rax | |
| ; SSE-NEXT: adcq %rdi, %rdx | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_i96: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: movq %rsi, %rax | |
| ; AVX2-NEXT: shldq $32, %rdi, %rax | |
| ; AVX2-NEXT: shlq $32, %rdi | |
| ; AVX2-NEXT: mulxq %rdi, %rsi, %rsi | |
| ; AVX2-NEXT: mulxq %rax, %r8, %r9 | |
| ; AVX2-NEXT: movq %rax, %r10 | |
| ; AVX2-NEXT: sarq $63, %r10 | |
| ; AVX2-NEXT: imulq %rdx, %r10 | |
| ; AVX2-NEXT: addq %rsi, %r8 | |
| ; AVX2-NEXT: adcq %r10, %r9 | |
| ; AVX2-NEXT: movslq %ecx, %rcx | |
| ; AVX2-NEXT: movq %r9, %rsi | |
| ; AVX2-NEXT: sarq $63, %rsi | |
| ; AVX2-NEXT: movq %rcx, %r10 | |
| ; AVX2-NEXT: sarq $63, %r10 | |
| ; AVX2-NEXT: imulq %rdi, %r10 | |
| ; AVX2-NEXT: movq %rdi, %rdx | |
| ; AVX2-NEXT: mulxq %rcx, %rdx, %rdi | |
| ; AVX2-NEXT: addq %r8, %rdx | |
| ; AVX2-NEXT: adcq %r10, %rdi | |
| ; AVX2-NEXT: movq %rdi, %r8 | |
| ; AVX2-NEXT: sarq $63, %r8 | |
| ; AVX2-NEXT: addq %r9, %rdi | |
| ; AVX2-NEXT: adcq %rsi, %r8 | |
| ; AVX2-NEXT: imulq %rcx | |
| ; AVX2-NEXT: addq %rdi, %rax | |
| ; AVX2-NEXT: adcq %r8, %rdx | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_i96: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: movq %rsi, %rax | |
| ; AVX512-NEXT: movslq %ecx, %rcx | |
| ; AVX512-NEXT: shldq $32, %rdi, %rax | |
| ; AVX512-NEXT: shlq $32, %rdi | |
| ; AVX512-NEXT: mulxq %rdi, %rsi, %rsi | |
| ; AVX512-NEXT: mulxq %rax, %r8, %r9 | |
| ; AVX512-NEXT: movq %rax, %r10 | |
| ; AVX512-NEXT: sarq $63, %r10 | |
| ; AVX512-NEXT: imulq %rdx, %r10 | |
| ; AVX512-NEXT: addq %rsi, %r8 | |
| ; AVX512-NEXT: adcq %r10, %r9 | |
| ; AVX512-NEXT: movq %r9, %rsi | |
| ; AVX512-NEXT: sarq $63, %rsi | |
| ; AVX512-NEXT: movq %rcx, %r10 | |
| ; AVX512-NEXT: sarq $63, %r10 | |
| ; AVX512-NEXT: imulq %rdi, %r10 | |
| ; AVX512-NEXT: movq %rdi, %rdx | |
| ; AVX512-NEXT: mulxq %rcx, %rdx, %rdi | |
| ; AVX512-NEXT: addq %r8, %rdx | |
| ; AVX512-NEXT: adcq %r10, %rdi | |
| ; AVX512-NEXT: movq %rdi, %r8 | |
| ; AVX512-NEXT: sarq $63, %r8 | |
| ; AVX512-NEXT: addq %r9, %rdi | |
| ; AVX512-NEXT: adcq %rsi, %r8 | |
| ; AVX512-NEXT: imulq %rcx | |
| ; AVX512-NEXT: addq %rdi, %rax | |
| ; AVX512-NEXT: adcq %r8, %rdx | |
| ; AVX512-NEXT: retq | |
| %r = call i96 @llvm.smulh(i96 %x, i96 %y) | |
| ret i96 %r | |
| } | |
| define i128 @smulh_i128(i128 %x, i128 %y) nounwind { | |
| ; SSE-LABEL: smulh_i128: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: movq %rdx, %r8 | |
| ; SSE-NEXT: movq %rsi, %r11 | |
| ; SSE-NEXT: sarq $63, %r11 | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %rdx | |
| ; SSE-NEXT: movq %rdx, %r9 | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r8 | |
| ; SSE-NEXT: movq %rax, %r10 | |
| ; SSE-NEXT: imulq %r8, %r11 | |
| ; SSE-NEXT: addq %r9, %r10 | |
| ; SSE-NEXT: adcq %rdx, %r11 | |
| ; SSE-NEXT: movq %r11, %r8 | |
| ; SSE-NEXT: sarq $63, %r8 | |
| ; SSE-NEXT: movq %rcx, %r9 | |
| ; SSE-NEXT: sarq $63, %r9 | |
| ; SSE-NEXT: imulq %rdi, %r9 | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %rcx | |
| ; SSE-NEXT: addq %r10, %rax | |
| ; SSE-NEXT: adcq %rdx, %r9 | |
| ; SSE-NEXT: movq %r9, %rdi | |
| ; SSE-NEXT: sarq $63, %rdi | |
| ; SSE-NEXT: addq %r11, %r9 | |
| ; SSE-NEXT: adcq %r8, %rdi | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: imulq %rcx | |
| ; SSE-NEXT: addq %r9, %rax | |
| ; SSE-NEXT: adcq %rdi, %rdx | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: smulh_i128: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: movq %rsi, %rax | |
| ; AVX-NEXT: mulxq %rdi, %rsi, %rsi | |
| ; AVX-NEXT: mulxq %rax, %r8, %r9 | |
| ; AVX-NEXT: movq %rax, %r10 | |
| ; AVX-NEXT: sarq $63, %r10 | |
| ; AVX-NEXT: imulq %rdx, %r10 | |
| ; AVX-NEXT: addq %rsi, %r8 | |
| ; AVX-NEXT: adcq %r10, %r9 | |
| ; AVX-NEXT: movq %r9, %rsi | |
| ; AVX-NEXT: sarq $63, %rsi | |
| ; AVX-NEXT: movq %rcx, %r10 | |
| ; AVX-NEXT: sarq $63, %r10 | |
| ; AVX-NEXT: imulq %rdi, %r10 | |
| ; AVX-NEXT: movq %rdi, %rdx | |
| ; AVX-NEXT: mulxq %rcx, %rdx, %rdi | |
| ; AVX-NEXT: addq %r8, %rdx | |
| ; AVX-NEXT: adcq %r10, %rdi | |
| ; AVX-NEXT: movq %rdi, %r8 | |
| ; AVX-NEXT: sarq $63, %r8 | |
| ; AVX-NEXT: addq %r9, %rdi | |
| ; AVX-NEXT: adcq %rsi, %r8 | |
| ; AVX-NEXT: imulq %rcx | |
| ; AVX-NEXT: addq %rdi, %rax | |
| ; AVX-NEXT: adcq %r8, %rdx | |
| ; AVX-NEXT: retq | |
| %r = call i128 @llvm.smulh(i128 %x, i128 %y) | |
| ret i128 %r | |
| } | |
| define <8 x i8> @smulh_v8i8(<8 x i8> %x, <8 x i8> %y) nounwind { | |
| ; SSE-LABEL: smulh_v8i8: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm1[8],xmm3[9],xmm1[9],xmm3[10],xmm1[10],xmm3[11],xmm1[11],xmm3[12],xmm1[12],xmm3[13],xmm1[13],xmm3[14],xmm1[14],xmm3[15],xmm1[15] | |
| ; SSE-NEXT: pxor %xmm4, %xmm4 | |
| ; SSE-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm0[8],xmm4[9],xmm0[9],xmm4[10],xmm0[10],xmm4[11],xmm0[11],xmm4[12],xmm0[12],xmm4[13],xmm0[13],xmm4[14],xmm0[14],xmm4[15],xmm0[15] | |
| ; SSE-NEXT: pmulhw %xmm3, %xmm4 | |
| ; SSE-NEXT: psrlw $8, %xmm4 | |
| ; SSE-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3],xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7] | |
| ; SSE-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] | |
| ; SSE-NEXT: pmulhw %xmm3, %xmm2 | |
| ; SSE-NEXT: psrlw $8, %xmm2 | |
| ; SSE-NEXT: packuswb %xmm4, %xmm2 | |
| ; SSE-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v8i8: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 | |
| ; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 | |
| ; AVX2-NEXT: vpmullw %ymm1, %ymm0, %ymm0 | |
| ; AVX2-NEXT: vpsrlw $8, %ymm0, %ymm0 | |
| ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 | |
| ; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 | |
| ; AVX2-NEXT: vzeroupper | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v8i8: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmovsxbw %xmm1, %ymm1 | |
| ; AVX512-NEXT: vpmovsxbw %xmm0, %ymm0 | |
| ; AVX512-NEXT: vpmullw %ymm1, %ymm0, %ymm0 | |
| ; AVX512-NEXT: vpsrlw $8, %ymm0, %ymm0 | |
| ; AVX512-NEXT: vpmovwb %ymm0, %xmm0 | |
| ; AVX512-NEXT: vzeroupper | |
| ; AVX512-NEXT: retq | |
| %r = call <8 x i8> @llvm.smulh(<8 x i8> %x, <8 x i8> %y) | |
| ret <8 x i8> %r | |
| } | |
| define <4 x i16> @smulh_v4i16(<4 x i16> %x, <4 x i16> %y) nounwind { | |
| ; SSE-LABEL: smulh_v4i16: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pmulhw %xmm1, %xmm0 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: smulh_v4i16: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpmulhw %xmm1, %xmm0, %xmm0 | |
| ; AVX-NEXT: retq | |
| %r = call <4 x i16> @llvm.smulh(<4 x i16> %x, <4 x i16> %y) | |
| ret <4 x i16> %r | |
| } | |
| define <2 x i32> @smulh_v2i32(<2 x i32> %x, <2 x i32> %y) nounwind { | |
| ; SSE2-LABEL: smulh_v2i32: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE2-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE2-NEXT: pcmpgtd %xmm1, %xmm3 | |
| ; SSE2-NEXT: pand %xmm0, %xmm3 | |
| ; SSE2-NEXT: pcmpgtd %xmm0, %xmm2 | |
| ; SSE2-NEXT: pand %xmm1, %xmm2 | |
| ; SSE2-NEXT: paddd %xmm3, %xmm2 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE2-NEXT: pmuludq %xmm1, %xmm0 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3] | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; SSE2-NEXT: pmuludq %xmm3, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] | |
| ; SSE2-NEXT: psubd %xmm2, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: smulh_v2i32: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pmuldq %xmm2, %xmm3 | |
| ; SSE42-NEXT: pmuldq %xmm1, %xmm0 | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v2i32: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpmuldq %xmm2, %xmm3, %xmm2 | |
| ; AVX2-NEXT: vpmuldq %xmm1, %xmm0, %xmm0 | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v2i32: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmuldq %xmm1, %xmm0, %xmm2 | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX512-NEXT: vpmuldq %xmm1, %xmm0, %xmm1 | |
| ; AVX512-NEXT: vmovdqa {{.*#+}} xmm0 = [1,5,3,7] | |
| ; AVX512-NEXT: vpermi2d %xmm1, %xmm2, %xmm0 | |
| ; AVX512-NEXT: retq | |
| %r = call <2 x i32> @llvm.smulh(<2 x i32> %x, <2 x i32> %y) | |
| ret <2 x i32> %r | |
| } | |
| define <1 x i64> @smulh_v1i64(<1 x i64> %x, <1 x i64> %y) nounwind { | |
| ; CHECK-LABEL: smulh_v1i64: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: imulq %rsi | |
| ; CHECK-NEXT: movq %rdx, %rax | |
| ; CHECK-NEXT: retq | |
| %r = call <1 x i64> @llvm.smulh(<1 x i64> %x, <1 x i64> %y) | |
| ret <1 x i64> %r | |
| } | |
| define <16 x i8> @smulh_v16i8(<16 x i8> %x, <16 x i8> %y) nounwind { | |
| ; SSE-LABEL: smulh_v16i8: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm1[8],xmm3[9],xmm1[9],xmm3[10],xmm1[10],xmm3[11],xmm1[11],xmm3[12],xmm1[12],xmm3[13],xmm1[13],xmm3[14],xmm1[14],xmm3[15],xmm1[15] | |
| ; SSE-NEXT: pxor %xmm4, %xmm4 | |
| ; SSE-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm0[8],xmm4[9],xmm0[9],xmm4[10],xmm0[10],xmm4[11],xmm0[11],xmm4[12],xmm0[12],xmm4[13],xmm0[13],xmm4[14],xmm0[14],xmm4[15],xmm0[15] | |
| ; SSE-NEXT: pmulhw %xmm3, %xmm4 | |
| ; SSE-NEXT: psrlw $8, %xmm4 | |
| ; SSE-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3],xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7] | |
| ; SSE-NEXT: punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7] | |
| ; SSE-NEXT: pmulhw %xmm3, %xmm2 | |
| ; SSE-NEXT: psrlw $8, %xmm2 | |
| ; SSE-NEXT: packuswb %xmm4, %xmm2 | |
| ; SSE-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v16i8: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpmovsxbw %xmm1, %ymm1 | |
| ; AVX2-NEXT: vpmovsxbw %xmm0, %ymm0 | |
| ; AVX2-NEXT: vpmullw %ymm1, %ymm0, %ymm0 | |
| ; AVX2-NEXT: vpsrlw $8, %ymm0, %ymm0 | |
| ; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 | |
| ; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 | |
| ; AVX2-NEXT: vzeroupper | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v16i8: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmovsxbw %xmm1, %ymm1 | |
| ; AVX512-NEXT: vpmovsxbw %xmm0, %ymm0 | |
| ; AVX512-NEXT: vpmullw %ymm1, %ymm0, %ymm0 | |
| ; AVX512-NEXT: vpsrlw $8, %ymm0, %ymm0 | |
| ; AVX512-NEXT: vpmovwb %ymm0, %xmm0 | |
| ; AVX512-NEXT: vzeroupper | |
| ; AVX512-NEXT: retq | |
| %r = call <16 x i8> @llvm.smulh(<16 x i8> %x, <16 x i8> %y) | |
| ret <16 x i8> %r | |
| } | |
| define <8 x i16> @smulh_v8i16(<8 x i16> %x, <8 x i16> %y) nounwind { | |
| ; SSE-LABEL: smulh_v8i16: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pmulhw %xmm1, %xmm0 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: smulh_v8i16: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpmulhw %xmm1, %xmm0, %xmm0 | |
| ; AVX-NEXT: retq | |
| %r = call <8 x i16> @llvm.smulh(<8 x i16> %x, <8 x i16> %y) | |
| ret <8 x i16> %r | |
| } | |
| define <4 x i32> @smulh_v4i32(<4 x i32> %x, <4 x i32> %y) nounwind { | |
| ; SSE2-LABEL: smulh_v4i32: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE2-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE2-NEXT: pcmpgtd %xmm1, %xmm3 | |
| ; SSE2-NEXT: pand %xmm0, %xmm3 | |
| ; SSE2-NEXT: pcmpgtd %xmm0, %xmm2 | |
| ; SSE2-NEXT: pand %xmm1, %xmm2 | |
| ; SSE2-NEXT: paddd %xmm3, %xmm2 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE2-NEXT: pmuludq %xmm1, %xmm0 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3] | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; SSE2-NEXT: pmuludq %xmm3, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] | |
| ; SSE2-NEXT: psubd %xmm2, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: smulh_v4i32: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pmuldq %xmm2, %xmm3 | |
| ; SSE42-NEXT: pmuldq %xmm1, %xmm0 | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v4i32: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpmuldq %xmm2, %xmm3, %xmm2 | |
| ; AVX2-NEXT: vpmuldq %xmm1, %xmm0, %xmm0 | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v4i32: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmuldq %xmm1, %xmm0, %xmm2 | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX512-NEXT: vpmuldq %xmm1, %xmm0, %xmm1 | |
| ; AVX512-NEXT: vmovdqa {{.*#+}} xmm0 = [1,5,3,7] | |
| ; AVX512-NEXT: vpermi2d %xmm1, %xmm2, %xmm0 | |
| ; AVX512-NEXT: retq | |
| %r = call <4 x i32> @llvm.smulh(<4 x i32> %x, <4 x i32> %y) | |
| ret <4 x i32> %r | |
| } | |
| define <2 x i64> @smulh_v2i64(<2 x i64> %x, <2 x i64> %y) nounwind { | |
| ; SSE2-LABEL: smulh_v2i64: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: movq %xmm0, %rax | |
| ; SSE2-NEXT: movq %xmm1, %rcx | |
| ; SSE2-NEXT: imulq %rcx | |
| ; SSE2-NEXT: movq %rdx, %xmm2 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] | |
| ; SSE2-NEXT: movq %xmm0, %rax | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3] | |
| ; SSE2-NEXT: movq %xmm0, %rcx | |
| ; SSE2-NEXT: imulq %rcx | |
| ; SSE2-NEXT: movq %rdx, %xmm0 | |
| ; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0] | |
| ; SSE2-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: smulh_v2i64: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pextrq $1, %xmm0, %rax | |
| ; SSE42-NEXT: pextrq $1, %xmm1, %rcx | |
| ; SSE42-NEXT: imulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm2 | |
| ; SSE42-NEXT: movq %xmm0, %rax | |
| ; SSE42-NEXT: movq %xmm1, %rcx | |
| ; SSE42-NEXT: imulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm0 | |
| ; SSE42-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX-LABEL: smulh_v2i64: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpextrq $1, %xmm0, %rax | |
| ; AVX-NEXT: vpextrq $1, %xmm1, %rcx | |
| ; AVX-NEXT: imulq %rcx | |
| ; AVX-NEXT: vmovq %rdx, %xmm2 | |
| ; AVX-NEXT: vmovq %xmm0, %rax | |
| ; AVX-NEXT: vmovq %xmm1, %rcx | |
| ; AVX-NEXT: imulq %rcx | |
| ; AVX-NEXT: vmovq %rdx, %xmm0 | |
| ; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; AVX-NEXT: retq | |
| %r = call <2 x i64> @llvm.smulh(<2 x i64> %x, <2 x i64> %y) | |
| ret <2 x i64> %r | |
| } | |
| define <3 x i32> @smulh_v3i32(<3 x i32> %x, <3 x i32> %y) nounwind { | |
| ; SSE2-LABEL: smulh_v3i32: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE2-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE2-NEXT: pcmpgtd %xmm1, %xmm3 | |
| ; SSE2-NEXT: pand %xmm0, %xmm3 | |
| ; SSE2-NEXT: pcmpgtd %xmm0, %xmm2 | |
| ; SSE2-NEXT: pand %xmm1, %xmm2 | |
| ; SSE2-NEXT: paddd %xmm3, %xmm2 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE2-NEXT: pmuludq %xmm1, %xmm0 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3] | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; SSE2-NEXT: pmuludq %xmm3, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] | |
| ; SSE2-NEXT: psubd %xmm2, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: smulh_v3i32: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pmuldq %xmm2, %xmm3 | |
| ; SSE42-NEXT: pmuldq %xmm1, %xmm0 | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v3i32: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpmuldq %xmm2, %xmm3, %xmm2 | |
| ; AVX2-NEXT: vpmuldq %xmm1, %xmm0, %xmm0 | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3] | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v3i32: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmuldq %xmm1, %xmm0, %xmm2 | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX512-NEXT: vpmuldq %xmm1, %xmm0, %xmm1 | |
| ; AVX512-NEXT: vmovdqa {{.*#+}} xmm0 = [1,5,3,7] | |
| ; AVX512-NEXT: vpermi2d %xmm1, %xmm2, %xmm0 | |
| ; AVX512-NEXT: retq | |
| %r = call <3 x i32> @llvm.smulh(<3 x i32> %x, <3 x i32> %y) | |
| ret <3 x i32> %r | |
| } | |
| define <2 x i48> @smulh_v2i48(<2 x i48> %x, <2 x i48> %y) nounwind { | |
| ; SSE2-LABEL: smulh_v2i48: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[0,2,2,3] | |
| ; SSE2-NEXT: psllq $16, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: psrad $16, %xmm1 | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1] | |
| ; SSE2-NEXT: movq %xmm2, %rcx | |
| ; SSE2-NEXT: psllq $16, %xmm0 | |
| ; SSE2-NEXT: movq %xmm0, %rax | |
| ; SSE2-NEXT: imulq %rcx | |
| ; SSE2-NEXT: movq %rdx, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm2[2,3,2,3] | |
| ; SSE2-NEXT: movq %xmm2, %rcx | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] | |
| ; SSE2-NEXT: movq %xmm0, %rax | |
| ; SSE2-NEXT: imulq %rcx | |
| ; SSE2-NEXT: movq %rdx, %xmm0 | |
| ; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0] | |
| ; SSE2-NEXT: movdqa %xmm1, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: smulh_v2i48: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: movdqa %xmm1, %xmm2 | |
| ; SSE42-NEXT: psllq $16, %xmm2 | |
| ; SSE42-NEXT: psrad $16, %xmm2 | |
| ; SSE42-NEXT: pblendw {{.*#+}} xmm2 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] | |
| ; SSE42-NEXT: pextrq $1, %xmm2, %rcx | |
| ; SSE42-NEXT: psllq $16, %xmm0 | |
| ; SSE42-NEXT: pextrq $1, %xmm0, %rax | |
| ; SSE42-NEXT: imulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm1 | |
| ; SSE42-NEXT: movq %xmm2, %rcx | |
| ; SSE42-NEXT: movq %xmm0, %rax | |
| ; SSE42-NEXT: imulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm0 | |
| ; SSE42-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v2i48: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpsllq $16, %xmm1, %xmm2 | |
| ; AVX2-NEXT: vpsrad $16, %xmm2, %xmm2 | |
| ; AVX2-NEXT: vpblendd {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3] | |
| ; AVX2-NEXT: vpextrq $1, %xmm1, %rcx | |
| ; AVX2-NEXT: vpsllq $16, %xmm0, %xmm0 | |
| ; AVX2-NEXT: vpextrq $1, %xmm0, %rax | |
| ; AVX2-NEXT: imulq %rcx | |
| ; AVX2-NEXT: vmovq %rdx, %xmm2 | |
| ; AVX2-NEXT: vmovq %xmm1, %rcx | |
| ; AVX2-NEXT: vmovq %xmm0, %rax | |
| ; AVX2-NEXT: imulq %rcx | |
| ; AVX2-NEXT: vmovq %rdx, %xmm0 | |
| ; AVX2-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v2i48: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpsllq $16, %xmm1, %xmm1 | |
| ; AVX512-NEXT: vpsllq $16, %xmm0, %xmm0 | |
| ; AVX512-NEXT: vpextrq $1, %xmm0, %rax | |
| ; AVX512-NEXT: vpsraq $16, %xmm1, %xmm1 | |
| ; AVX512-NEXT: vpextrq $1, %xmm1, %rcx | |
| ; AVX512-NEXT: imulq %rcx | |
| ; AVX512-NEXT: vmovq %rdx, %xmm2 | |
| ; AVX512-NEXT: vmovq %xmm0, %rax | |
| ; AVX512-NEXT: vmovq %xmm1, %rcx | |
| ; AVX512-NEXT: imulq %rcx | |
| ; AVX512-NEXT: vmovq %rdx, %xmm0 | |
| ; AVX512-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; AVX512-NEXT: retq | |
| %r = call <2 x i48> @llvm.smulh(<2 x i48> %x, <2 x i48> %y) | |
| ret <2 x i48> %r | |
| } | |
| define <2 x i128> @smulh_v2i128(<2 x i128> %x, <2 x i128> %y) nounwind { | |
| ; SSE-LABEL: smulh_v2i128: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pushq %r15 | |
| ; SSE-NEXT: pushq %r14 | |
| ; SSE-NEXT: pushq %r12 | |
| ; SSE-NEXT: pushq %rbx | |
| ; SSE-NEXT: movq %rdx, %r10 | |
| ; SSE-NEXT: movq {{[0-9]+}}(%rsp), %r15 | |
| ; SSE-NEXT: movq %rdx, %r12 | |
| ; SSE-NEXT: sarq $63, %r12 | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r9 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: movq %r10, %rax | |
| ; SSE-NEXT: mulq %r9 | |
| ; SSE-NEXT: movq %rax, %rbx | |
| ; SSE-NEXT: movq %rdx, %r14 | |
| ; SSE-NEXT: imulq %r9, %r12 | |
| ; SSE-NEXT: addq %r11, %rbx | |
| ; SSE-NEXT: adcq %r12, %r14 | |
| ; SSE-NEXT: movq %r14, %r9 | |
| ; SSE-NEXT: sarq $63, %r9 | |
| ; SSE-NEXT: movq %r15, %r12 | |
| ; SSE-NEXT: sarq $63, %r12 | |
| ; SSE-NEXT: imulq %rsi, %r12 | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r15 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: addq %rbx, %rax | |
| ; SSE-NEXT: adcq %r12, %r11 | |
| ; SSE-NEXT: movq %r11, %rbx | |
| ; SSE-NEXT: sarq $63, %rbx | |
| ; SSE-NEXT: addq %r14, %r11 | |
| ; SSE-NEXT: adcq %r9, %rbx | |
| ; SSE-NEXT: movq %r10, %rax | |
| ; SSE-NEXT: imulq %r15 | |
| ; SSE-NEXT: movq %rdx, %rsi | |
| ; SSE-NEXT: movq %rax, %r9 | |
| ; SSE-NEXT: addq %r11, %r9 | |
| ; SSE-NEXT: adcq %rbx, %rsi | |
| ; SSE-NEXT: movq {{[0-9]+}}(%rsp), %r10 | |
| ; SSE-NEXT: movq %r8, %r14 | |
| ; SSE-NEXT: sarq $63, %r14 | |
| ; SSE-NEXT: imulq %r10, %r14 | |
| ; SSE-NEXT: movq %rcx, %rax | |
| ; SSE-NEXT: mulq %r10 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: movq %r8, %rax | |
| ; SSE-NEXT: mulq %r10 | |
| ; SSE-NEXT: movq %rdx, %r10 | |
| ; SSE-NEXT: movq %rax, %rbx | |
| ; SSE-NEXT: addq %r11, %rbx | |
| ; SSE-NEXT: adcq %r14, %r10 | |
| ; SSE-NEXT: movq {{[0-9]+}}(%rsp), %r14 | |
| ; SSE-NEXT: movq %r10, %r15 | |
| ; SSE-NEXT: sarq $63, %r15 | |
| ; SSE-NEXT: movq %r14, %r12 | |
| ; SSE-NEXT: sarq $63, %r12 | |
| ; SSE-NEXT: movq %rcx, %rax | |
| ; SSE-NEXT: mulq %r14 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: imulq %rcx, %r12 | |
| ; SSE-NEXT: addq %rbx, %rax | |
| ; SSE-NEXT: adcq %r12, %r11 | |
| ; SSE-NEXT: movq %r11, %rcx | |
| ; SSE-NEXT: sarq $63, %rcx | |
| ; SSE-NEXT: addq %r10, %r11 | |
| ; SSE-NEXT: adcq %r15, %rcx | |
| ; SSE-NEXT: movq %r8, %rax | |
| ; SSE-NEXT: imulq %r14 | |
| ; SSE-NEXT: addq %r11, %rax | |
| ; SSE-NEXT: adcq %rcx, %rdx | |
| ; SSE-NEXT: movq %rax, 16(%rdi) | |
| ; SSE-NEXT: movq %r9, (%rdi) | |
| ; SSE-NEXT: movq %rdx, 24(%rdi) | |
| ; SSE-NEXT: movq %rsi, 8(%rdi) | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: popq %rbx | |
| ; SSE-NEXT: popq %r12 | |
| ; SSE-NEXT: popq %r14 | |
| ; SSE-NEXT: popq %r15 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: smulh_v2i128: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: pushq %r15 | |
| ; AVX2-NEXT: pushq %r14 | |
| ; AVX2-NEXT: pushq %rbx | |
| ; AVX2-NEXT: movq %rdx, %rax | |
| ; AVX2-NEXT: movq {{[0-9]+}}(%rsp), %r10 | |
| ; AVX2-NEXT: movq %rdx, %r11 | |
| ; AVX2-NEXT: sarq $63, %r11 | |
| ; AVX2-NEXT: movq %rsi, %rdx | |
| ; AVX2-NEXT: mulxq %r9, %rbx, %rbx | |
| ; AVX2-NEXT: imulq %r9, %r11 | |
| ; AVX2-NEXT: movq %rax, %rdx | |
| ; AVX2-NEXT: mulxq %r9, %r9, %r14 | |
| ; AVX2-NEXT: addq %rbx, %r9 | |
| ; AVX2-NEXT: adcq %r11, %r14 | |
| ; AVX2-NEXT: movq %r14, %r11 | |
| ; AVX2-NEXT: sarq $63, %r11 | |
| ; AVX2-NEXT: movq %r10, %rbx | |
| ; AVX2-NEXT: sarq $63, %rbx | |
| ; AVX2-NEXT: movq %rsi, %rdx | |
| ; AVX2-NEXT: mulxq %r10, %rdx, %r15 | |
| ; AVX2-NEXT: imulq %rsi, %rbx | |
| ; AVX2-NEXT: addq %r9, %rdx | |
| ; AVX2-NEXT: adcq %rbx, %r15 | |
| ; AVX2-NEXT: movq %r15, %rbx | |
| ; AVX2-NEXT: sarq $63, %rbx | |
| ; AVX2-NEXT: addq %r14, %r15 | |
| ; AVX2-NEXT: adcq %r11, %rbx | |
| ; AVX2-NEXT: movq {{[0-9]+}}(%rsp), %r11 | |
| ; AVX2-NEXT: imulq %r10 | |
| ; AVX2-NEXT: movq %rdx, %rsi | |
| ; AVX2-NEXT: movq %rax, %r9 | |
| ; AVX2-NEXT: addq %r15, %r9 | |
| ; AVX2-NEXT: adcq %rbx, %rsi | |
| ; AVX2-NEXT: movq %r8, %rax | |
| ; AVX2-NEXT: movq %rcx, %rdx | |
| ; AVX2-NEXT: mulxq %r11, %r10, %r10 | |
| ; AVX2-NEXT: sarq $63, %rax | |
| ; AVX2-NEXT: movq %r8, %rdx | |
| ; AVX2-NEXT: mulxq %r11, %rbx, %r14 | |
| ; AVX2-NEXT: imulq %r11, %rax | |
| ; AVX2-NEXT: addq %r10, %rbx | |
| ; AVX2-NEXT: adcq %rax, %r14 | |
| ; AVX2-NEXT: movq {{[0-9]+}}(%rsp), %r10 | |
| ; AVX2-NEXT: movq %r14, %rax | |
| ; AVX2-NEXT: sarq $63, %rax | |
| ; AVX2-NEXT: movq %r10, %r11 | |
| ; AVX2-NEXT: sarq $63, %r11 | |
| ; AVX2-NEXT: imulq %rcx, %r11 | |
| ; AVX2-NEXT: movq %rcx, %rdx | |
| ; AVX2-NEXT: mulxq %r10, %rcx, %r15 | |
| ; AVX2-NEXT: addq %rbx, %rcx | |
| ; AVX2-NEXT: adcq %r11, %r15 | |
| ; AVX2-NEXT: movq %r15, %rcx | |
| ; AVX2-NEXT: sarq $63, %rcx | |
| ; AVX2-NEXT: addq %r14, %r15 | |
| ; AVX2-NEXT: adcq %rax, %rcx | |
| ; AVX2-NEXT: movq %r8, %rax | |
| ; AVX2-NEXT: imulq %r10 | |
| ; AVX2-NEXT: addq %r15, %rax | |
| ; AVX2-NEXT: adcq %rcx, %rdx | |
| ; AVX2-NEXT: movq %rax, 16(%rdi) | |
| ; AVX2-NEXT: movq %r9, (%rdi) | |
| ; AVX2-NEXT: movq %rdx, 24(%rdi) | |
| ; AVX2-NEXT: movq %rsi, 8(%rdi) | |
| ; AVX2-NEXT: movq %rdi, %rax | |
| ; AVX2-NEXT: popq %rbx | |
| ; AVX2-NEXT: popq %r14 | |
| ; AVX2-NEXT: popq %r15 | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: smulh_v2i128: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: pushq %r15 | |
| ; AVX512-NEXT: pushq %r14 | |
| ; AVX512-NEXT: pushq %r13 | |
| ; AVX512-NEXT: pushq %r12 | |
| ; AVX512-NEXT: pushq %rbx | |
| ; AVX512-NEXT: movq %rdx, %rax | |
| ; AVX512-NEXT: movq {{[0-9]+}}(%rsp), %r11 | |
| ; AVX512-NEXT: movq {{[0-9]+}}(%rsp), %r10 | |
| ; AVX512-NEXT: movq {{[0-9]+}}(%rsp), %rbx | |
| ; AVX512-NEXT: movq %rdx, %r14 | |
| ; AVX512-NEXT: sarq $63, %r14 | |
| ; AVX512-NEXT: imulq %r9, %r14 | |
| ; AVX512-NEXT: movq %rsi, %rdx | |
| ; AVX512-NEXT: mulxq %r9, %r15, %r15 | |
| ; AVX512-NEXT: movq %rax, %rdx | |
| ; AVX512-NEXT: mulxq %r9, %r9, %r12 | |
| ; AVX512-NEXT: addq %r15, %r9 | |
| ; AVX512-NEXT: adcq %r14, %r12 | |
| ; AVX512-NEXT: movq %r12, %r14 | |
| ; AVX512-NEXT: sarq $63, %r14 | |
| ; AVX512-NEXT: movq %rbx, %r15 | |
| ; AVX512-NEXT: sarq $63, %r15 | |
| ; AVX512-NEXT: imulq %rsi, %r15 | |
| ; AVX512-NEXT: movq %rsi, %rdx | |
| ; AVX512-NEXT: mulxq %rbx, %rdx, %r13 | |
| ; AVX512-NEXT: addq %r9, %rdx | |
| ; AVX512-NEXT: adcq %r15, %r13 | |
| ; AVX512-NEXT: movq %r13, %r15 | |
| ; AVX512-NEXT: sarq $63, %r15 | |
| ; AVX512-NEXT: addq %r12, %r13 | |
| ; AVX512-NEXT: adcq %r14, %r15 | |
| ; AVX512-NEXT: imulq %rbx | |
| ; AVX512-NEXT: movq %rdx, %rsi | |
| ; AVX512-NEXT: movq %rax, %r9 | |
| ; AVX512-NEXT: addq %r13, %r9 | |
| ; AVX512-NEXT: adcq %r15, %rsi | |
| ; AVX512-NEXT: movq %r8, %rax | |
| ; AVX512-NEXT: sarq $63, %rax | |
| ; AVX512-NEXT: imulq %r11, %rax | |
| ; AVX512-NEXT: movq %rcx, %rdx | |
| ; AVX512-NEXT: mulxq %r11, %rbx, %rbx | |
| ; AVX512-NEXT: movq %r8, %rdx | |
| ; AVX512-NEXT: mulxq %r11, %r11, %r14 | |
| ; AVX512-NEXT: addq %rbx, %r11 | |
| ; AVX512-NEXT: adcq %rax, %r14 | |
| ; AVX512-NEXT: movq %r14, %rax | |
| ; AVX512-NEXT: sarq $63, %rax | |
| ; AVX512-NEXT: movq %r10, %rbx | |
| ; AVX512-NEXT: sarq $63, %rbx | |
| ; AVX512-NEXT: imulq %rcx, %rbx | |
| ; AVX512-NEXT: movq %rcx, %rdx | |
| ; AVX512-NEXT: mulxq %r10, %rcx, %r15 | |
| ; AVX512-NEXT: addq %r11, %rcx | |
| ; AVX512-NEXT: adcq %rbx, %r15 | |
| ; AVX512-NEXT: movq %r15, %rcx | |
| ; AVX512-NEXT: sarq $63, %rcx | |
| ; AVX512-NEXT: addq %r14, %r15 | |
| ; AVX512-NEXT: adcq %rax, %rcx | |
| ; AVX512-NEXT: movq %r8, %rax | |
| ; AVX512-NEXT: imulq %r10 | |
| ; AVX512-NEXT: addq %r15, %rax | |
| ; AVX512-NEXT: adcq %rcx, %rdx | |
| ; AVX512-NEXT: movq %rax, 16(%rdi) | |
| ; AVX512-NEXT: movq %r9, (%rdi) | |
| ; AVX512-NEXT: movq %rdx, 24(%rdi) | |
| ; AVX512-NEXT: movq %rsi, 8(%rdi) | |
| ; AVX512-NEXT: movq %rdi, %rax | |
| ; AVX512-NEXT: popq %rbx | |
| ; AVX512-NEXT: popq %r12 | |
| ; AVX512-NEXT: popq %r13 | |
| ; AVX512-NEXT: popq %r14 | |
| ; AVX512-NEXT: popq %r15 | |
| ; AVX512-NEXT: retq | |
| %r = call <2 x i128> @llvm.smulh(<2 x i128> %x, <2 x i128> %y) | |
| ret <2 x i128> %r | |
| } |