[llvm] f17e59b - [X86] Fold nested VGF2P8AFFINEQB instructions (#195210)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 15 04:13:27 PDT 2026


Author: Walter
Date: 2026-06-15T11:13:22Z
New Revision: f17e59baef0c01a08c0a37a517f7b7ee10d5a5c0

URL: https://github.com/llvm/llvm-project/commit/f17e59baef0c01a08c0a37a517f7b7ee10d5a5c0
DIFF: https://github.com/llvm/llvm-project/commit/f17e59baef0c01a08c0a37a517f7b7ee10d5a5c0.diff

LOG: [X86] Fold nested VGF2P8AFFINEQB instructions (#195210)

Given that `vgf2p8affineqb` can perform arbitrary XOR permutations of
the input, all nested affine transformations can be performed with a
single instruction. The matrix for such fold can be calculated by
permuting the sub-matrix by the super-matrix at a byte, rather than bit,
granularity. This patch:

- Folds nested `vgf2p8affineqb` instructions with constant matrix
operands into one.
- Folds the sub-immediate by performing a affine transformation by the
super-matrix.
- Can fold non-splat super-matrices if the sub-immediate is zero.
- Includes test coverage for complex nested affine transformations,
verifying the correctness of the folded matrix and immediate.
- Includes negative test coverage for when the fold isn't possible.

Fixes #179607

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/combine-gfni.ll
    llvm/test/CodeGen/X86/gfni-funnel-shifts.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6b05d52be02ef..2c378227ec9c9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -29520,6 +29520,25 @@ SDValue getGFNICtrlMask(unsigned Opcode, SelectionDAG &DAG, const SDLoc &DL,
   return DAG.getBuildVector(VT, DL, MaskBits);
 }
 
+static APInt getGFNIByteAffine(const APInt &ByteToAffine, const APInt &Matrix64,
+                               const APInt &Addend8) {
+  assert(ByteToAffine.getBitWidth() == 8 && "Byte input unexpected size!");
+  assert(Addend8.getBitWidth() == 8 && "8-bit addend input unexpected size!");
+  assert(Matrix64.getBitWidth() == 64 &&
+         "64-bit matrix input unexpected size!");
+
+  APInt ByteSplat = APInt::getSplat(64, ByteToAffine);
+  ByteSplat &= Matrix64.byteSwap();
+
+  // Cumulative parity
+  for (unsigned I = 0; I != 3; ++I)
+    ByteSplat ^= ByteSplat.lshr(1 << I);
+  ByteSplat &= 0x0101010101010101ull;
+
+  APInt Affined = APIntOps::ScaleBitMask(ByteSplat, 8);
+  return Affined ^ Addend8;
+}
+
 /// Lower a vector CTLZ using native supported vector CTLZ instruction.
 //
 // i8/i16 vector implemented using dword LZCNT vector instruction
@@ -62672,6 +62691,77 @@ static SDValue combineAndOnGF2P8AFFINEQBOperand(SDNode *N, const SDLoc &DL,
   return SDValue();
 }
 
+// Fold: GF2P8AFFINEQB(GF2P8AFFINEQB(X, YSub), YSup)
+//    => GF2P8AFFINEQB(X, YFolded)
+// Permuting the sub-matrix by the super-matrix at a byte, rather than bit,
+// granularity produces a matrix that performs both permutations at once.
+static SDValue combineNestedGF2P8AFFINEQB(SDNode *N, const SDLoc &DL,
+                                          SelectionDAG &DAG, EVT VT) {
+  using namespace SDPatternMatch;
+
+  unsigned VecWidth = VT.getSizeInBits();
+  unsigned NumElts = VT.getVectorNumElements();
+  unsigned EltWidth = VT.getScalarSizeInBits();
+
+  SDValue X, YSub, YSup;
+  APInt ImmSub, ImmSup, ConstUndef;
+  SmallVector<APInt> YSubEltBits, YSupEltBits;
+
+  if (!(sd_match(N, m_TernaryOp(X86ISD::GF2P8AFFINEQB,
+                                m_TernaryOp(X86ISD::GF2P8AFFINEQB, m_Value(X),
+                                            m_Value(YSub), m_ConstInt(ImmSub)),
+                                m_Value(YSup), m_ConstInt(ImmSup))) &&
+        getTargetConstantBitsFromNode(YSub, EltWidth, ConstUndef, YSubEltBits,
+                                      /*AllowWholeUndefs=*/false) &&
+        getTargetConstantBitsFromNode(YSup, EltWidth, ConstUndef, YSupEltBits,
+                                      /*AllowWholeUndefs=*/false)))
+    return SDValue();
+
+  APInt SubM(VecWidth, 0);
+  APInt SupM(VecWidth, 0);
+  for (unsigned I = 0; I != NumElts; ++I) {
+    SubM.insertBits(YSubEltBits[I], I * EltWidth);
+    SupM.insertBits(YSupEltBits[I], I * EltWidth);
+  }
+
+  // Immediate permute
+  APInt FoldedImm;
+  if (SupM.isSplat(64)) {
+    FoldedImm = getGFNIByteAffine(ImmSub, SupM.trunc(64), ImmSup);
+  } else {
+    // Immediate is shared and needs to be permuted in the same manner
+    if (ImmSub != 0)
+      return SDValue();
+    FoldedImm = ImmSup;
+  }
+
+  // Matrix permute
+  APInt FoldedMatrix = APInt(VecWidth, 0);
+  APInt LeastRowMask = APInt::getSplat(VecWidth, APInt(64, 0xFF));
+  APInt LeastBitInByte = APInt::getSplat(VecWidth, APInt(8, 0x01));
+  APInt RowSplatter = APInt(VecWidth, 0x0101010101010101ull);
+
+  for (unsigned Row = 0; Row != 8; ++Row) {
+    APInt RowSplat = (SubM & LeastRowMask) * RowSplatter;
+    SubM = SubM.lshr(EltWidth);
+
+    APInt ByteMaskIfSet = (SupM.lshr(7 - Row)) & LeastBitInByte;
+    ByteMaskIfSet *= 0xFF;
+
+    FoldedMatrix ^= RowSplat & ByteMaskIfSet;
+  }
+
+  SmallVector<SDValue> FoldedVector;
+  for (unsigned I = 0; I < NumElts; ++I) {
+    APInt FoldedElt = FoldedMatrix.extractBits(EltWidth, I * EltWidth);
+    FoldedVector.push_back(DAG.getConstant(FoldedElt, DL, MVT::i8));
+  }
+  SDValue NewMatrix = DAG.getBuildVector(VT, DL, FoldedVector);
+
+  return DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, VT, X, NewMatrix,
+                     DAG.getTargetConstant(FoldedImm, DL, MVT::i8));
+}
+
 static SDValue combineGF2P8AFFINEQB(SDNode *N, SelectionDAG &DAG) {
   EVT VT = N->getValueType(0);
   SDLoc dl(N);
@@ -62679,6 +62769,9 @@ static SDValue combineGF2P8AFFINEQB(SDNode *N, SelectionDAG &DAG) {
   if (SDValue R = combineAndOnGF2P8AFFINEQBOperand(N, dl, DAG, VT))
     return R;
 
+  if (SDValue R = combineNestedGF2P8AFFINEQB(N, dl, DAG, VT))
+    return R;
+
   return SDValue();
 }
 

diff  --git a/llvm/test/CodeGen/X86/combine-gfni.ll b/llvm/test/CodeGen/X86/combine-gfni.ll
index b105cdf7ea895..85d5a4ce4cf38 100644
--- a/llvm/test/CodeGen/X86/combine-gfni.ll
+++ b/llvm/test/CodeGen/X86/combine-gfni.ll
@@ -93,6 +93,379 @@ define <16 x i8> @gf2p8mulb_freeze(<16 x i8> %a0, <16 x i8> %a1, <16 x i8> %a2)
   ret <16 x i8> %r
 }
 
+;; Nested GF2P8AFFINEQB fold
+
+define <16 x i8> @nested_fold_ashr1_rotl2(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_ashr1_rotl2:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [64,32,16,8,4,2,128,128,64,32,16,8,4,2,128,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_ashr1_rotl2:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [64,32,16,8,4,2,128,128,64,32,16,8,4,2,128,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_ashr1_rotl2:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [64,32,16,8,4,2,128,128,64,32,16,8,4,2,128,128]
+; AVX512-NEXT:    retq
+  %ashr1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2>, i8 0)
+  %rotl2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %ashr1, <16 x i8> <i8 32, i8 16, i8 8, i8 4, i8 2, i8 1, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2, i8 1, i8 128, i8 64>, i8 0)
+  ret <16 x i8> %rotl2
+}
+
+define <16 x i8> @nested_fold_ashr2_reverse(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_ashr2_reverse:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [4,8,16,32,64,128,128,128,4,8,16,32,64,128,128,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_ashr2_reverse:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [4,8,16,32,64,128,128,128,4,8,16,32,64,128,128,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_ashr2_reverse:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [4,8,16,32,64,128,128,128,4,8,16,32,64,128,128,128]
+; AVX512-NEXT:    retq
+  %ashr2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 128, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 128, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4>, i8 0)
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %ashr2, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  ret <16 x i8> %rev
+}
+
+define <16 x i8> @nested_fold_ashr2_splat_lsb(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_ashr2_splat_lsb:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_ashr2_splat_lsb:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_ashr2_splat_lsb:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4]
+; AVX512-NEXT:    retq
+  %ashr2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 128, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 128, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4>, i8 0)
+  %lsb = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %ashr2, <16 x i8> splat(i8 1), i8 0)
+  ret <16 x i8> %lsb
+}
+
+define <16 x i8> @nested_fold_cumulative_parity_both_directions(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_cumulative_parity_both_directions:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [255,128,191,160,175,168,171,170,255,128,191,160,175,168,171,170]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_cumulative_parity_both_directions:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [255,128,191,160,175,168,171,170,255,128,191,160,175,168,171,170]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_cumulative_parity_both_directions:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [255,128,191,160,175,168,171,170,255,128,191,160,175,168,171,170]
+; AVX512-NEXT:    retq
+  %left = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>, i8 0)
+  %right = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %left, <16 x i8> <i8 128, i8 192, i8 224, i8 240, i8 248, i8 252, i8 254, i8 255, i8 128, i8 192, i8 224, i8 240, i8 248, i8 252, i8 254, i8 255>, i8 0)
+  ret <16 x i8> %right
+}
+
+define <16 x i8> @nested_fold_reverse_reverse_reverse(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_reverse_reverse_reverse:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_reverse_reverse_reverse:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_reverse_reverse_reverse:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX512-NEXT:    retq
+  %rev1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  %rev2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %rev1, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  %rev3 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %rev2, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  ret <16 x i8> %rev3
+}
+
+define <16 x i8> @nested_fold_parity_fill_cumulative_parity(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_parity_fill_cumulative_parity:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_parity_fill_cumulative_parity:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_parity_fill_cumulative_parity:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255]
+; AVX512-NEXT:    retq
+  %fill = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> splat(i8 -1), i8 0)
+  %parity = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %fill, <16 x i8> <i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>, i8 0)
+  ret <16 x i8> %parity
+}
+
+define <16 x i8> @nested_fold_ashr1_reverse_non_zero_imm(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_ashr1_reverse_non_zero_imm:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $240, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [2,4,8,16,32,64,128,128,2,4,8,16,32,64,128,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_ashr1_reverse_non_zero_imm:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $240, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [2,4,8,16,32,64,128,128,2,4,8,16,32,64,128,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_ashr1_reverse_non_zero_imm:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $240, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [2,4,8,16,32,64,128,128,2,4,8,16,32,64,128,128]
+; AVX512-NEXT:    retq
+  %ashr1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2>, i8 15)
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %ashr1, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  ret <16 x i8> %rev
+}
+
+define <16 x i8> @nested_fold_reverse_ashr1_non_zero_imm(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_reverse_ashr1_non_zero_imm:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $192, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [1,1,2,4,8,16,32,64,1,1,2,4,8,16,32,64]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_reverse_ashr1_non_zero_imm:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $192, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [1,1,2,4,8,16,32,64,1,1,2,4,8,16,32,64]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_reverse_ashr1_non_zero_imm:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $192, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [1,1,2,4,8,16,32,64,1,1,2,4,8,16,32,64]
+; AVX512-NEXT:    retq
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 129)
+  %ashr1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %rev, <16 x i8> <i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2>, i8 0)
+  ret <16 x i8> %ashr1
+}
+
+define <16 x i8> @nested_fold_const_gen_cumulative_parity_non_zero_imm(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_const_gen_cumulative_parity_non_zero_imm:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $213, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [96,32,0,32,0,32,0,32,96,32,0,32,0,32,0,32]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_const_gen_cumulative_parity_non_zero_imm:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $213, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [96,32,0,32,0,32,0,32,96,32,0,32,0,32,0,32]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_const_gen_cumulative_parity_non_zero_imm:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $213, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [96,32,0,32,0,32,0,32,96,32,0,32,0,32,0,32]
+; AVX512-NEXT:    retq
+  %gen = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 64, i8 32, i8 32, i8 32,i8 32, i8 32, i8 32, i8 32, i8 64, i8 32, i8 32, i8 32,i8 32, i8 32, i8 32, i8 32>, i8 127)
+  %parity = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %gen, <16 x i8> <i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>, i8 0)
+  ret <16 x i8> %parity
+}
+
+define <16 x i8> @nested_fold_rotr2_cumulative_parity_non_zero_imm(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_rotr2_cumulative_parity_non_zero_imm:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $170, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [255,253,252,124,60,28,12,4,255,253,252,124,60,28,12,4]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_rotr2_cumulative_parity_non_zero_imm:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $170, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [255,253,252,124,60,28,12,4,255,253,252,124,60,28,12,4]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_rotr2_cumulative_parity_non_zero_imm:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $170, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [255,253,252,124,60,28,12,4,255,253,252,124,60,28,12,4]
+; AVX512-NEXT:    retq
+  %rotr2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 2, i8 1, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2, i8 1, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4>, i8 255)
+  %parity = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %rotr2, <16 x i8> <i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>, i8 255)
+  ret <16 x i8> %parity
+}
+
+;; Positive case: Same number of instructions but shortens dependency chain
+define <16 x i8> @nested_fold_multi_use(<16 x i8> %src, ptr %sink) nounwind {
+; SSE-LABEL: nested_fold_multi_use:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movdqa %xmm0, %xmm1
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; SSE-NEXT:    movdqa %xmm1, (%rdi)
+; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
+; SSE-NEXT:    gf2p8affineqb $0, %xmm1, %xmm0
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_multi_use:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX-NEXT:    vmovdqa %xmm1, (%rdi)
+; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_multi_use:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm1 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX512-NEXT:    vmovdqa %xmm1, (%rdi)
+; AVX512-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX512-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  store <16 x i8> %rev, ptr %sink
+  %parity = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %rev, <16 x i8> splat(i8 -1), i8 0)
+  ret <16 x i8> %parity
+}
+
+;; Positive case: Non-splat sub-matrix can still fold
+define <16 x i8> @nested_fold_ashr12_reverse(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_ashr12_reverse:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [2,4,8,16,32,64,128,128,4,8,16,32,64,128,128,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_ashr12_reverse:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [2,4,8,16,32,64,128,128,4,8,16,32,64,128,128,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_ashr12_reverse:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [2,4,8,16,32,64,128,128,4,8,16,32,64,128,128,128]
+; AVX512-NEXT:    retq
+  %ashr12 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4, i8 2, i8 128, i8 128, i8 128, i8 64, i8 32, i8 16, i8 8, i8 4>, i8 0)
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %ashr12, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  ret <16 x i8> %rev
+}
+
+;; Positive case: Non-splat super-matrix can still fold with a zero immediate
+define <16 x i8> @nested_fold_cumulative_parity_fill_17(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_cumulative_parity_fill_17:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [3,3,3,3,3,3,3,3,255,255,255,255,255,255,255,255]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_cumulative_parity_fill_17:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [3,3,3,3,3,3,3,3,255,255,255,255,255,255,255,255]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_cumulative_parity_fill_17:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [3,3,3,3,3,3,3,3,255,255,255,255,255,255,255,255]
+; AVX512-NEXT:    retq
+  %parity = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>, i8 0)
+  %fill12 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %parity, <16 x i8> <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128>, i8 0)
+  ret <16 x i8> %fill12
+}
+
+;; Negative case: Non-splat super-matrix can't fold a non-zero immediate
+define <16 x i8> @nested_fold_cumulative_parity_fill_17_non_zero_imm(<16 x i8> %src) nounwind {
+; SSE-LABEL: nested_fold_cumulative_parity_fill_17_non_zero_imm:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $1, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [255,127,63,31,15,7,3,1,255,127,63,31,15,7,3,1]
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [2,2,2,2,2,2,2,2,128,128,128,128,128,128,128,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_cumulative_parity_fill_17_non_zero_imm:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $1, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [255,127,63,31,15,7,3,1,255,127,63,31,15,7,3,1]
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [2,2,2,2,2,2,2,2,128,128,128,128,128,128,128,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_cumulative_parity_fill_17_non_zero_imm:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $1, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [255,127,63,31,15,7,3,1,255,127,63,31,15,7,3,1]
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [2,2,2,2,2,2,2,2,128,128,128,128,128,128,128,128]
+; AVX512-NEXT:    retq
+  %parity = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1, i8 255, i8 127, i8 63, i8 31, i8 15, i8 7, i8 3, i8 1>, i8 1)
+  %fill12 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %parity, <16 x i8> <i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 2, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128>, i8 0)
+  ret <16 x i8> %fill12
+}
+
+;; Negative case: Can't fold if sub-matrix isn't constant
+define <16 x i8> @nested_fold_variable_sub(<16 x i8> %src, <16 x i8> %matrix) nounwind {
+; SSE-LABEL: nested_fold_variable_sub:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, %xmm1, %xmm0
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_variable_sub:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_variable_sub:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX512-NEXT:    retq
+  %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> %matrix, i8 0)
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %gfni, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  ret <16 x i8> %rev
+}
+
+;; Negative case: Can't fold if super-matrix isn't constant
+define <16 x i8> @nested_fold_variable_super(<16 x i8> %src, <16 x i8> %matrix) nounwind {
+; SSE-LABEL: nested_fold_variable_super:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; SSE-NEXT:    gf2p8affineqb $0, %xmm1, %xmm0
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_variable_super:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_variable_super:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
+; AVX512-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %rev = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128, i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 128>, i8 0)
+  %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %rev, <16 x i8> %matrix, i8 0)
+  ret <16 x i8> %gfni
+}
+
+;; Negative case: Can't fold with both variable
+define <16 x i8> @nested_fold_both_variable(<16 x i8> %src, <16 x i8> %submatrix, <16 x i8> %supmatrix) nounwind {
+; SSE-LABEL: nested_fold_both_variable:
+; SSE:       # %bb.0:
+; SSE-NEXT:    gf2p8affineqb $0, %xmm1, %xmm0
+; SSE-NEXT:    gf2p8affineqb $0, %xmm2, %xmm0
+; SSE-NEXT:    retq
+;
+; AVX-LABEL: nested_fold_both_variable:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vgf2p8affineqb $0, %xmm2, %xmm0, %xmm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: nested_fold_both_variable:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vgf2p8affineqb $0, %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %sub = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src, <16 x i8> %submatrix, i8 0)
+  %sup = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %sub, <16 x i8> %supmatrix, i8 0)
+  ret <16 x i8> %sup
+}
+
 declare <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8)
 declare <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8>, <32 x i8>, i8)
 declare <16 x i8> @llvm.x86.vgf2p8affineinvqb.128(<16 x i8>, <16 x i8>, i8)

diff  --git a/llvm/test/CodeGen/X86/gfni-funnel-shifts.ll b/llvm/test/CodeGen/X86/gfni-funnel-shifts.ll
index 87db9d1410c6d..2026046917ea0 100644
--- a/llvm/test/CodeGen/X86/gfni-funnel-shifts.ll
+++ b/llvm/test/CodeGen/X86/gfni-funnel-shifts.ll
@@ -679,14 +679,12 @@ define <32 x i8> @var_fshl_v32i8(<32 x i8> %a, <32 x i8> %b, <32 x i8> %amt) nou
 ; GFNIAVX512VL-NEXT:    vpand %ymm4, %ymm0, %ymm0
 ; GFNIAVX512VL-NEXT:    vgf2p8mulb %ymm6, %ymm0, %ymm0
 ; GFNIAVX512VL-NEXT:    vpandn %ymm3, %ymm2, %ymm2
-; GFNIAVX512VL-NEXT:    vpshufb %ymm2, %ymm7, %ymm3
-; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm1 # [0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2]
-; GFNIAVX512VL-NEXT:    vpbroadcastq {{.*#+}} ymm4 = [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
-; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, %ymm4, %ymm1, %ymm1
-; GFNIAVX512VL-NEXT:    vpand %ymm3, %ymm1, %ymm1
-; GFNIAVX512VL-NEXT:    vpshufb %ymm2, %ymm5, %ymm2
-; GFNIAVX512VL-NEXT:    vgf2p8mulb %ymm2, %ymm1, %ymm1
-; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, %ymm4, %ymm1, %ymm1
+; GFNIAVX512VL-NEXT:    vpshufb %ymm2, %ymm5, %ymm3
+; GFNIAVX512VL-NEXT:    vpshufb %ymm2, %ymm7, %ymm2
+; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm1 # [2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0]
+; GFNIAVX512VL-NEXT:    vpand %ymm2, %ymm1, %ymm1
+; GFNIAVX512VL-NEXT:    vgf2p8mulb %ymm3, %ymm1, %ymm1
+; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm1 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
 ; GFNIAVX512VL-NEXT:    vpor %ymm1, %ymm0, %ymm0
 ; GFNIAVX512VL-NEXT:    retq
 ;
@@ -1608,12 +1606,10 @@ define <64 x i8> @var_fshl_v64i8(<64 x i8> %a, <64 x i8> %b, <64 x i8> %amt) nou
 ; GFNIAVX512VL-NEXT:    vpshufb %ymm4, %ymm7, %ymm4
 ; GFNIAVX512VL-NEXT:    vpshufb %ymm2, %ymm7, %ymm2
 ; GFNIAVX512VL-NEXT:    vinserti64x4 $1, %ymm4, %zmm2, %zmm2
-; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm1 # [0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2,0,128,64,32,16,8,4,2]
-; GFNIAVX512VL-NEXT:    vpbroadcastq {{.*#+}} zmm4 = [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
-; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, %zmm4, %zmm1, %zmm1
+; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm1 # [2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0,2,4,8,16,32,64,128,0]
 ; GFNIAVX512VL-NEXT:    vpandq %zmm2, %zmm1, %zmm1
 ; GFNIAVX512VL-NEXT:    vgf2p8mulb %zmm3, %zmm1, %zmm1
-; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, %zmm4, %zmm1, %zmm1
+; GFNIAVX512VL-NEXT:    vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm1 # [1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128,1,2,4,8,16,32,64,128]
 ; GFNIAVX512VL-NEXT:    vporq %zmm1, %zmm0, %zmm0
 ; GFNIAVX512VL-NEXT:    retq
 ;


        


More information about the llvm-commits mailing list