Skip to content

Commit e5b5979

Browse files
committed
[SelectionDAG] Allow lowering CTPOP into a libcall
Some in-tree targets (e.g. ARM) could benefit from this lowering, at least in opt-size mode, but I don't know if the libcall is available in their libgcc, so no tests.
1 parent b4f3a96 commit e5b5979

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ HANDLE_LIBCALL(NEG_I64, "__negdi2")
8585
HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
8686
HANDLE_LIBCALL(CTLZ_I64, "__clzdi2")
8787
HANDLE_LIBCALL(CTLZ_I128, "__clzti2")
88+
HANDLE_LIBCALL(CTPOP_I32, "__popcountsi2")
89+
HANDLE_LIBCALL(CTPOP_I64, "__popcountdi2")
90+
HANDLE_LIBCALL(CTPOP_I128, "__popcountti2")
8891

8992
// Floating-point
9093
HANDLE_LIBCALL(ADD_F32, "__addsf3")

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,9 @@ class SelectionDAGLegalize {
140140
RTLIB::Libcall Call_F128,
141141
RTLIB::Libcall Call_PPCF128,
142142
SmallVectorImpl<SDValue> &Results);
143-
SDValue ExpandIntLibCall(SDNode *Node, bool isSigned,
144-
RTLIB::Libcall Call_I8,
145-
RTLIB::Libcall Call_I16,
146-
RTLIB::Libcall Call_I32,
147-
RTLIB::Libcall Call_I64,
148-
RTLIB::Libcall Call_I128);
143+
SDValue ExpandIntLibCall(SDNode *Node, bool IsSigned, RTLIB::Libcall Call_I8,
144+
RTLIB::Libcall Call_I16, RTLIB::Libcall Call_I32,
145+
RTLIB::Libcall Call_I64, RTLIB::Libcall Call_I128);
149146
void ExpandArgFPLibCall(SDNode *Node,
150147
RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64,
151148
RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128,
@@ -2209,7 +2206,7 @@ void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
22092206
ExpandFPLibCall(Node, LC, Results);
22102207
}
22112208

2212-
SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned,
2209+
SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode *Node, bool IsSigned,
22132210
RTLIB::Libcall Call_I8,
22142211
RTLIB::Libcall Call_I16,
22152212
RTLIB::Libcall Call_I32,
@@ -2224,7 +2221,9 @@ SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned,
22242221
case MVT::i64: LC = Call_I64; break;
22252222
case MVT::i128: LC = Call_I128; break;
22262223
}
2227-
return ExpandLibCall(LC, Node, isSigned).first;
2224+
assert(LC != RTLIB::UNKNOWN_LIBCALL &&
2225+
"LibCall explicitly requested, but not available");
2226+
return ExpandLibCall(LC, Node, IsSigned).first;
22282227
}
22292228

22302229
/// Expand the node to a libcall based on first argument type (for instance
@@ -4980,19 +4979,20 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
49804979
RTLIB::MUL_I64, RTLIB::MUL_I128));
49814980
break;
49824981
case ISD::CTLZ_ZERO_UNDEF:
4983-
switch (Node->getSimpleValueType(0).SimpleTy) {
4984-
default:
4985-
llvm_unreachable("LibCall explicitly requested, but not available");
4986-
case MVT::i32:
4987-
Results.push_back(ExpandLibCall(RTLIB::CTLZ_I32, Node, false).first);
4988-
break;
4989-
case MVT::i64:
4990-
Results.push_back(ExpandLibCall(RTLIB::CTLZ_I64, Node, false).first);
4991-
break;
4992-
case MVT::i128:
4993-
Results.push_back(ExpandLibCall(RTLIB::CTLZ_I128, Node, false).first);
4994-
break;
4995-
}
4982+
Results.push_back(ExpandIntLibCall(Node, /*IsSigned=*/false,
4983+
RTLIB::UNKNOWN_LIBCALL,
4984+
RTLIB::UNKNOWN_LIBCALL,
4985+
RTLIB::CTLZ_I32,
4986+
RTLIB::CTLZ_I64,
4987+
RTLIB::CTLZ_I128));
4988+
break;
4989+
case ISD::CTPOP:
4990+
Results.push_back(ExpandIntLibCall(Node, /*IsSigned=*/false,
4991+
RTLIB::UNKNOWN_LIBCALL,
4992+
RTLIB::UNKNOWN_LIBCALL,
4993+
RTLIB::CTPOP_I32,
4994+
RTLIB::CTPOP_I64,
4995+
RTLIB::CTPOP_I128));
49964996
break;
49974997
case ISD::RESET_FPENV: {
49984998
// It is legalized to call 'fesetenv(FE_DFL_ENV)'. On most targets

0 commit comments

Comments
 (0)