diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 110 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.h | 2 | 
5 files changed, 92 insertions, 32 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 4159eb19423..2920ac66290 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -71,6 +71,42 @@ static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) {    DiagInfo->DiagHandler(Diag, DiagInfo->DiagContext, LocCookie);  } +unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr, +                                            const MDNode *LocMDNode) const { +  if (!DiagInfo) { +    DiagInfo = make_unique<SrcMgrDiagInfo>(); + +    MCContext &Context = MMI->getContext(); +    Context.setInlineSourceManager(&DiagInfo->SrcMgr); + +    LLVMContext &LLVMCtx = MMI->getModule()->getContext(); +    if (LLVMCtx.getInlineAsmDiagnosticHandler()) { +      DiagInfo->DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler(); +      DiagInfo->DiagContext = LLVMCtx.getInlineAsmDiagnosticContext(); +      DiagInfo->SrcMgr.setDiagHandler(srcMgrDiagHandler, DiagInfo.get()); +    } +  } + +  SourceMgr &SrcMgr = DiagInfo->SrcMgr; + +  std::unique_ptr<MemoryBuffer> Buffer; +  // The inline asm source manager will outlive AsmStr, so make a copy of the +  // string for SourceMgr to own. +  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>"); + +  // Tell SrcMgr about this buffer, it takes ownership of the buffer. +  unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); + +  // Store LocMDNode in DiagInfo, using BufNum as an identifier. +  if (LocMDNode) { +    DiagInfo->LocInfos.resize(BufNum); +    DiagInfo->LocInfos[BufNum - 1] = LocMDNode; +  } + +  return BufNum; +} + +  /// EmitInlineAsm - Emit a blob of inline asm to the output streamer.  void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,                                 const MCTargetOptions &MCOptions, @@ -98,39 +134,11 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,      return;    } -  if (!DiagInfo) { -    DiagInfo = make_unique<SrcMgrDiagInfo>(); +  unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode); +  DiagInfo->SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths); -    MCContext &Context = MMI->getContext(); -    Context.setInlineSourceManager(&DiagInfo->SrcMgr); - -    LLVMContext &LLVMCtx = MMI->getModule()->getContext(); -    if (LLVMCtx.getInlineAsmDiagnosticHandler()) { -      DiagInfo->DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler(); -      DiagInfo->DiagContext = LLVMCtx.getInlineAsmDiagnosticContext(); -      DiagInfo->SrcMgr.setDiagHandler(srcMgrDiagHandler, DiagInfo.get()); -    } -  } - -  SourceMgr &SrcMgr = DiagInfo->SrcMgr; -  SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths); - -  std::unique_ptr<MemoryBuffer> Buffer; -  // The inline asm source manager will outlive Str, so make a copy of the -  // string for SourceMgr to own. -  Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>"); - -  // Tell SrcMgr about this buffer, it takes ownership of the buffer. -  unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); - -  // Store LocMDNode in DiagInfo, using BufNum as an identifier. -  if (LocMDNode) { -    DiagInfo->LocInfos.resize(BufNum); -    DiagInfo->LocInfos[BufNum-1] = LocMDNode; -  } - -  std::unique_ptr<MCAsmParser> Parser( -      createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum)); +  std::unique_ptr<MCAsmParser> Parser(createMCAsmParser( +          DiagInfo->SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));    // Do not use assembler-level information for parsing inline assembly.    OutStreamer->setUseAssemblerInfoForParsing(false); @@ -519,6 +527,44 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {    MCOptions.SanitizeAddress =        MF->getFunction().hasFnAttribute(Attribute::SanitizeAddress); +  // Emit warnings if we use reserved registers on the clobber list, as +  // that might give surprising results. +  std::vector<std::string> RestrRegs; +  // Start with the first operand descriptor, and iterate over them. +  for (unsigned I = InlineAsm::MIOp_FirstOperand, NumOps = MI->getNumOperands(); +       I < NumOps; ++I) { +    const MachineOperand &MO = MI->getOperand(I); +    if (MO.isImm()) { +      unsigned Flags = MO.getImm(); +      const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); +      if (InlineAsm::getKind(Flags) == InlineAsm::Kind_Clobber && +          !TRI->isAsmClobberable(*MF, MI->getOperand(I + 1).getReg())) { +        RestrRegs.push_back(TRI->getName(MI->getOperand(I + 1).getReg())); +      } +      // Skip to one before the next operand descriptor, if it exists. +      I += InlineAsm::getNumOperandRegisters(Flags); +    } +  } + +  if (!RestrRegs.empty()) { +    unsigned BufNum = addInlineAsmDiagBuffer(OS.str(), LocMD); +    auto &SrcMgr = DiagInfo->SrcMgr; +    SMLoc Loc = SMLoc::getFromPointer( +        SrcMgr.getMemoryBuffer(BufNum)->getBuffer().begin()); + +    std::string Msg = "inline asm clobber list contains reserved registers: "; +    for (auto I = RestrRegs.begin(), E = RestrRegs.end(); I != E; I++) { +      if(I != RestrRegs.begin()) +        Msg += ", "; +      Msg += *I; +    } +    std::string Note = "Reserved registers on the clobber list may not be " +                "preserved across the asm statement, and clobbering them may " +                "lead to undefined behaviour."; +    SrcMgr.PrintMessage(Loc, SourceMgr::DK_Warning, Msg); +    SrcMgr.PrintMessage(Loc, SourceMgr::DK_Note, Note); +  } +    EmitInlineAsm(OS.str(), getSubtargetInfo(), MCOptions, LocMD,                  MI->getInlineAsmDialect()); diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index a7c2c1b8125..8d7639b78ef 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -189,6 +189,11 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,    return false;  } +bool AArch64RegisterInfo::isAsmClobberable(const MachineFunction &MF, +                                          unsigned PhysReg) const { +  return !isReservedReg(MF, PhysReg); +} +  bool AArch64RegisterInfo::isConstantPhysReg(unsigned PhysReg) const {    return PhysReg == AArch64::WZR || PhysReg == AArch64::XZR;  } diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h index 57000d37090..d57ebbe9c00 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h @@ -69,6 +69,8 @@ public:    const uint32_t *getWindowsStackProbePreservedMask() const;    BitVector getReservedRegs(const MachineFunction &MF) const override; +  bool isAsmClobberable(const MachineFunction &MF, +                       unsigned PhysReg) const override;    bool isConstantPhysReg(unsigned PhysReg) const override;    const TargetRegisterClass *    getPointerRegClass(const MachineFunction &MF, diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 5342e6e2cd1..02b3daf3c6f 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -209,6 +209,11 @@ getReservedRegs(const MachineFunction &MF) const {    return Reserved;  } +bool ARMBaseRegisterInfo:: +isAsmClobberable(const MachineFunction &MF, unsigned PhysReg) const { +  return !getReservedRegs(MF).test(PhysReg); +} +  const TargetRegisterClass *  ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,                                                 const MachineFunction &) const { diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h index f755f66a0f3..521e1b84f88 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -131,6 +131,8 @@ public:                                               CallingConv::ID) const;    BitVector getReservedRegs(const MachineFunction &MF) const override; +  bool isAsmClobberable(const MachineFunction &MF, +                       unsigned PhysReg) const override;    const TargetRegisterClass *    getPointerRegClass(const MachineFunction &MF,  | 

