@@ -129,7 +129,8 @@ class SelectionDAGLegalize {
129129 ArrayRef<int > Mask) const ;
130130
131131 std::pair<SDValue, SDValue> ExpandLibCall (RTLIB::Libcall LC, SDNode *Node,
132- TargetLowering::ArgListTy &&Args, bool isSigned);
132+ TargetLowering::ArgListTy &&Args,
133+ bool IsSigned, EVT RetVT);
133134 std::pair<SDValue, SDValue> ExpandLibCall (RTLIB::Libcall LC, SDNode *Node, bool isSigned);
134135
135136 void ExpandFrexpLibCall (SDNode *Node, SmallVectorImpl<SDValue> &Results);
@@ -140,14 +141,20 @@ class SelectionDAGLegalize {
140141 RTLIB::Libcall Call_F128,
141142 RTLIB::Libcall Call_PPCF128,
142143 SmallVectorImpl<SDValue> &Results);
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);
144+ SDValue ExpandIntLibCall (SDNode *Node, bool isSigned,
145+ RTLIB::Libcall Call_I8,
146+ RTLIB::Libcall Call_I16,
147+ RTLIB::Libcall Call_I32,
148+ RTLIB::Libcall Call_I64,
149+ RTLIB::Libcall Call_I128);
146150 void ExpandArgFPLibCall (SDNode *Node,
147151 RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64,
148152 RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128,
149153 RTLIB::Libcall Call_PPCF128,
150154 SmallVectorImpl<SDValue> &Results);
155+ SDValue ExpandBitCountingLibCall (SDNode *Node, RTLIB::Libcall CallI32,
156+ RTLIB::Libcall CallI64,
157+ RTLIB::Libcall CallI128);
151158 void ExpandDivRemLibCall (SDNode *Node, SmallVectorImpl<SDValue> &Results);
152159 void ExpandSinCosLibCall (SDNode *Node, SmallVectorImpl<SDValue> &Results);
153160
@@ -2056,9 +2063,10 @@ SDValue SelectionDAGLegalize::ExpandSPLAT_VECTOR(SDNode *Node) {
20562063// register, return the lo part and set the hi part to the by-reg argument in
20572064// the first. If it does fit into a single register, return the result and
20582065// leave the Hi part unset.
2059- std::pair<SDValue, SDValue> SelectionDAGLegalize::ExpandLibCall (RTLIB::Libcall LC, SDNode *Node,
2060- TargetLowering::ArgListTy &&Args,
2061- bool isSigned) {
2066+ std::pair<SDValue, SDValue>
2067+ SelectionDAGLegalize::ExpandLibCall (RTLIB::Libcall LC, SDNode *Node,
2068+ TargetLowering::ArgListTy &&Args,
2069+ bool IsSigned, EVT RetVT) {
20622070 EVT CodePtrTy = TLI.getPointerTy (DAG.getDataLayout ());
20632071 SDValue Callee;
20642072 if (const char *LibcallName = TLI.getLibcallName (LC))
@@ -2069,7 +2077,6 @@ std::pair<SDValue, SDValue> SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall L
20692077 Node->getOperationName (&DAG));
20702078 }
20712079
2072- EVT RetVT = Node->getValueType (0 );
20732080 Type *RetTy = RetVT.getTypeForEVT (*DAG.getContext ());
20742081
20752082 // By default, the input chain to this libcall is the entry node of the
@@ -2089,7 +2096,7 @@ std::pair<SDValue, SDValue> SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall L
20892096 InChain = TCChain;
20902097
20912098 TargetLowering::CallLoweringInfo CLI (DAG);
2092- bool signExtend = TLI.shouldSignExtendTypeInLibCall (RetVT, isSigned );
2099+ bool signExtend = TLI.shouldSignExtendTypeInLibCall (RetVT, IsSigned );
20932100 CLI.setDebugLoc (SDLoc (Node))
20942101 .setChain (InChain)
20952102 .setLibCallee (TLI.getLibcallCallingConv (LC), RetTy, Callee,
@@ -2125,7 +2132,8 @@ std::pair<SDValue, SDValue> SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall L
21252132 Args.push_back (Entry);
21262133 }
21272134
2128- return ExpandLibCall (LC, Node, std::move (Args), isSigned);
2135+ return ExpandLibCall (LC, Node, std::move (Args), isSigned,
2136+ Node->getValueType (0 ));
21292137}
21302138
21312139void SelectionDAGLegalize::ExpandFrexpLibCall (
@@ -2152,7 +2160,8 @@ void SelectionDAGLegalize::ExpandFrexpLibCall(
21522160 TargetLowering::ArgListTy Args = {FPArgEntry, PtrArgEntry};
21532161
21542162 RTLIB::Libcall LC = RTLIB::getFREXP (VT);
2155- auto [Call, Chain] = ExpandLibCall (LC, Node, std::move (Args), false );
2163+ auto [Call, Chain] = ExpandLibCall (LC, Node, std::move (Args),
2164+ /* IsSigned=*/ false , VT);
21562165
21572166 // FIXME: Get type of int for libcall declaration and cast
21582167
@@ -2206,7 +2215,7 @@ void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
22062215 ExpandFPLibCall (Node, LC, Results);
22072216}
22082217
2209- SDValue SelectionDAGLegalize::ExpandIntLibCall (SDNode * Node, bool IsSigned ,
2218+ SDValue SelectionDAGLegalize::ExpandIntLibCall (SDNode* Node, bool isSigned ,
22102219 RTLIB::Libcall Call_I8,
22112220 RTLIB::Libcall Call_I16,
22122221 RTLIB::Libcall Call_I32,
@@ -2221,9 +2230,7 @@ SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode *Node, bool IsSigned,
22212230 case MVT::i64 : LC = Call_I64; break ;
22222231 case MVT::i128 : LC = Call_I128; break ;
22232232 }
2224- assert (LC != RTLIB::UNKNOWN_LIBCALL &&
2225- " LibCall explicitly requested, but not available" );
2226- return ExpandLibCall (LC, Node, IsSigned).first ;
2233+ return ExpandLibCall (LC, Node, isSigned).first ;
22272234}
22282235
22292236// / Expand the node to a libcall based on first argument type (for instance
@@ -2242,6 +2249,50 @@ void SelectionDAGLegalize::ExpandArgFPLibCall(SDNode* Node,
22422249 ExpandFPLibCall (Node, LC, Results);
22432250}
22442251
2252+ SDValue SelectionDAGLegalize::ExpandBitCountingLibCall (
2253+ SDNode *Node, RTLIB::Libcall CallI32, RTLIB::Libcall CallI64,
2254+ RTLIB::Libcall CallI128) {
2255+ RTLIB::Libcall LC;
2256+ switch (Node->getSimpleValueType (0 ).SimpleTy ) {
2257+ default :
2258+ llvm_unreachable (" Unexpected request for libcall!" );
2259+ case MVT::i32 :
2260+ LC = CallI32;
2261+ break ;
2262+ case MVT::i64 :
2263+ LC = CallI64;
2264+ break ;
2265+ case MVT::i128 :
2266+ LC = CallI128;
2267+ break ;
2268+ }
2269+
2270+ // Bit-counting libcalls have one unsigned argument and return `int`.
2271+ // Note that `int` may be illegal on this target; ExpandLibCall will
2272+ // take care of promoting it to a legal type.
2273+ SDValue Op = Node->getOperand (0 );
2274+ EVT IntVT =
2275+ EVT::getIntegerVT (*DAG.getContext (), DAG.getLibInfo ().getIntSize ());
2276+
2277+ TargetLowering::ArgListEntry Arg;
2278+ EVT ArgVT = Op.getValueType ();
2279+ Type *ArgTy = ArgVT.getTypeForEVT (*DAG.getContext ());
2280+ Arg.Node = Op;
2281+ Arg.Ty = ArgTy;
2282+ Arg.IsSExt = TLI.shouldSignExtendTypeInLibCall (ArgVT, /* IsSigned=*/ false );
2283+ Arg.IsZExt = !Arg.IsSExt ;
2284+
2285+ SDValue Res = ExpandLibCall (LC, Node, TargetLowering::ArgListTy{Arg},
2286+ /* IsSigned=*/ true , IntVT)
2287+ .first ;
2288+
2289+ // If ExpandLibCall created a tail call, the result was already
2290+ // of the correct type. Otherwise, we need to sign extend it.
2291+ if (Res.getValueType () != MVT::Other)
2292+ Res = DAG.getSExtOrTrunc (Res, SDLoc (Node), Node->getValueType (0 ));
2293+ return Res;
2294+ }
2295+
22452296// / Issue libcalls to __{u}divmod to compute div / rem pairs.
22462297void
22472298SelectionDAGLegalize::ExpandDivRemLibCall (SDNode *Node,
@@ -4999,16 +5050,12 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
49995050 RTLIB::MUL_I64, RTLIB::MUL_I128));
50005051 break ;
50015052 case ISD::CTLZ_ZERO_UNDEF:
5002- Results.push_back (ExpandIntLibCall (Node, /* IsSigned=*/ false ,
5003- RTLIB::UNKNOWN_LIBCALL,
5004- RTLIB::UNKNOWN_LIBCALL, RTLIB::CTLZ_I32,
5005- RTLIB::CTLZ_I64, RTLIB::CTLZ_I128));
5053+ Results.push_back (ExpandBitCountingLibCall (
5054+ Node, RTLIB::CTLZ_I32, RTLIB::CTLZ_I64, RTLIB::CTLZ_I128));
50065055 break ;
50075056 case ISD::CTPOP:
5008- Results.push_back (ExpandIntLibCall (Node, /* IsSigned=*/ false ,
5009- RTLIB::UNKNOWN_LIBCALL,
5010- RTLIB::UNKNOWN_LIBCALL, RTLIB::CTPOP_I32,
5011- RTLIB::CTPOP_I64, RTLIB::CTPOP_I128));
5057+ Results.push_back (ExpandBitCountingLibCall (
5058+ Node, RTLIB::CTPOP_I32, RTLIB::CTPOP_I64, RTLIB::CTPOP_I128));
50125059 break ;
50135060 case ISD::RESET_FPENV: {
50145061 // It is legalized to call 'fesetenv(FE_DFL_ENV)'. On most targets
0 commit comments