[llvm] [X86] Fold OR of constant splats into GF2P8AFFINEQB (PR #194330)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 27 03:34:19 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: hanbeom (ParkHanbum)
<details>
<summary>Changes</summary>
Fold OR of a constant byte splat into X86ISD::GF2P8AFFINEQB when the
affine matrix is known at compile time.
For bits forced to 1 by the OR mask, zero the corresponding matrix rows
(in reverse row order within each 64-bit lane) and set the same bits in
the immediate. This turns:
gf2p8affineqb(x, M, imm) | C
into:
gf2p8affineqb(x, M & KeepMask, imm | C)
where KeepMask clears the rows for output bits selected by C.
This removes a separate OR after GF2P8AFFINEQB for constant-matrix cases
and extends the existing GFNI combine coverage beyond XOR folds.
Fixes: https://github.com/llvm/llvm-project/issues/191173
---
Patch is 26.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/194330.diff
3 Files Affected:
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+50)
- (added) llvm/test/CodeGen/X86/gfni-or-fold-avx512.ll (+248)
- (added) llvm/test/CodeGen/X86/gfni-or-fold.ll (+436)
``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ebc8766969251..e37080cc62e80 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -53171,6 +53171,53 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, const SDLoc &DL,
return SDValue();
}
+static SDValue combineOrWithGF2P8AFFINEQB(SDNode *N, const SDLoc &DL,
+ SelectionDAG &DAG, EVT VT) {
+ using namespace SDPatternMatch;
+ SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
+ auto TryMatch = [&](SDValue GFSide, SDValue ConstSide) -> SDValue {
+ SDValue GF = GFSide;
+ SDValue X, Matrix;
+ APInt Imm;
+ if (!sd_match(GF, m_OneUse(m_TernaryOp(X86ISD::GF2P8AFFINEQB, m_Value(X),
+ m_Value(Matrix), m_ConstInt(Imm)))))
+ return SDValue();
+
+ APInt SplatVal;
+ if (!X86::isConstantSplat(ConstSide, SplatVal,
+ /*AllowPartialUndefs=*/false))
+ return SDValue();
+
+ APInt UndefElts;
+ SmallVector<APInt, 16> OldMatrix;
+ if (!getTargetConstantBitsFromNode(Matrix, 8, UndefElts, OldMatrix,
+ /*AllowWholeUndefs=*/false,
+ /*AllowPartialUndefs=*/false))
+ return SDValue();
+
+ EVT GFVT = GF.getValueType();
+ uint8_t Mask8 = SplatVal.getZExtValue() & 0xFF;
+ uint8_t NewImm = Imm.getZExtValue() | Mask8;
+ SmallVector<SDValue, 64> MaskOps;
+ for (unsigned I = 0, E = GFVT.getVectorNumElements(); I != E; ++I) {
+ unsigned OutBit = 7 - (I & 7);
+ uint8_t Keep = ((Mask8 >> OutBit) & 1) ? 0x00 : 0xFF;
+ MaskOps.push_back(DAG.getConstant(Keep, DL, MVT::i8));
+ }
+
+ SDValue KeepMask = DAG.getBuildVector(GFVT, DL, MaskOps);
+ SDValue NewMatrix = DAG.getNode(ISD::AND, DL, GFVT, Matrix, KeepMask);
+ SDValue NewGF = DAG.getNode(X86ISD::GF2P8AFFINEQB, DL, GFVT, X, NewMatrix,
+ DAG.getTargetConstant(NewImm, DL, MVT::i8));
+ return NewGF;
+ };
+
+ if (SDValue R = TryMatch(LHS, RHS))
+ return R;
+
+ return TryMatch(RHS, LHS);
+}
+
static SDValue combineOrXorWithSETCC(unsigned Opc, const SDLoc &DL, EVT VT,
SDValue N0, SDValue N1,
SelectionDAG &DAG) {
@@ -53375,6 +53422,9 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG,
if (SDValue R = combineOrXorWithSETCC(N->getOpcode(), dl, VT, N0, N1, DAG))
return R;
+ if (SDValue R = combineOrWithGF2P8AFFINEQB(N, dl, DAG, VT))
+ return R;
+
return SDValue();
}
diff --git a/llvm/test/CodeGen/X86/gfni-or-fold-avx512.ll b/llvm/test/CodeGen/X86/gfni-or-fold-avx512.ll
new file mode 100644
index 0000000000000..020fdbc8db540
--- /dev/null
+++ b/llvm/test/CodeGen/X86/gfni-or-fold-avx512.ll
@@ -0,0 +1,248 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512bw,+gfni | FileCheck %s
+
+declare <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8>, <64 x i8>, i8)
+
+define dso_local <64 x i8> @test_affine_or_fold_512_v64i8(<64 x i8> noundef %a) local_unnamed_addr {
+; CHECK: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 2
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+;
+; CHECK-LABEL: test_affine_or_fold_512_v64i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; CHECK-NEXT: retq
+entry:
+ %gf = tail call <64 x i8> @llvm.x86.vgf2p8affineqb.512(
+ <64 x i8> %a,
+ <64 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 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 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 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)
+ %or = or <64 x i8> %gf, splat(i8 15)
+ ret <64 x i8> %or
+}
+
+define dso_local <64 x i8> @test_affine_or_fold_512_v64i8_commuted(<64 x i8> noundef %a) local_unnamed_addr {
+; CHECK-LABEL: test_affine_or_fold_512_v64i8_commuted:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; CHECK-NEXT: retq
+entry:
+ %gf = tail call <64 x i8> @llvm.x86.vgf2p8affineqb.512(
+ <64 x i8> %a,
+ <64 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 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 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 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)
+ %or = or <64 x i8> splat (i8 15), %gf
+ ret <64 x i8> %or
+}
+
+define dso_local <64 x i8> @test_affine_or_fold_v64i8_mask33(<64 x i8> noundef %a) {
+; CHECK: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 90
+; CHECK-NEXT: .byte 165
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 24
+; CHECK-NEXT: .byte 129
+; CHECK-NEXT: .byte 0
+; CHECK-NEXT: .byte 0
+;
+; CHECK-LABEL: _v64i8_mask33:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vgf2p8affineqb $51, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; CHECK-NEXT: retq
+entry:
+ %gf = tail call <64 x i8> @llvm.x86.vgf2p8affineqb.512(
+ <64 x i8> %a,
+ <64 x i8> <i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1>,
+ i8 0)
+ %or = or <64 x i8> %gf, splat(i8 51)
+ ret <64 x i8> %or
+}
+
+; Negative
+
+define dso_local <64 x i8> @test_affine_or_nofold_nonconst_matrix_v64i8(<64 x i8> noundef %a, <64 x i8> noundef %m) {
+; CHECK-LABEL: test_affine_or_nofold_nonconst_matrix_v64i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vgf2p8affineqb $0, %zmm1, %zmm0, %zmm0
+; CHECK-NEXT: vpord {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm0, %zmm0
+; CHECK-NEXT: retq
+entry:
+ %gf = tail call <64 x i8> @llvm.x86.vgf2p8affineqb.512(
+ <64 x i8> %a,
+ <64 x i8> %m,
+ i8 0)
+ %or = or <64 x i8> %gf, splat(i8 51)
+ ret <64 x i8> %or
+}
+
+define dso_local <64 x i8> @test_affine_or_nofold_nonsplat_mask_v64i8(<64 x i8> noundef %a) {
+; CHECK-LABEL: test_affine_or_nofold_nonsplat_mask_v64i8:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm0
+; CHECK-NEXT: vporq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %zmm0, %zmm0
+; CHECK-NEXT: retq
+entry:
+ %gf = tail call <64 x i8> @llvm.x86.vgf2p8affineqb.512(
+ <64 x i8> %a,
+ <64 x i8> <i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1>,
+ i8 0)
+ %or = or <64 x i8> %gf,
+ <i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51,
+ i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 51, i8 50>
+ ret <64 x i8> %or
+}
+
+
diff --git a/llvm/test/CodeGen/X86/gfni-or-fold.ll b/llvm/test/CodeGen/X86/gfni-or-fold.ll
new file mode 100644
index 0000000000000..92258158d4619
--- /dev/null
+++ b/llvm/test/CodeGen/X86/gfni-or-fold.ll
@@ -0,0 +1,436 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+gfni,+avx | FileCheck %s --check-prefixes=AVX
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512vl,+gfni,+avx512bw | FileCheck %s --check-prefixes=AVX512
+
+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)
+
+define dso_local <16 x i8> @test_affine_or_fold_v16i8(<16 x i8> noundef %a) {
+; AVX: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; AVX-NEXT: .byte 1
+; AVX-NEXT: .byte 2
+; AVX-NEXT: .byte 4
+; AVX-NEXT: .byte 8
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 1
+; AVX-NEXT: .byte 2
+; AVX-NEXT: .byte 4
+; AVX-NEXT: .byte 8
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+;
+; AVX-LABEL: test_affine_or_fold_v16i8:
+; AVX: # %bb.0: # %entry
+; AVX-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: retq
+;
+; AVX512: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; AVX512-NEXT: .byte 1
+; AVX512-NEXT: .byte 2
+; AVX512-NEXT: .byte 4
+; AVX512-NEXT: .byte 8
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 1
+; AVX512-NEXT: .byte 2
+; AVX512-NEXT: .byte 4
+; AVX512-NEXT: .byte 8
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+;
+; AVX512-LABEL: test_affine_or_fold_v16i8:
+; AVX512: # %bb.0: # %entry
+; AVX512-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0
+; AVX512-NEXT: retq
+entry:
+ %gf = tail call <16 x i8> @llvm.x86.vgf2p8affineqb.128(
+ <16 x i8> %a,
+ <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)
+ %or = or <16 x i8> %gf, splat(i8 15)
+ ret <16 x i8> %or
+}
+
+define dso_local <16 x i8> @test_affine_or_fold_v16i8_commuted(<16 x i8> noundef %a) {
+; AVX-LABEL: test_affine_or_fold_v16i8_commuted:
+; AVX: # %bb.0: # %entry
+; AVX-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: retq
+;
+; AVX512-LABEL: test_affine_or_fold_v16i8_commuted:
+; AVX512: # %bb.0: # %entry
+; AVX512-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0
+; AVX512-NEXT: retq
+entry:
+ %gf = tail call <16 x i8> @llvm.x86.vgf2p8affineqb.128(
+ <16 x i8> %a,
+ <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)
+ %or = or <16 x i8> splat(i8 15), %gf
+ ret <16 x i8> %or
+}
+
+define dso_local <16 x i8> @test_affine_or_fold_v16i8_mask33(<16 x i8> noundef %a) {
+; AVX: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; AVX-NEXT: .byte 90
+; AVX-NEXT: .byte 165
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 24
+; AVX-NEXT: .byte 129
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 90
+; AVX-NEXT: .byte 165
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 24
+; AVX-NEXT: .byte 129
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+;
+; AVX-LABEL: test_affine_or_fold_v16i8_mask33:
+; AVX: # %bb.0: # %entry
+; AVX-NEXT: vgf2p8affineqb $51, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: retq
+;
+; AVX512: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; AVX512-NEXT: .byte 90
+; AVX512-NEXT: .byte 165
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 24
+; AVX512-NEXT: .byte 129
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 90
+; AVX512-NEXT: .byte 165
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 24
+; AVX512-NEXT: .byte 129
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+;
+; AVX512-LABEL: test_affine_or_fold_v16i8_mask33:
+; AVX512: # %bb.0: # %entry
+; AVX512-NEXT: vgf2p8affineqb $51, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0
+; AVX512-NEXT: retq
+entry:
+ %gf = tail call <16 x i8> @llvm.x86.vgf2p8affineqb.128(
+ <16 x i8> %a,
+ <16 x i8> <i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1,
+ i8 90, i8 -91, i8 60, i8 -61, i8 24, i8 -127, i8 126, i8 1>,
+ i8 0)
+ %or = or <16 x i8> %gf, splat(i8 51)
+ ret <16 x i8> %or
+}
+
+
+define dso_local <32 x i8> @test_affine_or_fold_v32i8(<32 x i8> noundef %a) {
+; AVX: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; AVX-NEXT: .byte 1
+; AVX-NEXT: .byte 2
+; AVX-NEXT: .byte 4
+; AVX-NEXT: .byte 8
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 1
+; AVX-NEXT: .byte 2
+; AVX-NEXT: .byte 4
+; AVX-NEXT: .byte 8
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 1
+; AVX-NEXT: .byte 2
+; AVX-NEXT: .byte 4
+; AVX-NEXT: .byte 8
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 1
+; AVX-NEXT: .byte 2
+; AVX-NEXT: .byte 4
+; AVX-NEXT: .byte 8
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-NEXT: .byte 0
+; AVX-LABEL: test_affine_or_fold_v32i8:
+; AVX: # %bb.0: # %entry
+; AVX-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX-NEXT: retq
+;
+; AVX512: [[MAT:\.LCPI[0-9]+_[0-9]+]]:
+; AVX512-NEXT: .byte 1
+; AVX512-NEXT: .byte 2
+; AVX512-NEXT: .byte 4
+; AVX512-NEXT: .byte 8
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 1
+; AVX512-NEXT: .byte 2
+; AVX512-NEXT: .byte 4
+; AVX512-NEXT: .byte 8
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 1
+; AVX512-NEXT: .byte 2
+; AVX512-NEXT: .byte 4
+; AVX512-NEXT: .byte 8
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 1
+; AVX512-NEXT: .byte 2
+; AVX512-NEXT: .byte 4
+; AVX512-NEXT: .byte 8
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-NEXT: .byte 0
+; AVX512-LABEL: test_affine_or_fold_v32i8:
+; AVX512: # %bb.0: # %entry
+; AVX512-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %ymm0
+; AVX512-NEXT: retq
+entry:
+ %gf = tail call <32 x i8> @llvm.x86.vgf2p8affineqb.256(
+ <32 x i8> %a,
+ <32 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 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)
+ %or = or <32 x i8> %gf, splat (i8 15)
+ ret <32 x i8> %or
+}
+
+define dso_local <32 x i8> @test_affine_or_fold_v32i8_commuted(<32 x i8> noundef %a) {
+; AVX-LABEL: test_affine_or_fold_v32i8_commuted:
+; AVX: # %bb.0: # %entry
+; AVX-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX-NEXT: retq
+;
+; AVX512-LABEL: test_affine_or_fold_v32i8_commuted:
+; AVX512: # %bb.0: # %entry
+; AVX512-NEXT: vgf2p8affineqb $15, {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %ymm0
+; AVX512-NEXT: retq
+entry:
+ %gf = tail call <32 x i8> @llvm.x86.vgf2p8affineqb.256(
+ <32 x i8> %a,
+ <32 x i8> <i8 1, i8 2, i8 4, i8 8, i8 16, i8 32, i8 64, i8 -128,
+ i8 1, i8 2, i8 4, i...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/194330
More information about the llvm-commits
mailing list