[llvm] [NVPTX] Optimize v2x16 BUILD_VECTORs to PRMT (PR #116675)
Fraser Cormack via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 11 02:54:20 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:
I suppose so, yes.
I was also wondering whether we'd need a way of encapsulating the idea of an "unused" byte for maximum effect, as in the example of truncation: `i16 = trunc (i32 a)` -> `prmt a, b, 0xXX10`. There's no concrete byte of `a` or `b` to select for the truncated-out bytes, nor any concrete value of `b` - both can be anything we want. If we choose any concrete values or indices, it might hinder or confuse optimal combines/lowering. Using something like `undef` as `b` would work, and maybe selecting any byte from an `undef` operand would give us enough info to know we can replace them with anything.
In any case, I won't have the time to dedicate to trying out any of these ideas, I'm afraid. If you want to take it on, go ahead! We could either merge this PR as-is, or just abandon it. I'm easy.
https://github.com/llvm/llvm-project/pull/116675
More information about the llvm-commits
mailing list