@@ -5117,6 +5117,15 @@ static unsigned getCallOpcode(bool isIndirectCall, bool isPatchPoint,
5117
5117
5118
5118
return PPCISD::CALL;
5119
5119
}
5120
+
5121
+ static bool isValidAIXExternalSymSDNode(StringRef SymName) {
5122
+ return StringSwitch<bool>(SymName)
5123
+ .Cases("__divdi3", "__fixunsdfdi", "__floatundidf", "__floatundisf",
5124
+ "__moddi3", "__udivdi3", "__umoddi3", true)
5125
+ .Cases("ceil", "floor", "memcpy", "memmove", "memset", "round", true)
5126
+ .Default(false);
5127
+ }
5128
+
5120
5129
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
5121
5130
const SDLoc &dl, const PPCSubtarget &Subtarget) {
5122
5131
if (!Subtarget.usesFunctionDescriptors() && !Subtarget.isELFv2ABI())
@@ -5141,41 +5150,72 @@ static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
5141
5150
Subtarget.is32BitELFABI() && !isLocalCallee() &&
5142
5151
Subtarget.getTargetMachine().getRelocationModel() == Reloc::PIC_;
5143
5152
5153
+ // On AIX, direct function calls reference the symbol for the function's
5154
+ // entry point, which is named by prepending a "." before the function's
5155
+ // C-linkage name.
5156
+ const auto getAIXFuncEntryPointSymbolSDNode =
5157
+ [&](StringRef FuncName, bool IsDeclaration,
5158
+ const XCOFF::StorageClass &SC) {
5159
+ auto &Context = DAG.getMachineFunction().getMMI().getContext();
5160
+
5161
+ MCSymbolXCOFF *S = cast<MCSymbolXCOFF>(
5162
+ Context.getOrCreateSymbol(Twine(".") + Twine(FuncName)));
5163
+
5164
+ if (IsDeclaration && !S->hasContainingCsect()) {
5165
+ // On AIX, an undefined symbol needs to be associated with a
5166
+ // MCSectionXCOFF to get the correct storage mapping class.
5167
+ // In this case, XCOFF::XMC_PR.
5168
+ MCSectionXCOFF *Sec = Context.getXCOFFSection(
5169
+ S->getName(), XCOFF::XMC_PR, XCOFF::XTY_ER, SC,
5170
+ SectionKind::getMetadata());
5171
+ S->setContainingCsect(Sec);
5172
+ }
5173
+
5174
+ MVT PtrVT =
5175
+ DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
5176
+ return DAG.getMCSymbol(S, PtrVT);
5177
+ };
5178
+
5144
5179
if (isFunctionGlobalAddress(Callee)) {
5145
5180
const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Callee);
5181
+ const GlobalValue *GV = G->getGlobal();
5182
+
5146
5183
if (!Subtarget.isAIXABI())
5147
- return DAG.getTargetGlobalAddress(G->getGlobal(), dl,
5148
- Callee.getValueType(), 0,
5184
+ return DAG.getTargetGlobalAddress(GV, dl, Callee.getValueType(), 0,
5149
5185
UsePlt ? PPCII::MO_PLT : 0);
5150
5186
5151
- // On AIX, direct function calls reference the symbol for the function's
5152
- // entry point, which is named by prepending a "." before the function's
5153
- // C-linkage name.
5154
- auto &Context = DAG.getMachineFunction().getMMI().getContext();
5187
+ assert(!isa<GlobalIFunc>(GV) && "IFunc is not supported on AIX.");
5188
+ const GlobalObject *GO = cast<GlobalObject>(GV);
5189
+ const XCOFF::StorageClass SC =
5190
+ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
5191
+ return getAIXFuncEntryPointSymbolSDNode(GO->getName(), GO->isDeclaration(),
5192
+ SC);
5193
+ }
5155
5194
5156
- const GlobalObject *GO = cast<GlobalObject>(G->getGlobal());
5157
- MCSymbolXCOFF *S = cast<MCSymbolXCOFF>(
5158
- Context.getOrCreateSymbol(Twine(".") + Twine(GO->getName())));
5195
+ if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
5196
+ const char *SymName = S->getSymbol();
5197
+ if (!Subtarget.isAIXABI())
5198
+ return DAG.getTargetExternalSymbol(SymName, Callee.getValueType(),
5199
+ UsePlt ? PPCII::MO_PLT : 0);
5159
5200
5160
- if (GO && GO->isDeclaration() && !S->hasContainingCsect()) {
5161
- // On AIX, an undefined symbol needs to be associated with a
5162
- // MCSectionXCOFF to get the correct storage mapping class.
5163
- // In this case, XCOFF::XMC_PR.
5201
+ // If there exists a user-declared function whose name is the same as the
5202
+ // ExternalSymbol's, then we pick up the user-declared version.
5203
+ const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
5204
+ if (const Function *F =
5205
+ dyn_cast_or_null<Function>(Mod->getNamedValue(SymName))) {
5164
5206
const XCOFF::StorageClass SC =
5165
- TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
5166
- MCSectionXCOFF *Sec =
5167
- Context.getXCOFFSection(S->getName(), XCOFF::XMC_PR, XCOFF::XTY_ER,
5168
- SC, SectionKind::getMetadata());
5169
- S->setContainingCsect(Sec);
5207
+ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(F);
5208
+ return getAIXFuncEntryPointSymbolSDNode(F->getName(), F->isDeclaration(),
5209
+ SC);
5170
5210
}
5171
5211
5172
- EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
5173
- return DAG.getMCSymbol(S, PtrVT);
5174
- }
5212
+ // TODO: Remove this when the support for ExternalSymbolSDNode is complete.
5213
+ if (isValidAIXExternalSymSDNode(SymName)) {
5214
+ return getAIXFuncEntryPointSymbolSDNode(SymName, true, XCOFF::C_EXT);
5215
+ }
5175
5216
5176
- if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
5177
- return DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(),
5178
- UsePlt ? PPCII::MO_PLT : 0);
5217
+ report_fatal_error("Unexpected ExternalSymbolSDNode: " + Twine(SymName));
5218
+ }
5179
5219
5180
5220
// No transformation needed.
5181
5221
assert(Callee.getNode() && "What no callee?");
0 commit comments