Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit c32c110

Browse files
committed
Make sure NVPTX doesn't emit symbol names that aren't valid in PTX.
NVPTX, like the other backends, relies on generic symbol name sanitizing done by MCSymbol. However, the ptxas assembler is more stringent and disallows some additional characters in symbol names. See PR19099 for more details. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203483 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent b7dec21 commit c32c110

File tree

2 files changed

+48
-16
lines changed

2 files changed

+48
-16
lines changed

lib/Target/NVPTX/NVPTXAsmPrinter.cpp

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ void NVPTXAsmPrinter::emitDeclaration(const Function *F, raw_ostream &O) {
684684
else
685685
O << ".func ";
686686
printReturnValStr(F, O);
687-
O << *getSymbol(F) << "\n";
687+
O << getSymbolName(F) << "\n";
688688
emitFunctionParamList(F, O);
689689
O << ";\n";
690690
}
@@ -1209,7 +1209,7 @@ void NVPTXAsmPrinter::printModuleLevelGV(const GlobalVariable *GVar,
12091209
else
12101210
O << getPTXFundamentalTypeStr(ETy, false);
12111211
O << " ";
1212-
O << *getSymbol(GVar);
1212+
O << getSymbolName(GVar);
12131213

12141214
// Ptx allows variable initilization only for constant and global state
12151215
// spaces.
@@ -1245,31 +1245,31 @@ void NVPTXAsmPrinter::printModuleLevelGV(const GlobalVariable *GVar,
12451245
bufferAggregateConstant(Initializer, &aggBuffer);
12461246
if (aggBuffer.numSymbols) {
12471247
if (nvptxSubtarget.is64Bit()) {
1248-
O << " .u64 " << *getSymbol(GVar) << "[";
1248+
O << " .u64 " << getSymbolName(GVar) << "[";
12491249
O << ElementSize / 8;
12501250
} else {
1251-
O << " .u32 " << *getSymbol(GVar) << "[";
1251+
O << " .u32 " << getSymbolName(GVar) << "[";
12521252
O << ElementSize / 4;
12531253
}
12541254
O << "]";
12551255
} else {
1256-
O << " .b8 " << *getSymbol(GVar) << "[";
1256+
O << " .b8 " << getSymbolName(GVar) << "[";
12571257
O << ElementSize;
12581258
O << "]";
12591259
}
12601260
O << " = {";
12611261
aggBuffer.print();
12621262
O << "}";
12631263
} else {
1264-
O << " .b8 " << *getSymbol(GVar);
1264+
O << " .b8 " << getSymbolName(GVar);
12651265
if (ElementSize) {
12661266
O << "[";
12671267
O << ElementSize;
12681268
O << "]";
12691269
}
12701270
}
12711271
} else {
1272-
O << " .b8 " << *getSymbol(GVar);
1272+
O << " .b8 " << getSymbolName(GVar);
12731273
if (ElementSize) {
12741274
O << "[";
12751275
O << ElementSize;
@@ -1376,7 +1376,7 @@ void NVPTXAsmPrinter::emitPTXGlobalVariable(const GlobalVariable *GVar,
13761376
O << " .";
13771377
O << getPTXFundamentalTypeStr(ETy);
13781378
O << " ";
1379-
O << *getSymbol(GVar);
1379+
O << getSymbolName(GVar);
13801380
return;
13811381
}
13821382

@@ -1391,7 +1391,7 @@ void NVPTXAsmPrinter::emitPTXGlobalVariable(const GlobalVariable *GVar,
13911391
case Type::ArrayTyID:
13921392
case Type::VectorTyID:
13931393
ElementSize = TD->getTypeStoreSize(ETy);
1394-
O << " .b8 " << *getSymbol(GVar) << "[";
1394+
O << " .b8 " << getSymbolName(GVar) << "[";
13951395
if (ElementSize) {
13961396
O << itostr(ElementSize);
13971397
}
@@ -1446,7 +1446,7 @@ void NVPTXAsmPrinter::printParamName(Function::const_arg_iterator I,
14461446
int paramIndex, raw_ostream &O) {
14471447
if ((nvptxSubtarget.getDrvInterface() == NVPTX::NVCL) ||
14481448
(nvptxSubtarget.getDrvInterface() == NVPTX::CUDA))
1449-
O << *getSymbol(I->getParent()) << "_param_" << paramIndex;
1449+
O << getSymbolName(I->getParent()) << "_param_" << paramIndex;
14501450
else {
14511451
std::string argName = I->getName();
14521452
const char *p = argName.c_str();
@@ -1505,13 +1505,13 @@ void NVPTXAsmPrinter::emitFunctionParamList(const Function *F, raw_ostream &O) {
15051505
if (llvm::isImage(*I)) {
15061506
std::string sname = I->getName();
15071507
if (llvm::isImageWriteOnly(*I))
1508-
O << "\t.param .surfref " << *getSymbol(F) << "_param_"
1508+
O << "\t.param .surfref " << getSymbolName(F) << "_param_"
15091509
<< paramIndex;
15101510
else // Default image is read_only
1511-
O << "\t.param .texref " << *getSymbol(F) << "_param_"
1511+
O << "\t.param .texref " << getSymbolName(F) << "_param_"
15121512
<< paramIndex;
15131513
} else // Should be llvm::isSampler(*I)
1514-
O << "\t.param .samplerref " << *getSymbol(F) << "_param_"
1514+
O << "\t.param .samplerref " << getSymbolName(F) << "_param_"
15151515
<< paramIndex;
15161516
continue;
15171517
}
@@ -1758,13 +1758,13 @@ void NVPTXAsmPrinter::printScalarConstant(const Constant *CPV, raw_ostream &O) {
17581758
return;
17591759
}
17601760
if (const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
1761-
O << *getSymbol(GVar);
1761+
O << getSymbolName(GVar);
17621762
return;
17631763
}
17641764
if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
17651765
const Value *v = Cexpr->stripPointerCasts();
17661766
if (const GlobalValue *GVar = dyn_cast<GlobalValue>(v)) {
1767-
O << *getSymbol(GVar);
1767+
O << getSymbolName(GVar);
17681768
return;
17691769
} else {
17701770
O << *LowerConstant(CPV, *this);
@@ -2078,7 +2078,7 @@ void NVPTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
20782078
break;
20792079

20802080
case MachineOperand::MO_GlobalAddress:
2081-
O << *getSymbol(MO.getGlobal());
2081+
O << getSymbolName(MO.getGlobal());
20822082
break;
20832083

20842084
case MachineOperand::MO_MachineBasicBlock:
@@ -2139,6 +2139,33 @@ LineReader *NVPTXAsmPrinter::getReader(std::string filename) {
21392139
return reader;
21402140
}
21412141

2142+
std::string NVPTXAsmPrinter::getSymbolName(const GlobalValue *GV) const {
2143+
// Obtain the original symbol name.
2144+
MCSymbol *Sym = getSymbol(GV);
2145+
std::string OriginalName;
2146+
raw_string_ostream OriginalNameStream(OriginalName);
2147+
Sym->print(OriginalNameStream);
2148+
OriginalNameStream.flush();
2149+
2150+
// MCSymbol already does symbol-name sanitizing, so names it produces are
2151+
// valid for object files. The only two characters valida in that context
2152+
// and indigestible by the PTX assembler are '.' and '@'.
2153+
std::string CleanName;
2154+
raw_string_ostream CleanNameStream(CleanName);
2155+
for (unsigned I = 0, E = OriginalName.size(); I != E; ++I) {
2156+
char C = OriginalName[I];
2157+
if (C == '.') {
2158+
CleanNameStream << "_$_";
2159+
} else if (C == '@') {
2160+
CleanNameStream << "_%_";
2161+
} else {
2162+
CleanNameStream << C;
2163+
}
2164+
}
2165+
2166+
return CleanNameStream.str();
2167+
}
2168+
21422169
std::string LineReader::readLine(unsigned lineNum) {
21432170
if (lineNum < theCurLine) {
21442171
theCurLine = 0;

lib/Target/NVPTX/NVPTXAsmPrinter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter {
276276

277277
LineReader *reader;
278278
LineReader *getReader(std::string);
279+
280+
// Get the symbol name of the given global symbol.
281+
//
282+
// Cleans up the name so it's a valid in PTX assembly.
283+
std::string getSymbolName(const GlobalValue *GV) const;
279284
public:
280285
NVPTXAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
281286
: AsmPrinter(TM, Streamer),

0 commit comments

Comments
 (0)