[llvm] 0483b00 - Mark the $local function begin symbol as a function

Alex Richardson via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 26 02:34:34 PDT 2022


Author: Alex Richardson
Date: 2022-08-26T09:34:04Z
New Revision: 0483b008759b566984f040269b7a90210922a145

URL: https://github.com/llvm/llvm-project/commit/0483b008759b566984f040269b7a90210922a145
DIFF: https://github.com/llvm/llvm-project/commit/0483b008759b566984f040269b7a90210922a145.diff

LOG: Mark the $local function begin symbol as a function

While this does not matter for most targets, when building for Arm Morello,
we have to mark the symbol as a function and add size information, so that
LLD can correctly evaluate relocations against the local symbol.
Since Morello is an out-of-tree target, I tried to reproduce this with
in-tree backends and with the previous reviews applied this results in
a noticeable difference when targeting Thumb.

Background: Morello uses a method similar Thumb where the encoding mode is
specified in the LSB of the symbol. If we don't mark the target as a
function, the relocation will not have the LSB set and calls will end up
using the wrong encoding mode (which will almost certainly crash).

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D131429

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/AsmPrinter.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/test/CodeGen/AArch64/elf-preemption.ll
    llvm/test/CodeGen/AArch64/semantic-interposition-asm.ll
    llvm/test/CodeGen/ARM/dso-local-func.ll
    llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.generated.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.generated.expected
    llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.nogenerated.expected
    llvm/utils/UpdateTestChecks/asm.py

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index d5b844b706b2f..989cb715df23b 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -194,6 +194,9 @@ class AsmPrinter : public MachineFunctionPass {
 protected:
   MCSymbol *CurrentFnBegin = nullptr;
 
+  /// For dso_local functions, the current $local alias for the function.
+  MCSymbol *CurrentFnBeginLocal = nullptr;
+
   /// A vector of all debug/EH info emitters we should use. This vector
   /// maintains ownership of the emitters.
   std::vector<HandlerInfo> Handlers;

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index c335577df4b5a..ea9399c07eb08 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1042,8 +1042,13 @@ void AsmPrinter::emitFunctionEntryLabel() {
 
   if (TM.getTargetTriple().isOSBinFormatELF()) {
     MCSymbol *Sym = getSymbolPreferLocal(MF->getFunction());
-    if (Sym != CurrentFnSym)
+    if (Sym != CurrentFnSym) {
+      cast<MCSymbolELF>(Sym)->setType(ELF::STT_FUNC);
+      CurrentFnBeginLocal = Sym;
       OutStreamer->emitLabel(Sym);
+      if (MAI->hasDotTypeDotSizeDirective())
+        OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
+    }
   }
 }
 
@@ -1709,6 +1714,8 @@ void AsmPrinter::emitFunctionBody() {
         MCSymbolRefExpr::create(CurrentFnEnd, OutContext),
         MCSymbolRefExpr::create(CurrentFnSymForSize, OutContext), OutContext);
     OutStreamer->emitELFSize(CurrentFnSym, SizeExp);
+    if (CurrentFnBeginLocal)
+      OutStreamer->emitELFSize(CurrentFnBeginLocal, SizeExp);
   }
 
   for (const HandlerInfo &HI : Handlers) {
@@ -2240,6 +2247,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
 
   CurrentFnSymForSize = CurrentFnSym;
   CurrentFnBegin = nullptr;
+  CurrentFnBeginLocal = nullptr;
   CurrentSectionBeginSym = nullptr;
   MBBSectionRanges.clear();
   MBBSectionExceptionSyms.clear();

diff  --git a/llvm/test/CodeGen/AArch64/elf-preemption.ll b/llvm/test/CodeGen/AArch64/elf-preemption.ll
index 7507837dc25c9..3b77f5b8e02a6 100644
--- a/llvm/test/CodeGen/AArch64/elf-preemption.ll
+++ b/llvm/test/CodeGen/AArch64/elf-preemption.ll
@@ -76,12 +76,18 @@ define dso_local void()* @dsolocal_func() nounwind {
 ;
 ; PIC-LABEL: dsolocal_func:
 ; PIC:       .Ldsolocal_func$local:
+; PIC-NEXT:    .type .Ldsolocal_func$local, at function
 ; PIC-NEXT:  // %bb.0:
 ; PIC-NEXT:    adrp x0, .Ldsolocal_func$local
 ; PIC-NEXT:    add x0, x0, :lo12:.Ldsolocal_func$local
 ; PIC-NEXT:    ret
   ret void()* bitcast(void()*()* @dsolocal_func to void()*)
 }
+; UTC-ARGS: --disable
+; PIC: [[END_LABEL:.Lfunc_end.+]]:
+; PIC-NEXT: .size	dsolocal_func, [[END_LABEL]]-dsolocal_func
+; PIC-NEXT: .size	.Ldsolocal_func$local, [[END_LABEL]]-dsolocal_func
+; UTC-ARGS: --enable
 
 define weak dso_local void()* @weak_dsolocal_func() nounwind {
 ; CHECK-LABEL: weak_dsolocal_func:
@@ -104,6 +110,7 @@ define dso_local void @call_dsolocal_func() nounwind {
 ;
 ; PIC-LABEL: call_dsolocal_func:
 ; PIC:       .Lcall_dsolocal_func$local:
+; PIC-NEXT:    .type .Lcall_dsolocal_func$local, at function
 ; PIC-NEXT:  // %bb.0:
 ; PIC-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
 ; PIC-NEXT:    bl .Ldsolocal_func$local
@@ -112,3 +119,8 @@ define dso_local void @call_dsolocal_func() nounwind {
   call void()* @dsolocal_func()
   ret void
 }
+; UTC-ARGS: --disable
+; PIC: [[END_LABEL:.Lfunc_end.+]]:
+; PIC-NEXT: .size	call_dsolocal_func, [[END_LABEL]]-call_dsolocal_func
+; PIC-NEXT: .size	.Lcall_dsolocal_func$local, [[END_LABEL]]-call_dsolocal_func
+; UTC-ARGS: --enable

diff  --git a/llvm/test/CodeGen/AArch64/semantic-interposition-asm.ll b/llvm/test/CodeGen/AArch64/semantic-interposition-asm.ll
index e09d16d16f13c..7c14664dc7715 100644
--- a/llvm/test/CodeGen/AArch64/semantic-interposition-asm.ll
+++ b/llvm/test/CodeGen/AArch64/semantic-interposition-asm.ll
@@ -25,6 +25,7 @@ entry:
 define dso_local void @fun0() nounwind {
 ; CHECK-LABEL: fun0:
 ; CHECK:       .Lfun0$local:
+; CHECK-NEXT:    .type .Lfun0$local, at function
 ; CHECK-NEXT:  // %bb.0: // %entry
 ; CHECK-NEXT:    ret
 entry:

diff  --git a/llvm/test/CodeGen/ARM/dso-local-func.ll b/llvm/test/CodeGen/ARM/dso-local-func.ll
index ae57bbe527cb3..6dfbe324f05fc 100644
--- a/llvm/test/CodeGen/ARM/dso-local-func.ll
+++ b/llvm/test/CodeGen/ARM/dso-local-func.ll
@@ -11,6 +11,7 @@ define dso_local ptr @dsolocal_func() nounwind {
 ; CHECK-NEXT: 	.code	32
 ; CHECK-NEXT: dsolocal_func:
 ; PIC-NEXT: .Ldsolocal_func$local:
+; PIC-NEXT: .type .Ldsolocal_func$local,%function
 ; CHECK-NEXT: 	.fnstart
 ; CHECK-NEXT: @ %bb.0:
 ; STATIC-NEXT: 	movw	r0, :lower16:dsolocal_func
@@ -26,6 +27,7 @@ define dso_local ptr @dsolocal_func() nounwind {
 ; PIC-NEXT:     .long	dsolocal_func-(.LPC0_0+8)
 ; CHECK-NEXT: .Lfunc_end0:
 ; CHECK-NEXT: 	.size	dsolocal_func, .Lfunc_end0-dsolocal_func
+; PIC-NEXT:     .size .Ldsolocal_func$local, .Lfunc_end0-dsolocal_func
 ; CHECK-NEXT: 	.cantunwind
 ; CHECK-NEXT: 	.fnend
   ret ptr @dsolocal_func

diff  --git a/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll b/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll
index 31f6ae2dc58cb..e5a980faa2c48 100644
--- a/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll
+++ b/llvm/test/CodeGen/ARM/thumb-function-section-reloc.ll
@@ -18,9 +18,8 @@
 ; RELOCS-NEXT:   }
 ; RELOCS-NEXT:   Section (7) .rel.text.test {
 ; RELOCS-NEXT:     0x4 R_ARM_CALL _ZdlPv
-; FIXME: these two relocation should not be against the section!
-; RELOCS-NEXT:     0xC R_ARM_ABS32 .text._ZdlPv
-; RELOCS-NEXT:     0x10 R_ARM_ABS32 .text._ZdlPv
+; RELOCS-NEXT:     0xC R_ARM_ABS32 .L_ZdlPv$local
+; RELOCS-NEXT:     0x10 R_ARM_ABS32 .L_ZdlPv$local
 ; RELOCS-NEXT:     0x1C R_ARM_REL32 _ZdlPv
 ; RELOCS-NEXT:   }
 ; RELOCS-NEXT:   Section (9) .rel.ARM.exidx.text.test {
@@ -32,17 +31,15 @@
 ; RELOCS-NEXT: ]
 
 ; RELOCS-LABEL: Symbols [
-; RELOCS: Symbol {
-; FIXME: we should include the symbol in the symbol table!
-; RELOCS-NOT:    Name: .L_ZdlPv$local
-; RELOCS-TODO:   Name: .L_ZdlPv$local
-; RELOCS-TODO:   Value: 0x1
-; RELOCS-TODO:   Size: 2
-; RELOCS-TODO:   Binding: Local (0x0)
-; RELOCS-TODO:   Type: Function (0x2)
-; RELOCS-TODO:   Other: 0
-; RELOCS-TODO:   Section: .text._ZdlPv (
-; RELOCS-TODO: }
+; RELOCS:      Symbol {
+; RELOCS:        Name: .L_ZdlPv$local
+; RELOCS-NEXT:   Value: 0x1
+; RELOCS-NEXT:   Size: 2
+; RELOCS-NEXT:   Binding: Local (0x0)
+; RELOCS-NEXT:   Type: Function (0x2)
+; RELOCS-NEXT:   Other: 0
+; RELOCS-NEXT:   Section: .text._ZdlPv (
+; RELOCS-NEXT: }
 
 define dso_local void @_ZdlPv(ptr %ptr) local_unnamed_addr nounwind "target-features"="+armv7-a,+thumb-mode" {
 ; CHECK-LABEL: 	.section	.text._ZdlPv,"ax",%progbits
@@ -53,11 +50,13 @@ define dso_local void @_ZdlPv(ptr %ptr) local_unnamed_addr nounwind "target-feat
 ; CHECK-NEXT: 	.thumb_func
 ; CHECK-NEXT: _ZdlPv:
 ; CHECK-NEXT: .L_ZdlPv$local:
+; CHECK-NEXT: .type .L_ZdlPv$local,%function
 ; CHECK-NEXT: 	.fnstart
 ; CHECK-NEXT: @ %bb.0:
 ; CHECK-NEXT: 	bx	lr
 ; CHECK-NEXT: .Lfunc_end0:
 ; CHECK-NEXT: 	.size	_ZdlPv, .Lfunc_end0-_ZdlPv
+; CHECK-NEXT: 	.size .L_ZdlPv$local, .Lfunc_end0-_ZdlPv
 ; CHECK-NEXT: 	.cantunwind
 ; CHECK-NEXT: 	.fnend
   ret void

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.generated.expected
index d8880ffec1dce..758ea1a3bdc48 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.generated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.generated.expected
@@ -66,6 +66,7 @@ define dso_local i32 @main() #0 {
 attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-LABEL: check_boundaries:
 ; CHECK:       check_boundaries$local:
+; CHECK-NEXT:    .type check_boundaries$local, at function
 ; CHECK-NEXT:  ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    s_mov_b32 s4, s33
@@ -76,6 +77,7 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ;
 ; CHECK-LABEL: main:
 ; CHECK:       main$local:
+; CHECK-NEXT:    .type main$local, at function
 ; CHECK-NEXT:  ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    s_mov_b32 s6, s33

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected
index be208f0606f7b..a8a36fd2328c2 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/amdgpu_generated_funcs.ll.nogenerated.expected
@@ -7,6 +7,7 @@
 define dso_local i32 @check_boundaries() #0 {
 ; CHECK-LABEL: check_boundaries:
 ; CHECK:       check_boundaries$local:
+; CHECK-NEXT:    .type check_boundaries$local, at function
 ; CHECK-NEXT:  ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    s_mov_b32 s4, s33
@@ -53,6 +54,7 @@ define dso_local i32 @check_boundaries() #0 {
 define dso_local i32 @main() #0 {
 ; CHECK-LABEL: main:
 ; CHECK:       main$local:
+; CHECK-NEXT:    .type main$local, at function
 ; CHECK-NEXT:  ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    s_mov_b32 s6, s33

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.generated.expected
index 36a9525c0c6f6..a41bc63a285b2 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.generated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.generated.expected
@@ -66,6 +66,7 @@ define dso_local i32 @main() #0 {
 attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ; CHECK-LABEL: check_boundaries:
 ; CHECK:       .Lcheck_boundaries$local:
+; CHECK-NEXT:    .type .Lcheck_boundaries$local, at function
 ; CHECK-NEXT:    .cfi_startproc
 ; CHECK-NEXT:  ! %bb.0:
 ; CHECK-NEXT:    st %fp, [--%sp]
@@ -113,6 +114,7 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
 ;
 ; CHECK-LABEL: main:
 ; CHECK:       .Lmain$local:
+; CHECK-NEXT:    .type .Lmain$local, at function
 ; CHECK-NEXT:    .cfi_startproc
 ; CHECK-NEXT:  ! %bb.0:
 ; CHECK-NEXT:    st %fp, [--%sp]

diff  --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.nogenerated.expected
index 93366097ceea5..35ebbf9984738 100644
--- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.nogenerated.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/lanai_generated_funcs.ll.nogenerated.expected
@@ -7,6 +7,7 @@
 define dso_local i32 @check_boundaries() #0 {
 ; CHECK-LABEL: check_boundaries:
 ; CHECK:       .Lcheck_boundaries$local:
+; CHECK-NEXT:    .type .Lcheck_boundaries$local, at function
 ; CHECK-NEXT:    .cfi_startproc
 ; CHECK-NEXT:  ! %bb.0:
 ; CHECK-NEXT:    st %fp, [--%sp]
@@ -90,6 +91,7 @@ define dso_local i32 @check_boundaries() #0 {
 define dso_local i32 @main() #0 {
 ; CHECK-LABEL: main:
 ; CHECK:       .Lmain$local:
+; CHECK-NEXT:    .type .Lmain$local, at function
 ; CHECK-NEXT:    .cfi_startproc
 ; CHECK-NEXT:  ! %bb.0:
 ; CHECK-NEXT:    st %fp, [--%sp]

diff  --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py
index db853ea4600ec..1366e10e92e26 100644
--- a/llvm/utils/UpdateTestChecks/asm.py
+++ b/llvm/utils/UpdateTestChecks/asm.py
@@ -16,7 +16,8 @@ class string:
 
 ASM_FUNCTION_X86_RE = re.compile(
     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*(@"?(?P=func)"?| -- Begin function (?P=func))\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?'
-    r'(?:\.L[^$]+\$local:\n)?'      # drop .L<func>$local:
+    r'(?:\.L(?P=func)\$local:\n)?'      # drop .L<func>$local:
+    r'(?:\s*\.type\s+\.L(?P=func)\$local, at function\n)?'  # drop .type .L<func>$local
     r'(?:[ \t]+.cfi_startproc\n|.seh_proc[^\n]+\n)?'  # drop optional cfi
     r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
     r'^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)',
@@ -25,6 +26,7 @@ class string:
 ASM_FUNCTION_ARM_RE = re.compile(
     r'^(?P<func>[0-9a-zA-Z_$]+):\n' # f: (name of function)
     r'(?:\.L(?P=func)\$local:\n)?'  # drop .L<func>$local:
+    r'(?:\s*\.type\s+\.L(?P=func)\$local, at function\n)?'  # drop .type .L<func>$local
     r'\s+\.fnstart\n' # .fnstart
     r'(?P<body>.*?)' # (body of the function)
     r'^.Lfunc_end[0-9]+:', # .Lfunc_end0: or # -- End function
@@ -95,6 +97,7 @@ class string:
 ASM_FUNCTION_RISCV_RE = re.compile(
     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
     r'(?:\s*\.?L(?P=func)\$local:\n)?'  # optional .L<func>$local: due to -fno-semantic-interposition
+    r'(?:\s*\.type\s+\.?L(?P=func)\$local, at function\n)?'  # optional .type .L<func>$local
     r'(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
     r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
     r'.Lfunc_end[0-9]+:\n',


        


More information about the llvm-commits mailing list