[llvm] [X86] Fold chained i32 CLMUL operands (PR #202250)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 23:14:11 PDT 2026
https://github.com/mygitljf updated https://github.com/llvm/llvm-project/pull/202250
>From 1bdbbff201d6d3433ca39b6cd0d4ae481f008ef3 Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Tue, 9 Jun 2026 14:11:55 +0000
Subject: [PATCH] [X86] Fold chained i32 CLMUL operands
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 65 ++++
llvm/test/CodeGen/X86/clmul-vector.ll | 38 +--
llvm/test/CodeGen/X86/clmul.ll | 200 ++---------
llvm/test/CodeGen/X86/combine-clmul.ll | 420 +++++++++++++++++++++++-
4 files changed, 532 insertions(+), 191 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a8236f02f8df4..ca841ff9ad4dc 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -45461,6 +45461,71 @@ bool X86TargetLowering::SimplifyDemandedBitsForTargetNode(
}
break;
}
+ case X86ISD::PCLMULQDQ: {
+ // Carry-less product bit i only depends on source bits [0, i], so a
+ // low-qword extract+narrow+scalar_to_vector round-trip on an operand can be
+ // replaced by its source vector when only those low result bits are wanted.
+ unsigned NumElts = VT.getVectorNumElements();
+ APInt HighElts = APInt::getSplat(NumElts, APInt(2, 0b10));
+ unsigned DemandedLoBits = OriginalDemandedBits.getActiveBits();
+ if (!(OriginalDemandedElts & HighElts).isZero() || DemandedLoBits == 0 ||
+ DemandedLoBits >= BitWidth)
+ break;
+
+ uint64_t Imm = Op.getConstantOperandVal(2);
+ uint64_t M0 = Imm & 0x01, M1 = (Imm & 0x10) >> 4;
+ APInt LoElts = APInt::getSplat(NumElts, APInt(2, 0b01));
+ APInt SrcBits = APInt::getLowBitsSet(BitWidth, DemandedLoBits);
+ KnownBits KnownLHS, KnownRHS;
+ if (SimplifyDemandedBits(Op.getOperand(0), SrcBits, M0 ? HighElts : LoElts,
+ KnownLHS, TLO, Depth + 1))
+ return true;
+ if (SimplifyDemandedBits(Op.getOperand(1), SrcBits, M1 ? HighElts : LoElts,
+ KnownRHS, TLO, Depth + 1))
+ return true;
+
+ auto PeelToVector = [&](SDValue Operand, uint64_t M) -> SDValue {
+ // scalar_to_vector only defines the low qword, so the imm must select it.
+ if (M != 0)
+ return SDValue();
+
+ SDValue S2V = peekThroughBitcasts(Operand);
+ if (S2V.getOpcode() != ISD::SCALAR_TO_VECTOR ||
+ S2V.getValueSizeInBits() != VT.getSizeInBits())
+ return SDValue();
+
+ uint64_t MinScalarBits = S2V.getScalarValueSizeInBits();
+ SDValue Inner = S2V.getOperand(0);
+ while (Inner.getOpcode() == ISD::ANY_EXTEND ||
+ Inner.getOpcode() == ISD::TRUNCATE) {
+ MinScalarBits =
+ std::min(MinScalarBits, Inner.getScalarValueSizeInBits());
+ Inner = Inner.getOperand(0);
+ }
+ MinScalarBits = std::min(MinScalarBits, Inner.getScalarValueSizeInBits());
+
+ if (Inner.getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
+ !isNullConstant(Inner.getOperand(1)) ||
+ DemandedLoBits > MinScalarBits)
+ return SDValue();
+
+ SDValue Src = Inner.getOperand(0);
+ if (!Src.getValueType().isVector() ||
+ Src.getValueSizeInBits() != VT.getSizeInBits())
+ return SDValue();
+ return TLO.DAG.getBitcast(VT, Src);
+ };
+
+ SDValue NewLHS = PeelToVector(Op.getOperand(0), M0);
+ SDValue NewRHS = PeelToVector(Op.getOperand(1), M1);
+ if (NewLHS || NewRHS) {
+ NewLHS = NewLHS ? NewLHS : Op.getOperand(0);
+ NewRHS = NewRHS ? NewRHS : Op.getOperand(1);
+ return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, SDLoc(Op), VT, NewLHS,
+ NewRHS, Op.getOperand(2)));
+ }
+ break;
+ }
case X86ISD::ANDNP: {
KnownBits Known2;
SDValue Op0 = Op.getOperand(0);
diff --git a/llvm/test/CodeGen/X86/clmul-vector.ll b/llvm/test/CodeGen/X86/clmul-vector.ll
index 4099273c15ade..f81d3d13006f3 100644
--- a/llvm/test/CodeGen/X86/clmul-vector.ll
+++ b/llvm/test/CodeGen/X86/clmul-vector.ll
@@ -12604,28 +12604,25 @@ define <8 x i16> @clmulr_v8i16_allones(<8 x i16> %x) nounwind {
;
; SSE2-PCLMUL-LABEL: clmulr_v8i16_allones:
; SSE2-PCLMUL: # %bb.0:
+; SSE2-PCLMUL-NEXT: pxor %xmm2, %xmm2
; SSE2-PCLMUL-NEXT: movdqa %xmm0, %xmm1
-; SSE2-PCLMUL-NEXT: pxor %xmm3, %xmm3
+; SSE2-PCLMUL-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
+; SSE2-PCLMUL-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
; SSE2-PCLMUL-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
; SSE2-PCLMUL-NEXT: movq %rax, %xmm2
-; SSE2-PCLMUL-NEXT: pextrw $3, %xmm0, %eax
-; SSE2-PCLMUL-NEXT: movd %eax, %xmm4
-; SSE2-PCLMUL-NEXT: pextrw $1, %xmm0, %eax
-; SSE2-PCLMUL-NEXT: movd %eax, %xmm5
-; SSE2-PCLMUL-NEXT: pextrw $7, %xmm0, %eax
-; SSE2-PCLMUL-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm3[4],xmm1[5],xmm3[5],xmm1[6],xmm3[6],xmm1[7],xmm3[7]
-; SSE2-PCLMUL-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3]
; SSE2-PCLMUL-NEXT: movdqa %xmm0, %xmm3
; SSE2-PCLMUL-NEXT: pclmulqdq $1, %xmm2, %xmm3
+; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm0[3,3,3,3]
; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm4
; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
+; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1]
; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm0
-; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm5
-; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm5[0],xmm0[1],xmm5[1]
+; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm4
+; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1]
; SSE2-PCLMUL-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]
; SSE2-PCLMUL-NEXT: movdqa %xmm1, %xmm3
; SSE2-PCLMUL-NEXT: pclmulqdq $1, %xmm2, %xmm3
-; SSE2-PCLMUL-NEXT: movd %eax, %xmm4
+; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm1[3,3,3,3]
; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm4
; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm1[1,1,1,1]
@@ -13539,28 +13536,25 @@ define <8 x i16> @clmulh_v8i16_allones(<8 x i16> %x) nounwind {
;
; SSE2-PCLMUL-LABEL: clmulh_v8i16_allones:
; SSE2-PCLMUL: # %bb.0:
+; SSE2-PCLMUL-NEXT: pxor %xmm2, %xmm2
; SSE2-PCLMUL-NEXT: movdqa %xmm0, %xmm1
-; SSE2-PCLMUL-NEXT: pxor %xmm3, %xmm3
+; SSE2-PCLMUL-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
+; SSE2-PCLMUL-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
; SSE2-PCLMUL-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
; SSE2-PCLMUL-NEXT: movq %rax, %xmm2
-; SSE2-PCLMUL-NEXT: pextrw $3, %xmm0, %eax
-; SSE2-PCLMUL-NEXT: movd %eax, %xmm4
-; SSE2-PCLMUL-NEXT: pextrw $1, %xmm0, %eax
-; SSE2-PCLMUL-NEXT: movd %eax, %xmm5
-; SSE2-PCLMUL-NEXT: pextrw $7, %xmm0, %eax
-; SSE2-PCLMUL-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm3[4],xmm1[5],xmm3[5],xmm1[6],xmm3[6],xmm1[7],xmm3[7]
-; SSE2-PCLMUL-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3]
; SSE2-PCLMUL-NEXT: movdqa %xmm0, %xmm3
; SSE2-PCLMUL-NEXT: pclmulqdq $1, %xmm2, %xmm3
+; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm0[3,3,3,3]
; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm4
; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
+; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1]
; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm0
-; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm5
-; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm5[0],xmm0[1],xmm5[1]
+; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm4
+; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1]
; SSE2-PCLMUL-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]
; SSE2-PCLMUL-NEXT: movdqa %xmm1, %xmm3
; SSE2-PCLMUL-NEXT: pclmulqdq $1, %xmm2, %xmm3
-; SSE2-PCLMUL-NEXT: movd %eax, %xmm4
+; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm1[3,3,3,3]
; SSE2-PCLMUL-NEXT: pclmulqdq $0, %xmm2, %xmm4
; SSE2-PCLMUL-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
; SSE2-PCLMUL-NEXT: pshufd {{.*#+}} xmm4 = xmm1[1,1,1,1]
diff --git a/llvm/test/CodeGen/X86/clmul.ll b/llvm/test/CodeGen/X86/clmul.ll
index 638243ff309fe..b78892d6ca88a 100644
--- a/llvm/test/CodeGen/X86/clmul.ll
+++ b/llvm/test/CodeGen/X86/clmul.ll
@@ -3628,23 +3628,11 @@ define i8 @clmul_i8_allones(i8 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmul_i8_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $255, %eax
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: # kill: def $al killed $al killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmul_i8_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $255, %eax
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: # kill: def $al killed $al killed $rax
-; AVX-NEXT: retq
%r = call i8 @llvm.clmul.i8(i8 %x, i8 -1)
ret i8 %r
}
@@ -3668,23 +3656,11 @@ define i16 @clmul_i16_allones(i16 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmul_i16_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $65535, %eax # imm = 0xFFFF
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: # kill: def $ax killed $ax killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmul_i16_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $65535, %eax # imm = 0xFFFF
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: # kill: def $ax killed $ax killed $rax
-; AVX-NEXT: retq
%r = call i16 @llvm.clmul.i16(i16 %x, i16 -1)
ret i16 %r
}
@@ -3710,23 +3686,11 @@ define i32 @clmul_i32_allones(i32 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmul_i32_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: # kill: def $eax killed $eax killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmul_i32_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: # kill: def $eax killed $eax killed $rax
-; AVX-NEXT: retq
%r = call i32 @llvm.clmul.i32(i32 %x, i32 -1)
ret i32 %r
}
@@ -3788,23 +3752,11 @@ define i7 @clmul_i7_allones(i7 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmul_i7_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $127, %eax
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: # kill: def $al killed $al killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmul_i7_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $127, %eax
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: # kill: def $al killed $al killed $rax
-; AVX-NEXT: retq
%r = call i7 @llvm.clmul.i7(i7 %x, i7 -1)
ret i7 %r
}
@@ -3828,23 +3780,11 @@ define i10 @clmul_i10_allones(i10 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmul_i10_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $1023, %eax # imm = 0x3FF
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: # kill: def $ax killed $ax killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmul_i10_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $1023, %eax # imm = 0x3FF
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: # kill: def $ax killed $ax killed $rax
-; AVX-NEXT: retq
%r = call i10 @llvm.clmul.i10(i10 %x, i10 -1)
ret i10 %r
}
@@ -3870,23 +3810,11 @@ define i25 @clmul_i25_allones(i25 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmul_i25_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $33554431, %eax # imm = 0x1FFFFFF
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: # kill: def $eax killed $eax killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmul_i25_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $33554431, %eax # imm = 0x1FFFFFF
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: # kill: def $eax killed $eax killed $rax
-; AVX-NEXT: retq
%r = call i25 @llvm.clmul.i25(i25 %x, i25 -1)
ret i25 %r
}
@@ -3953,27 +3881,13 @@ define i8 @clmulr_i8_allones(i8 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmulr_i8_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $65535, %eax # imm = 0xFFFF
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
; SSE-PCLMUL-NEXT: movzbl %dil, %eax
-; SSE-PCLMUL-NEXT: movd %eax, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %eax, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: shrl $7, %eax
; SSE-PCLMUL-NEXT: # kill: def $al killed $al killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmulr_i8_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $65535, %eax # imm = 0xFFFF
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: movzbl %dil, %eax
-; AVX-NEXT: vmovd %eax, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: shrl $7, %eax
-; AVX-NEXT: # kill: def $al killed $al killed $rax
-; AVX-NEXT: retq
%x.ext = zext i8 %x to i16
%clmul = call i16 @llvm.clmul.i16(i16 %x.ext, i16 -1)
%res.ext = lshr i16 %clmul, 7
@@ -4005,26 +3919,12 @@ define i16 @clmulr_i16_allones(i16 %x) nounwind {
; SSE-PCLMUL-LABEL: clmulr_i16_allones:
; SSE-PCLMUL: # %bb.0:
; SSE-PCLMUL-NEXT: movzwl %di, %eax
-; SSE-PCLMUL-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF
-; SSE-PCLMUL-NEXT: movq %rcx, %xmm0
-; SSE-PCLMUL-NEXT: movd %eax, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %eax, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: shrl $15, %eax
; SSE-PCLMUL-NEXT: # kill: def $ax killed $ax killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmulr_i16_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movzwl %di, %eax
-; AVX-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF
-; AVX-NEXT: vmovq %rcx, %xmm0
-; AVX-NEXT: vmovd %eax, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: shrl $15, %eax
-; AVX-NEXT: # kill: def $ax killed $ax killed $rax
-; AVX-NEXT: retq
%x.ext = zext i16 %x to i32
%clmul = call i32 @llvm.clmul.i32(i32 %x.ext, i32 -1)
%res.ext = lshr i32 %clmul, 15
@@ -4058,9 +3958,8 @@ define i32 @clmulr_i32_allones(i32 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmulr_i32_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movq $-1, %rax
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
-; SSE-PCLMUL-NEXT: movd %edi, %xmm1
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: pcmpeqd %xmm1, %xmm1
; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
; SSE-PCLMUL-NEXT: movq %xmm1, %rax
; SSE-PCLMUL-NEXT: shrq $31, %rax
@@ -4069,10 +3968,9 @@ define i32 @clmulr_i32_allones(i32 %x) nounwind {
;
; AVX-LABEL: clmulr_i32_allones:
; AVX: # %bb.0:
-; AVX-NEXT: movq $-1, %rax
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: vmovd %edi, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
+; AVX-NEXT: vmovd %edi, %xmm0
+; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX-NEXT: vpclmulqdq $0, %xmm1, %xmm0, %xmm0
; AVX-NEXT: vmovq %xmm0, %rax
; AVX-NEXT: shrq $31, %rax
; AVX-NEXT: # kill: def $eax killed $eax killed $rax
@@ -4224,27 +4122,13 @@ define i8 @clmulh_i8_allones(i8 %x) nounwind {
;
; SSE-PCLMUL-LABEL: clmulh_i8_allones:
; SSE-PCLMUL: # %bb.0:
-; SSE-PCLMUL-NEXT: movl $65535, %eax # imm = 0xFFFF
-; SSE-PCLMUL-NEXT: movq %rax, %xmm0
; SSE-PCLMUL-NEXT: movzbl %dil, %eax
-; SSE-PCLMUL-NEXT: movd %eax, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %eax, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: shrl $8, %eax
; SSE-PCLMUL-NEXT: # kill: def $al killed $al killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmulh_i8_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movl $65535, %eax # imm = 0xFFFF
-; AVX-NEXT: vmovq %rax, %xmm0
-; AVX-NEXT: movzbl %dil, %eax
-; AVX-NEXT: vmovd %eax, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: shrl $8, %eax
-; AVX-NEXT: # kill: def $al killed $al killed $rax
-; AVX-NEXT: retq
%x.ext = zext i8 %x to i16
%clmul = call i16 @llvm.clmul.i16(i16 %x.ext, i16 -1)
%res.ext = lshr i16 %clmul, 8
@@ -4276,26 +4160,12 @@ define i16 @clmulh_i16_allones(i16 %x) nounwind {
; SSE-PCLMUL-LABEL: clmulh_i16_allones:
; SSE-PCLMUL: # %bb.0:
; SSE-PCLMUL-NEXT: movzwl %di, %eax
-; SSE-PCLMUL-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF
-; SSE-PCLMUL-NEXT: movq %rcx, %xmm0
-; SSE-PCLMUL-NEXT: movd %eax, %xmm1
-; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
-; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: movd %eax, %xmm0
+; SSE-PCLMUL-NEXT: pclmulqdq $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-PCLMUL-NEXT: movq %xmm0, %rax
; SSE-PCLMUL-NEXT: shrl $16, %eax
; SSE-PCLMUL-NEXT: # kill: def $ax killed $ax killed $rax
; SSE-PCLMUL-NEXT: retq
-;
-; AVX-LABEL: clmulh_i16_allones:
-; AVX: # %bb.0:
-; AVX-NEXT: movzwl %di, %eax
-; AVX-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF
-; AVX-NEXT: vmovq %rcx, %xmm0
-; AVX-NEXT: vmovd %eax, %xmm1
-; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
-; AVX-NEXT: vmovq %xmm0, %rax
-; AVX-NEXT: shrl $16, %eax
-; AVX-NEXT: # kill: def $ax killed $ax killed $rax
-; AVX-NEXT: retq
%x.ext = zext i16 %x to i32
%clmul = call i32 @llvm.clmul.i32(i32 %x.ext, i32 -1)
%res.ext = lshr i32 %clmul, 16
diff --git a/llvm/test/CodeGen/X86/combine-clmul.ll b/llvm/test/CodeGen/X86/combine-clmul.ll
index 1581f7cfc64e2..f4ba79e3a6554 100644
--- a/llvm/test/CodeGen/X86/combine-clmul.ll
+++ b/llvm/test/CodeGen/X86/combine-clmul.ll
@@ -36,7 +36,419 @@ define i32 @clmul_i32_pow2(i32 %a) {
%res = call i32 @llvm.clmul.i32(i32 %a, i32 16) ; 0x10 = 1 << 4
ret i32 %res
}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; AVX: {{.*}}
-; SCALAR: {{.*}}
-; SSE-PCLMUL: {{.*}}
+
+; Chained i32 clmul should feed the intermediate result straight into the next
+; multiply in vector form instead of round-tripping it through a scalar.
+define i32 @clmul_i32_chain(i32 %m) nounwind {
+; SCALAR-LABEL: clmul_i32_chain:
+; SCALAR: # %bb.0:
+; SCALAR-NEXT: pushq %rbp
+; SCALAR-NEXT: pushq %r15
+; SCALAR-NEXT: pushq %r14
+; SCALAR-NEXT: pushq %r13
+; SCALAR-NEXT: pushq %r12
+; SCALAR-NEXT: pushq %rbx
+; SCALAR-NEXT: movl %edi, %esi
+; SCALAR-NEXT: leal (%rsi,%rsi), %edx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $2, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %edx
+; SCALAR-NEXT: movl %edi, %ecx
+; SCALAR-NEXT: andl $1, %ecx
+; SCALAR-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: cmovel %ecx, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %eax, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: leal (,%rsi,4), %ecx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $4, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %ecx
+; SCALAR-NEXT: xorl %edx, %ecx
+; SCALAR-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: leal (,%rsi,8), %edx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $8, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %edx
+; SCALAR-NEXT: xorl %ecx, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %edi, %ecx
+; SCALAR-NEXT: shll $4, %ecx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $16, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %ecx
+; SCALAR-NEXT: xorl %edx, %ecx
+; SCALAR-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %edi, %edx
+; SCALAR-NEXT: shll $5, %edx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $32, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %edx
+; SCALAR-NEXT: xorl %ecx, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %edi, %ecx
+; SCALAR-NEXT: shll $6, %ecx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $64, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %ecx
+; SCALAR-NEXT: xorl %edx, %ecx
+; SCALAR-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %edi, %edx
+; SCALAR-NEXT: shll $7, %edx
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $128, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %edx
+; SCALAR-NEXT: xorl %ecx, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %edi, %r13d
+; SCALAR-NEXT: shll $8, %r13d
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $256, %eax # imm = 0x100
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %r13d
+; SCALAR-NEXT: xorl %edx, %r13d
+; SCALAR-NEXT: movl %edi, %r12d
+; SCALAR-NEXT: shll $9, %r12d
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $512, %eax # imm = 0x200
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %r12d
+; SCALAR-NEXT: xorl %r13d, %r12d
+; SCALAR-NEXT: movl %edi, %ebp
+; SCALAR-NEXT: shll $10, %ebp
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $1024, %eax # imm = 0x400
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %ebp
+; SCALAR-NEXT: xorl %r12d, %ebp
+; SCALAR-NEXT: movl %edi, %r15d
+; SCALAR-NEXT: shll $11, %r15d
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $2048, %eax # imm = 0x800
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %r15d
+; SCALAR-NEXT: xorl %ebp, %r15d
+; SCALAR-NEXT: movl %edi, %r11d
+; SCALAR-NEXT: shll $12, %r11d
+; SCALAR-NEXT: movl %edi, %eax
+; SCALAR-NEXT: andl $4096, %eax # imm = 0x1000
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: cmovel %eax, %r11d
+; SCALAR-NEXT: xorl %r15d, %r11d
+; SCALAR-NEXT: movl %edi, %r10d
+; SCALAR-NEXT: shll $13, %r10d
+; SCALAR-NEXT: movl %edi, %r14d
+; SCALAR-NEXT: andl $8192, %r14d # imm = 0x2000
+; SCALAR-NEXT: cmovel %r14d, %r10d
+; SCALAR-NEXT: xorl %r11d, %r10d
+; SCALAR-NEXT: movl %edi, %edx
+; SCALAR-NEXT: shll $14, %edx
+; SCALAR-NEXT: movl %edi, %ebx
+; SCALAR-NEXT: andl $16384, %ebx # imm = 0x4000
+; SCALAR-NEXT: cmovel %ebx, %edx
+; SCALAR-NEXT: xorl %r10d, %edx
+; SCALAR-NEXT: movl %edi, %r8d
+; SCALAR-NEXT: shll $15, %r8d
+; SCALAR-NEXT: andl $32768, %edi # imm = 0x8000
+; SCALAR-NEXT: cmovel %edi, %r8d
+; SCALAR-NEXT: xorl %edx, %r8d
+; SCALAR-NEXT: movl %esi, %ecx
+; SCALAR-NEXT: shll $16, %ecx
+; SCALAR-NEXT: movl %r8d, %r9d
+; SCALAR-NEXT: shll $16, %r9d
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: andl $65536, %eax # imm = 0x10000
+; SCALAR-NEXT: cmovel %eax, %ecx
+; SCALAR-NEXT: cmovnel %r9d, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %r8d, %ecx
+; SCALAR-NEXT: movl %ecx, %eax
+; SCALAR-NEXT: shll $15, %eax
+; SCALAR-NEXT: testl %edi, %edi
+; SCALAR-NEXT: cmovel %edi, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $17, %eax
+; SCALAR-NEXT: shll $17, %edx
+; SCALAR-NEXT: movl %esi, %edi
+; SCALAR-NEXT: andl $131072, %edi # imm = 0x20000
+; SCALAR-NEXT: cmovel %edi, %eax
+; SCALAR-NEXT: cmovnel %edx, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %ecx, %eax
+; SCALAR-NEXT: movl %eax, %ecx
+; SCALAR-NEXT: shll $14, %ecx
+; SCALAR-NEXT: testl %ebx, %ebx
+; SCALAR-NEXT: cmovel %ebx, %ecx
+; SCALAR-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %ecx
+; SCALAR-NEXT: shll $18, %ecx
+; SCALAR-NEXT: shll $18, %r10d
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: andl $262144, %edx # imm = 0x40000
+; SCALAR-NEXT: cmovel %edx, %ecx
+; SCALAR-NEXT: cmovnel %r10d, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %eax, %ecx
+; SCALAR-NEXT: movl %ecx, %eax
+; SCALAR-NEXT: shll $13, %eax
+; SCALAR-NEXT: testl %r14d, %r14d
+; SCALAR-NEXT: cmovel %r14d, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $19, %eax
+; SCALAR-NEXT: shll $19, %r11d
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: andl $524288, %edx # imm = 0x80000
+; SCALAR-NEXT: cmovel %edx, %eax
+; SCALAR-NEXT: cmovnel %r11d, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %ecx, %eax
+; SCALAR-NEXT: movl %eax, %ecx
+; SCALAR-NEXT: shll $12, %ecx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edx # 4-byte Reload
+; SCALAR-NEXT: testl %edx, %edx
+; SCALAR-NEXT: cmovel %edx, %ecx
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: shll $20, %edx
+; SCALAR-NEXT: shll $20, %r15d
+; SCALAR-NEXT: movl %esi, %edi
+; SCALAR-NEXT: andl $1048576, %edi # imm = 0x100000
+; SCALAR-NEXT: cmovel %edi, %edx
+; SCALAR-NEXT: cmovnel %r15d, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %eax, %edx
+; SCALAR-NEXT: movl %edx, %eax
+; SCALAR-NEXT: shll $11, %eax
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: testl %edi, %edi
+; SCALAR-NEXT: cmovel %edi, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $21, %eax
+; SCALAR-NEXT: shll $21, %ebp
+; SCALAR-NEXT: movl %esi, %edi
+; SCALAR-NEXT: andl $2097152, %edi # imm = 0x200000
+; SCALAR-NEXT: cmovel %edi, %eax
+; SCALAR-NEXT: cmovnel %ebp, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %edx, %eax
+; SCALAR-NEXT: movl %eax, %edx
+; SCALAR-NEXT: shll $10, %edx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: testl %edi, %edi
+; SCALAR-NEXT: cmovel %edi, %edx
+; SCALAR-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: shll $22, %edx
+; SCALAR-NEXT: shll $22, %r12d
+; SCALAR-NEXT: movl %esi, %edi
+; SCALAR-NEXT: andl $4194304, %edi # imm = 0x400000
+; SCALAR-NEXT: cmovel %edi, %edx
+; SCALAR-NEXT: cmovnel %r12d, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %eax, %edx
+; SCALAR-NEXT: movl %edx, %eax
+; SCALAR-NEXT: shll $9, %eax
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: testl %edi, %edi
+; SCALAR-NEXT: cmovel %edi, %eax
+; SCALAR-NEXT: movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $23, %eax
+; SCALAR-NEXT: shll $23, %r13d
+; SCALAR-NEXT: movl %esi, %edi
+; SCALAR-NEXT: andl $8388608, %edi # imm = 0x800000
+; SCALAR-NEXT: cmovel %edi, %eax
+; SCALAR-NEXT: cmovnel %r13d, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %edx, %eax
+; SCALAR-NEXT: movl %eax, %edi
+; SCALAR-NEXT: shll $8, %edi
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edx # 4-byte Reload
+; SCALAR-NEXT: testl %edx, %edx
+; SCALAR-NEXT: cmovel %edx, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: shll $24, %edx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: shll $24, %edi
+; SCALAR-NEXT: movl %esi, %r8d
+; SCALAR-NEXT: andl $16777216, %r8d # imm = 0x1000000
+; SCALAR-NEXT: cmovel %r8d, %edx
+; SCALAR-NEXT: cmovnel %edi, %r8d
+; SCALAR-NEXT: movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %eax, %edx
+; SCALAR-NEXT: movl %edx, %edi
+; SCALAR-NEXT: shll $7, %edi
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; SCALAR-NEXT: testl %eax, %eax
+; SCALAR-NEXT: cmovel %eax, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $25, %eax
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: shll $25, %edi
+; SCALAR-NEXT: movl %esi, %r8d
+; SCALAR-NEXT: andl $33554432, %r8d # imm = 0x2000000
+; SCALAR-NEXT: cmovel %r8d, %eax
+; SCALAR-NEXT: cmovnel %edi, %r8d
+; SCALAR-NEXT: movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %edx, %eax
+; SCALAR-NEXT: movl %eax, %edi
+; SCALAR-NEXT: shll $6, %edi
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edx # 4-byte Reload
+; SCALAR-NEXT: testl %edx, %edx
+; SCALAR-NEXT: cmovel %edx, %edi
+; SCALAR-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: shll $26, %edx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: shll $26, %edi
+; SCALAR-NEXT: movl %esi, %r8d
+; SCALAR-NEXT: andl $67108864, %r8d # imm = 0x4000000
+; SCALAR-NEXT: cmovel %r8d, %edx
+; SCALAR-NEXT: cmovnel %edi, %r8d
+; SCALAR-NEXT: movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: xorl %eax, %edx
+; SCALAR-NEXT: movl %edx, %r8d
+; SCALAR-NEXT: shll $5, %r8d
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; SCALAR-NEXT: testl %eax, %eax
+; SCALAR-NEXT: cmovel %eax, %r8d
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $27, %eax
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: shll $27, %edi
+; SCALAR-NEXT: movl %esi, %r13d
+; SCALAR-NEXT: andl $134217728, %r13d # imm = 0x8000000
+; SCALAR-NEXT: cmovel %r13d, %eax
+; SCALAR-NEXT: cmovnel %edi, %r13d
+; SCALAR-NEXT: xorl %edx, %eax
+; SCALAR-NEXT: movl %eax, %ebx
+; SCALAR-NEXT: shll $4, %ebx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edx # 4-byte Reload
+; SCALAR-NEXT: testl %edx, %edx
+; SCALAR-NEXT: cmovel %edx, %ebx
+; SCALAR-NEXT: movl %esi, %edx
+; SCALAR-NEXT: shll $28, %edx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: shll $28, %edi
+; SCALAR-NEXT: movl %esi, %r14d
+; SCALAR-NEXT: andl $268435456, %r14d # imm = 0x10000000
+; SCALAR-NEXT: cmovel %r14d, %edx
+; SCALAR-NEXT: cmovnel %edi, %r14d
+; SCALAR-NEXT: xorl %eax, %edx
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; SCALAR-NEXT: testl %eax, %eax
+; SCALAR-NEXT: leal (,%rdx,8), %r15d
+; SCALAR-NEXT: cmovel %eax, %r15d
+; SCALAR-NEXT: movl %esi, %eax
+; SCALAR-NEXT: shll $29, %eax
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: shll $29, %edi
+; SCALAR-NEXT: movl %esi, %ebp
+; SCALAR-NEXT: andl $536870912, %ebp # imm = 0x20000000
+; SCALAR-NEXT: cmovel %ebp, %eax
+; SCALAR-NEXT: cmovnel %edi, %ebp
+; SCALAR-NEXT: xorl %edx, %eax
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
+; SCALAR-NEXT: testl %edi, %edi
+; SCALAR-NEXT: leal (,%rax,4), %edx
+; SCALAR-NEXT: cmovel %edi, %edx
+; SCALAR-NEXT: movl %esi, %edi
+; SCALAR-NEXT: shll $30, %edi
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %r10d # 4-byte Reload
+; SCALAR-NEXT: shll $30, %r10d
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %r9d # 4-byte Reload
+; SCALAR-NEXT: shll $31, %r9d
+; SCALAR-NEXT: movl %esi, %r12d
+; SCALAR-NEXT: andl $-2147483648, %r12d # imm = 0x80000000
+; SCALAR-NEXT: cmovel %r12d, %r9d
+; SCALAR-NEXT: movl %r9d, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; SCALAR-NEXT: movl %esi, %r11d
+; SCALAR-NEXT: andl $1073741824, %r11d # imm = 0x40000000
+; SCALAR-NEXT: cmovel %r11d, %edi
+; SCALAR-NEXT: cmovnel %r10d, %r11d
+; SCALAR-NEXT: xorl %eax, %edi
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; SCALAR-NEXT: testl %eax, %eax
+; SCALAR-NEXT: leal (%rdi,%rdi), %r9d
+; SCALAR-NEXT: cmovel %eax, %r9d
+; SCALAR-NEXT: shll $31, %esi
+; SCALAR-NEXT: testl %r12d, %r12d
+; SCALAR-NEXT: cmovnel %esi, %r12d
+; SCALAR-NEXT: xorl %edi, %r12d
+; SCALAR-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %esi # 4-byte Reload
+; SCALAR-NEXT: testl %esi, %esi
+; SCALAR-NEXT: cmovel %esi, %r12d
+; SCALAR-NEXT: xorl %r9d, %r12d
+; SCALAR-NEXT: xorl %r15d, %edx
+; SCALAR-NEXT: xorl %ebx, %edx
+; SCALAR-NEXT: xorl %r12d, %edx
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r8d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl %edx, %r8d
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %ecx # 4-byte Folded Reload
+; SCALAR-NEXT: xorl %r8d, %ecx
+; SCALAR-NEXT: xorl %r13d, %r14d
+; SCALAR-NEXT: xorl %ebp, %r14d
+; SCALAR-NEXT: xorl %r11d, %r14d
+; SCALAR-NEXT: xorl {{[-0-9]+}}(%r{{[sb]}}p), %r14d # 4-byte Folded Reload
+; SCALAR-NEXT: xorl %ecx, %r14d
+; SCALAR-NEXT: movl %r14d, %eax
+; SCALAR-NEXT: popq %rbx
+; SCALAR-NEXT: popq %r12
+; SCALAR-NEXT: popq %r13
+; SCALAR-NEXT: popq %r14
+; SCALAR-NEXT: popq %r15
+; SCALAR-NEXT: popq %rbp
+; SCALAR-NEXT: retq
+;
+; SSE-PCLMUL-LABEL: clmul_i32_chain:
+; SSE-PCLMUL: # %bb.0:
+; SSE-PCLMUL-NEXT: movd %edi, %xmm0
+; SSE-PCLMUL-NEXT: movdqa %xmm0, %xmm1
+; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
+; SSE-PCLMUL-NEXT: pclmulqdq $0, %xmm0, %xmm1
+; SSE-PCLMUL-NEXT: movq %xmm1, %rax
+; SSE-PCLMUL-NEXT: # kill: def $eax killed $eax killed $rax
+; SSE-PCLMUL-NEXT: retq
+;
+; AVX-LABEL: clmul_i32_chain:
+; AVX: # %bb.0:
+; AVX-NEXT: vmovd %edi, %xmm0
+; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm0, %xmm1
+; AVX-NEXT: vpclmulqdq $0, %xmm0, %xmm1, %xmm0
+; AVX-NEXT: vmovq %xmm0, %rax
+; AVX-NEXT: # kill: def $eax killed $eax killed $rax
+; AVX-NEXT: retq
+ %c0 = tail call i32 @llvm.clmul.i32(i32 %m, i32 %m)
+ %c1 = tail call i32 @llvm.clmul.i32(i32 %c0, i32 %m)
+ ret i32 %c1
+}
More information about the llvm-commits
mailing list