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