Index: llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ llvm/trunk/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -802,6 +802,13 @@ } } +static bool isEmptyXXStructor(GlobalVariable *GV) { + if (!GV) return true; + const ConstantArray *InitList = dyn_cast(GV->getInitializer()); + if (!InitList) return true; // Not an array; we don't know how to parse. + return InitList->getNumOperands() == 0; +} + bool NVPTXAsmPrinter::doInitialization(Module &M) { // Construct a default subtarget off of the TargetMachine defaults. The // rest of NVPTX isn't friendly to change subtargets per function and @@ -816,6 +823,16 @@ report_fatal_error("Module has aliases, which NVPTX does not support."); return true; // error } + if (!isEmptyXXStructor(M.getNamedGlobal("llvm.global_ctors"))) { + report_fatal_error( + "Module has a nontrivial global ctor, which NVPTX does not support."); + return true; // error + } + if (!isEmptyXXStructor(M.getNamedGlobal("llvm.global_dtors"))) { + report_fatal_error( + "Module has a nontrivial global dtor, which NVPTX does not support."); + return true; // error + } SmallString<128> Str1; raw_svector_ostream OS1(Str1); Index: llvm/trunk/test/CodeGen/NVPTX/global-ctor-empty.ll =================================================================== --- llvm/trunk/test/CodeGen/NVPTX/global-ctor-empty.ll +++ llvm/trunk/test/CodeGen/NVPTX/global-ctor-empty.ll @@ -0,0 +1,5 @@ +; RUN: llc < %s -march=nvptx -mcpu=sm_20 2>&1 + +; Check that llc doesn't die when given an empty global ctor / dtor. +@llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] [] +@llvm.global_dtors = appending global [0 x { i32, void ()*, i8* }] [] Index: llvm/trunk/test/CodeGen/NVPTX/global-ctor.ll =================================================================== --- llvm/trunk/test/CodeGen/NVPTX/global-ctor.ll +++ llvm/trunk/test/CodeGen/NVPTX/global-ctor.ll @@ -0,0 +1,9 @@ +; RUN: not llc < %s -march=nvptx -mcpu=sm_20 2>&1 | FileCheck %s + +; Check that llc dies when given a nonempty global ctor. +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }] + +; CHECK: ERROR: Module has a nontrivial global ctor +define internal void @foo() { + ret void +} Index: llvm/trunk/test/CodeGen/NVPTX/global-dtor.ll =================================================================== --- llvm/trunk/test/CodeGen/NVPTX/global-dtor.ll +++ llvm/trunk/test/CodeGen/NVPTX/global-dtor.ll @@ -0,0 +1,9 @@ +; RUN: not llc < %s -march=nvptx -mcpu=sm_20 2>&1 | FileCheck %s + +; Check that llc dies when given a nonempty global dtor. +@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }] + +; CHECK: ERROR: Module has a nontrivial global dtor +define internal void @foo() { + ret void +}