[llvm] [X86] Add test coverage for #176879 (PR #177393)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 22 09:01:58 PST 2026
https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/177393
>From d900e1965807670c4283a8b2b0f99352019a6fcd Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 22 Jan 2026 16:27:19 +0000
Subject: [PATCH] [X86] Add test coverage for #176879
---
llvm/test/CodeGen/X86/pclmulqdq.ll | 545 +++++++++++++++++++++++++++++
1 file changed, 545 insertions(+)
create mode 100644 llvm/test/CodeGen/X86/pclmulqdq.ll
diff --git a/llvm/test/CodeGen/X86/pclmulqdq.ll b/llvm/test/CodeGen/X86/pclmulqdq.ll
new file mode 100644
index 0000000000000..c72399c0633c9
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pclmulqdq.ll
@@ -0,0 +1,545 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+pclmul | FileCheck %s --check-prefixes=SSE
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx,+pclmul | FileCheck %s --check-prefixes=AVX,AVX-PCLMUL
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx,+vpclmulqdq | FileCheck %s --check-prefixes=AVX,AVX-VPCLMULQDQ
+
+; PR176879 - Match PCLMULQDQ codegen with llvm.clmul intrinsic implementations
+
+define <2 x i64> @pclmul128_lo_hi(<2 x i64> %v0, <2 x i64> %v1) {
+; SSE-LABEL: pclmul128_lo_hi:
+; SSE: # %bb.0:
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: movq %rax, %xmm2
+; SSE-NEXT: movdqa %xmm1, %xmm3
+; SSE-NEXT: pclmulqdq $1, %xmm2, %xmm3
+; SSE-NEXT: movq %xmm3, %rax
+; SSE-NEXT: pclmulqdq $0, %xmm0, %xmm2
+; SSE-NEXT: movq %xmm2, %rcx
+; SSE-NEXT: xorq %rax, %rcx
+; SSE-NEXT: pclmulqdq $16, %xmm1, %xmm0
+; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE-NEXT: movq %xmm1, %rax
+; SSE-NEXT: xorq %rcx, %rax
+; SSE-NEXT: movq %rax, %xmm1
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pclmul128_lo_hi:
+; AVX: # %bb.0:
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: vmovq %rax, %xmm2
+; AVX-NEXT: vpclmulqdq $1, %xmm2, %xmm1, %xmm3
+; AVX-NEXT: vmovq %xmm3, %rax
+; AVX-NEXT: vpclmulqdq $0, %xmm2, %xmm0, %xmm2
+; AVX-NEXT: vmovq %xmm2, %rcx
+; AVX-NEXT: xorq %rax, %rcx
+; AVX-NEXT: vpclmulqdq $16, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: vpextrq $1, %xmm0, %rax
+; AVX-NEXT: xorq %rcx, %rax
+; AVX-NEXT: vmovq %rax, %xmm1
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; AVX-NEXT: retq
+ %i0 = zext i1 0 to i64 ; constant time lo/hi select
+ %i1 = zext i1 1 to i64 ; constant time lo/hi select
+ %a0 = extractelement <2 x i64> %v0, i64 %i0
+ %a1 = extractelement <2 x i64> %v1, i64 %i1
+ %x0 = zext i64 %a0 to i128
+ %x1 = zext i64 %a1 to i128
+ %cl = call i128 @llvm.clmul.i128(i128 %x0, i128 %x1)
+ %r = bitcast i128 %cl to <2 x i64>
+ ret <2 x i64> %r
+}
+
+define <2 x i64> @pclmul128_hi_hi(<2 x i64> %v0, <2 x i64> %v1) {
+; SSE-LABEL: pclmul128_hi_hi:
+; SSE: # %bb.0:
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: movq %rax, %xmm2
+; SSE-NEXT: movdqa %xmm1, %xmm3
+; SSE-NEXT: pclmulqdq $1, %xmm2, %xmm3
+; SSE-NEXT: movq %xmm3, %rax
+; SSE-NEXT: pclmulqdq $16, %xmm0, %xmm2
+; SSE-NEXT: movq %xmm2, %rcx
+; SSE-NEXT: xorq %rax, %rcx
+; SSE-NEXT: pclmulqdq $17, %xmm1, %xmm0
+; SSE-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
+; SSE-NEXT: movq %xmm1, %rax
+; SSE-NEXT: xorq %rcx, %rax
+; SSE-NEXT: movq %rax, %xmm1
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pclmul128_hi_hi:
+; AVX: # %bb.0:
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: vmovq %rax, %xmm2
+; AVX-NEXT: vpclmulqdq $1, %xmm2, %xmm1, %xmm3
+; AVX-NEXT: vmovq %xmm3, %rax
+; AVX-NEXT: vpclmulqdq $1, %xmm2, %xmm0, %xmm2
+; AVX-NEXT: vmovq %xmm2, %rcx
+; AVX-NEXT: xorq %rax, %rcx
+; AVX-NEXT: vpclmulqdq $17, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: vpextrq $1, %xmm0, %rax
+; AVX-NEXT: xorq %rcx, %rax
+; AVX-NEXT: vmovq %rax, %xmm1
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; AVX-NEXT: retq
+ %i0 = zext i1 1 to i64 ; constant time lo/hi select
+ %i1 = zext i1 1 to i64 ; constant time lo/hi select
+ %a0 = extractelement <2 x i64> %v0, i64 %i0
+ %a1 = extractelement <2 x i64> %v1, i64 %i1
+ %x0 = zext i64 %a0 to i128
+ %x1 = zext i64 %a1 to i128
+ %cl = call i128 @llvm.clmul.i128(i128 %x0, i128 %x1)
+ %r = bitcast i128 %cl to <2 x i64>
+ ret <2 x i64> %r
+}
+
+define <4 x i64> @pclmul256_lo_lo(<4 x i64> %v0, <4 x i64> %v1) {
+; SSE-LABEL: pclmul256_lo_lo:
+; SSE: # %bb.0:
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: movq %rax, %xmm4
+; SSE-NEXT: movdqa %xmm0, %xmm5
+; SSE-NEXT: pclmulqdq $0, %xmm2, %xmm0
+; SSE-NEXT: pclmulqdq $0, %xmm4, %xmm2
+; SSE-NEXT: movq %xmm2, %rax
+; SSE-NEXT: pclmulqdq $0, %xmm4, %xmm5
+; SSE-NEXT: movq %xmm5, %rcx
+; SSE-NEXT: xorq %rax, %rcx
+; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE-NEXT: movq %xmm2, %rax
+; SSE-NEXT: xorq %rcx, %rax
+; SSE-NEXT: movdqa %xmm3, %xmm2
+; SSE-NEXT: pclmulqdq $0, %xmm4, %xmm2
+; SSE-NEXT: movq %xmm2, %rcx
+; SSE-NEXT: pclmulqdq $0, %xmm1, %xmm4
+; SSE-NEXT: movq %xmm4, %rdx
+; SSE-NEXT: xorq %rcx, %rdx
+; SSE-NEXT: pclmulqdq $0, %xmm3, %xmm1
+; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
+; SSE-NEXT: movq %xmm2, %rcx
+; SSE-NEXT: xorq %rdx, %rcx
+; SSE-NEXT: movq %rax, %xmm2
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; SSE-NEXT: movq %rcx, %xmm2
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pclmul256_lo_lo:
+; AVX: # %bb.0:
+; AVX-NEXT: vextractf128 $1, %ymm0, %xmm2
+; AVX-NEXT: vextractf128 $1, %ymm1, %xmm3
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: vmovq %rax, %xmm4
+; AVX-NEXT: vpclmulqdq $0, %xmm4, %xmm1, %xmm5
+; AVX-NEXT: vmovq %xmm5, %rax
+; AVX-NEXT: vpclmulqdq $0, %xmm4, %xmm0, %xmm5
+; AVX-NEXT: vmovq %xmm5, %rcx
+; AVX-NEXT: xorq %rax, %rcx
+; AVX-NEXT: vpclmulqdq $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: vpextrq $1, %xmm0, %rax
+; AVX-NEXT: xorq %rcx, %rax
+; AVX-NEXT: vpclmulqdq $0, %xmm4, %xmm3, %xmm1
+; AVX-NEXT: vmovq %xmm1, %rcx
+; AVX-NEXT: vpclmulqdq $0, %xmm4, %xmm2, %xmm1
+; AVX-NEXT: vmovq %xmm1, %rdx
+; AVX-NEXT: xorq %rcx, %rdx
+; AVX-NEXT: vpclmulqdq $0, %xmm3, %xmm2, %xmm1
+; AVX-NEXT: vpextrq $1, %xmm1, %rcx
+; AVX-NEXT: xorq %rdx, %rcx
+; AVX-NEXT: vmovq %rcx, %xmm2
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; AVX-NEXT: vmovq %rax, %xmm2
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; AVX-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
+; AVX-NEXT: retq
+ %i0 = zext i1 0 to i64 ; constant time lo/hi select
+ %i1 = zext i1 0 to i64 ; constant time lo/hi select
+ %i2 = add i64 %i0, 2
+ %i3 = add i64 %i1, 2
+ %a0 = extractelement <4 x i64> %v0, i64 %i0
+ %a1 = extractelement <4 x i64> %v1, i64 %i1
+ %a2 = extractelement <4 x i64> %v0, i64 %i2
+ %a3 = extractelement <4 x i64> %v1, i64 %i3
+ %x0 = zext i64 %a0 to i128
+ %x1 = zext i64 %a1 to i128
+ %x2 = zext i64 %a2 to i128
+ %x3 = zext i64 %a3 to i128
+ %c0 = call i128 @llvm.clmul.i128(i128 %x0, i128 %x1)
+ %c1 = call i128 @llvm.clmul.i128(i128 %x2, i128 %x3)
+ %r0 = bitcast i128 %c0 to <2 x i64>
+ %r1 = bitcast i128 %c1 to <2 x i64>
+ %r = shufflevector <2 x i64> %r0, <2 x i64> %r1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x i64> %r
+}
+
+define <4 x i64> @pclmul256_lo_hi(<4 x i64> %v0, <4 x i64> %v1) {
+; SSE-LABEL: pclmul256_lo_hi:
+; SSE: # %bb.0:
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: movq %rax, %xmm4
+; SSE-NEXT: movdqa %xmm0, %xmm5
+; SSE-NEXT: pclmulqdq $16, %xmm2, %xmm0
+; SSE-NEXT: pclmulqdq $1, %xmm4, %xmm2
+; SSE-NEXT: movq %xmm2, %rax
+; SSE-NEXT: pclmulqdq $0, %xmm4, %xmm5
+; SSE-NEXT: movq %xmm5, %rcx
+; SSE-NEXT: xorq %rax, %rcx
+; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
+; SSE-NEXT: movq %xmm2, %rax
+; SSE-NEXT: xorq %rcx, %rax
+; SSE-NEXT: movdqa %xmm3, %xmm2
+; SSE-NEXT: pclmulqdq $1, %xmm4, %xmm2
+; SSE-NEXT: movq %xmm2, %rcx
+; SSE-NEXT: pclmulqdq $0, %xmm1, %xmm4
+; SSE-NEXT: movq %xmm4, %rdx
+; SSE-NEXT: xorq %rcx, %rdx
+; SSE-NEXT: pclmulqdq $16, %xmm3, %xmm1
+; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
+; SSE-NEXT: movq %xmm2, %rcx
+; SSE-NEXT: xorq %rdx, %rcx
+; SSE-NEXT: movq %rax, %xmm2
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; SSE-NEXT: movq %rcx, %xmm2
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pclmul256_lo_hi:
+; AVX: # %bb.0:
+; AVX-NEXT: vextractf128 $1, %ymm0, %xmm2
+; AVX-NEXT: vextractf128 $1, %ymm1, %xmm3
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: vmovq %rax, %xmm4
+; AVX-NEXT: vpclmulqdq $1, %xmm4, %xmm1, %xmm5
+; AVX-NEXT: vmovq %xmm5, %rax
+; AVX-NEXT: vpclmulqdq $0, %xmm4, %xmm0, %xmm5
+; AVX-NEXT: vmovq %xmm5, %rcx
+; AVX-NEXT: xorq %rax, %rcx
+; AVX-NEXT: vpclmulqdq $16, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: vpextrq $1, %xmm0, %rax
+; AVX-NEXT: xorq %rcx, %rax
+; AVX-NEXT: vpclmulqdq $1, %xmm4, %xmm3, %xmm1
+; AVX-NEXT: vmovq %xmm1, %rcx
+; AVX-NEXT: vpclmulqdq $0, %xmm4, %xmm2, %xmm1
+; AVX-NEXT: vmovq %xmm1, %rdx
+; AVX-NEXT: xorq %rcx, %rdx
+; AVX-NEXT: vpclmulqdq $16, %xmm3, %xmm2, %xmm1
+; AVX-NEXT: vpextrq $1, %xmm1, %rcx
+; AVX-NEXT: xorq %rdx, %rcx
+; AVX-NEXT: vmovq %rcx, %xmm2
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; AVX-NEXT: vmovq %rax, %xmm2
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; AVX-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
+; AVX-NEXT: retq
+ %i0 = zext i1 0 to i64 ; constant time lo/hi select
+ %i1 = zext i1 1 to i64 ; constant time lo/hi select
+ %i2 = add i64 %i0, 2
+ %i3 = add i64 %i1, 2
+ %a0 = extractelement <4 x i64> %v0, i64 %i0
+ %a1 = extractelement <4 x i64> %v1, i64 %i1
+ %a2 = extractelement <4 x i64> %v0, i64 %i2
+ %a3 = extractelement <4 x i64> %v1, i64 %i3
+ %x0 = zext i64 %a0 to i128
+ %x1 = zext i64 %a1 to i128
+ %x2 = zext i64 %a2 to i128
+ %x3 = zext i64 %a3 to i128
+ %c0 = call i128 @llvm.clmul.i128(i128 %x0, i128 %x1)
+ %c1 = call i128 @llvm.clmul.i128(i128 %x2, i128 %x3)
+ %r0 = bitcast i128 %c0 to <2 x i64>
+ %r1 = bitcast i128 %c1 to <2 x i64>
+ %r = shufflevector <2 x i64> %r0, <2 x i64> %r1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ ret <4 x i64> %r
+}
+
+define <8 x i64> @pclmul512_lo_hi(<8 x i64> %v0, <8 x i64> %v1) {
+; SSE-LABEL: pclmul512_lo_hi:
+; SSE: # %bb.0:
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: movq %rax, %xmm8
+; SSE-NEXT: movdqa %xmm0, %xmm9
+; SSE-NEXT: pclmulqdq $16, %xmm4, %xmm0
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rax
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm9
+; SSE-NEXT: movq %xmm9, %rcx
+; SSE-NEXT: xorq %rax, %rcx
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rax
+; SSE-NEXT: xorq %rcx, %rax
+; SSE-NEXT: movdqa %xmm1, %xmm4
+; SSE-NEXT: pclmulqdq $16, %xmm5, %xmm1
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm5
+; SSE-NEXT: movq %xmm5, %rcx
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rdx
+; SSE-NEXT: xorq %rcx, %rdx
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rcx
+; SSE-NEXT: xorq %rdx, %rcx
+; SSE-NEXT: movdqa %xmm2, %xmm4
+; SSE-NEXT: pclmulqdq $16, %xmm6, %xmm2
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm6
+; SSE-NEXT: movq %xmm6, %rdx
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rsi
+; SSE-NEXT: xorq %rdx, %rsi
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rdx
+; SSE-NEXT: xorq %rsi, %rdx
+; SSE-NEXT: movdqa %xmm7, %xmm4
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rsi
+; SSE-NEXT: pclmulqdq $0, %xmm3, %xmm8
+; SSE-NEXT: movq %xmm8, %rdi
+; SSE-NEXT: xorq %rsi, %rdi
+; SSE-NEXT: pclmulqdq $16, %xmm7, %xmm3
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm3[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rsi
+; SSE-NEXT: xorq %rdi, %rsi
+; SSE-NEXT: movq %rax, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0]
+; SSE-NEXT: movq %rcx, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm4[0]
+; SSE-NEXT: movq %rdx, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm4[0]
+; SSE-NEXT: movq %rsi, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm4[0]
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pclmul512_lo_hi:
+; AVX: # %bb.0:
+; AVX-NEXT: vextractf128 $1, %ymm0, %xmm7
+; AVX-NEXT: vextractf128 $1, %ymm2, %xmm8
+; AVX-NEXT: vextractf128 $1, %ymm1, %xmm4
+; AVX-NEXT: vextractf128 $1, %ymm3, %xmm5
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: vmovq %rax, %xmm6
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm2, %xmm9
+; AVX-NEXT: vmovq %xmm9, %rax
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm0, %xmm9
+; AVX-NEXT: vmovq %xmm9, %rcx
+; AVX-NEXT: xorq %rax, %rcx
+; AVX-NEXT: vpclmulqdq $16, %xmm2, %xmm0, %xmm0
+; AVX-NEXT: vpextrq $1, %xmm0, %rax
+; AVX-NEXT: xorq %rcx, %rax
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm8, %xmm2
+; AVX-NEXT: vmovq %xmm2, %rcx
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm7, %xmm2
+; AVX-NEXT: vmovq %xmm2, %rdx
+; AVX-NEXT: xorq %rcx, %rdx
+; AVX-NEXT: vpclmulqdq $16, %xmm8, %xmm7, %xmm2
+; AVX-NEXT: vpextrq $1, %xmm2, %rcx
+; AVX-NEXT: xorq %rdx, %rcx
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm3, %xmm7
+; AVX-NEXT: vmovq %xmm7, %rdx
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm1, %xmm7
+; AVX-NEXT: vmovq %xmm7, %rsi
+; AVX-NEXT: xorq %rdx, %rsi
+; AVX-NEXT: vpclmulqdq $16, %xmm3, %xmm1, %xmm1
+; AVX-NEXT: vpextrq $1, %xmm1, %rdx
+; AVX-NEXT: xorq %rsi, %rdx
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm5, %xmm3
+; AVX-NEXT: vmovq %xmm3, %rsi
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm4, %xmm3
+; AVX-NEXT: vmovq %xmm3, %rdi
+; AVX-NEXT: xorq %rsi, %rdi
+; AVX-NEXT: vpclmulqdq $16, %xmm5, %xmm4, %xmm3
+; AVX-NEXT: vpextrq $1, %xmm3, %rsi
+; AVX-NEXT: xorq %rdi, %rsi
+; AVX-NEXT: vmovq %rcx, %xmm4
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm4[0]
+; AVX-NEXT: vmovq %rax, %xmm4
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0]
+; AVX-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
+; AVX-NEXT: vmovq %rsi, %xmm2
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm3[0],xmm2[0]
+; AVX-NEXT: vmovq %rdx, %xmm3
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; AVX-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX-NEXT: retq
+ %i0 = zext i1 0 to i64 ; constant time lo/hi select
+ %i1 = zext i1 1 to i64 ; constant time lo/hi select
+ %i2 = add i64 %i0, 2
+ %i3 = add i64 %i1, 2
+ %i4 = add i64 %i2, 2
+ %i5 = add i64 %i3, 2
+ %i6 = add i64 %i4, 2
+ %i7 = add i64 %i5, 2
+ %a0 = extractelement <8 x i64> %v0, i64 %i0
+ %a1 = extractelement <8 x i64> %v1, i64 %i1
+ %a2 = extractelement <8 x i64> %v0, i64 %i2
+ %a3 = extractelement <8 x i64> %v1, i64 %i3
+ %a4 = extractelement <8 x i64> %v0, i64 %i4
+ %a5 = extractelement <8 x i64> %v1, i64 %i5
+ %a6 = extractelement <8 x i64> %v0, i64 %i6
+ %a7 = extractelement <8 x i64> %v1, i64 %i7
+ %x0 = zext i64 %a0 to i128
+ %x1 = zext i64 %a1 to i128
+ %x2 = zext i64 %a2 to i128
+ %x3 = zext i64 %a3 to i128
+ %x4 = zext i64 %a4 to i128
+ %x5 = zext i64 %a5 to i128
+ %x6 = zext i64 %a6 to i128
+ %x7 = zext i64 %a7 to i128
+ %c0 = call i128 @llvm.clmul.i128(i128 %x0, i128 %x1)
+ %c1 = call i128 @llvm.clmul.i128(i128 %x2, i128 %x3)
+ %c2 = call i128 @llvm.clmul.i128(i128 %x4, i128 %x5)
+ %c3 = call i128 @llvm.clmul.i128(i128 %x6, i128 %x7)
+ %r0 = bitcast i128 %c0 to <2 x i64>
+ %r1 = bitcast i128 %c1 to <2 x i64>
+ %r2 = bitcast i128 %c2 to <2 x i64>
+ %r3 = bitcast i128 %c3 to <2 x i64>
+ %r01 = shufflevector <2 x i64> %r0, <2 x i64> %r1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %r23 = shufflevector <2 x i64> %r2, <2 x i64> %r3, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %r = shufflevector <4 x i64> %r01, <4 x i64> %r23, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+ ret <8 x i64> %r
+}
+
+define <8 x i64> @pclmul512_hi_lo(<8 x i64> %v0, <8 x i64> %v1) {
+; SSE-LABEL: pclmul512_hi_lo:
+; SSE: # %bb.0:
+; SSE-NEXT: xorl %eax, %eax
+; SSE-NEXT: movq %rax, %xmm8
+; SSE-NEXT: movdqa %xmm0, %xmm9
+; SSE-NEXT: pclmulqdq $1, %xmm4, %xmm0
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rax
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm9
+; SSE-NEXT: movq %xmm9, %rcx
+; SSE-NEXT: xorq %rax, %rcx
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm0[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rax
+; SSE-NEXT: xorq %rcx, %rax
+; SSE-NEXT: movdqa %xmm1, %xmm4
+; SSE-NEXT: pclmulqdq $1, %xmm5, %xmm1
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm5
+; SSE-NEXT: movq %xmm5, %rcx
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rdx
+; SSE-NEXT: xorq %rcx, %rdx
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm1[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rcx
+; SSE-NEXT: xorq %rdx, %rcx
+; SSE-NEXT: movdqa %xmm2, %xmm4
+; SSE-NEXT: pclmulqdq $1, %xmm6, %xmm2
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm6
+; SSE-NEXT: movq %xmm6, %rdx
+; SSE-NEXT: pclmulqdq $1, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rsi
+; SSE-NEXT: xorq %rdx, %rsi
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rdx
+; SSE-NEXT: xorq %rsi, %rdx
+; SSE-NEXT: movdqa %xmm7, %xmm4
+; SSE-NEXT: pclmulqdq $0, %xmm8, %xmm4
+; SSE-NEXT: movq %xmm4, %rsi
+; SSE-NEXT: pclmulqdq $16, %xmm3, %xmm8
+; SSE-NEXT: movq %xmm8, %rdi
+; SSE-NEXT: xorq %rsi, %rdi
+; SSE-NEXT: pclmulqdq $1, %xmm7, %xmm3
+; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm3[2,3,2,3]
+; SSE-NEXT: movq %xmm4, %rsi
+; SSE-NEXT: xorq %rdi, %rsi
+; SSE-NEXT: movq %rax, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0]
+; SSE-NEXT: movq %rcx, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm4[0]
+; SSE-NEXT: movq %rdx, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm4[0]
+; SSE-NEXT: movq %rsi, %xmm4
+; SSE-NEXT: punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm4[0]
+; SSE-NEXT: retq
+;
+; AVX-LABEL: pclmul512_hi_lo:
+; AVX: # %bb.0:
+; AVX-NEXT: vextractf128 $1, %ymm0, %xmm7
+; AVX-NEXT: vextractf128 $1, %ymm2, %xmm8
+; AVX-NEXT: vextractf128 $1, %ymm1, %xmm4
+; AVX-NEXT: vextractf128 $1, %ymm3, %xmm5
+; AVX-NEXT: xorl %eax, %eax
+; AVX-NEXT: vmovq %rax, %xmm6
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm2, %xmm9
+; AVX-NEXT: vmovq %xmm9, %rax
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm0, %xmm9
+; AVX-NEXT: vmovq %xmm9, %rcx
+; AVX-NEXT: xorq %rax, %rcx
+; AVX-NEXT: vpclmulqdq $1, %xmm2, %xmm0, %xmm0
+; AVX-NEXT: vpextrq $1, %xmm0, %rax
+; AVX-NEXT: xorq %rcx, %rax
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm8, %xmm2
+; AVX-NEXT: vmovq %xmm2, %rcx
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm7, %xmm2
+; AVX-NEXT: vmovq %xmm2, %rdx
+; AVX-NEXT: xorq %rcx, %rdx
+; AVX-NEXT: vpclmulqdq $1, %xmm8, %xmm7, %xmm2
+; AVX-NEXT: vpextrq $1, %xmm2, %rcx
+; AVX-NEXT: xorq %rdx, %rcx
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm3, %xmm7
+; AVX-NEXT: vmovq %xmm7, %rdx
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm1, %xmm7
+; AVX-NEXT: vmovq %xmm7, %rsi
+; AVX-NEXT: xorq %rdx, %rsi
+; AVX-NEXT: vpclmulqdq $1, %xmm3, %xmm1, %xmm1
+; AVX-NEXT: vpextrq $1, %xmm1, %rdx
+; AVX-NEXT: xorq %rsi, %rdx
+; AVX-NEXT: vpclmulqdq $0, %xmm6, %xmm5, %xmm3
+; AVX-NEXT: vmovq %xmm3, %rsi
+; AVX-NEXT: vpclmulqdq $1, %xmm6, %xmm4, %xmm3
+; AVX-NEXT: vmovq %xmm3, %rdi
+; AVX-NEXT: xorq %rsi, %rdi
+; AVX-NEXT: vpclmulqdq $1, %xmm5, %xmm4, %xmm3
+; AVX-NEXT: vpextrq $1, %xmm3, %rsi
+; AVX-NEXT: xorq %rdi, %rsi
+; AVX-NEXT: vmovq %rcx, %xmm4
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm4[0]
+; AVX-NEXT: vmovq %rax, %xmm4
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0]
+; AVX-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
+; AVX-NEXT: vmovq %rsi, %xmm2
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm2 = xmm3[0],xmm2[0]
+; AVX-NEXT: vmovq %rdx, %xmm3
+; AVX-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
+; AVX-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1
+; AVX-NEXT: retq
+ %i0 = zext i1 1 to i64 ; constant time lo/hi select
+ %i1 = zext i1 0 to i64 ; constant time lo/hi select
+ %i2 = add i64 %i0, 2
+ %i3 = add i64 %i1, 2
+ %i4 = add i64 %i2, 2
+ %i5 = add i64 %i3, 2
+ %i6 = add i64 %i4, 2
+ %i7 = add i64 %i5, 2
+ %a0 = extractelement <8 x i64> %v0, i64 %i0
+ %a1 = extractelement <8 x i64> %v1, i64 %i1
+ %a2 = extractelement <8 x i64> %v0, i64 %i2
+ %a3 = extractelement <8 x i64> %v1, i64 %i3
+ %a4 = extractelement <8 x i64> %v0, i64 %i4
+ %a5 = extractelement <8 x i64> %v1, i64 %i5
+ %a6 = extractelement <8 x i64> %v0, i64 %i6
+ %a7 = extractelement <8 x i64> %v1, i64 %i7
+ %x0 = zext i64 %a0 to i128
+ %x1 = zext i64 %a1 to i128
+ %x2 = zext i64 %a2 to i128
+ %x3 = zext i64 %a3 to i128
+ %x4 = zext i64 %a4 to i128
+ %x5 = zext i64 %a5 to i128
+ %x6 = zext i64 %a6 to i128
+ %x7 = zext i64 %a7 to i128
+ %c0 = call i128 @llvm.clmul.i128(i128 %x0, i128 %x1)
+ %c1 = call i128 @llvm.clmul.i128(i128 %x2, i128 %x3)
+ %c2 = call i128 @llvm.clmul.i128(i128 %x4, i128 %x5)
+ %c3 = call i128 @llvm.clmul.i128(i128 %x6, i128 %x7)
+ %r0 = bitcast i128 %c0 to <2 x i64>
+ %r1 = bitcast i128 %c1 to <2 x i64>
+ %r2 = bitcast i128 %c2 to <2 x i64>
+ %r3 = bitcast i128 %c3 to <2 x i64>
+ %r01 = shufflevector <2 x i64> %r0, <2 x i64> %r1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %r23 = shufflevector <2 x i64> %r2, <2 x i64> %r3, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %r = shufflevector <4 x i64> %r01, <4 x i64> %r23, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+ ret <8 x i64> %r
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; AVX-PCLMUL: {{.*}}
+; AVX-VPCLMULQDQ: {{.*}}
More information about the llvm-commits
mailing list