aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/CodeGen/X86/elf-unique-sections-by-flags.ll
blob: 01a113fdd9b2f5aa008e7992b802d6ba74ef13d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
; 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
}
; FNSECTIONS:   .section	.text.fn_text,"ax",@progbits{{$}}
; CHECK:        .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: