Index: lib/Target/Mips/MCTargetDesc/MipsMCExpr.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCExpr.h +++ lib/Target/Mips/MCTargetDesc/MipsMCExpr.h @@ -22,6 +22,7 @@ MEK_None, MEK_CALL_HI16, MEK_CALL_LO16, + MEK_DTPREL, MEK_DTPREL_HI, MEK_DTPREL_LO, MEK_GOT, Index: lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -43,6 +43,9 @@ case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); break; + case MEK_DTPREL: + llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); + break; case MEK_CALL_HI16: OS << "%call_hi"; break; @@ -157,6 +160,8 @@ case MEK_None: case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); + case MEK_DTPREL: + llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); case MEK_DTPREL_HI: case MEK_DTPREL_LO: case MEK_GOT: @@ -244,6 +249,9 @@ case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); break; + case MEK_DTPREL: + llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); + break; case MEK_CALL_HI16: case MEK_CALL_LO16: case MEK_GOT: Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp +++ lib/Target/Mips/MipsAsmPrinter.cpp @@ -1206,16 +1206,23 @@ // and value for debug thread local expression. void MipsAsmPrinter::EmitDebugThreadLocal(const MCExpr *Value, unsigned Size) const { - switch (Size) { - case 4: - OutStreamer->EmitDTPRel32Value(Value); - break; - case 8: - OutStreamer->EmitDTPRel64Value(Value); - break; - default: - llvm_unreachable("Unexpected size of expression value."); + if (auto *MipsExpr = dyn_cast(Value)) { + if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) { + switch (Size) { + case 4: + OutStreamer->EmitDTPRel32Value(MipsExpr->getSubExpr()); + break; + case 8: + OutStreamer->EmitDTPRel64Value(MipsExpr->getSubExpr()); + break; + default: + llvm_unreachable("Unexpected size of expression value."); + } + return; + } } + + AsmPrinter::EmitDebugThreadLocal(Value, Size); } // Align all targets of indirect branches on bundle size. Used only if target Index: lib/Target/Mips/MipsTargetObjectFile.cpp =================================================================== --- lib/Target/Mips/MipsTargetObjectFile.cpp +++ lib/Target/Mips/MipsTargetObjectFile.cpp @@ -10,6 +10,7 @@ #include "MipsTargetObjectFile.h" #include "MipsSubtarget.h" #include "MipsTargetMachine.h" +#include "MCTargetDesc/MipsMCExpr.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -189,6 +190,7 @@ MipsTargetObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { const MCExpr *Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); - return MCBinaryExpr::createAdd( + Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(0x8000, getContext()), getContext()); + return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL, Expr, getContext()); }