[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