| ; 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 @umulh_i16(i16 %x, i16 %y) nounwind { | |
| ; CHECK-LABEL: umulh_i16: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movzwl %si, %ecx | |
| ; CHECK-NEXT: movzwl %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.umulh(i16 %x, i16 %y) | |
| ret i16 %r | |
| } | |
| define i32 @umulh_i32(i32 %x, i32 %y) nounwind { | |
| ; CHECK-LABEL: umulh_i32: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %ecx | |
| ; CHECK-NEXT: movl %edi, %eax | |
| ; 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.umulh(i32 %x, i32 %y) | |
| ret i32 %r | |
| } | |
| define i64 @umulh_i64(i64 %x, i64 %y) nounwind { | |
| ; SSE-LABEL: umulh_i64: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %rsi | |
| ; SSE-NEXT: movq %rdx, %rax | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: umulh_i64: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: movq %rdi, %rdx | |
| ; AVX-NEXT: mulxq %rsi, %rax, %rax | |
| ; AVX-NEXT: retq | |
| %r = call i64 @llvm.umulh(i64 %x, i64 %y) | |
| ret i64 %r | |
| } | |
| define i96 @umulh_i96(i96 %x, i96 %y) nounwind { | |
| ; SSE-LABEL: umulh_i96: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: movq %rdx, %r8 | |
| ; SSE-NEXT: movl %ecx, %r10d | |
| ; SSE-NEXT: shldq $32, %rdi, %rsi | |
| ; SSE-NEXT: shlq $32, %rdi | |
| ; 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 %rdx, %rcx | |
| ; SSE-NEXT: movq %rax, %r8 | |
| ; SSE-NEXT: addq %r9, %r8 | |
| ; SSE-NEXT: adcq $0, %rcx | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %r10 | |
| ; SSE-NEXT: addq %r8, %rax | |
| ; SSE-NEXT: adcq %rdx, %rcx | |
| ; SSE-NEXT: setb %dil | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r10 | |
| ; SSE-NEXT: movzbl %dil, %esi | |
| ; SSE-NEXT: addq %rcx, %rax | |
| ; SSE-NEXT: adcq %rsi, %rdx | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: umulh_i96: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: movq %rdi, %rax | |
| ; AVX2-NEXT: shlq $32, %rax | |
| ; AVX2-NEXT: mulxq %rax, %r8, %r8 | |
| ; AVX2-NEXT: shldq $32, %rdi, %rsi | |
| ; AVX2-NEXT: mulxq %rsi, %rdi, %r9 | |
| ; AVX2-NEXT: addq %r8, %rdi | |
| ; AVX2-NEXT: adcq $0, %r9 | |
| ; AVX2-NEXT: movl %ecx, %ecx | |
| ; AVX2-NEXT: movq %rax, %rdx | |
| ; AVX2-NEXT: mulxq %rcx, %rax, %r8 | |
| ; AVX2-NEXT: addq %rdi, %rax | |
| ; AVX2-NEXT: adcq %r9, %r8 | |
| ; AVX2-NEXT: setb %dil | |
| ; AVX2-NEXT: movq %rsi, %rdx | |
| ; AVX2-NEXT: mulxq %rcx, %rax, %rdx | |
| ; AVX2-NEXT: movzbl %dil, %ecx | |
| ; AVX2-NEXT: addq %r8, %rax | |
| ; AVX2-NEXT: adcq %rcx, %rdx | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: umulh_i96: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: shldq $32, %rdi, %rsi | |
| ; AVX512-NEXT: shlq $32, %rdi | |
| ; AVX512-NEXT: mulxq %rdi, %rax, %rax | |
| ; AVX512-NEXT: movl %ecx, %ecx | |
| ; AVX512-NEXT: mulxq %rsi, %r8, %r9 | |
| ; AVX512-NEXT: addq %rax, %r8 | |
| ; AVX512-NEXT: adcq $0, %r9 | |
| ; AVX512-NEXT: movq %rdi, %rdx | |
| ; AVX512-NEXT: mulxq %rcx, %rax, %rdi | |
| ; AVX512-NEXT: addq %r8, %rax | |
| ; AVX512-NEXT: adcq %r9, %rdi | |
| ; AVX512-NEXT: setb %al | |
| ; AVX512-NEXT: movzbl %al, %r8d | |
| ; AVX512-NEXT: movq %rsi, %rdx | |
| ; AVX512-NEXT: mulxq %rcx, %rax, %rdx | |
| ; AVX512-NEXT: addq %rdi, %rax | |
| ; AVX512-NEXT: adcq %r8, %rdx | |
| ; AVX512-NEXT: retq | |
| %r = call i96 @llvm.umulh(i96 %x, i96 %y) | |
| ret i96 %r | |
| } | |
| define i128 @umulh_i128(i128 %x, i128 %y) nounwind { | |
| ; SSE-LABEL: umulh_i128: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: movq %rdx, %r8 | |
| ; SSE-NEXT: movq %rdi, %r9 | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %rdx | |
| ; SSE-NEXT: movq %rdx, %r10 | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r8 | |
| ; SSE-NEXT: movq %rdx, %rdi | |
| ; SSE-NEXT: movq %rax, %r8 | |
| ; SSE-NEXT: addq %r10, %r8 | |
| ; SSE-NEXT: adcq $0, %rdi | |
| ; SSE-NEXT: movq %r9, %rax | |
| ; SSE-NEXT: mulq %rcx | |
| ; SSE-NEXT: addq %r8, %rax | |
| ; SSE-NEXT: adcq %rdx, %rdi | |
| ; SSE-NEXT: setb %r8b | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %rcx | |
| ; SSE-NEXT: movzbl %r8b, %ecx | |
| ; SSE-NEXT: addq %rdi, %rax | |
| ; SSE-NEXT: adcq %rcx, %rdx | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: umulh_i128: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: mulxq %rdi, %rax, %rax | |
| ; AVX2-NEXT: mulxq %rsi, %r8, %r9 | |
| ; AVX2-NEXT: addq %rax, %r8 | |
| ; AVX2-NEXT: adcq $0, %r9 | |
| ; AVX2-NEXT: movq %rdi, %rdx | |
| ; AVX2-NEXT: mulxq %rcx, %rax, %rdi | |
| ; AVX2-NEXT: addq %r8, %rax | |
| ; AVX2-NEXT: adcq %r9, %rdi | |
| ; AVX2-NEXT: setb %r8b | |
| ; AVX2-NEXT: movq %rsi, %rdx | |
| ; AVX2-NEXT: mulxq %rcx, %rax, %rdx | |
| ; AVX2-NEXT: movzbl %r8b, %ecx | |
| ; AVX2-NEXT: addq %rdi, %rax | |
| ; AVX2-NEXT: adcq %rcx, %rdx | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: umulh_i128: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: mulxq %rdi, %rax, %rax | |
| ; AVX512-NEXT: mulxq %rsi, %r8, %r9 | |
| ; AVX512-NEXT: addq %rax, %r8 | |
| ; AVX512-NEXT: adcq $0, %r9 | |
| ; AVX512-NEXT: movq %rdi, %rdx | |
| ; AVX512-NEXT: mulxq %rcx, %rax, %rdi | |
| ; AVX512-NEXT: addq %r8, %rax | |
| ; AVX512-NEXT: adcq %r9, %rdi | |
| ; AVX512-NEXT: setb %al | |
| ; AVX512-NEXT: movzbl %al, %r8d | |
| ; AVX512-NEXT: movq %rsi, %rdx | |
| ; AVX512-NEXT: mulxq %rcx, %rax, %rdx | |
| ; AVX512-NEXT: addq %rdi, %rax | |
| ; AVX512-NEXT: adcq %r8, %rdx | |
| ; AVX512-NEXT: retq | |
| %r = call i128 @llvm.umulh(i128 %x, i128 %y) | |
| ret i128 %r | |
| } | |
| define <8 x i8> @umulh_v8i8(<8 x i8> %x, <8 x i8> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v8i8: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE2-NEXT: movdqa %xmm1, %xmm3 | |
| ; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15] | |
| ; SSE2-NEXT: movdqa %xmm0, %xmm4 | |
| ; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm2[8],xmm4[9],xmm2[9],xmm4[10],xmm2[10],xmm4[11],xmm2[11],xmm4[12],xmm2[12],xmm4[13],xmm2[13],xmm4[14],xmm2[14],xmm4[15],xmm2[15] | |
| ; SSE2-NEXT: pmullw %xmm3, %xmm4 | |
| ; SSE2-NEXT: psrlw $8, %xmm4 | |
| ; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7] | |
| ; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] | |
| ; SSE2-NEXT: pmullw %xmm1, %xmm0 | |
| ; SSE2-NEXT: psrlw $8, %xmm0 | |
| ; SSE2-NEXT: packuswb %xmm4, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v8i8: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE42-NEXT: pmovzxbw {{.*#+}} xmm4 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero | |
| ; SSE42-NEXT: punpckhbw {{.*#+}} xmm1 = xmm1[8],xmm3[8],xmm1[9],xmm3[9],xmm1[10],xmm3[10],xmm1[11],xmm3[11],xmm1[12],xmm3[12],xmm1[13],xmm3[13],xmm1[14],xmm3[14],xmm1[15],xmm3[15] | |
| ; SSE42-NEXT: pmovzxbw {{.*#+}} xmm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero | |
| ; SSE42-NEXT: punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm3[8],xmm0[9],xmm3[9],xmm0[10],xmm3[10],xmm0[11],xmm3[11],xmm0[12],xmm3[12],xmm0[13],xmm3[13],xmm0[14],xmm3[14],xmm0[15],xmm3[15] | |
| ; SSE42-NEXT: pmullw %xmm1, %xmm0 | |
| ; SSE42-NEXT: psrlw $8, %xmm0 | |
| ; SSE42-NEXT: pmullw %xmm4, %xmm2 | |
| ; SSE42-NEXT: psrlw $8, %xmm2 | |
| ; SSE42-NEXT: packuswb %xmm0, %xmm2 | |
| ; SSE42-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: umulh_v8i8: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero | |
| ; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero | |
| ; 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: umulh_v8i8: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero | |
| ; AVX512-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero | |
| ; 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.umulh(<8 x i8> %x, <8 x i8> %y) | |
| ret <8 x i8> %r | |
| } | |
| define <4 x i16> @umulh_v4i16(<4 x i16> %x, <4 x i16> %y) nounwind { | |
| ; SSE-LABEL: umulh_v4i16: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pmulhuw %xmm1, %xmm0 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: umulh_v4i16: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpmulhuw %xmm1, %xmm0, %xmm0 | |
| ; AVX-NEXT: retq | |
| %r = call <4 x i16> @llvm.umulh(<4 x i16> %x, <4 x i16> %y) | |
| ret <4 x i16> %r | |
| } | |
| define <2 x i32> @umulh_v2i32(<2 x i32> %x, <2 x i32> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v2i32: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = 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 %xmm2, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v2i32: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pmuludq %xmm2, %xmm3 | |
| ; SSE42-NEXT: pmuludq %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: umulh_v2i32: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpmuludq %xmm2, %xmm3, %xmm2 | |
| ; AVX2-NEXT: vpmuludq %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: umulh_v2i32: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmuludq %xmm1, %xmm0, %xmm2 | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX512-NEXT: vpmuludq %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.umulh(<2 x i32> %x, <2 x i32> %y) | |
| ret <2 x i32> %r | |
| } | |
| define <1 x i64> @umulh_v1i64(<1 x i64> %x, <1 x i64> %y) nounwind { | |
| ; SSE-LABEL: umulh_v1i64: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: movq %rdi, %rax | |
| ; SSE-NEXT: mulq %rsi | |
| ; SSE-NEXT: movq %rdx, %rax | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: umulh_v1i64: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: movq %rdi, %rdx | |
| ; AVX-NEXT: mulxq %rsi, %rax, %rax | |
| ; AVX-NEXT: retq | |
| %r = call <1 x i64> @llvm.umulh(<1 x i64> %x, <1 x i64> %y) | |
| ret <1 x i64> %r | |
| } | |
| define <16 x i8> @umulh_v16i8(<16 x i8> %x, <16 x i8> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v16i8: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE2-NEXT: movdqa %xmm1, %xmm3 | |
| ; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm2[8],xmm3[9],xmm2[9],xmm3[10],xmm2[10],xmm3[11],xmm2[11],xmm3[12],xmm2[12],xmm3[13],xmm2[13],xmm3[14],xmm2[14],xmm3[15],xmm2[15] | |
| ; SSE2-NEXT: movdqa %xmm0, %xmm4 | |
| ; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8],xmm2[8],xmm4[9],xmm2[9],xmm4[10],xmm2[10],xmm4[11],xmm2[11],xmm4[12],xmm2[12],xmm4[13],xmm2[13],xmm4[14],xmm2[14],xmm4[15],xmm2[15] | |
| ; SSE2-NEXT: pmullw %xmm3, %xmm4 | |
| ; SSE2-NEXT: psrlw $8, %xmm4 | |
| ; SSE2-NEXT: punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3],xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7] | |
| ; SSE2-NEXT: punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7] | |
| ; SSE2-NEXT: pmullw %xmm1, %xmm0 | |
| ; SSE2-NEXT: psrlw $8, %xmm0 | |
| ; SSE2-NEXT: packuswb %xmm4, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v16i8: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pxor %xmm3, %xmm3 | |
| ; SSE42-NEXT: pmovzxbw {{.*#+}} xmm4 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero | |
| ; SSE42-NEXT: punpckhbw {{.*#+}} xmm1 = xmm1[8],xmm3[8],xmm1[9],xmm3[9],xmm1[10],xmm3[10],xmm1[11],xmm3[11],xmm1[12],xmm3[12],xmm1[13],xmm3[13],xmm1[14],xmm3[14],xmm1[15],xmm3[15] | |
| ; SSE42-NEXT: pmovzxbw {{.*#+}} xmm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero | |
| ; SSE42-NEXT: punpckhbw {{.*#+}} xmm0 = xmm0[8],xmm3[8],xmm0[9],xmm3[9],xmm0[10],xmm3[10],xmm0[11],xmm3[11],xmm0[12],xmm3[12],xmm0[13],xmm3[13],xmm0[14],xmm3[14],xmm0[15],xmm3[15] | |
| ; SSE42-NEXT: pmullw %xmm1, %xmm0 | |
| ; SSE42-NEXT: psrlw $8, %xmm0 | |
| ; SSE42-NEXT: pmullw %xmm4, %xmm2 | |
| ; SSE42-NEXT: psrlw $8, %xmm2 | |
| ; SSE42-NEXT: packuswb %xmm0, %xmm2 | |
| ; SSE42-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX2-LABEL: umulh_v16i8: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero | |
| ; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero | |
| ; 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: umulh_v16i8: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero | |
| ; AVX512-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero | |
| ; 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.umulh(<16 x i8> %x, <16 x i8> %y) | |
| ret <16 x i8> %r | |
| } | |
| define <8 x i16> @umulh_v8i16(<8 x i16> %x, <8 x i16> %y) nounwind { | |
| ; SSE-LABEL: umulh_v8i16: | |
| ; SSE: # %bb.0: | |
| ; SSE-NEXT: pmulhuw %xmm1, %xmm0 | |
| ; SSE-NEXT: retq | |
| ; | |
| ; AVX-LABEL: umulh_v8i16: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpmulhuw %xmm1, %xmm0, %xmm0 | |
| ; AVX-NEXT: retq | |
| %r = call <8 x i16> @llvm.umulh(<8 x i16> %x, <8 x i16> %y) | |
| ret <8 x i16> %r | |
| } | |
| define <4 x i32> @umulh_v4i32(<4 x i32> %x, <4 x i32> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v4i32: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = 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 %xmm2, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v4i32: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pmuludq %xmm2, %xmm3 | |
| ; SSE42-NEXT: pmuludq %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: umulh_v4i32: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpmuludq %xmm2, %xmm3, %xmm2 | |
| ; AVX2-NEXT: vpmuludq %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: umulh_v4i32: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmuludq %xmm1, %xmm0, %xmm2 | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX512-NEXT: vpmuludq %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.umulh(<4 x i32> %x, <4 x i32> %y) | |
| ret <4 x i32> %r | |
| } | |
| define <2 x i64> @umulh_v2i64(<2 x i64> %x, <2 x i64> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v2i64: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: movq %xmm0, %rax | |
| ; SSE2-NEXT: movq %xmm1, %rcx | |
| ; SSE2-NEXT: mulq %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: mulq %rcx | |
| ; SSE2-NEXT: movq %rdx, %xmm0 | |
| ; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0] | |
| ; SSE2-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v2i64: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pextrq $1, %xmm0, %rax | |
| ; SSE42-NEXT: pextrq $1, %xmm1, %rcx | |
| ; SSE42-NEXT: mulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm2 | |
| ; SSE42-NEXT: movq %xmm0, %rax | |
| ; SSE42-NEXT: movq %xmm1, %rcx | |
| ; SSE42-NEXT: mulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm0 | |
| ; SSE42-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX-LABEL: umulh_v2i64: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpextrq $1, %xmm0, %rdx | |
| ; AVX-NEXT: vpextrq $1, %xmm1, %rax | |
| ; AVX-NEXT: mulxq %rax, %rax, %rax | |
| ; AVX-NEXT: vmovq %rax, %xmm2 | |
| ; AVX-NEXT: vmovq %xmm0, %rdx | |
| ; AVX-NEXT: vmovq %xmm1, %rax | |
| ; AVX-NEXT: mulxq %rax, %rax, %rax | |
| ; AVX-NEXT: vmovq %rax, %xmm0 | |
| ; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; AVX-NEXT: retq | |
| %r = call <2 x i64> @llvm.umulh(<2 x i64> %x, <2 x i64> %y) | |
| ret <2 x i64> %r | |
| } | |
| define <3 x i32> @umulh_v3i32(<3 x i32> %x, <3 x i32> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v3i32: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = 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 %xmm2, %xmm1 | |
| ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3] | |
| ; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v3i32: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; SSE42-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; SSE42-NEXT: pmuludq %xmm2, %xmm3 | |
| ; SSE42-NEXT: pmuludq %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: umulh_v3i32: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm2 = xmm1[1,1,3,3] | |
| ; AVX2-NEXT: vpshufd {{.*#+}} xmm3 = xmm0[1,1,3,3] | |
| ; AVX2-NEXT: vpmuludq %xmm2, %xmm3, %xmm2 | |
| ; AVX2-NEXT: vpmuludq %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: umulh_v3i32: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: vpmuludq %xmm1, %xmm0, %xmm2 | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm1 = xmm1[1,1,3,3] | |
| ; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3] | |
| ; AVX512-NEXT: vpmuludq %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.umulh(<3 x i32> %x, <3 x i32> %y) | |
| ret <3 x i32> %r | |
| } | |
| define <2 x i48> @umulh_v2i48(<2 x i48> %x, <2 x i48> %y) nounwind { | |
| ; SSE2-LABEL: umulh_v2i48: | |
| ; SSE2: # %bb.0: | |
| ; SSE2-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 | |
| ; SSE2-NEXT: psllq $16, %xmm0 | |
| ; SSE2-NEXT: movq %xmm0, %rax | |
| ; SSE2-NEXT: movq %xmm1, %rcx | |
| ; SSE2-NEXT: mulq %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: mulq %rcx | |
| ; SSE2-NEXT: movq %rdx, %xmm0 | |
| ; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0] | |
| ; SSE2-NEXT: movdqa %xmm2, %xmm0 | |
| ; SSE2-NEXT: retq | |
| ; | |
| ; SSE42-LABEL: umulh_v2i48: | |
| ; SSE42: # %bb.0: | |
| ; SSE42-NEXT: pxor %xmm2, %xmm2 | |
| ; SSE42-NEXT: pblendw {{.*#+}} xmm2 = xmm1[0,1,2],xmm2[3],xmm1[4,5,6],xmm2[7] | |
| ; SSE42-NEXT: pextrq $1, %xmm2, %rcx | |
| ; SSE42-NEXT: psllq $16, %xmm0 | |
| ; SSE42-NEXT: pextrq $1, %xmm0, %rax | |
| ; SSE42-NEXT: mulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm1 | |
| ; SSE42-NEXT: movq %xmm2, %rcx | |
| ; SSE42-NEXT: movq %xmm0, %rax | |
| ; SSE42-NEXT: mulq %rcx | |
| ; SSE42-NEXT: movq %rdx, %xmm0 | |
| ; SSE42-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] | |
| ; SSE42-NEXT: retq | |
| ; | |
| ; AVX-LABEL: umulh_v2i48: | |
| ; AVX: # %bb.0: | |
| ; AVX-NEXT: vpxor %xmm2, %xmm2, %xmm2 | |
| ; AVX-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1,2],xmm2[3],xmm1[4,5,6],xmm2[7] | |
| ; AVX-NEXT: vpextrq $1, %xmm1, %rax | |
| ; AVX-NEXT: vpsllq $16, %xmm0, %xmm0 | |
| ; AVX-NEXT: vpextrq $1, %xmm0, %rdx | |
| ; AVX-NEXT: mulxq %rax, %rax, %rax | |
| ; AVX-NEXT: vmovq %rax, %xmm2 | |
| ; AVX-NEXT: vmovq %xmm1, %rax | |
| ; AVX-NEXT: vmovq %xmm0, %rdx | |
| ; AVX-NEXT: mulxq %rax, %rax, %rax | |
| ; AVX-NEXT: vmovq %rax, %xmm0 | |
| ; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] | |
| ; AVX-NEXT: retq | |
| %r = call <2 x i48> @llvm.umulh(<2 x i48> %x, <2 x i48> %y) | |
| ret <2 x i48> %r | |
| } | |
| define <2 x i128> @umulh_v2i128(<2 x i128> %x, <2 x i128> %y) nounwind { | |
| ; SSE-LABEL: umulh_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 %rsi, %rax | |
| ; SSE-NEXT: mulq %r9 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: movq %r10, %rax | |
| ; SSE-NEXT: mulq %r9 | |
| ; SSE-NEXT: movq %rdx, %r9 | |
| ; SSE-NEXT: movq %rax, %rbx | |
| ; SSE-NEXT: addq %r11, %rbx | |
| ; SSE-NEXT: adcq $0, %r9 | |
| ; SSE-NEXT: movq {{[0-9]+}}(%rsp), %r12 | |
| ; SSE-NEXT: movq %rsi, %rax | |
| ; SSE-NEXT: mulq %r12 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: movq {{[0-9]+}}(%rsp), %r14 | |
| ; SSE-NEXT: addq %rbx, %rax | |
| ; SSE-NEXT: adcq %r9, %r11 | |
| ; SSE-NEXT: setb %al | |
| ; SSE-NEXT: movzbl %al, %ebx | |
| ; SSE-NEXT: movq %r10, %rax | |
| ; SSE-NEXT: mulq %r12 | |
| ; SSE-NEXT: movq %rdx, %rsi | |
| ; SSE-NEXT: movq %rax, %r9 | |
| ; SSE-NEXT: addq %r11, %r9 | |
| ; SSE-NEXT: adcq %rbx, %rsi | |
| ; SSE-NEXT: movq %rcx, %rax | |
| ; SSE-NEXT: mulq %r15 | |
| ; SSE-NEXT: movq %rdx, %r10 | |
| ; SSE-NEXT: movq %r8, %rax | |
| ; SSE-NEXT: mulq %r15 | |
| ; SSE-NEXT: movq %rdx, %r11 | |
| ; SSE-NEXT: movq %rax, %rbx | |
| ; SSE-NEXT: addq %r10, %rbx | |
| ; SSE-NEXT: adcq $0, %r11 | |
| ; SSE-NEXT: movq %rcx, %rax | |
| ; SSE-NEXT: mulq %r14 | |
| ; SSE-NEXT: movq %rdx, %rcx | |
| ; SSE-NEXT: addq %rbx, %rax | |
| ; SSE-NEXT: adcq %r11, %rcx | |
| ; SSE-NEXT: setb %al | |
| ; SSE-NEXT: movzbl %al, %r10d | |
| ; SSE-NEXT: movq %r8, %rax | |
| ; SSE-NEXT: mulq %r14 | |
| ; SSE-NEXT: addq %rcx, %rax | |
| ; SSE-NEXT: adcq %r10, %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: umulh_v2i128: | |
| ; AVX2: # %bb.0: | |
| ; AVX2-NEXT: pushq %r14 | |
| ; AVX2-NEXT: pushq %rbx | |
| ; AVX2-NEXT: movq %rdx, %rax | |
| ; AVX2-NEXT: movq %rsi, %rdx | |
| ; AVX2-NEXT: mulxq %r9, %r10, %r10 | |
| ; AVX2-NEXT: movq {{[0-9]+}}(%rsp), %r11 | |
| ; AVX2-NEXT: movq %rax, %rdx | |
| ; AVX2-NEXT: mulxq %r9, %r9, %rbx | |
| ; AVX2-NEXT: movq {{[0-9]+}}(%rsp), %r14 | |
| ; AVX2-NEXT: addq %r10, %r9 | |
| ; AVX2-NEXT: adcq $0, %rbx | |
| ; AVX2-NEXT: movq %rsi, %rdx | |
| ; AVX2-NEXT: mulxq %r14, %rdx, %r10 | |
| ; AVX2-NEXT: addq %r9, %rdx | |
| ; AVX2-NEXT: adcq %rbx, %r10 | |
| ; AVX2-NEXT: setb %dl | |
| ; AVX2-NEXT: movzbl %dl, %ebx | |
| ; AVX2-NEXT: movq %rax, %rdx | |
| ; AVX2-NEXT: mulxq %r14, %r9, %rsi | |
| ; AVX2-NEXT: addq %r10, %r9 | |
| ; AVX2-NEXT: adcq %rbx, %rsi | |
| ; AVX2-NEXT: movq %rcx, %rdx | |
| ; AVX2-NEXT: mulxq %r11, %rax, %rax | |
| ; AVX2-NEXT: movq %r8, %rdx | |
| ; AVX2-NEXT: mulxq %r11, %r10, %r11 | |
| ; AVX2-NEXT: addq %rax, %r10 | |
| ; AVX2-NEXT: adcq $0, %r11 | |
| ; AVX2-NEXT: movq {{[0-9]+}}(%rsp), %rbx | |
| ; AVX2-NEXT: movq %rcx, %rdx | |
| ; AVX2-NEXT: mulxq %rbx, %rcx, %r14 | |
| ; AVX2-NEXT: movq %rdi, %rax | |
| ; AVX2-NEXT: addq %r10, %rcx | |
| ; AVX2-NEXT: adcq %r11, %r14 | |
| ; AVX2-NEXT: setb %cl | |
| ; AVX2-NEXT: movq %r8, %rdx | |
| ; AVX2-NEXT: mulxq %rbx, %rdx, %rdi | |
| ; AVX2-NEXT: movzbl %cl, %ecx | |
| ; AVX2-NEXT: addq %r14, %rdx | |
| ; AVX2-NEXT: adcq %rcx, %rdi | |
| ; AVX2-NEXT: movq %rdx, 16(%rax) | |
| ; AVX2-NEXT: movq %r9, (%rax) | |
| ; AVX2-NEXT: movq %rdi, 24(%rax) | |
| ; AVX2-NEXT: movq %rsi, 8(%rax) | |
| ; AVX2-NEXT: popq %rbx | |
| ; AVX2-NEXT: popq %r14 | |
| ; AVX2-NEXT: retq | |
| ; | |
| ; AVX512-LABEL: umulh_v2i128: | |
| ; AVX512: # %bb.0: | |
| ; AVX512-NEXT: pushq %r15 | |
| ; AVX512-NEXT: pushq %r14 | |
| ; AVX512-NEXT: pushq %rbx | |
| ; AVX512-NEXT: movq %rdx, %r10 | |
| ; AVX512-NEXT: movq %rdi, %rax | |
| ; AVX512-NEXT: movq {{[0-9]+}}(%rsp), %r11 | |
| ; AVX512-NEXT: movq {{[0-9]+}}(%rsp), %rdi | |
| ; AVX512-NEXT: movq {{[0-9]+}}(%rsp), %rbx | |
| ; AVX512-NEXT: movq %rsi, %rdx | |
| ; AVX512-NEXT: mulxq %r9, %r14, %r14 | |
| ; AVX512-NEXT: movq %r10, %rdx | |
| ; AVX512-NEXT: mulxq %r9, %r9, %r15 | |
| ; AVX512-NEXT: addq %r14, %r9 | |
| ; AVX512-NEXT: adcq $0, %r15 | |
| ; AVX512-NEXT: movq %rsi, %rdx | |
| ; AVX512-NEXT: mulxq %rbx, %rdx, %r14 | |
| ; AVX512-NEXT: addq %r9, %rdx | |
| ; AVX512-NEXT: adcq %r15, %r14 | |
| ; AVX512-NEXT: setb %dl | |
| ; AVX512-NEXT: movzbl %dl, %r9d | |
| ; AVX512-NEXT: movq %r10, %rdx | |
| ; AVX512-NEXT: mulxq %rbx, %r10, %rsi | |
| ; AVX512-NEXT: addq %r14, %r10 | |
| ; AVX512-NEXT: adcq %r9, %rsi | |
| ; AVX512-NEXT: movq %rcx, %rdx | |
| ; AVX512-NEXT: mulxq %r11, %r9, %r9 | |
| ; AVX512-NEXT: movq %r8, %rdx | |
| ; AVX512-NEXT: mulxq %r11, %r11, %rbx | |
| ; AVX512-NEXT: addq %r9, %r11 | |
| ; AVX512-NEXT: adcq $0, %rbx | |
| ; AVX512-NEXT: movq %rcx, %rdx | |
| ; AVX512-NEXT: mulxq %rdi, %rcx, %r9 | |
| ; AVX512-NEXT: addq %r11, %rcx | |
| ; AVX512-NEXT: adcq %rbx, %r9 | |
| ; AVX512-NEXT: setb %cl | |
| ; AVX512-NEXT: movzbl %cl, %ecx | |
| ; AVX512-NEXT: movq %r8, %rdx | |
| ; AVX512-NEXT: mulxq %rdi, %rdx, %rdi | |
| ; AVX512-NEXT: addq %r9, %rdx | |
| ; AVX512-NEXT: adcq %rcx, %rdi | |
| ; AVX512-NEXT: movq %rdx, 16(%rax) | |
| ; AVX512-NEXT: movq %r10, (%rax) | |
| ; AVX512-NEXT: movq %rdi, 24(%rax) | |
| ; AVX512-NEXT: movq %rsi, 8(%rax) | |
| ; AVX512-NEXT: popq %rbx | |
| ; AVX512-NEXT: popq %r14 | |
| ; AVX512-NEXT: popq %r15 | |
| ; AVX512-NEXT: retq | |
| %r = call <2 x i128> @llvm.umulh(<2 x i128> %x, <2 x i128> %y) | |
| ret <2 x i128> %r | |
| } |