[llvm] e19d1f5 - [X86] Fold XOR of two VGF2P8AFFINEQB instructions with same matrix (#199146)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 14 08:13:36 PDT 2026


Author: Walter
Date: 2026-06-14T15:13:30Z
New Revision: e19d1f51a2c80b63cd8ca95bcc757b7077112808

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

LOG: [X86] Fold XOR of two VGF2P8AFFINEQB instructions with same matrix (#199146)

Adds an optimization to fold a XOR between two `vgf2p8affineqb`
instructions that share the same matrix by XORing their sources
beforehand. This patch:

- Can eliminate one `vgf2p8affineqb` instruction.
- Doesn't occur if either affine is multi use, preventing an increase in code size.
- Includes test coverage for both positive and negative cases.

Fixes #196879

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/gfni-xor-fold-avx512.ll
    llvm/test/CodeGen/X86/gfni-xor-fold.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5e2a4888f4ddc..af1e5db995302 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -56508,32 +56508,49 @@ static SDValue combineXorWithGF2P8AFFINEQB(SDNode *N, const SDLoc &DL,
                      DAG.getTargetConstant(NewImm, DL, MVT::i8));
 }
 
-// Fold: vgf2p8affineqb(x, m1, i1) ^ vgf2p8affineqb(x, m2, i2)
-//   =>  vgf2p8affineqb(x, m1 ^ m2, i1 ^ i2)
-// The matrix in vgf2p8affineqb determines which bits of the input are XORed
-// together. XORing two affine transformations of the same input can be folded
-// by XORing both their matrices and immediates together.
+// Given that vgf2p8affineqb performs a XOR permutation, two affines that share
+// a operand can be reassociated through a standalone XOR.
 static SDValue combineXorWithTwoGF2P8AFFINEQB(SDNode *N, const SDLoc &DL,
                                               SelectionDAG &DAG, EVT VT) {
   using namespace SDPatternMatch;
 
-  SDValue X0, Y0, Y1;
+  SDValue X0, X1, M0, M1;
   APInt Imm0, Imm1;
   // Use sd_match for structure matching - m_Xor handles commutation
-  // Match: GF2P8AFFINEQB(x, m1, i1) ^ GF2P8AFFINEQB(x, m2, i2)
-  if (!sd_match(
-          N, m_Xor(m_OneUse(m_TernaryOp(X86ISD::GF2P8AFFINEQB, m_Value(X0),
-                                        m_Value(Y0), m_ConstInt(Imm0))),
-                   m_OneUse(m_TernaryOp(X86ISD::GF2P8AFFINEQB, m_Deferred(X0),
-                                        m_Value(Y1), m_ConstInt(Imm1))))))
+  if (!sd_match(N,
+                m_Xor(m_OneUse(m_TernaryOp(X86ISD::GF2P8AFFINEQB, m_Value(X0),
+                                           m_Value(M0), m_ConstInt(Imm0))),
+                      m_OneUse(m_TernaryOp(X86ISD::GF2P8AFFINEQB, m_Value(X1),
+                                           m_Value(M1), m_ConstInt(Imm1))))))
     return SDValue();
 
   assert((VT == MVT::v16i8 || VT == MVT::v32i8 || VT == MVT::v64i8) &&
          "Unsupported GFNI type");
 
+  // Fold: GF2P8AFFINEQB(x0, m, i1) ^ GF2P8AFFINEQB(x1, m, i2)
+  //   =>  GF2P8AFFINEQB(x0 ^ x1, m, i1 ^ i2)
+  // This instruction performs an XOR permutation of the input, which is
+  // associative. Therefore XORing before permuting is equivalent.
+  if (M0 == M1) {
+    uint64_t NewImm = Imm0.getZExtValue() ^ Imm1.getZExtValue();
+
+    SDValue NewSrc = DAG.getNode(ISD::XOR, DL, VT, X0, X1);
+
+    return DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, VT, NewSrc, M0,
+                       DAG.getTargetConstant(NewImm, DL, MVT::i8));
+  }
+
+  // Fold: vgf2p8affineqb(x, m0, i1) ^ vgf2p8affineqb(x, m1, i2)
+  //   =>  vgf2p8affineqb(x, m0 ^ m1, i1 ^ i2)
+  // The matrix in vgf2p8affineqb determines which bits of the input are XORed
+  // together. XORing two affine transformations of the same input can be folded
+  // by XORing both their matrices and immediates together.
+  if (X0 != X1)
+    return SDValue();
+
   uint64_t NewImm = Imm0.getZExtValue() ^ Imm1.getZExtValue();
 
-  SDValue NewMatrix = DAG.getNode(ISD::XOR, DL, VT, Y0, Y1);
+  SDValue NewMatrix = DAG.getNode(ISD::XOR, DL, VT, M0, M1);
 
   return DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, VT, X0, NewMatrix,
                      DAG.getTargetConstant(NewImm, DL, MVT::i8));

diff  --git a/llvm/test/CodeGen/X86/gfni-xor-fold-avx512.ll b/llvm/test/CodeGen/X86/gfni-xor-fold-avx512.ll
index 4107f07741991..1c8a605e3c094 100644
--- a/llvm/test/CodeGen/X86/gfni-xor-fold-avx512.ll
+++ b/llvm/test/CodeGen/X86/gfni-xor-fold-avx512.ll
@@ -117,9 +117,9 @@ define <64 x i8> @test_affine_src_xor_no_fold_var_matrix(<64 x i8> %src, <64 x i
 }
 
 ;; Test folding XOR of two vgf2p8affineqb with same input - 512-bit
-define <64 x i8> @test_affine_affine_xor_fold_512(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2) nounwind {
+define <64 x i8> @test_affine_affine_xor_same_source_fold_512(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2) nounwind {
 ;
-; CHECK-LABEL: test_affine_affine_xor_fold_512:
+; CHECK-LABEL: test_affine_affine_xor_same_source_fold_512:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    vpxorq %zmm2, %zmm1, %zmm1
 ; CHECK-NEXT:    vgf2p8affineqb $89, %zmm1, %zmm0, %zmm0
@@ -131,9 +131,9 @@ define <64 x i8> @test_affine_affine_xor_fold_512(<64 x i8> %src, <64 x i8> %m1,
 }
 
 ;; Test with non-zero immediates - 512-bit
-define <64 x i8> @test_affine_affine_xor_fold_512_nonzero(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2) nounwind {
+define <64 x i8> @test_affine_affine_xor_same_source_fold_512_nonzero(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2) nounwind {
 ;
-; CHECK-LABEL: test_affine_affine_xor_fold_512_nonzero:
+; CHECK-LABEL: test_affine_affine_xor_same_source_fold_512_nonzero:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    vpxorq %zmm2, %zmm1, %zmm1
 ; CHECK-NEXT:    vgf2p8affineqb $15, %zmm1, %zmm0, %zmm0
@@ -145,9 +145,9 @@ define <64 x i8> @test_affine_affine_xor_fold_512_nonzero(<64 x i8> %src, <64 x
 }
 
 ;; Test commutative XOR - 512-bit
-define <64 x i8> @test_affine_affine_xor_fold_512_commutative(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2) nounwind {
+define <64 x i8> @test_affine_affine_xor_same_source_fold_512_commutative(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2) nounwind {
 ;
-; CHECK-LABEL: test_affine_affine_xor_fold_512_commutative:
+; CHECK-LABEL: test_affine_affine_xor_same_source_fold_512_commutative:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    vpxorq %zmm1, %zmm2, %zmm1
 ; CHECK-NEXT:    vgf2p8affineqb $166, %zmm1, %zmm0, %zmm0
@@ -159,9 +159,9 @@ define <64 x i8> @test_affine_affine_xor_fold_512_commutative(<64 x i8> %src, <6
 }
 
 ;; Negative test: multi-use should not fold - 512-bit
-define <64 x i8> @test_affine_affine_xor_no_fold_512_multi_use(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2, ptr %out) nounwind {
+define <64 x i8> @test_affine_affine_xor_same_source_no_fold_512_multi_use(<64 x i8> %src, <64 x i8> %m1, <64 x i8> %m2, ptr %out) nounwind {
 ;
-; CHECK-LABEL: test_affine_affine_xor_no_fold_512_multi_use:
+; CHECK-LABEL: test_affine_affine_xor_same_source_no_fold_512_multi_use:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    vgf2p8affineqb $23, %zmm1, %zmm0, %zmm1
 ; CHECK-NEXT:    vgf2p8affineqb $200, %zmm2, %zmm0, %zmm0
@@ -175,6 +175,46 @@ define <64 x i8> @test_affine_affine_xor_no_fold_512_multi_use(<64 x i8> %src, <
   ret <64 x i8> %xor
 }
 
+;; Test folding XOR of two vgf2p8affineqb with same matrix
+define <64 x i8> @test_affine_affine_same_matrix_fold_512(<64 x i8> %src1, <64 x i8> %src2, <64 x i8> %m) nounwind {
+; CHECK-LABEL: test_affine_affine_same_matrix_fold_512:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpxorq %zmm1, %zmm0, %zmm0
+; CHECK-NEXT:    vgf2p8affineqb $0, %zmm2, %zmm0, %zmm0
+; CHECK-NEXT:    retq
+  %gfni1 = call <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8> %src1, <64 x i8> %m, i8 0)
+  %gfni2 = call <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8> %src2, <64 x i8> %m, i8 0)
+  %xor = xor <64 x i8> %gfni1, %gfni2
+  ret <64 x i8> %xor
+}
+
+define <64 x i8> @test_affine_affine_same_matrix_fold_512_immediate(<64 x i8> %src1, <64 x i8> %src2, <64 x i8> %m) nounwind {
+; CHECK-LABEL: test_affine_affine_same_matrix_fold_512_immediate:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vpxorq %zmm1, %zmm0, %zmm0
+; CHECK-NEXT:    vgf2p8affineqb $130, %zmm2, %zmm0, %zmm0
+; CHECK-NEXT:    retq
+  %gfni1 = call <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8> %src1, <64 x i8> %m, i8 183)
+  %gfni2 = call <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8> %src2, <64 x i8> %m, i8 53)
+  %xor = xor <64 x i8> %gfni1, %gfni2
+  ret <64 x i8> %xor
+}
+
+define <64 x i8> @test_affine_affine_same_matrix_no_fold_512_multi_use(<64 x i8> %src1, <64 x i8> %src2, <64 x i8> %m, ptr %sink) nounwind {
+; CHECK-LABEL: test_affine_affine_same_matrix_no_fold_512_multi_use:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vgf2p8affineqb $23, %zmm2, %zmm0, %zmm0
+; CHECK-NEXT:    vgf2p8affineqb $200, %zmm2, %zmm1, %zmm1
+; CHECK-NEXT:    vmovdqa64 %zmm0, (%rdi)
+; CHECK-NEXT:    vpxorq %zmm1, %zmm0, %zmm0
+; CHECK-NEXT:    retq
+  %gfni1 = call <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8> %src1, <64 x i8> %m, i8 23)
+  %gfni2 = call <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8> %src2, <64 x i8> %m, i8 200)
+  store <64 x i8> %gfni1, ptr %sink
+  %xor = xor <64 x i8> %gfni1, %gfni2
+  ret <64 x i8> %xor
+}
+
 ;; Negative test: 
diff erent inputs should not fold - 512-bit
 define <64 x i8> @test_affine_affine_xor_no_fold_512_
diff erent_inputs(<64 x i8> %src1, <64 x i8> %src2, <64 x i8> %m1, <64 x i8> %m2) nounwind {
 ;

diff  --git a/llvm/test/CodeGen/X86/gfni-xor-fold.ll b/llvm/test/CodeGen/X86/gfni-xor-fold.ll
index d7bd66377bc3d..602e317ef2685 100644
--- a/llvm/test/CodeGen/X86/gfni-xor-fold.ll
+++ b/llvm/test/CodeGen/X86/gfni-xor-fold.ll
@@ -241,15 +241,15 @@ define <16 x i8> @test_affine_src_xor_no_fold_var_matrix(<16 x i8> %src, <16 x i
 }
 
 ;; Test folding XOR of two vgf2p8affineqb with same input - 128-bit
-define <16 x i8> @test_affine_affine_xor_fold_128(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2) nounwind {
+define <16 x i8> @test_affine_affine_xor_same_source_fold_128(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2) nounwind {
 ;
-; AVX-LABEL: test_affine_affine_xor_fold_128:
+; AVX-LABEL: test_affine_affine_xor_same_source_fold_128:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vpxor %xmm2, %xmm1, %xmm1
 ; AVX-NEXT:    vgf2p8affineqb $89, %xmm1, %xmm0, %xmm0
 ; AVX-NEXT:    retq
 ;
-; AVX512-LABEL: test_affine_affine_xor_fold_128:
+; AVX512-LABEL: test_affine_affine_xor_same_source_fold_128:
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vpxor %xmm2, %xmm1, %xmm1
 ; AVX512-NEXT:    vgf2p8affineqb $89, %xmm1, %xmm0, %xmm0
@@ -261,15 +261,15 @@ define <16 x i8> @test_affine_affine_xor_fold_128(<16 x i8> %src, <16 x i8> %m1,
 }
 
 ;; Test with non-zero immediates - 128-bit
-define <16 x i8> @test_affine_affine_xor_fold_128_nonzero(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2) nounwind {
+define <16 x i8> @test_affine_affine_xor_same_source_fold_128_nonzero(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2) nounwind {
 ;
-; AVX-LABEL: test_affine_affine_xor_fold_128_nonzero:
+; AVX-LABEL: test_affine_affine_xor_same_source_fold_128_nonzero:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vpxor %xmm2, %xmm1, %xmm1
 ; AVX-NEXT:    vgf2p8affineqb $15, %xmm1, %xmm0, %xmm0
 ; AVX-NEXT:    retq
 ;
-; AVX512-LABEL: test_affine_affine_xor_fold_128_nonzero:
+; AVX512-LABEL: test_affine_affine_xor_same_source_fold_128_nonzero:
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vpxor %xmm2, %xmm1, %xmm1
 ; AVX512-NEXT:    vgf2p8affineqb $15, %xmm1, %xmm0, %xmm0
@@ -281,15 +281,15 @@ define <16 x i8> @test_affine_affine_xor_fold_128_nonzero(<16 x i8> %src, <16 x
 }
 
 ;; Test commutative XOR - 128-bit
-define <16 x i8> @test_affine_affine_xor_fold_128_commutative(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2) nounwind {
+define <16 x i8> @test_affine_affine_xor_same_source_fold_128_commutative(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2) nounwind {
 ;
-; AVX-LABEL: test_affine_affine_xor_fold_128_commutative:
+; AVX-LABEL: test_affine_affine_xor_same_source_fold_128_commutative:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vpxor %xmm1, %xmm2, %xmm1
 ; AVX-NEXT:    vgf2p8affineqb $166, %xmm1, %xmm0, %xmm0
 ; AVX-NEXT:    retq
 ;
-; AVX512-LABEL: test_affine_affine_xor_fold_128_commutative:
+; AVX512-LABEL: test_affine_affine_xor_same_source_fold_128_commutative:
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vpxor %xmm1, %xmm2, %xmm1
 ; AVX512-NEXT:    vgf2p8affineqb $166, %xmm1, %xmm0, %xmm0
@@ -301,9 +301,9 @@ define <16 x i8> @test_affine_affine_xor_fold_128_commutative(<16 x i8> %src, <1
 }
 
 ;; Negative test: multi-use should not fold - 128-bit
-define <16 x i8> @test_affine_affine_xor_no_fold_multi_use(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2, ptr %out) nounwind {
+define <16 x i8> @test_affine_affine_xor_same_source_no_fold_multi_use(<16 x i8> %src, <16 x i8> %m1, <16 x i8> %m2, ptr %out) nounwind {
 ;
-; AVX-LABEL: test_affine_affine_xor_no_fold_multi_use:
+; AVX-LABEL: test_affine_affine_xor_same_source_no_fold_multi_use:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vgf2p8affineqb $23, %xmm1, %xmm0, %xmm1
 ; AVX-NEXT:    vgf2p8affineqb $200, %xmm2, %xmm0, %xmm0
@@ -311,7 +311,7 @@ define <16 x i8> @test_affine_affine_xor_no_fold_multi_use(<16 x i8> %src, <16 x
 ; AVX-NEXT:    vpxor %xmm0, %xmm1, %xmm0
 ; AVX-NEXT:    retq
 ;
-; AVX512-LABEL: test_affine_affine_xor_no_fold_multi_use:
+; AVX512-LABEL: test_affine_affine_xor_same_source_no_fold_multi_use:
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vgf2p8affineqb $23, %xmm1, %xmm0, %xmm1
 ; AVX512-NEXT:    vgf2p8affineqb $200, %xmm2, %xmm0, %xmm0
@@ -325,6 +325,66 @@ define <16 x i8> @test_affine_affine_xor_no_fold_multi_use(<16 x i8> %src, <16 x
   ret <16 x i8> %xor
 }
 
+;; Test folding XOR of two vgf2p8affineqb with same matrix
+define <16 x i8> @test_affine_affine_same_matrix_fold_128(<16 x i8> %src1, <16 x i8> %src2, <16 x i8> %m) nounwind {
+; AVX-LABEL: test_affine_affine_same_matrix_fold_128:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vgf2p8affineqb $0, %xmm2, %xmm0, %xmm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: test_affine_affine_same_matrix_fold_128:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vgf2p8affineqb $0, %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %gfni1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src1, <16 x i8> %m, i8 0)
+  %gfni2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src2, <16 x i8> %m, i8 0)
+  %xor = xor <16 x i8> %gfni1, %gfni2
+  ret <16 x i8> %xor
+}
+
+define <16 x i8> @test_affine_affine_same_matrix_fold_immediate(<16 x i8> %src1, <16 x i8> %src2, <16 x i8> %m) nounwind {
+; AVX-LABEL: test_affine_affine_same_matrix_fold_immediate:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    vgf2p8affineqb $130, %xmm2, %xmm0, %xmm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: test_affine_affine_same_matrix_fold_immediate:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    vgf2p8affineqb $130, %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %gfni1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src1, <16 x i8> %m, i8 183)
+  %gfni2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src2, <16 x i8> %m, i8 53)
+  %xor = xor <16 x i8> %gfni1, %gfni2
+  ret <16 x i8> %xor
+}
+
+define <16 x i8> @test_affine_affine_same_matrix_no_fold_multi_use(<16 x i8> %src1, <16 x i8> %src2, <16 x i8> %m, ptr %sink) nounwind {
+; AVX-LABEL: test_affine_affine_same_matrix_no_fold_multi_use:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vgf2p8affineqb $23, %xmm2, %xmm0, %xmm0
+; AVX-NEXT:    vgf2p8affineqb $200, %xmm2, %xmm1, %xmm1
+; AVX-NEXT:    vmovdqa %xmm0, (%rdi)
+; AVX-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: test_affine_affine_same_matrix_no_fold_multi_use:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vgf2p8affineqb $23, %xmm2, %xmm0, %xmm0
+; AVX512-NEXT:    vgf2p8affineqb $200, %xmm2, %xmm1, %xmm1
+; AVX512-NEXT:    vmovdqa %xmm0, (%rdi)
+; AVX512-NEXT:    vpxor %xmm1, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %gfni1 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src1, <16 x i8> %m, i8 23)
+  %gfni2 = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %src2, <16 x i8> %m, i8 200)
+  store <16 x i8> %gfni1, ptr %sink
+  %xor = xor <16 x i8> %gfni1, %gfni2
+  ret <16 x i8> %xor
+}
+
 ;; Negative test: 
diff erent inputs should not fold - 128-bit
 define <16 x i8> @test_affine_affine_xor_no_fold_
diff erent_inputs(<16 x i8> %src1, <16 x i8> %src2, <16 x i8> %m1, <16 x i8> %m2) nounwind {
 ;
@@ -348,15 +408,15 @@ define <16 x i8> @test_affine_affine_xor_no_fold_
diff erent_inputs(<16 x i8> %src
 }
 
 ;; Test 256-bit vectors
-define <32 x i8> @test_affine_affine_xor_fold_256(<32 x i8> %src, <32 x i8> %m1, <32 x i8> %m2) nounwind {
+define <32 x i8> @test_affine_affine_xor_same_source_fold_256(<32 x i8> %src, <32 x i8> %m1, <32 x i8> %m2) nounwind {
 ;
-; AVX-LABEL: test_affine_affine_xor_fold_256:
+; AVX-LABEL: test_affine_affine_xor_same_source_fold_256:
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vxorps %ymm2, %ymm1, %ymm1
 ; AVX-NEXT:    vgf2p8affineqb $89, %ymm1, %ymm0, %ymm0
 ; AVX-NEXT:    retq
 ;
-; AVX512-LABEL: test_affine_affine_xor_fold_256:
+; AVX512-LABEL: test_affine_affine_xor_same_source_fold_256:
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vpxor %ymm2, %ymm1, %ymm1
 ; AVX512-NEXT:    vgf2p8affineqb $89, %ymm1, %ymm0, %ymm0
@@ -366,3 +426,21 @@ define <32 x i8> @test_affine_affine_xor_fold_256(<32 x i8> %src, <32 x i8> %m1,
   %xor = xor <32 x i8> %gfni1, %gfni2
   ret <32 x i8> %xor
 }
+
+define <32 x i8> @test_affine_affine_same_matrix_fold_256(<32 x i8> %src1, <32 x i8> %src2, <32 x i8> %m) nounwind {
+; AVX-LABEL: test_affine_affine_same_matrix_fold_256:
+; AVX:       # %bb.0:
+; AVX-NEXT:    vxorps %ymm1, %ymm0, %ymm0
+; AVX-NEXT:    vgf2p8affineqb $89, %ymm2, %ymm0, %ymm0
+; AVX-NEXT:    retq
+;
+; AVX512-LABEL: test_affine_affine_same_matrix_fold_256:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vpxor %ymm1, %ymm0, %ymm0
+; AVX512-NEXT:    vgf2p8affineqb $89, %ymm2, %ymm0, %ymm0
+; AVX512-NEXT:    retq
+  %gfni1 = call <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8> %src1, <32 x i8> %m, i8 42)
+  %gfni2 = call <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8> %src2, <32 x i8> %m, i8 115)
+  %xor = xor <32 x i8> %gfni1, %gfni2
+  ret <32 x i8> %xor
+}


        


More information about the llvm-commits mailing list