[llvm] [X86] Fold shift into GF2P8AFFINEQB instruction (PR #180019)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 14 04:43:04 PST 2026


================
@@ -50755,6 +50663,56 @@ static SDValue combineShiftLeft(SDNode *N, SelectionDAG &DAG,
   unsigned EltSizeInBits = VT.getScalarSizeInBits();
   SDLoc DL(N);
 
+  // Fold: shl(gf2p8affineqb(X, M), amt) -> gf2p8affineqb(X, M')
+  // where M' = M composed with shift matrix.
+  // This folds the shift into the matrix transformation.
+  // Handle both the X86ISD::GF2P8AFFINEQB form and the intrinsic form.
+  if (Subtarget.hasGFNI() && VT.isVector() && EltSizeInBits == 8) {
+    bool IsGF2P8 = N0.getOpcode() == X86ISD::GF2P8AFFINEQB;
+    bool IsIntrinsic =
+        N0.getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
+        (N0.getConstantOperandVal(0) == Intrinsic::x86_vgf2p8affineqb_128 ||
+         N0.getConstantOperandVal(0) == Intrinsic::x86_vgf2p8affineqb_256 ||
+         N0.getConstantOperandVal(0) == Intrinsic::x86_vgf2p8affineqb_512);
+
+    if (IsGF2P8 || IsIntrinsic) {
+      // For vector shifts, the shift amount is a splat vector
+      APInt SplatVal;
+      if (ISD::isConstantSplatVector(N1.getNode(), SplatVal)) {
+        uint64_t ShiftAmt = SplatVal.getZExtValue();
+        if (ShiftAmt > 0 && ShiftAmt < 8) {
+          // Operand indices differ: X86ISD::GF2P8AFFINEQB uses 0,1,2
+          // INTRINSIC_WO_CHAIN uses 1,2,3 (operand 0 is intrinsic ID)
+          unsigned BaseIdx = IsIntrinsic ? 1 : 0;
+          SDValue Input = N0.getOperand(BaseIdx);
+          SDValue MatrixOp = N0.getOperand(BaseIdx + 1);
+          SDValue Imm = N0.getOperand(BaseIdx + 2);
----------------
RKSimon wrote:

Isn't the imm always target constant so afaict you can you just do:
```suggestion
          uint64_t Imm = N0.getConstantOperandVal(BaseIdx + 2);
```

https://github.com/llvm/llvm-project/pull/180019


More information about the llvm-commits mailing list