[llvm] [LegalizeDAG] Optimize CodeGen for `ISD::CTLZ_ZERO_UNDEF` (PR #83039)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 17 07:54:25 PDT 2024
================
@@ -4982,15 +4981,30 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
// Perform the larger operation. For CTPOP and CTTZ_ZERO_UNDEF, this is
// already the correct result.
Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
- if (Node->getOpcode() == ISD::CTLZ ||
- Node->getOpcode() == ISD::CTLZ_ZERO_UNDEF) {
+ if (Node->getOpcode() == ISD::CTLZ) {
// Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
Tmp1 = DAG.getNode(ISD::SUB, dl, NVT, Tmp1,
DAG.getConstant(NVT.getSizeInBits() -
OVT.getSizeInBits(), dl, NVT));
}
Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1));
break;
+ case ISD::CTLZ_ZERO_UNDEF:
+ // We know that the argument is unlikely to be zero, hence we can take a
+ // different approach as compared to ISD::CTLZ
+
+ // Any Extend the argument
+ Tmp1 = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Node->getOperand(0));
+
+ // Tmp1 = Tmp1 << (sizeinbits(NVT) - sizeinbits(Old VT))
+ Tmp2 = DAG.getShiftAmountConstant(NVT.getSizeInBits() - OVT.getSizeInBits(),
+ Tmp1.getValueType(), dl);
+ Tmp1 = DAG.getNode(ISD::SHL, dl, NVT, Tmp1, Tmp2);
+
+ // Perform the larger operation
+ Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
+ Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1));
----------------
arsenm wrote:
I think I never got around to fixing this in the DAG, but all of these bitcount operations in principle could have a different return type from the source operand. It would be a bit better to truncate to the result type, and use the source type as the old type throughout
https://github.com/llvm/llvm-project/pull/83039
More information about the llvm-commits
mailing list