Index: llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.h =================================================================== --- llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.h +++ llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.h @@ -258,9 +258,6 @@ typedef DenseMap VRegRCMap; VRegRCMap VRegMapping; - // Cache the subtarget here. - const NVPTXSubtarget *nvptxSubtarget; - // List of variables demoted to a function scope. std::map> localDecls; Index: llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -219,11 +219,12 @@ return; } + const NVPTXSubtarget &STI = MI->getMF()->getSubtarget(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); MCOperand MCOp; - if (!nvptxSubtarget->hasImageHandles()) { + if (!STI.hasImageHandles()) { if (lowerImageHandleOperand(MI, i, MCOp)) { OutMI.addOperand(MCOp); continue; @@ -329,11 +330,12 @@ void NVPTXAsmPrinter::printReturnValStr(const Function *F, raw_ostream &O) { const DataLayout &DL = getDataLayout(); - const TargetLowering *TLI = nvptxSubtarget->getTargetLowering(); + const NVPTXSubtarget &STI = TM.getSubtarget(*F); + const TargetLowering *TLI = STI.getTargetLowering(); Type *Ty = F->getReturnType(); - bool isABI = (nvptxSubtarget->getSmVersion() >= 20); + bool isABI = (STI.getSmVersion() >= 20); if (Ty->getTypeID() == Type::VoidTyID) return; @@ -474,7 +476,6 @@ } bool NVPTXAsmPrinter::runOnMachineFunction(MachineFunction &F) { - nvptxSubtarget = &F.getSubtarget(); bool Result = AsmPrinter::runOnMachineFunction(F); // Emit closing brace for the body of function F. // The closing brace must be emitted here because we need to emit additional @@ -508,8 +509,9 @@ OutStreamer->AddComment(Twine("implicit-def: ") + getVirtualRegisterName(RegNo)); } else { + const NVPTXSubtarget &STI = MI->getMF()->getSubtarget(); OutStreamer->AddComment(Twine("implicit-def: ") + - nvptxSubtarget->getRegisterInfo()->getName(RegNo)); + STI.getRegisterInfo()->getName(RegNo)); } OutStreamer->AddBlankLine(); } @@ -1431,12 +1433,14 @@ void NVPTXAsmPrinter::emitFunctionParamList(const Function *F, raw_ostream &O) { const DataLayout &DL = getDataLayout(); const AttributeList &PAL = F->getAttributes(); - const TargetLowering *TLI = nvptxSubtarget->getTargetLowering(); + const NVPTXSubtarget &STI = TM.getSubtarget(*F); + const TargetLowering *TLI = STI.getTargetLowering(); Function::const_arg_iterator I, E; unsigned paramIndex = 0; bool first = true; bool isKernelFunc = isKernelFunction(*F); - bool isABI = (nvptxSubtarget->getSmVersion() >= 20); + bool isABI = (STI.getSmVersion() >= 20); + bool hasImageHandles = STI.hasImageHandles(); MVT thePointerTy = TLI->getPointerTy(DL); if (F->arg_empty()) { @@ -1460,7 +1464,7 @@ if (isImage(*I)) { std::string sname = I->getName(); if (isImageWriteOnly(*I) || isImageReadWrite(*I)) { - if (nvptxSubtarget->hasImageHandles()) + if (hasImageHandles) O << "\t.param .u64 .ptr .surfref "; else O << "\t.param .surfref "; @@ -1468,7 +1472,7 @@ O << "_param_" << paramIndex; } else { // Default image is read_only - if (nvptxSubtarget->hasImageHandles()) + if (hasImageHandles) O << "\t.param .u64 .ptr .texref "; else O << "\t.param .texref "; @@ -1476,7 +1480,7 @@ O << "_param_" << paramIndex; } } else { - if (nvptxSubtarget->hasImageHandles()) + if (hasImageHandles) O << "\t.param .u64 .ptr .samplerref "; else O << "\t.param .samplerref "; Index: llvm/trunk/test/CodeGen/NVPTX/nofunc.ll =================================================================== --- llvm/trunk/test/CodeGen/NVPTX/nofunc.ll +++ llvm/trunk/test/CodeGen/NVPTX/nofunc.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s +; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s + +; Test that we don't crash if we're compiling a module with function references, +; but without any functions in it. + +target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64" +target triple = "nvptx64-nvidia-cuda" + +@Funcs = local_unnamed_addr addrspace(1) externally_initialized + global [1 x void (i8*)*] [void (i8*)* @func], align 8 + +declare void @func(i8*) + +; CHECK: Funcs[1] = {func}