[llvm] [X86] Fold splat AND on VGF2P8AFFINEQB source (PR #193364)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 22 19:21:35 PDT 2026
================
@@ -0,0 +1,163 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+gfni,+avx2 | FileCheck %s --check-prefixes=AVX
+
+declare <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8)
+
+define <16 x i8> @test_const_splat_on_const_matrix(<16 x i8> %src) nounwind {
+; AVX-LABEL: test_const_splat_on_const_matrix:
+; AVX: # %bb.0:
+; AVX-NEXT: vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: retq
+ %and = and <16 x i8> %src, splat(i8 15)
+ %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %and, <16 x i8> <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 2, i8 1, i8 -128>, i8 0)
+ ret <16 x i8> %gfni
+}
+
+define <32 x i8> @test_const_splat_on_const_matrix256(<32 x i8> %src) nounwind {
+; AVX-LABEL: test_const_splat_on_const_matrix256:
+; AVX: # %bb.0:
+; AVX-NEXT: vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
+; AVX-NEXT: retq
+ %and = and <32 x i8> %src, splat(i8 15)
+ %gfni = call <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8> %and, <32 x i8> <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 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 2, i8 1, i8 -128>, i8 0)
+ ret <32 x i8> %gfni
+}
+
+define <16 x i8> @test_const_splat_parity_matrix(<16 x i8> %src) nounwind {
+; AVX-LABEL: test_const_splat_parity_matrix:
+; AVX: # %bb.0:
+; AVX-NEXT: vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: retq
+ %and = and <16 x i8> %src, splat(i8 85)
+ %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %and, <16 x i8> <i8 1, i8 3, i8 7, i8 15, i8 31, i8 63, i8 127, i8 255, i8 1, i8 3, i8 7, i8 15, i8 31, i8 63, i8 127, i8 255>, i8 0)
+ ret <16 x i8> %gfni
+}
+
+define <16 x i8> @test_const_splat_on_const_matrix_nonzero_imm(<16 x i8> %src) nounwind {
+; AVX-LABEL: test_const_splat_on_const_matrix_nonzero_imm:
+; AVX: # %bb.0:
+; AVX-NEXT: vgf2p8affineqb $127, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: retq
+ %and = and <16 x i8> %src, splat(i8 15)
+ %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %and, <16 x i8> <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 2, i8 1, i8 -128>, i8 127)
+ ret <16 x i8> %gfni
+}
+
+define <16 x i8> @test_var_splat_on_const_matrix(<16 x i8> %src, i8 %scalar) nounwind {
+; AVX-LABEL: test_var_splat_on_const_matrix:
+; AVX: # %bb.0:
+; AVX-NEXT: vmovd %edi, %xmm1
+; AVX-NEXT: vpbroadcastb %xmm1, %xmm1
+; AVX-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
+; AVX-NEXT: vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: retq
+ %inlo = insertelement <16 x i8> poison, i8 %scalar, i64 0
+ %varsplat = shufflevector <16 x i8> %inlo, <16 x i8> poison, <16 x i32> zeroinitializer
+ %and = and <16 x i8> %src, %varsplat
+ %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %and, <16 x i8> splat(i8 2), i8 0)
+ ret <16 x i8> %gfni
+}
+
+define <16 x i8> @test_var_splat_parity_fill_matrix(<16 x i8> %src, i8 %scalar) nounwind {
+; AVX-LABEL: test_var_splat_parity_fill_matrix:
+; AVX: # %bb.0:
+; AVX-NEXT: vmovd %edi, %xmm1
+; AVX-NEXT: vpbroadcastb %xmm1, %xmm1
+; AVX-NEXT: vgf2p8affineqb $0, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: retq
+ %inlo = insertelement <16 x i8> poison, i8 %scalar, i64 0
+ %varsplat = shufflevector <16 x i8> %inlo, <16 x i8> poison, <16 x i32> zeroinitializer
+ %and = and <16 x i8> %src, %varsplat
+ %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %and, <16 x i8> splat(i8 -1), i8 0)
+ ret <16 x i8> %gfni
+}
+
+define <16 x i8> @test_var_splat_on_const_matrix_nonzero_imm(<16 x i8> %src, i8 %scalar) nounwind {
+; AVX-LABEL: test_var_splat_on_const_matrix_nonzero_imm:
+; AVX: # %bb.0:
+; AVX-NEXT: vmovd %edi, %xmm1
+; AVX-NEXT: vpbroadcastb %xmm1, %xmm1
+; AVX-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
+; AVX-NEXT: vgf2p8affineqb $170, %xmm1, %xmm0, %xmm0
+; AVX-NEXT: retq
+ %inlo = insertelement <16 x i8> poison, i8 %scalar, i64 0
+ %varsplat = shufflevector <16 x i8> %inlo, <16 x i8> poison, <16 x i32> zeroinitializer
+ %and = and <16 x i8> %src, %varsplat
+ %gfni = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8> %and, <16 x i8> splat(i8 2), i8 170)
+ ret <16 x i8> %gfni
+}
+
+;; Negative test: multi use should not fold
+define <16 x i8> @test_const_splat_on_const_matrix_multi_use(<16 x i8> %src) nounwind {
+; AVX-LABEL: test_const_splat_on_const_matrix_multi_use:
+; AVX: # %bb.0:
+; AVX-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; AVX-NEXT: vgf2p8affineqb $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1
+; AVX-NEXT: vpxor %xmm0, %xmm1, %xmm0
+; AVX-NEXT: retq
+ %matrix = bitcast <2 x i64> splat(i64 9223655728169885760) to <16 x i8>
----------------
WalterKruger wrote:
Yes, I chose a 64-bit splat as that is the actual matrix width and I thought it would look cleaner. It has no requirement to be a splat of any kind. Only the AND operand is strictly required to be a 8-bit splat, so that test excludes larger splats.
https://github.com/llvm/llvm-project/pull/193364
More information about the llvm-commits
mailing list