[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