Skip to content

Commit 14340fe

Browse files
committed
Fixes
1 parent ae98e96 commit 14340fe

File tree

9 files changed

+155
-115
lines changed

9 files changed

+155
-115
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

21312139
void 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.
22462297
void
22472298
SelectionDAGLegalize::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

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,8 +3866,10 @@ void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N, SDValue &Lo, SDValue &Hi) {
38663866
assert(LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC) &&
38673867
"LibCall explicitly requested, but not available");
38683868
TargetLowering::MakeLibCallOptions CallOptions;
3869-
SDValue Res = TLI.makeLibCall(DAG, LC, VT, Op, CallOptions, DL).first;
3870-
SplitInteger(Res, Lo, Hi);
3869+
EVT IntVT =
3870+
EVT::getIntegerVT(*DAG.getContext(), DAG.getLibInfo().getIntSize());
3871+
SDValue Res = TLI.makeLibCall(DAG, LC, IntVT, Op, CallOptions, DL).first;
3872+
SplitInteger(DAG.getSExtOrTrunc(Res, DL, VT), Lo, Hi);
38713873
return;
38723874
}
38733875

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
394394
}
395395
} else {
396396
setOperationAction(ISD::CTTZ, XLenVT, Expand);
397-
if (!Subtarget.is64Bit())
397+
if (Subtarget.is64Bit())
398+
setOperationAction(ISD::CTPOP, MVT::i128, LibCall);
399+
else
398400
setOperationAction(ISD::CTPOP, MVT::i32, LibCall);
399401
setOperationAction(ISD::CTPOP, MVT::i64, LibCall);
400402
if (RV64LegalI32 && Subtarget.is64Bit())

llvm/test/CodeGen/ARM/popcnt.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ define i64 @ctpop64(i64 %x) nounwind readnone {
335335
; CHECK-NEXT: .save {r11, lr}
336336
; CHECK-NEXT: push {r11, lr}
337337
; CHECK-NEXT: bl __popcountdi2
338+
; CHECK-NEXT: asr r1, r0, #31
338339
; CHECK-NEXT: pop {r11, lr}
339340
; CHECK-NEXT: mov pc, lr
340341
%count = tail call i64 @llvm.ctpop.i64(i64 %x)

0 commit comments

Comments
 (0)