forked from OSchip/llvm-project
141 lines
5.1 KiB
LLVM
141 lines
5.1 KiB
LLVM
; Test that global values with the same specified section produces multiple
|
|
; sections with different sets of flags, depending on the properties (mutable,
|
|
; executable) of the global value.
|
|
|
|
; RUN: llc < %s | FileCheck %s
|
|
; RUN: llc -function-sections < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FNSECTIONS
|
|
target triple="x86_64-unknown-unknown-elf"
|
|
|
|
; Normal function goes in .text, or in it's own named section with -function-sections.
|
|
define i32 @fn_text() {
|
|
entry:
|
|
ret i32 0
|
|
}
|
|
; CHECK: .text{{$}}
|
|
; CHECK-NEXT: .file
|
|
; FNSECTIONS: .section .text.fn_text,"ax",@progbits{{$}}
|
|
; CHECK-NEXT: .globl fn_text
|
|
; CHECK: fn_text:
|
|
|
|
; A second function placed in .text, to check the behaviour with -function-sections.
|
|
; It should be emitted to a new section with a new name, not expected to require unique.
|
|
define i32 @fn_text2() {
|
|
entry:
|
|
ret i32 0
|
|
}
|
|
; FNSECTIONS: .section .text.fn_text2,"ax",@progbits{{$}}
|
|
; CHECK: .globl fn_text2
|
|
; CHECK: fn_text2:
|
|
|
|
; Functions in user defined executable sections
|
|
define i32 @fn_s1() section "s1" {
|
|
entry:
|
|
ret i32 0
|
|
}
|
|
; CHECK: .section s1,"ax",@progbits{{$}}
|
|
; CHECK-NEXT: .globl fn_s1
|
|
; CHECK: fn_s1:
|
|
|
|
define i32 @fn_s2() section "s2" {
|
|
entry:
|
|
ret i32 0
|
|
}
|
|
; CHECK: .section s2,"ax",@progbits{{$}}
|
|
; CHECK-NEXT: .globl fn_s2
|
|
; CHECK: fn_s2:
|
|
|
|
; A second function in s2 should share the same .section
|
|
define i32 @fn2_s2() section "s2" {
|
|
entry:
|
|
ret i32 0
|
|
}
|
|
; CHECK-NOT: .section
|
|
; CHECK: .globl fn2_s2
|
|
; CHECK: fn2_s2:
|
|
|
|
; Values that share a section name with a function are placed in different sections without executable flag
|
|
@rw_s1 = global i32 10, section "s1", align 4
|
|
@ro_s2 = constant i32 10, section "s2", align 4
|
|
; CHECK: .section s1,"aw",@progbits,unique,[[#UNIQUE_S1_aw:]]
|
|
; CHECK-NEXT: .globl rw_s1
|
|
; CHECK: rw_s1:
|
|
; CHECK: .section s2,"a",@progbits,unique,[[#UNIQUE_S2_a:]]
|
|
; CHECK-NEXT: .globl ro_s2
|
|
; CHECK: ro_s2:
|
|
|
|
; Placing another value in the same section with the same flags uses the same unique ID
|
|
@rw2_s1 = global i32 10, section "s1", align 4
|
|
@ro2_s2 = constant i32 10, section "s2", align 4
|
|
; CHECK: .section s1,"aw",@progbits,unique,[[#UNIQUE_S1_aw]]
|
|
; CHECK-NEXT: .globl rw2_s1
|
|
; CHECK: rw2_s1:
|
|
; CHECK: .section s2,"a",@progbits,unique,[[#UNIQUE_S2_a]]
|
|
; CHECK-NEXT: .globl ro2_s2
|
|
; CHECK: ro2_s2:
|
|
|
|
; Normal user defined section, first is the generic section, second should be unique
|
|
@ro_s3 = constant i32 10, section "s3", align 4
|
|
@rw_s3 = global i32 10, section "s3", align 4
|
|
; CHECK: .section s3,"a",@progbits{{$}}
|
|
; CHECK-NEXT: .globl ro_s3
|
|
; CHECK: ro_s3:
|
|
; CHECK: .section s3,"aw",@progbits,unique,[[#U:]]
|
|
; CHECK-NEXT: .globl rw_s3
|
|
; CHECK: rw_s3:
|
|
|
|
; Values declared without explicit sections go into compatible default sections and don't require unique
|
|
@rw_nosec = global i32 10, align 4
|
|
@ro_nosec = constant i32 10, align 4
|
|
; CHECK: .data{{$}}
|
|
; CHECK-NEXT: .globl rw_nosec
|
|
; CHECK: rw_nosec:
|
|
; CHECK: .section .rodata,"a",@progbits{{$}}
|
|
; CHECK-NEXT: .globl ro_nosec
|
|
; CHECK: ro_nosec:
|
|
|
|
; Explicitly placed in .rodata with writeable set. The writable section should be uniqued, not the default ro section, even if it comes first.
|
|
@rw_rodata = global [2 x i32] zeroinitializer, section ".rodata", align 4
|
|
@ro_rodata = constant [2 x i32] zeroinitializer, section ".rodata", align 4
|
|
; CHECK: .section .rodata,"aw",@progbits,unique,[[#U+1]]{{$}}
|
|
; CHECK-NEXT: .globl rw_rodata{{$}}
|
|
; CHECK: rw_rodata:
|
|
; CHECK: .section .rodata,"a",@progbits{{$}}
|
|
; CHECK-NEXT: .globl ro_rodata{{$}}
|
|
; CHECK: ro_rodata:
|
|
|
|
; Writable symbols in writable default sections; no need to unique
|
|
@w_sdata = global [4 x i32] zeroinitializer, section ".sdata", align 4
|
|
@w_sbss = global [4 x i32] zeroinitializer, section ".sbss", align 4
|
|
; CHECK: .section .sdata,"aw",@progbits{{$}}
|
|
; CHECK-NEXT: .globl w_sdata{{$}}
|
|
; CHECK: w_sdata:
|
|
; CHECK: .section .sbss,"aw",@nobits{{$}}
|
|
; CHECK-NEXT: .globl w_sbss{{$}}
|
|
; CHECK: w_sbss:
|
|
|
|
; Multiple .text sections are emitted for read-only and read-write sections using .text name.
|
|
@rw_text = global i32 10, section ".text", align 4
|
|
@ro_text = constant i32 10, section ".text", align 4
|
|
; CHECK: .section .text,"aw",@progbits,unique,[[#U+2]]
|
|
; CHECK-NEXT: .globl rw_text
|
|
; CHECK: rw_text:
|
|
; CHECK: .section .text,"a",@progbits,unique,[[#U+3]]
|
|
; CHECK-NEXT: .globl ro_text
|
|
; CHECK: ro_text:
|
|
|
|
; A read-only .data section is emitted
|
|
@ro_data = constant i32 10, section ".data", align 4
|
|
; CHECK: .section .data,"a",@progbits,unique,[[#U+4]]
|
|
; CHECK-NEXT: .globl ro_data
|
|
; CHECK: ro_data:
|
|
|
|
; TLS and non-TLS symbols cannot live in the same section
|
|
@tls_var = thread_local global i32 10, section "s4", align 4
|
|
@non_tls_var = global i32 10, section "s4", align 4
|
|
; CHECK: .section s4,"awT",@progbits{{$}}
|
|
; CHECK-NEXT: .globl tls_var
|
|
; CHECK: tls_var:
|
|
; CHECK: .section s4,"aw",@progbits,unique,[[#U+5]]
|
|
; CHECK-NEXT: .globl non_tls_var
|
|
; CHECK: non_tls_var:
|