Commit 8bb0d048 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r368477:

------------------------------------------------------------------------
r368477 | void | 2019-08-09 22:16:31 +0200 (Fri, 09 Aug 2019) | 22 lines

[MC] Don't recreate a label if it's already used

Summary:
This patch keeps track of MCSymbols created for blocks that were
referenced in inline asm. It prevents creating a new symbol which
doesn't refer to the block.

Inline asm may have a reference to a label. The asm parser however
doesn't recognize it as a label and tries to create a new symbol. The
result being that instead of the original symbol (e.g. ".Ltmp0") the
parser replaces it in the inline asm with the new one (e.g. ".Ltmp00")
without updating it in the symbol table. So the machine basic block
retains the "old" symbol (".Ltmp0"), but the inline asm uses the new one
(".Ltmp00").

Reviewers: nickdesaulniers, craig.topper

Subscribers: nathanchance, javed.absar, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65304
------------------------------------------------------------------------

llvm-svn: 368676
parent 3f910512
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -112,6 +112,9 @@ namespace llvm {
    /// number of section symbols with the same name).
    StringMap<bool, BumpPtrAllocator &> UsedNames;

    /// Keeps track of labels that are used in inline assembly.
    SymbolTable InlineAsmUsedLabelNames;

    /// The next ID to dole out to an unnamed assembler temporary symbol with
    /// a given prefix.
    StringMap<unsigned> NextID;
@@ -377,6 +380,16 @@ namespace llvm {
    /// APIs.
    const SymbolTable &getSymbols() const { return Symbols; }

    /// isInlineAsmLabel - Return true if the name is a label referenced in
    /// inline assembly.
    MCSymbol *getInlineAsmLabel(StringRef Name) const {
      return InlineAsmUsedLabelNames.lookup(Name);
    }

    /// registerInlineAsmLabel - Records that the name is a label referenced in
    /// inline assembly.
    void registerInlineAsmLabel(MCSymbol *Sym);

    /// @}

    /// \name Section Management
+1 −0
Original line number Diff line number Diff line
@@ -432,6 +432,7 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
              const BlockAddress *BA = MI->getOperand(OpNo).getBlockAddress();
              MCSymbol *Sym = AP->GetBlockAddressSymbol(BA);
              Sym->print(OS, AP->MAI);
              MMI->getContext().registerInlineAsmLabel(Sym);
            } else if (MI->getOperand(OpNo).isMBB()) {
              const MCSymbol *Sym = MI->getOperand(OpNo).getMBB()->getSymbol();
              Sym->print(OS, AP->MAI);
+6 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
                     bool DoAutoReset)
    : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi),
      Symbols(Allocator), UsedNames(Allocator),
      InlineAsmUsedLabelNames(Allocator),
      CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
      AutoReset(DoAutoReset) {
  SecureLogFile = AsSecureLogFileName;
@@ -90,6 +91,7 @@ void MCContext::reset() {
  XCOFFAllocator.DestroyAll();

  MCSubtargetAllocator.DestroyAll();
  InlineAsmUsedLabelNames.clear();
  UsedNames.clear();
  Symbols.clear();
  Allocator.Reset();
@@ -272,6 +274,10 @@ void MCContext::setSymbolValue(MCStreamer &Streamer,
  Streamer.EmitAssignment(Symbol, MCConstantExpr::create(Val, *this));
}

void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {
  InlineAsmUsedLabelNames[Sym->getName()] = Sym;
}

//===----------------------------------------------------------------------===//
// Section Management
//===----------------------------------------------------------------------===//
+3 −1
Original line number Diff line number Diff line
@@ -1142,7 +1142,9 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
      }
    }

    MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
    MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
    if (!Sym)
      Sym = getContext().getOrCreateSymbol(SymbolName);

    // If this is an absolute variable reference, substitute it now to preserve
    // semantics in the face of reassignment.
+63 −0
Original line number Diff line number Diff line
; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s

@X = common local_unnamed_addr global i32 0, align 4

define i32 @test1() {
; CHECK-LABEL: test1:
; CHECK:         .word b
; CHECK-NEXT:    .word .Ltmp0
; CHECK-LABEL: .Ltmp0:
; CHECK-LABEL: .LBB0_1: // %l_yes
; CHECK-LABEL: .LBB0_2: // %cleanup
entry:
  callbr void asm sideeffect "1:\0A\09.word b, ${0:l}\0A\09", "X"(i8* blockaddress(@test1, %l_yes))
          to label %cleanup [label %l_yes]

l_yes:
  br label %cleanup

cleanup:
  %retval.0 = phi i32 [ 1, %l_yes ], [ 0, %entry ]
  ret i32 %retval.0
}

define void @test2() {
; CHECK-LABEL: test2:
entry:
  %0 = load i32, i32* @X, align 4
  %and = and i32 %0, 1
  %tobool = icmp eq i32 %and, 0
  br i1 %tobool, label %if.end10, label %if.then

if.then:
; CHECK:       .word b
; CHECK-NEXT:  .word .Ltmp2
; CHECK-LABEL: .Ltmp2:
; CHECK-NEXT:  .LBB1_3: // %if.end6
  callbr void asm sideeffect "1:\0A\09.word b, ${0:l}\0A\09", "X"(i8* blockaddress(@test2, %if.end6))
          to label %if.then4 [label %if.end6]

if.then4:
  %call5 = tail call i32 bitcast (i32 (...)* @g to i32 ()*)()
  br label %if.end6

if.end6:
  %.pre = load i32, i32* @X, align 4
  %.pre13 = and i32 %.pre, 1
  %phitmp = icmp eq i32 %.pre13, 0
  br i1 %phitmp, label %if.end10, label %if.then9

if.then9:
; CHECK-LABEL: .Ltmp4:
; CHECK-NEXT:  .LBB1_5: // %l_yes
  callbr void asm sideeffect "", "X"(i8* blockaddress(@test2, %l_yes))
          to label %if.end10 [label %l_yes]

if.end10:
  br label %l_yes

l_yes:
  ret void
}

declare i32 @g(...)
Loading