Index: llvm/trunk/lib/Target/Mips/MipsTargetObjectFile.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsTargetObjectFile.cpp +++ llvm/trunk/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -136,6 +136,13 @@ return false; Type *Ty = GVA->getValueType(); + + // It is possible that the type of the global is unsized, i.e. a declaration + // of a extern struct. In this case don't presume it is in the small data + // section. This happens e.g. when building the FreeBSD kernel. + if (!Ty->isSized()) + return false; + return IsInSmallSection( GVA->getParent()->getDataLayout().getTypeAllocSize(Ty)); } Index: llvm/trunk/test/CodeGen/Mips/unsized-global.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/unsized-global.ll +++ llvm/trunk/test/CodeGen/Mips/unsized-global.ll @@ -0,0 +1,22 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; Check that -mgpopt doesn't crash on unsized externals +; RUN: llc -mtriple=mips64-unknown-freebsd -mattr=+noabicalls -target-abi n64 -mgpopt -o - %s | FileCheck %s + +%struct.a = type opaque + +@b = external global %struct.a, align 1 + +; Function Attrs: norecurse nounwind readnone +define %struct.a* @d() { +; CHECK-LABEL: d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lui $1, %highest(b) +; CHECK-NEXT: daddiu $1, $1, %higher(b) +; CHECK-NEXT: dsll $1, $1, 16 +; CHECK-NEXT: daddiu $1, $1, %hi(b) +; CHECK-NEXT: dsll $1, $1, 16 +; CHECK-NEXT: jr $ra +; CHECK-NEXT: daddiu $2, $1, %lo(b) +entry: + ret %struct.a* @b +}