[llvm] [X86] added computeKnownBits for X86ISD::GF2P8AFFINEQB (PR #194197)

Kartik Ohlan via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 18:38:12 PDT 2026


https://github.com/Ko496-glitch updated https://github.com/llvm/llvm-project/pull/194197

>From 3d8a12444086312c733d881b295e6727233249e2 Mon Sep 17 00:00:00 2001
From: Kartik Ohlan <kartik7ohlan at gmail.com>
Date: Sat, 25 Apr 2026 20:08:03 -0400
Subject: [PATCH 1/5] Added implementation for X86ISD::GF2P8AFFINEQB

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 53 +++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 56d8060272dc1..1876eff0e4326 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -39026,6 +39026,59 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
   Known.resetAll();
   switch (Opc) {
   default: break;
+  case X86ISD::GF2P8AFFINEQB: {
+    SDValue Input = Op.getOperand(0);
+    SDValue Matrix = Op.getOperand(1);
+    SDValue Imm = Op.getOperand(2);
+
+    KnownBits InputKnown = DAG.computeKnownBits(Input, DemandedElts, Depth + 1);
+    KnownBits MatrixKnown =
+        DAG.computeKnownBits(Matrix, DemandedElts, Depth + 1);
+
+    auto *ImmN = dyn_cast<ConstantSDNode>(Imm);
+    if (!ImmN || !MatrixKnown.isConstant())
+      break;
+
+    APInt Mat = MatrixKnown.getConstant();
+    uint8_t Imm8 = ImmN->getZExtValue();
+
+    KnownBits Res(BitWidth);
+    Res.resetAll();
+
+    APInt KnownMask = InputKnown.Zero | InputKnown.One;
+
+    for (unsigned OutBit = 0; OutBit != 8; ++OutBit) {
+      APInt RowMask = APInt::getZero(BitWidth);
+
+      for (unsigned ByteBase = 0; ByteBase < BitWidth; ByteBase += 8) {
+        unsigned MatrixBase = (ByteBase / 64) * 64;
+        unsigned RowOffset = MatrixBase + (7 - OutBit) * 8;
+
+        uint8_t Row = Mat.extractBits(8, RowOffset).getZExtValue();
+        RowMask.insertBits(APInt(8, Row), ByteBase);
+      }
+
+      if (!(RowMask & ~KnownMask).isZero())
+        continue;
+
+      APInt SelectedOnes = InputKnown.One & RowMask;
+
+      for (unsigned ByteBase = 0; ByteBase < BitWidth; ByteBase += 8) {
+        uint8_t Bits = SelectedOnes.extractBits(8, ByteBase).getZExtValue();
+
+        bool Parity = llvm::popcount(Bits) & 1;
+        bool FinalBit = Parity ^ ((Imm8 >> OutBit) & 1);
+
+        if (FinalBit)
+          Res.One.setBit(ByteBase + OutBit);
+        else
+          Res.Zero.setBit(ByteBase + OutBit);
+      }
+    }
+
+    Known = Res;
+    break;
+  }
   case X86ISD::MUL_IMM: {
     KnownBits Known2;
     Known = DAG.computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);

>From f48415a996c3ef0815c924c5ce72fe1dc945d06e Mon Sep 17 00:00:00 2001
From: Kartik Ohlan <kartik7ohlan at gmail.com>
Date: Sun, 26 Apr 2026 18:23:40 -0400
Subject: [PATCH 2/5] added Demandedelts approch to fix the extraction

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 65 ++++++++++++++++---------
 1 file changed, 42 insertions(+), 23 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1876eff0e4326..2293772ca3589 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -39031,52 +39031,71 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
     SDValue Matrix = Op.getOperand(1);
     SDValue Imm = Op.getOperand(2);
 
-    KnownBits InputKnown = DAG.computeKnownBits(Input, DemandedElts, Depth + 1);
-    KnownBits MatrixKnown =
-        DAG.computeKnownBits(Matrix, DemandedElts, Depth + 1);
-
     auto *ImmN = dyn_cast<ConstantSDNode>(Imm);
-    if (!ImmN || !MatrixKnown.isConstant())
+    if (!ImmN)
       break;
 
-    APInt Mat = MatrixKnown.getConstant();
     uint8_t Imm8 = ImmN->getZExtValue();
+    unsigned NumElts = DemandedElts.getBitWidth();
 
     KnownBits Res(BitWidth);
     Res.resetAll();
 
-    APInt KnownMask = InputKnown.Zero | InputKnown.One;
+    bool HaveAny = false;
 
-    for (unsigned OutBit = 0; OutBit != 8; ++OutBit) {
-      APInt RowMask = APInt::getZero(BitWidth);
+    for (unsigned Elt = 0; Elt != NumElts; ++Elt) {
+      if (!DemandedElts[Elt])
+        continue;
 
-      for (unsigned ByteBase = 0; ByteBase < BitWidth; ByteBase += 8) {
-        unsigned MatrixBase = (ByteBase / 64) * 64;
-        unsigned RowOffset = MatrixBase + (7 - OutBit) * 8;
+      APInt SingleElt = APInt::getOneBitSet(NumElts, Elt);
+      KnownBits InputKnown = DAG.computeKnownBits(Input, SingleElt, Depth + 1);
 
-        uint8_t Row = Mat.extractBits(8, RowOffset).getZExtValue();
-        RowMask.insertBits(APInt(8, Row), ByteBase);
-      }
+      KnownBits EltKnown(BitWidth);
+      EltKnown.resetAll();
 
-      if (!(RowMask & ~KnownMask).isZero())
-        continue;
+      APInt KnownMask = InputKnown.Zero | InputKnown.One;
 
-      APInt SelectedOnes = InputKnown.One & RowMask;
+      for (unsigned OutBit = 0; OutBit != 8; ++OutBit) {
+        unsigned MatIdx = (Elt / 8) * 8 + (7 - OutBit);
+        if (MatIdx >= NumElts)
+          continue;
+
+        APInt SingleMat = APInt::getOneBitSet(NumElts, MatIdx);
+        KnownBits MatrixKnown =
+            DAG.computeKnownBits(Matrix, SingleMat, Depth + 1);
+
+        if (!MatrixKnown.isConstant())
+          continue;
 
-      for (unsigned ByteBase = 0; ByteBase < BitWidth; ByteBase += 8) {
-        uint8_t Bits = SelectedOnes.extractBits(8, ByteBase).getZExtValue();
+        uint8_t Row = MatrixKnown.getConstant().getZExtValue();
+        APInt RowMask(BitWidth, Row);
+
+        if (!(RowMask & ~KnownMask).isZero())
+          continue;
+
+        uint8_t Bits = (InputKnown.One & RowMask).getZExtValue();
 
         bool Parity = llvm::popcount(Bits) & 1;
         bool FinalBit = Parity ^ ((Imm8 >> OutBit) & 1);
 
         if (FinalBit)
-          Res.One.setBit(ByteBase + OutBit);
+          EltKnown.One.setBit(OutBit);
         else
-          Res.Zero.setBit(ByteBase + OutBit);
+          EltKnown.Zero.setBit(OutBit);
+      }
+
+      if (!HaveAny) {
+        Res = EltKnown;
+        HaveAny = true;
+      } else {
+        Res.One &= EltKnown.One;
+        Res.Zero &= EltKnown.Zero;
       }
     }
 
-    Known = Res;
+    if (HaveAny)
+      Known = Res;
+
     break;
   }
   case X86ISD::MUL_IMM: {

>From c6544f071e3c94525ec3810ff2846e41e3696e5b Mon Sep 17 00:00:00 2001
From: Kartik Ohlan <kartik7ohlan at gmail.com>
Date: Sun, 26 Apr 2026 20:44:24 -0400
Subject: [PATCH 3/5] Fixed the clang-format issue

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 65 ++++++++-----------------
 1 file changed, 21 insertions(+), 44 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 2293772ca3589..e2eac910195d8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -39041,61 +39041,38 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
     KnownBits Res(BitWidth);
     Res.resetAll();
 
-    bool HaveAny = false;
+    KnownBits InputKnown = DAG.computeKnownBits(Input, DemandedElts, Depth + 1);
 
-    for (unsigned Elt = 0; Elt != NumElts; ++Elt) {
-      if (!DemandedElts[Elt])
-        continue;
-
-      APInt SingleElt = APInt::getOneBitSet(NumElts, Elt);
-      KnownBits InputKnown = DAG.computeKnownBits(Input, SingleElt, Depth + 1);
-
-      KnownBits EltKnown(BitWidth);
-      EltKnown.resetAll();
-
-      APInt KnownMask = InputKnown.Zero | InputKnown.One;
+    APInt KnownMask = InputKnown.Zero | InputKnown.One;
 
-      for (unsigned OutBit = 0; OutBit != 8; ++OutBit) {
-        unsigned MatIdx = (Elt / 8) * 8 + (7 - OutBit);
-        if (MatIdx >= NumElts)
-          continue;
-
-        APInt SingleMat = APInt::getOneBitSet(NumElts, MatIdx);
-        KnownBits MatrixKnown =
-            DAG.computeKnownBits(Matrix, SingleMat, Depth + 1);
+    for (unsigned OutBit = 0; OutBit != 8; ++OutBit) {
+      unsigned RowIdx = 7 - OutBit;
 
-        if (!MatrixKnown.isConstant())
-          continue;
+      APInt RowDemandedElts = APInt::getSplat(NumElts, APInt(8, 1u << RowIdx));
 
-        uint8_t Row = MatrixKnown.getConstant().getZExtValue();
-        APInt RowMask(BitWidth, Row);
+      KnownBits RowKnown =
+          DAG.computeKnownBits(Matrix, RowDemandedElts, Depth + 1);
 
-        if (!(RowMask & ~KnownMask).isZero())
-          continue;
+      if (!RowKnown.isConstant())
+        continue;
 
-        uint8_t Bits = (InputKnown.One & RowMask).getZExtValue();
+      uint8_t Row = RowKnown.getConstant().getZExtValue();
+      APInt RowMask(BitWidth, Row);
 
-        bool Parity = llvm::popcount(Bits) & 1;
-        bool FinalBit = Parity ^ ((Imm8 >> OutBit) & 1);
+      if (!(RowMask & ~KnownMask).isZero())
+        continue;
 
-        if (FinalBit)
-          EltKnown.One.setBit(OutBit);
-        else
-          EltKnown.Zero.setBit(OutBit);
-      }
+      uint8_t Bits = (InputKnown.One & RowMask).getZExtValue();
+      bool Parity = llvm::popcount(Bits) & 1;
+      bool FinalBit = Parity ^ ((Imm8 >> OutBit) & 1);
 
-      if (!HaveAny) {
-        Res = EltKnown;
-        HaveAny = true;
-      } else {
-        Res.One &= EltKnown.One;
-        Res.Zero &= EltKnown.Zero;
-      }
+      if (FinalBit)
+        Res.One.setBit(OutBit);
+      else
+        Res.Zero.setBit(OutBit);
     }
 
-    if (HaveAny)
-      Known = Res;
-
+    Known = Res;
     break;
   }
   case X86ISD::MUL_IMM: {

>From 6e7b4481f04d5f09a0c3ab1d2040b0b9ea0d4b9e Mon Sep 17 00:00:00 2001
From: Kartik Ohlan <kartik7ohlan at gmail.com>
Date: Thu, 30 Apr 2026 17:26:55 -0400
Subject: [PATCH 4/5] removed the runtime behav

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e2eac910195d8..749d5ce08d36c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -39036,28 +39036,24 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
       break;
 
     uint8_t Imm8 = ImmN->getZExtValue();
-    unsigned NumElts = DemandedElts.getBitWidth();
-
-    KnownBits Res(BitWidth);
-    Res.resetAll();
+    APInt UndefElts;
+    SmallVector<APInt, 64> MatEltBits;
+    if (!getTargetConstantBitsFromNode(Matrix, 8, UndefElts, MatEltBits,
+                                       /*AllowWholeUndefs=*/false,
+                                       /*AllowPartialUndefs=*/false))
+      break;
 
     KnownBits InputKnown = DAG.computeKnownBits(Input, DemandedElts, Depth + 1);
 
     APInt KnownMask = InputKnown.Zero | InputKnown.One;
+    KnownBits Res(BitWidth);
+    Res.resetAll();
 
     for (unsigned OutBit = 0; OutBit != 8; ++OutBit) {
       unsigned RowIdx = 7 - OutBit;
 
-      APInt RowDemandedElts = APInt::getSplat(NumElts, APInt(8, 1u << RowIdx));
-
-      KnownBits RowKnown =
-          DAG.computeKnownBits(Matrix, RowDemandedElts, Depth + 1);
-
-      if (!RowKnown.isConstant())
-        continue;
-
-      uint8_t Row = RowKnown.getConstant().getZExtValue();
-      APInt RowMask(BitWidth, Row);
+      uint8_t Row = MatEltBits[RowIdx].getZExtValue();
+      APInt RowMask(8, Row);
 
       if (!(RowMask & ~KnownMask).isZero())
         continue;

>From b32e382550aa45fcc9e03c1f5c9e4c79a72cbec0 Mon Sep 17 00:00:00 2001
From: Kartik Ohlan <kartik7ohlan at gmail.com>
Date: Thu, 30 Apr 2026 21:37:44 -0400
Subject: [PATCH 5/5] Added the test file

---
 llvm/test/CodeGen/X86/gf2-knownbits.ll | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/gf2-knownbits.ll

diff --git a/llvm/test/CodeGen/X86/gf2-knownbits.ll b/llvm/test/CodeGen/X86/gf2-knownbits.ll
new file mode 100644
index 0000000000000..acced16b60333
--- /dev/null
+++ b/llvm/test/CodeGen/X86/gf2-knownbits.ll
@@ -0,0 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+gfni,+avx | FileCheck %s
+
+declare <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8 immarg)
+
+define i32 @test_knownbits_identity(<16 x i8> %a) {
+; CHECK-LABEL: test_knownbits_identity:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    retq
+  %input = and <16 x i8> %a, splat (i8 15)
+
+  ; _GFNI_DEMO_IDENT: 0x0102040810204080
+  %matrix = bitcast <2 x i64>
+      <i64 72624976668147840, i64 72624976668147840> to <16 x i8>
+
+  %res = call <16 x i8> @llvm.x86.vgf2p8affineqb.128(
+      <16 x i8> %input, <16 x i8> %matrix, i8 0)
+
+  %elt = extractelement <16 x i8> %res, i32 0
+  %bit7 = and i8 %elt, -128
+  %ret = zext i8 %bit7 to i32
+  ret i32 %ret
+}



More information about the llvm-commits mailing list