]> granicus.if.org Git - llvm/commitdiff
[MC] Don't recreate a label if it's already used
authorBill Wendling <isanbard@gmail.com>
Fri, 9 Aug 2019 20:16:31 +0000 (20:16 +0000)
committerBill Wendling <isanbard@gmail.com>
Fri, 9 Aug 2019 20:16:31 +0000 (20:16 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368477 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCContext.h
lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
lib/MC/MCContext.cpp
lib/MC/MCParser/AsmParser.cpp
test/CodeGen/AArch64/callbr-asm-label.ll [new file with mode: 0644]
test/CodeGen/X86/callbr-asm-label-addr.ll [new file with mode: 0644]
test/CodeGen/X86/callbr-asm.ll

index d5bbff5834d26c6cf875e3d96160f2cbd1ac12bc..69e3128e1944532784c4f1e955728ed6adb6a0b8 100644 (file)
@@ -113,6 +113,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;
@@ -382,6 +385,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
index 7721e996aca5a55333bc430a412322f867d1adea..5e49fec9c053ace90e985d94e6798756bf8d9386 100644 (file)
@@ -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);
index a030f5e4eb05a59c7a9052622b2016a3a3d145b5..6975ab3af532767e1d044e5f3e8c211fad350ba5 100644 (file)
@@ -61,6 +61,7 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
                      MCTargetOptions const *TargetOpts, 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), TargetOptions(TargetOpts) {
   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
 //===----------------------------------------------------------------------===//
index 27def715ca047faf7e3cd65f51d8bd2e915c0f7d..381bf96416166e69c266a7eb712633383d266f94 100644 (file)
@@ -1158,7 +1158,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.
diff --git a/test/CodeGen/AArch64/callbr-asm-label.ll b/test/CodeGen/AArch64/callbr-asm-label.ll
new file mode 100644 (file)
index 0000000..583587d
--- /dev/null
@@ -0,0 +1,63 @@
+; 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(...)
diff --git a/test/CodeGen/X86/callbr-asm-label-addr.ll b/test/CodeGen/X86/callbr-asm-label-addr.ll
new file mode 100644 (file)
index 0000000..dc0e836
--- /dev/null
@@ -0,0 +1,30 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+define i32 @test1(i32 %x) {
+; CHECK-LABEL: test1:
+; CHECK:         .quad .Ltmp0
+; CHECK-NEXT:    .quad .Ltmp1
+; CHECK-LABEL: .Ltmp1:
+; CHECK-LABEL: .LBB0_1: # %bar
+; CHECK-NEXT:    callq foo
+; CHECK-LABEL: .Ltmp0:
+; CHECK-NEXT:  # %bb.2: # %baz
+entry:
+  callbr void asm sideeffect ".quad ${0:l}\0A\09.quad ${1:l}", "i,X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@test1, %baz), i8* blockaddress(@test1, %bar))
+          to label %asm.fallthrough [label %bar]
+
+asm.fallthrough:
+  br label %bar
+
+bar:
+  %call = tail call i32 @foo(i32 %x)
+  br label %baz
+
+baz:
+  %call1 = tail call i32 @mux(i32 %call)
+  ret i32 %call1
+}
+
+declare i32 @foo(i32)
+
+declare i32 @mux(i32)
index 48a80ae167ba1b4833c42a845e4a1aa1d4b2ee29..ed3c314ed4241afaee169666577bd0c10c8df704 100644 (file)
@@ -12,7 +12,7 @@ define i32 @test1(i32 %a) {
 ; CHECK-NEXT:    addl $4, %eax
 ; CHECK-NEXT:    #APP
 ; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    jmp .Ltmp00
+; CHECK-NEXT:    jmp .Ltmp0
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:  .LBB0_1: # %normal
 ; CHECK-NEXT:    xorl %eax, %eax
@@ -87,17 +87,17 @@ define dso_local i32 @test3(i32 %a) {
 ; CHECK-NEXT:    # Parent Loop BB2_3 Depth=3
 ; CHECK-NEXT:    # => This Inner Loop Header: Depth=4
 ; CHECK-NEXT:    #APP
-; CHECK-NEXT:    jmp .Ltmp10
-; CHECK-NEXT:    jmp .Ltmp20
-; CHECK-NEXT:    jmp .Ltmp30
+; CHECK-NEXT:    jmp .Ltmp1
+; CHECK-NEXT:    jmp .Ltmp2
+; CHECK-NEXT:    jmp .Ltmp3
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:  .LBB2_5: # %normal0
 ; CHECK-NEXT:    # in Loop: Header=BB2_4 Depth=4
 ; CHECK-NEXT:    #APP
-; CHECK-NEXT:    jmp .Ltmp10
-; CHECK-NEXT:    jmp .Ltmp20
-; CHECK-NEXT:    jmp .Ltmp30
-; CHECK-NEXT:    jmp .Ltmp40
+; CHECK-NEXT:    jmp .Ltmp1
+; CHECK-NEXT:    jmp .Ltmp2
+; CHECK-NEXT:    jmp .Ltmp3
+; CHECK-NEXT:    jmp .Ltmp4
 ; CHECK-NEXT:    #NO_APP
 ; CHECK-NEXT:  .LBB2_6: # %normal1
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax