Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp @@ -12,6 +12,7 @@ #include "SystemZTargetStreamer.h" #include "TargetInfo/SystemZTargetInfo.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" @@ -183,6 +184,21 @@ return new SystemZInstPrinter(MAI, MII, MRI); } +void SystemZTargetStreamer::emitConstantPools() { + // Emit EXRL target instructions. + if (EXRLTargets2Sym.empty()) + return; + // Switch to the .text section. + const MCObjectFileInfo &OFI = *Streamer.getContext().getObjectFileInfo(); + Streamer.SwitchSection(OFI.getTextSection()); + for (auto &I : EXRLTargets2Sym) { + Streamer.emitLabel(I.second); + const MCInstSTIPair &MCI_STI = I.first; + Streamer.emitInstruction(MCI_STI.first, *MCI_STI.second); + } + EXRLTargets2Sym.clear(); +} + namespace { class SystemZTargetAsmStreamer : public SystemZTargetStreamer { formatted_raw_ostream &OS; Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -11,6 +11,7 @@ #include "SystemZMCInstLower.h" #include "SystemZTargetMachine.h" +#include "SystemZTargetStreamer.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/StackMaps.h" #include "llvm/MC/MCInstBuilder.h" @@ -27,32 +28,10 @@ private: StackMaps SM; - typedef std::pair MCInstSTIPair; - struct CmpMCInst { - bool operator()(const MCInstSTIPair &MCI_STI_A, - const MCInstSTIPair &MCI_STI_B) const { - if (MCI_STI_A.second != MCI_STI_B.second) - return uintptr_t(MCI_STI_A.second) < uintptr_t(MCI_STI_B.second); - const MCInst &A = MCI_STI_A.first; - const MCInst &B = MCI_STI_B.first; - assert(A.getNumOperands() == B.getNumOperands() && - A.getNumOperands() == 5 && A.getOperand(2).getImm() == 1 && - B.getOperand(2).getImm() == 1 && "Unexpected EXRL target MCInst"); - if (A.getOpcode() != B.getOpcode()) - return A.getOpcode() < B.getOpcode(); - if (A.getOperand(0).getReg() != B.getOperand(0).getReg()) - return A.getOperand(0).getReg() < B.getOperand(0).getReg(); - if (A.getOperand(1).getImm() != B.getOperand(1).getImm()) - return A.getOperand(1).getImm() < B.getOperand(1).getImm(); - if (A.getOperand(3).getReg() != B.getOperand(3).getReg()) - return A.getOperand(3).getReg() < B.getOperand(3).getReg(); - if (A.getOperand(4).getImm() != B.getOperand(4).getImm()) - return A.getOperand(4).getImm() < B.getOperand(4).getImm(); - return false; - } - }; - typedef std::map EXRLT2SymMap; - EXRLT2SymMap EXRLTargets2Sym; + SystemZTargetStreamer *getTargetStreamer() { + MCTargetStreamer *TS = OutStreamer->getTargetStreamer(); + return static_cast(TS); + } public: SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) @@ -77,7 +56,6 @@ void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL); void LowerSTACKMAP(const MachineInstr &MI); void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower); - void emitEXRLTargetInstructions(); }; } // end namespace llvm Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -549,15 +549,18 @@ Register SrcReg = MI->getOperand(4).getReg(); int64_t SrcDisp = MI->getOperand(5).getImm(); + SystemZTargetStreamer *TS = getTargetStreamer(); + assert(TS && "do not have a target streamer"); MCSymbol *DotSym = nullptr; MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg) .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp); - MCInstSTIPair ET_STI(ET, &MF->getSubtarget()); - EXRLT2SymMap::iterator I = EXRLTargets2Sym.find(ET_STI); - if (I != EXRLTargets2Sym.end()) + SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget()); + SystemZTargetStreamer::EXRLT2SymMap::iterator I = + TS->EXRLTargets2Sym.find(ET_STI); + if (I != TS->EXRLTargets2Sym.end()) DotSym = I->second; else - EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol(); + TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol(); const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); EmitToStreamer( *OutStreamer, @@ -722,19 +725,6 @@ getSubtargetInfo()); } -void SystemZAsmPrinter::emitEXRLTargetInstructions() { - if (EXRLTargets2Sym.empty()) - return; - // Switch to the .text section. - OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); - for (auto &I : EXRLTargets2Sym) { - OutStreamer->emitLabel(I.second); - const MCInstSTIPair &MCI_STI = I.first; - OutStreamer->emitInstruction(MCI_STI.first, *MCI_STI.second); - } - EXRLTargets2Sym.clear(); -} - // Convert a SystemZ-specific constant pool modifier into the associated // MCSymbolRefExpr variant kind. static MCSymbolRefExpr::VariantKind @@ -793,7 +783,6 @@ } void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { - emitEXRLTargetInstructions(); emitStackMaps(SM); } Index: llvm/lib/Target/SystemZ/SystemZTargetStreamer.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZTargetStreamer.h +++ llvm/lib/Target/SystemZ/SystemZTargetStreamer.h @@ -18,6 +18,35 @@ public: SystemZTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} + typedef std::pair MCInstSTIPair; + struct CmpMCInst { + bool operator()(const MCInstSTIPair &MCI_STI_A, + const MCInstSTIPair &MCI_STI_B) const { + if (MCI_STI_A.second != MCI_STI_B.second) + return uintptr_t(MCI_STI_A.second) < uintptr_t(MCI_STI_B.second); + const MCInst &A = MCI_STI_A.first; + const MCInst &B = MCI_STI_B.first; + assert(A.getNumOperands() == B.getNumOperands() && + A.getNumOperands() == 5 && A.getOperand(2).getImm() == 1 && + B.getOperand(2).getImm() == 1 && "Unexpected EXRL target MCInst"); + if (A.getOpcode() != B.getOpcode()) + return A.getOpcode() < B.getOpcode(); + if (A.getOperand(0).getReg() != B.getOperand(0).getReg()) + return A.getOperand(0).getReg() < B.getOperand(0).getReg(); + if (A.getOperand(1).getImm() != B.getOperand(1).getImm()) + return A.getOperand(1).getImm() < B.getOperand(1).getImm(); + if (A.getOperand(3).getReg() != B.getOperand(3).getReg()) + return A.getOperand(3).getReg() < B.getOperand(3).getReg(); + if (A.getOperand(4).getImm() != B.getOperand(4).getImm()) + return A.getOperand(4).getImm() < B.getOperand(4).getImm(); + return false; + } + }; + typedef std::map EXRLT2SymMap; + EXRLT2SymMap EXRLTargets2Sym; + + void emitConstantPools() override; + virtual void emitMachine(StringRef CPU) = 0; }; Index: llvm/test/CodeGen/SystemZ/memset-06.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/memset-06.ll @@ -0,0 +1,46 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu -generate-arange-section +; +; Test that the EXRL target instruction is emitted successfully (before text +; section is closed). + +@a = dso_local global i32* null, align 8, !dbg !0 +@j = dso_local global i32 0, align 4, !dbg !5 + +define void @fun() !dbg !14 { +entry: + %0 = load i32*, i32** @a, align 8, !dbg !18 + %1 = bitcast i32* %0 to i8*, !dbg !19 + %2 = load i32, i32* @j, align 4, !dbg !20 + %conv = sext i32 %2 to i64, !dbg !20 + call void @llvm.memset.p0i8.i64(i8* align 4 %1, i8 0, i64 %conv, i1 false), !dbg !19 + ret void, !dbg !21 +} + +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11, !12} +!llvm.ident = !{!13} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "file.c", directory: "") +!4 = !{!0, !5} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "j", scope: !2, file: !3, line: 2, type: !7, isLocal: false, isDefinition: true) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!9 = !{i32 7, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{i32 7, !"frame-pointer", i32 2} +!13 = !{!"clang version 14.0.0"} +!14 = distinct !DISubprogram(name: "fun", scope: !3, file: !3, line: 3, type: !15, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17) +!15 = !DISubroutineType(types: !16) +!16 = !{null} +!17 = !{} +!18 = !DILocation(line: 4, column: 11, scope: !14) +!19 = !DILocation(line: 4, column: 4, scope: !14) +!20 = !DILocation(line: 4, column: 15, scope: !14) +!21 = !DILocation(line: 5, column: 1, scope: !14)