[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