[llvm] [NVPTX] Optimize v2x16 BUILD_VECTORs to PRMT (PR #116675)

Fraser Cormack via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 01:21:47 PST 2024


================
@@ -6176,6 +6176,57 @@ static SDValue PerformLOADCombine(SDNode *N,
       DL);
 }
 
+static SDValue
+PerformBUILD_VECTORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
+  auto VT = N->getValueType(0);
+  if (!DCI.isAfterLegalizeDAG() || !Isv2x16VT(VT))
+    return SDValue();
+
+  auto Op0 = N->getOperand(0);
+  auto Op1 = N->getOperand(1);
+
+  // Start out by assuming we want to take the lower 2 bytes of each i32
+  // operand.
+  uint64_t Op0Bytes = 0x10;
+  uint64_t Op1Bytes = 0x54;
+
+  std::pair<SDValue *, uint64_t *> OpData[2] = {{&Op0, &Op0Bytes},
+                                                {&Op1, &Op1Bytes}};
+
+  // Check that each operand is an i16, truncated from an i32 operand. We'll
+  // select individual bytes from those original operands. Optionally, fold in a
+  // shift right of that original operand.
+  for (auto &[Op, OpBytes] : OpData) {
+    // Eat up any bitcast
+    if (Op->getOpcode() == ISD::BITCAST)
+      *Op = Op->getOperand(0);
+
+    if (Op->getValueType() != MVT::i16 || Op->getOpcode() != ISD::TRUNCATE ||
+        Op->getOperand(0).getValueType() != MVT::i32)
+      return SDValue();
+
+    *Op = Op->getOperand(0);
+
+    // Optionally, fold in a shift-right of the original operand and permute
+    // the two higher bytes from the shifted operand
+    if (Op->getOpcode() == ISD::SRL && isa<ConstantSDNode>(Op->getOperand(1))) {
+      if (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue() == 16) {
+        *OpBytes += 0x22;
+        *Op = Op->getOperand(0);
+      }
+    }
----------------
frasercrmck wrote:

My original approach was custom-lower v2x16 BUILD_VECTORs to PRMT, but I found it was getting too complicated to identify the cases that were optimal to use with PRMT. As discussed in another comment thread, unless the original values are i32, this optimization broadly isn't worth it. During lowering of BUILD_VECTOR, we often don't as easily see the 16-bit-from-32-bit values that make it worthwhile. My concern with being too eager about BUILD_VECTOR, is that there will necessarily be cases where we need to undo a suboptimal PRMT, which feels wrong to me.

I imagine that Artem's idea could work, however. I suspect we'll still have to undo an eagerly matched PRMT, though. Perhaps we'd have to be more careful with one-use nodes?

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


More information about the llvm-commits mailing list