xref: /llvm-project/llvm/test/CodeGen/PowerPC/mergeable-string-pool-tls.ll (revision 935bbbbde4b2661ed7f8f2975a39bda360572572)
1; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \
2; RUN:     -ppc-asm-full-reg-names < %s | FileCheck %s \
3; RUN:     --check-prefix=CHECK64
4; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \
5; RUN:     -ppc-asm-full-reg-names < %s | FileCheck %s \
6; RUN:     --check-prefix=CHECK32
7; RUN: llc -verify-machineinstrs -mtriple powerpc64le-unknown-linux \
8; RUN:     -ppc-asm-full-reg-names < %s | FileCheck %s \
9; RUN:     --check-prefix=LINUX64LE
10; RUN: llc -verify-machineinstrs -mtriple powerpc64-unknown-linux \
11; RUN:     -ppc-asm-full-reg-names < %s | FileCheck %s \
12; RUN:     --check-prefix=LINUX64BE
13
14@.str = private unnamed_addr constant [47 x i8] c"TLS variable 1, 2 and non-TLS var: %s, %s, %s\0A\00", align 1
15@a = internal thread_local constant [5 x i8] c"tls1\00", align 1
16@b = internal thread_local constant [5 x i8] c"tls2\00", align 1
17@c = internal constant [15 x i8] c"Regular global\00", align 1
18@d = internal constant [10 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10], align 4
19@e = internal constant [4 x float] [float 0x4055F33340000000, float 0x4056333340000000, float 0x40567999A0000000, float 0x4056B33340000000], align 4
20
21declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #0
22declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1
23declare void @callee(ptr noundef) local_unnamed_addr #3
24declare void @callee2(ptr noundef) local_unnamed_addr #3
25
26define void @print_tls_func() {
27; CHECK64-LABEL: print_tls_func:
28; CHECK64:       # %bb.0: # %entry
29; CHECK64-NEXT:    mflr r0
30; CHECK64-NEXT:    stdu r1, -112(r1)
31; CHECK64-NEXT:    ld r3, L..C0(r2) # target-flags(ppc-tlsldm) @"_$TLSML"
32; CHECK64-NEXT:    std r0, 128(r1)
33; CHECK64-NEXT:    ld r6, L..C1(r2) # @_MergedGlobals
34; CHECK64-NEXT:    bla .__tls_get_mod[PR]
35; CHECK64-NEXT:    ld r4, L..C2(r2) # target-flags(ppc-tlsld) @a
36; CHECK64-NEXT:    ld r5, L..C3(r2) # target-flags(ppc-tlsld) @b
37; CHECK64-NEXT:    add r4, r3, r4
38; CHECK64-NEXT:    add r5, r3, r5
39; CHECK64-NEXT:    addi r3, r6, 72
40; CHECK64-NEXT:    bl .printf[PR]
41; CHECK64-NEXT:    nop
42; CHECK64-NEXT:    addi r1, r1, 112
43; CHECK64-NEXT:    ld r0, 16(r1)
44; CHECK64-NEXT:    mtlr r0
45; CHECK64-NEXT:    blr
46;
47; CHECK32-LABEL: print_tls_func:
48; CHECK32:       # %bb.0: # %entry
49; CHECK32-NEXT:    mflr r0
50; CHECK32-NEXT:    stwu r1, -64(r1)
51; CHECK32-NEXT:    lwz r3, L..C0(r2) # target-flags(ppc-tlsldm) @"_$TLSML"
52; CHECK32-NEXT:    stw r0, 72(r1)
53; CHECK32-NEXT:    lwz r6, L..C1(r2) # @_MergedGlobals
54; CHECK32-NEXT:    bla .__tls_get_mod[PR]
55; CHECK32-NEXT:    lwz r4, L..C2(r2) # target-flags(ppc-tlsld) @a
56; CHECK32-NEXT:    lwz r5, L..C3(r2) # target-flags(ppc-tlsld) @b
57; CHECK32-NEXT:    add r4, r3, r4
58; CHECK32-NEXT:    add r5, r3, r5
59; CHECK32-NEXT:    addi r3, r6, 72
60; CHECK32-NEXT:    bl .printf[PR]
61; CHECK32-NEXT:    nop
62; CHECK32-NEXT:    addi r1, r1, 64
63; CHECK32-NEXT:    lwz r0, 8(r1)
64; CHECK32-NEXT:    mtlr r0
65; CHECK32-NEXT:    blr
66;
67; LINUX64LE-LABEL: print_tls_func:
68; LINUX64LE:       # %bb.0: # %entry
69; LINUX64LE-NEXT:    mflr r0
70; LINUX64LE-NEXT:    stdu r1, -96(r1)
71; LINUX64LE-NEXT:    std r0, 112(r1)
72; LINUX64LE-NEXT:    .cfi_def_cfa_offset 96
73; LINUX64LE-NEXT:    .cfi_offset lr, 16
74; LINUX64LE-NEXT:    addis r3, r13, a@tprel@ha
75; LINUX64LE-NEXT:    addi r4, r3, a@tprel@l
76; LINUX64LE-NEXT:    addis r3, r13, b@tprel@ha
77; LINUX64LE-NEXT:    addi r5, r3, b@tprel@l
78; LINUX64LE-NEXT:    addis r3, r2, .L_MergedGlobals@toc@ha
79; LINUX64LE-NEXT:    addi r6, r3, .L_MergedGlobals@toc@l
80; LINUX64LE-NEXT:    addi r3, r6, 72
81; LINUX64LE-NEXT:    bl printf
82; LINUX64LE-NEXT:    nop
83; LINUX64LE-NEXT:    addi r1, r1, 96
84; LINUX64LE-NEXT:    ld r0, 16(r1)
85; LINUX64LE-NEXT:    mtlr r0
86; LINUX64LE-NEXT:    blr
87;
88; LINUX64BE-LABEL: print_tls_func:
89; LINUX64BE:       # %bb.0: # %entry
90; LINUX64BE-NEXT:    mflr r0
91; LINUX64BE-NEXT:    stdu r1, -128(r1)
92; LINUX64BE-NEXT:    std r0, 144(r1)
93; LINUX64BE-NEXT:    .cfi_def_cfa_offset 128
94; LINUX64BE-NEXT:    .cfi_offset lr, 16
95; LINUX64BE-NEXT:    .cfi_offset r30, -16
96; LINUX64BE-NEXT:    addis r3, r2, a@got@tlsld@ha
97; LINUX64BE-NEXT:    std r30, 112(r1) # 8-byte Folded Spill
98; LINUX64BE-NEXT:    addi r3, r3, a@got@tlsld@l
99; LINUX64BE-NEXT:    bl __tls_get_addr(a@tlsld)
100; LINUX64BE-NEXT:    nop
101; LINUX64BE-NEXT:    addis r4, r2, b@got@tlsld@ha
102; LINUX64BE-NEXT:    addis r3, r3, a@dtprel@ha
103; LINUX64BE-NEXT:    addi r30, r3, a@dtprel@l
104; LINUX64BE-NEXT:    addi r3, r4, b@got@tlsld@l
105; LINUX64BE-NEXT:    bl __tls_get_addr(b@tlsld)
106; LINUX64BE-NEXT:    nop
107; LINUX64BE-NEXT:    addis r3, r3, b@dtprel@ha
108; LINUX64BE-NEXT:    mr r4, r30
109; LINUX64BE-NEXT:    addi r5, r3, b@dtprel@l
110; LINUX64BE-NEXT:    addis r3, r2, .L_MergedGlobals@toc@ha
111; LINUX64BE-NEXT:    addi r6, r3, .L_MergedGlobals@toc@l
112; LINUX64BE-NEXT:    addi r3, r6, 72
113; LINUX64BE-NEXT:    bl printf
114; LINUX64BE-NEXT:    nop
115; LINUX64BE-NEXT:    ld r30, 112(r1) # 8-byte Folded Reload
116; LINUX64BE-NEXT:    addi r1, r1, 128
117; LINUX64BE-NEXT:    ld r0, 16(r1)
118; LINUX64BE-NEXT:    mtlr r0
119; LINUX64BE-NEXT:    blr
120entry:
121  %0 = tail call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @a)
122  %1 = tail call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @b)
123  %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, ptr noundef nonnull %0, ptr noundef nonnull %1, ptr noundef nonnull @c)
124  ret void
125}
126
127define void @test_func() {
128; CHECK64-LABEL: test_func:
129; CHECK64:       # %bb.0: # %entry
130; CHECK64-NEXT:    mflr r0
131; CHECK64-NEXT:    stdu r1, -112(r1)
132; CHECK64-NEXT:    ld r3, L..C1(r2) # @_MergedGlobals
133; CHECK64-NEXT:    std r0, 128(r1)
134; CHECK64-NEXT:    addi r3, r3, 32
135; CHECK64-NEXT:    bl .callee[PR]
136; CHECK64-NEXT:    nop
137; CHECK64-NEXT:    addi r1, r1, 112
138; CHECK64-NEXT:    ld r0, 16(r1)
139; CHECK64-NEXT:    mtlr r0
140; CHECK64-NEXT:    blr
141;
142; CHECK32-LABEL: test_func:
143; CHECK32:       # %bb.0: # %entry
144; CHECK32-NEXT:    mflr r0
145; CHECK32-NEXT:    stwu r1, -64(r1)
146; CHECK32-NEXT:    lwz r3, L..C1(r2) # @_MergedGlobals
147; CHECK32-NEXT:    stw r0, 72(r1)
148; CHECK32-NEXT:    addi r3, r3, 32
149; CHECK32-NEXT:    bl .callee[PR]
150; CHECK32-NEXT:    nop
151; CHECK32-NEXT:    addi r1, r1, 64
152; CHECK32-NEXT:    lwz r0, 8(r1)
153; CHECK32-NEXT:    mtlr r0
154; CHECK32-NEXT:    blr
155
156; LINUX64LE-LABEL: test_func:
157; LINUX64LE:       # %bb.0: # %entry
158; LINUX64LE-NEXT:    mflr r0
159; LINUX64LE-NEXT:    stdu r1, -32(r1)
160; LINUX64LE-NEXT:    std r0, 48(r1)
161; LINUX64LE-NEXT:    .cfi_def_cfa_offset 32
162; LINUX64LE-NEXT:    .cfi_offset lr, 16
163; LINUX64LE-NEXT:    addis r3, r2, .L_MergedGlobals@toc@ha
164; LINUX64LE-NEXT:    addi r3, r3, .L_MergedGlobals@toc@l
165; LINUX64LE-NEXT:    addi r3, r3, 32
166; LINUX64LE-NEXT:    bl callee
167; LINUX64LE-NEXT:    nop
168; LINUX64LE-NEXT:    addi r1, r1, 32
169; LINUX64LE-NEXT:    ld r0, 16(r1)
170; LINUX64LE-NEXT:    mtlr r0
171; LINUX64LE-NEXT:    blr
172;
173; LINUX64BE-LABEL: test_func:
174; LINUX64BE:       # %bb.0: # %entry
175; LINUX64BE-NEXT:    mflr r0
176; LINUX64BE-NEXT:    stdu r1, -112(r1)
177; LINUX64BE-NEXT:    std r0, 128(r1)
178; LINUX64BE-NEXT:    .cfi_def_cfa_offset 112
179; LINUX64BE-NEXT:    .cfi_offset lr, 16
180; LINUX64BE-NEXT:    addis r3, r2, .L_MergedGlobals@toc@ha
181; LINUX64BE-NEXT:    addi r3, r3, .L_MergedGlobals@toc@l
182; LINUX64BE-NEXT:    addi r3, r3, 32
183; LINUX64BE-NEXT:    bl callee
184; LINUX64BE-NEXT:    nop
185; LINUX64BE-NEXT:    addi r1, r1, 112
186; LINUX64BE-NEXT:    ld r0, 16(r1)
187; LINUX64BE-NEXT:    mtlr r0
188; LINUX64BE-NEXT:    blr
189entry:
190  tail call void @callee(ptr noundef nonnull @d) #4
191  ret void
192}
193
194define void @test_func2() {
195; CHECK64-LABEL: test_func2:
196; CHECK64:       # %bb.0: # %entry
197; CHECK64-NEXT:    mflr r0
198; CHECK64-NEXT:    stdu r1, -112(r1)
199; CHECK64-NEXT:    ld r3, L..C1(r2) # @_MergedGlobals
200; CHECK64-NEXT:    std r0, 128(r1)
201; CHECK64-NEXT:    addi r3, r3, 16
202; CHECK64-NEXT:    bl .callee2[PR]
203; CHECK64-NEXT:    nop
204; CHECK64-NEXT:    addi r1, r1, 112
205; CHECK64-NEXT:    ld r0, 16(r1)
206; CHECK64-NEXT:    mtlr r0
207; CHECK64-NEXT:    blr
208;
209; CHECK32-LABEL: test_func2:
210; CHECK32:       # %bb.0: # %entry
211; CHECK32-NEXT:    mflr r0
212; CHECK32-NEXT:    stwu r1, -64(r1)
213; CHECK32-NEXT:    lwz r3, L..C1(r2) # @_MergedGlobals
214; CHECK32-NEXT:    stw r0, 72(r1)
215; CHECK32-NEXT:    addi r3, r3, 16
216; CHECK32-NEXT:    bl .callee2[PR]
217; CHECK32-NEXT:    nop
218; CHECK32-NEXT:    addi r1, r1, 64
219; CHECK32-NEXT:    lwz r0, 8(r1)
220; CHECK32-NEXT:    mtlr r0
221; CHECK32-NEXT:    blr
222;
223; LINUX64LE-LABEL: test_func2:
224; LINUX64LE:       # %bb.0: # %entry
225; LINUX64LE-NEXT:    mflr r0
226; LINUX64LE-NEXT:    stdu r1, -32(r1)
227; LINUX64LE-NEXT:    std r0, 48(r1)
228; LINUX64LE-NEXT:    .cfi_def_cfa_offset 32
229; LINUX64LE-NEXT:    .cfi_offset lr, 16
230; LINUX64LE-NEXT:    addis r3, r2, .L_MergedGlobals@toc@ha
231; LINUX64LE-NEXT:    addi r3, r3, .L_MergedGlobals@toc@l
232; LINUX64LE-NEXT:    addi r3, r3, 16
233; LINUX64LE-NEXT:    bl callee2
234; LINUX64LE-NEXT:    nop
235; LINUX64LE-NEXT:    addi r1, r1, 32
236; LINUX64LE-NEXT:    ld r0, 16(r1)
237; LINUX64LE-NEXT:    mtlr r0
238; LINUX64LE-NEXT:    blr
239;
240; LINUX64BE-LABEL: test_func2:
241; LINUX64BE:       # %bb.0: # %entry
242; LINUX64BE-NEXT:    mflr r0
243; LINUX64BE-NEXT:    stdu r1, -112(r1)
244; LINUX64BE-NEXT:    std r0, 128(r1)
245; LINUX64BE-NEXT:    .cfi_def_cfa_offset 112
246; LINUX64BE-NEXT:    .cfi_offset lr, 16
247; LINUX64BE-NEXT:    addis r3, r2, .L_MergedGlobals@toc@ha
248; LINUX64BE-NEXT:    addi r3, r3, .L_MergedGlobals@toc@l
249; LINUX64BE-NEXT:    addi r3, r3, 16
250; LINUX64BE-NEXT:    bl callee2
251; LINUX64BE-NEXT:    nop
252; LINUX64BE-NEXT:    addi r1, r1, 112
253; LINUX64BE-NEXT:    ld r0, 16(r1)
254; LINUX64BE-NEXT:    mtlr r0
255; LINUX64BE-NEXT:    blr
256entry:
257  tail call void @callee2(ptr noundef nonnull @e) #4
258  ret void
259}
260
261; Check the contents of the TLS data and the _MergedGlobals structure to
262; check that TLS data has been skipped during global merge.
263
264; CHECK64: 	.csect a[TL],2
265; CHECK64-NEXT:	.lglobl	a[TL]
266; CHECK64-NEXT:	.string	"tls1"
267; CHECK64:	.csect b[TL],2
268; CHECK64-NEXT:	.lglobl	b[TL]
269; CHECK64-NEXT:	.string	"tls2"
270; CHECK64:	.csect L.._MergedGlobals[RO],2
271; CHECK64:	.align	2
272; CHECK64-LABEL: c:
273; CHECK64:	.string	"Regular global"
274; CHECK64-LABEL: e:
275; CHECK64:	.vbyte	4, 0x42af999a
276; CHECK64-NEXT:	.vbyte	4, 0x42b1999a
277; CHECK64-NEXT:	.vbyte	4, 0x42b3cccd
278; CHECK64-NEXT:	.vbyte	4, 0x42b5999a
279; CHECK64-LABEL: d:
280; CHECK64:	.vbyte	4, 1
281; CHECK64-NEXT:	.vbyte	4, 2
282; CHECK64-NEXT:	.vbyte	4, 3
283; CHECK64-NEXT:	.vbyte	4, 4
284; CHECK64-NEXT:	.vbyte	4, 5
285; CHECK64-NEXT:	.vbyte	4, 6
286; CHECK64-NEXT:	.vbyte	4, 7
287; CHECK64-NEXT:	.vbyte	4, 8
288; CHECK64-NEXT:	.vbyte	4, 9
289; CHECK64-NEXT:	.vbyte	4, 10
290; CHECK64-LABEL: L...str
291; CHECK64:	.byte	'T,'L,'S,' ,'v,'a,'r,'i,'a,'b,'l,'e,' ,'1,',,' ,'2,' ,'a,'n,'d,' ,'n,'o,'n,'-,'T,'L,'S,' ,'v,'a,'r,':,' ,'%,'s,',,' ,'%,'s,',,' ,'%,'s,0012,0000
292; CHECK64: L..C1:
293; CHECK64-NEXT: .tc L.._MergedGlobals[TC],L.._MergedGlobals[RO]
294; CHECK64: L..C2:
295; CHECK64-NEXT:	.tc a[TC],a[TL]@ld
296; CHECK64: L..C3:
297; CHECK64-NEXT:	.tc b[TC],b[TL]@ld
298
299; CHECK32: 	.csect a[TL],2
300; CHECK32-NEXT:	.lglobl	a[TL]
301; CHECK32-NEXT:	.string	"tls1"
302; CHECK32:	.csect b[TL],2
303; CHECK32-NEXT:	.lglobl	b[TL]
304; CHECK32-NEXT:	.string	"tls2"
305; CHECK32:	.csect L.._MergedGlobals[RO],2
306; CHECK32:	.align	2
307; CHECK32-LABEL: c:
308; CHECK32:	.string "Regular global"
309; CHECK32-LABEL: e:
310; CHECK32:	.vbyte	4, 0x42af999a
311; CHECK32-NEXT:	.vbyte	4, 0x42b1999a
312; CHECK32-NEXT:	.vbyte	4, 0x42b3cccd
313; CHECK32-NEXT:	.vbyte	4, 0x42b5999a
314; CHECK32-LABEL: d:
315; CHECK32:	.vbyte	4, 1
316; CHECK32-NEXT:	.vbyte	4, 2
317; CHECK32-NEXT:	.vbyte	4, 3
318; CHECK32-NEXT:	.vbyte	4, 4
319; CHECK32-NEXT:	.vbyte	4, 5
320; CHECK32-NEXT:	.vbyte	4, 6
321; CHECK32-NEXT:	.vbyte	4, 7
322; CHECK32-NEXT:	.vbyte	4, 8
323; CHECK32-NEXT:	.vbyte	4, 9
324; CHECK32-NEXT:	.vbyte	4, 10
325; CHECK32-LABEL: L...str:
326; CHECK32:	.byte	'T,'L,'S,' ,'v,'a,'r,'i,'a,'b,'l,'e,' ,'1,',,' ,'2,' ,'a,'n,'d,' ,'n,'o,'n,'-,'T,'L,'S,' ,'v,'a,'r,':,' ,'%,'s,',,' ,'%,'s,',,' ,'%,'s,0012,0000
327; CHECK32: L..C1:
328; CHECK32-NEXT: .tc L.._MergedGlobals[TC],L.._MergedGlobals[RO]
329; CHECK32: L..C2:
330; CHECK32-NEXT:	.tc a[TC],a[TL]@ld
331; CHECK32: L..C3:
332; CHECK32-NEXT:	.tc b[TC],b[TL]@ld
333
334; LINUX64LE: a:
335; LINUX64LE-NEXT:       .asciz  "tls1"
336; LINUX64LE-NEXT:       .size   a, 5
337; LINUX64LE: b:
338; LINUX64LE-NEXT:       .asciz  "tls2"
339; LINUX64LE-NEXT:       .size   b, 5
340; LINUX64LE: .L_MergedGlobals:
341; LINUX64LE-NEXT:       .asciz  "Regular global"
342; LINUX64LE-NEXT:       .space  1
343; LINUX64LE-NEXT:       .long   0x42af999a
344; LINUX64LE-NEXT:       .long   0x42b1999a
345; LINUX64LE-NEXT:       .long   0x42b3cccd
346; LINUX64LE-NEXT:       .long   0x42b5999a
347; LINUX64LE-NEXT:       .long   1
348; LINUX64LE-NEXT:       .long   2
349; LINUX64LE-NEXT:       .long   3
350; LINUX64LE-NEXT:       .long   4
351; LINUX64LE-NEXT:       .long   5
352; LINUX64LE-NEXT:       .long   6
353; LINUX64LE-NEXT:       .long   7
354; LINUX64LE-NEXT:       .long   8
355; LINUX64LE-NEXT:       .long   9
356; LINUX64LE-NEXT:       .long   10
357; LINUX64LE-NEXT:       .asciz  "TLS variable 1, 2 and non-TLS var: %s, %s, %s\n"
358
359; LINUX64BE: a:
360; LINUX64BE-NEXT:       .asciz  "tls1"
361; LINUX64BE-NEXT:       .size   a, 5
362; LINUX64BE: b:
363; LINUX64BE-NEXT:       .asciz  "tls2"
364; LINUX64BE-NEXT:       .size   b, 5
365; LINUX64BE: .L_MergedGlobals:
366; LINUX64BE-NEXT:       .asciz  "Regular global"
367; LINUX64BE-NEXT:       .space  1
368; LINUX64BE-NEXT:       .long   0x42af999a
369; LINUX64BE-NEXT:       .long   0x42b1999a
370; LINUX64BE-NEXT:       .long   0x42b3cccd
371; LINUX64BE-NEXT:       .long   0x42b5999a
372; LINUX64BE-NEXT:       .long   1
373; LINUX64BE-NEXT:       .long   2
374; LINUX64BE-NEXT:       .long   3
375; LINUX64BE-NEXT:       .long   4
376; LINUX64BE-NEXT:       .long   5
377; LINUX64BE-NEXT:       .long   6
378; LINUX64BE-NEXT:       .long   7
379; LINUX64BE-NEXT:       .long   8
380; LINUX64BE-NEXT:       .long   9
381; LINUX64BE-NEXT:       .long   10
382; LINUX64BE-NEXT:       .asciz  "TLS variable 1, 2 and non-TLS var: %s, %s, %s\n"
383