xref: /llvm-project/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-longlong.ll (revision 69b056d5638bbe3c8098b5d3a4980eb9929b9bbe)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2; RUN: llc  -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
3; RUN:      -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \
4; RUN:      --check-prefix=SMALL64
5; RUN: llc  -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
6; RUN:      -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \
7; RUN:      | FileCheck %s --check-prefix=LARGE64
8; RUN: llc  -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
9; RUN:      -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s \
10; RUN:      --check-prefix=SMALL32
11; RUN: llc  -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
12; RUN:      -mtriple powerpc-ibm-aix-xcoff --code-model=large < %s \
13; RUN:      | FileCheck %s --check-prefix=LARGE32
14
15@ThreadLocalVarInit = thread_local(localexec) global i64 1, align 8
16@VarInit = global i64 87, align 8
17@IThreadLocalVarUninit = internal thread_local(localexec) global i64 0, align 8
18@IThreadLocalVarInit = internal thread_local(localexec) global i64 1, align 8
19@ThreadLocalVarUninit = thread_local(localexec) global i64 0, align 8
20declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1
21
22define void @storeITLUninit(i64 noundef %x) {
23; SMALL64-LABEL: storeITLUninit:
24; SMALL64:       # %bb.0: # %entry
25; SMALL64-NEXT:    ld r4, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit
26; SMALL64-NEXT:    stdx r3, r13, r4
27; SMALL64-NEXT:    blr
28;
29; LARGE64-LABEL: storeITLUninit:
30; LARGE64:       # %bb.0: # %entry
31; LARGE64-NEXT:    addis r4, L..C0@u(r2)
32; LARGE64-NEXT:    ld r4, L..C0@l(r4)
33; LARGE64-NEXT:    stdx r3, r13, r4
34; LARGE64-NEXT:    blr
35;
36; SMALL32-LABEL: storeITLUninit:
37; SMALL32:       # %bb.0: # %entry
38; SMALL32-NEXT:    mflr r0
39; SMALL32-NEXT:    stwu r1, -32(r1)
40; SMALL32-NEXT:    lwz r6, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit
41; SMALL32-NEXT:    mr r5, r3
42; SMALL32-NEXT:    bla .__get_tpointer[PR]
43; SMALL32-NEXT:    stw r0, 40(r1)
44; SMALL32-NEXT:    add r3, r3, r6
45; SMALL32-NEXT:    stw r4, 4(r3)
46; SMALL32-NEXT:    stw r5, 0(r3)
47; SMALL32-NEXT:    addi r1, r1, 32
48; SMALL32-NEXT:    lwz r0, 8(r1)
49; SMALL32-NEXT:    mtlr r0
50; SMALL32-NEXT:    blr
51;
52; LARGE32-LABEL: storeITLUninit:
53; LARGE32:       # %bb.0: # %entry
54; LARGE32-NEXT:    mflr r0
55; LARGE32-NEXT:    stwu r1, -32(r1)
56; LARGE32-NEXT:    stw r0, 40(r1)
57; LARGE32-NEXT:    mr r5, r3
58; LARGE32-NEXT:    addis r3, L..C0@u(r2)
59; LARGE32-NEXT:    lwz r6, L..C0@l(r3)
60; LARGE32-NEXT:    bla .__get_tpointer[PR]
61; LARGE32-NEXT:    add r3, r3, r6
62; LARGE32-NEXT:    stw r4, 4(r3)
63; LARGE32-NEXT:    stw r5, 0(r3)
64; LARGE32-NEXT:    addi r1, r1, 32
65; LARGE32-NEXT:    lwz r0, 8(r1)
66; LARGE32-NEXT:    mtlr r0
67; LARGE32-NEXT:    blr
68entry:
69  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit)
70  store i64 %x, ptr %0, align 8
71  ret void
72}
73
74define void @storeITLInit(i64 noundef %x) {
75; SMALL64-LABEL: storeITLInit:
76; SMALL64:       # %bb.0: # %entry
77; SMALL64-NEXT:    ld r4, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit
78; SMALL64-NEXT:    stdx r3, r13, r4
79; SMALL64-NEXT:    blr
80;
81; LARGE64-LABEL: storeITLInit:
82; LARGE64:       # %bb.0: # %entry
83; LARGE64-NEXT:    addis r4, L..C1@u(r2)
84; LARGE64-NEXT:    ld r4, L..C1@l(r4)
85; LARGE64-NEXT:    stdx r3, r13, r4
86; LARGE64-NEXT:    blr
87;
88; SMALL32-LABEL: storeITLInit:
89; SMALL32:       # %bb.0: # %entry
90; SMALL32-NEXT:    mflr r0
91; SMALL32-NEXT:    stwu r1, -32(r1)
92; SMALL32-NEXT:    lwz r6, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit
93; SMALL32-NEXT:    mr r5, r3
94; SMALL32-NEXT:    bla .__get_tpointer[PR]
95; SMALL32-NEXT:    stw r0, 40(r1)
96; SMALL32-NEXT:    add r3, r3, r6
97; SMALL32-NEXT:    stw r4, 4(r3)
98; SMALL32-NEXT:    stw r5, 0(r3)
99; SMALL32-NEXT:    addi r1, r1, 32
100; SMALL32-NEXT:    lwz r0, 8(r1)
101; SMALL32-NEXT:    mtlr r0
102; SMALL32-NEXT:    blr
103;
104; LARGE32-LABEL: storeITLInit:
105; LARGE32:       # %bb.0: # %entry
106; LARGE32-NEXT:    mflr r0
107; LARGE32-NEXT:    stwu r1, -32(r1)
108; LARGE32-NEXT:    stw r0, 40(r1)
109; LARGE32-NEXT:    mr r5, r3
110; LARGE32-NEXT:    addis r3, L..C1@u(r2)
111; LARGE32-NEXT:    lwz r6, L..C1@l(r3)
112; LARGE32-NEXT:    bla .__get_tpointer[PR]
113; LARGE32-NEXT:    add r3, r3, r6
114; LARGE32-NEXT:    stw r4, 4(r3)
115; LARGE32-NEXT:    stw r5, 0(r3)
116; LARGE32-NEXT:    addi r1, r1, 32
117; LARGE32-NEXT:    lwz r0, 8(r1)
118; LARGE32-NEXT:    mtlr r0
119; LARGE32-NEXT:    blr
120entry:
121  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit)
122  store i64 %x, ptr %0, align 8
123  ret void
124}
125
126define void @storeTLUninit(i64 noundef %x) {
127; SMALL64-LABEL: storeTLUninit:
128; SMALL64:       # %bb.0: # %entry
129; SMALL64-NEXT:    ld r4, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit
130; SMALL64-NEXT:    stdx r3, r13, r4
131; SMALL64-NEXT:    blr
132;
133; LARGE64-LABEL: storeTLUninit:
134; LARGE64:       # %bb.0: # %entry
135; LARGE64-NEXT:    addis r4, L..C2@u(r2)
136; LARGE64-NEXT:    ld r4, L..C2@l(r4)
137; LARGE64-NEXT:    stdx r3, r13, r4
138; LARGE64-NEXT:    blr
139;
140; SMALL32-LABEL: storeTLUninit:
141; SMALL32:       # %bb.0: # %entry
142; SMALL32-NEXT:    mflr r0
143; SMALL32-NEXT:    stwu r1, -32(r1)
144; SMALL32-NEXT:    lwz r6, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit
145; SMALL32-NEXT:    mr r5, r3
146; SMALL32-NEXT:    bla .__get_tpointer[PR]
147; SMALL32-NEXT:    stw r0, 40(r1)
148; SMALL32-NEXT:    add r3, r3, r6
149; SMALL32-NEXT:    stw r4, 4(r3)
150; SMALL32-NEXT:    stw r5, 0(r3)
151; SMALL32-NEXT:    addi r1, r1, 32
152; SMALL32-NEXT:    lwz r0, 8(r1)
153; SMALL32-NEXT:    mtlr r0
154; SMALL32-NEXT:    blr
155;
156; LARGE32-LABEL: storeTLUninit:
157; LARGE32:       # %bb.0: # %entry
158; LARGE32-NEXT:    mflr r0
159; LARGE32-NEXT:    stwu r1, -32(r1)
160; LARGE32-NEXT:    stw r0, 40(r1)
161; LARGE32-NEXT:    mr r5, r3
162; LARGE32-NEXT:    addis r3, L..C2@u(r2)
163; LARGE32-NEXT:    lwz r6, L..C2@l(r3)
164; LARGE32-NEXT:    bla .__get_tpointer[PR]
165; LARGE32-NEXT:    add r3, r3, r6
166; LARGE32-NEXT:    stw r4, 4(r3)
167; LARGE32-NEXT:    stw r5, 0(r3)
168; LARGE32-NEXT:    addi r1, r1, 32
169; LARGE32-NEXT:    lwz r0, 8(r1)
170; LARGE32-NEXT:    mtlr r0
171; LARGE32-NEXT:    blr
172entry:
173  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit)
174  store i64 %x, ptr %0, align 8
175  ret void
176}
177
178define void @storeTLInit(i64 noundef %x) {
179; SMALL64-LABEL: storeTLInit:
180; SMALL64:       # %bb.0: # %entry
181; SMALL64-NEXT:    ld r4, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit
182; SMALL64-NEXT:    stdx r3, r13, r4
183; SMALL64-NEXT:    blr
184;
185; LARGE64-LABEL: storeTLInit:
186; LARGE64:       # %bb.0: # %entry
187; LARGE64-NEXT:    addis r4, L..C3@u(r2)
188; LARGE64-NEXT:    ld r4, L..C3@l(r4)
189; LARGE64-NEXT:    stdx r3, r13, r4
190; LARGE64-NEXT:    blr
191;
192; SMALL32-LABEL: storeTLInit:
193; SMALL32:       # %bb.0: # %entry
194; SMALL32-NEXT:    mflr r0
195; SMALL32-NEXT:    stwu r1, -32(r1)
196; SMALL32-NEXT:    lwz r6, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit
197; SMALL32-NEXT:    mr r5, r3
198; SMALL32-NEXT:    bla .__get_tpointer[PR]
199; SMALL32-NEXT:    stw r0, 40(r1)
200; SMALL32-NEXT:    add r3, r3, r6
201; SMALL32-NEXT:    stw r4, 4(r3)
202; SMALL32-NEXT:    stw r5, 0(r3)
203; SMALL32-NEXT:    addi r1, r1, 32
204; SMALL32-NEXT:    lwz r0, 8(r1)
205; SMALL32-NEXT:    mtlr r0
206; SMALL32-NEXT:    blr
207;
208; LARGE32-LABEL: storeTLInit:
209; LARGE32:       # %bb.0: # %entry
210; LARGE32-NEXT:    mflr r0
211; LARGE32-NEXT:    stwu r1, -32(r1)
212; LARGE32-NEXT:    stw r0, 40(r1)
213; LARGE32-NEXT:    mr r5, r3
214; LARGE32-NEXT:    addis r3, L..C3@u(r2)
215; LARGE32-NEXT:    lwz r6, L..C3@l(r3)
216; LARGE32-NEXT:    bla .__get_tpointer[PR]
217; LARGE32-NEXT:    add r3, r3, r6
218; LARGE32-NEXT:    stw r4, 4(r3)
219; LARGE32-NEXT:    stw r5, 0(r3)
220; LARGE32-NEXT:    addi r1, r1, 32
221; LARGE32-NEXT:    lwz r0, 8(r1)
222; LARGE32-NEXT:    mtlr r0
223; LARGE32-NEXT:    blr
224entry:
225  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit)
226  store i64 %x, ptr %0, align 8
227  ret void
228}
229
230define i64 @loadITLUninit() {
231; SMALL64-LABEL: loadITLUninit:
232; SMALL64:       # %bb.0: # %entry
233; SMALL64-NEXT:    ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit
234; SMALL64-NEXT:    ldx r3, r13, r3
235; SMALL64-NEXT:    blr
236;
237; LARGE64-LABEL: loadITLUninit:
238; LARGE64:       # %bb.0: # %entry
239; LARGE64-NEXT:    addis r3, L..C0@u(r2)
240; LARGE64-NEXT:    ld r3, L..C0@l(r3)
241; LARGE64-NEXT:    ldx r3, r13, r3
242; LARGE64-NEXT:    blr
243;
244; SMALL32-LABEL: loadITLUninit:
245; SMALL32:       # %bb.0: # %entry
246; SMALL32-NEXT:    mflr r0
247; SMALL32-NEXT:    stwu r1, -32(r1)
248; SMALL32-NEXT:    lwz r4, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit
249; SMALL32-NEXT:    bla .__get_tpointer[PR]
250; SMALL32-NEXT:    stw r0, 40(r1)
251; SMALL32-NEXT:    add r4, r3, r4
252; SMALL32-NEXT:    lwz r3, 0(r4)
253; SMALL32-NEXT:    lwz r4, 4(r4)
254; SMALL32-NEXT:    addi r1, r1, 32
255; SMALL32-NEXT:    lwz r0, 8(r1)
256; SMALL32-NEXT:    mtlr r0
257; SMALL32-NEXT:    blr
258;
259; LARGE32-LABEL: loadITLUninit:
260; LARGE32:       # %bb.0: # %entry
261; LARGE32-NEXT:    mflr r0
262; LARGE32-NEXT:    stwu r1, -32(r1)
263; LARGE32-NEXT:    stw r0, 40(r1)
264; LARGE32-NEXT:    addis r3, L..C0@u(r2)
265; LARGE32-NEXT:    lwz r4, L..C0@l(r3)
266; LARGE32-NEXT:    bla .__get_tpointer[PR]
267; LARGE32-NEXT:    add r4, r3, r4
268; LARGE32-NEXT:    lwz r3, 0(r4)
269; LARGE32-NEXT:    lwz r4, 4(r4)
270; LARGE32-NEXT:    addi r1, r1, 32
271; LARGE32-NEXT:    lwz r0, 8(r1)
272; LARGE32-NEXT:    mtlr r0
273; LARGE32-NEXT:    blr
274entry:
275  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit)
276  %1 = load i64, ptr %0, align 8
277  ret i64 %1
278}
279
280define i64 @loadITLUninit2() {
281; SMALL64-LABEL: loadITLUninit2:
282; SMALL64:       # %bb.0: # %entry
283; SMALL64-NEXT:    ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit
284; SMALL64-NEXT:    ld r4, L..C4(r2) # @VarInit
285; SMALL64-NEXT:    ldx r3, r13, r3
286; SMALL64-NEXT:    ld r4, 0(r4)
287; SMALL64-NEXT:    add r3, r4, r3
288; SMALL64-NEXT:    blr
289;
290; LARGE64-LABEL: loadITLUninit2:
291; LARGE64:       # %bb.0: # %entry
292; LARGE64-NEXT:    addis r3, L..C0@u(r2)
293; LARGE64-NEXT:    addis r4, L..C4@u(r2)
294; LARGE64-NEXT:    ld r3, L..C0@l(r3)
295; LARGE64-NEXT:    ld r4, L..C4@l(r4)
296; LARGE64-NEXT:    ldx r3, r13, r3
297; LARGE64-NEXT:    ld r4, 0(r4)
298; LARGE64-NEXT:    add r3, r4, r3
299; LARGE64-NEXT:    blr
300;
301; SMALL32-LABEL: loadITLUninit2:
302; SMALL32:       # %bb.0: # %entry
303; SMALL32-NEXT:    mflr r0
304; SMALL32-NEXT:    stwu r1, -32(r1)
305; SMALL32-NEXT:    lwz r4, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit
306; SMALL32-NEXT:    bla .__get_tpointer[PR]
307; SMALL32-NEXT:    lwz r5, L..C4(r2) # @VarInit
308; SMALL32-NEXT:    stw r0, 40(r1)
309; SMALL32-NEXT:    add r3, r3, r4
310; SMALL32-NEXT:    lwz r6, 4(r5)
311; SMALL32-NEXT:    lwz r5, 0(r5)
312; SMALL32-NEXT:    lwz r4, 4(r3)
313; SMALL32-NEXT:    lwz r3, 0(r3)
314; SMALL32-NEXT:    addc r4, r6, r4
315; SMALL32-NEXT:    adde r3, r5, r3
316; SMALL32-NEXT:    addi r1, r1, 32
317; SMALL32-NEXT:    lwz r0, 8(r1)
318; SMALL32-NEXT:    mtlr r0
319; SMALL32-NEXT:    blr
320;
321; LARGE32-LABEL: loadITLUninit2:
322; LARGE32:       # %bb.0: # %entry
323; LARGE32-NEXT:    mflr r0
324; LARGE32-NEXT:    stwu r1, -32(r1)
325; LARGE32-NEXT:    stw r0, 40(r1)
326; LARGE32-NEXT:    addis r3, L..C0@u(r2)
327; LARGE32-NEXT:    lwz r4, L..C0@l(r3)
328; LARGE32-NEXT:    bla .__get_tpointer[PR]
329; LARGE32-NEXT:    add r3, r3, r4
330; LARGE32-NEXT:    lwz r4, 4(r3)
331; LARGE32-NEXT:    lwz r3, 0(r3)
332; LARGE32-NEXT:    addis r5, L..C4@u(r2)
333; LARGE32-NEXT:    lwz r5, L..C4@l(r5)
334; LARGE32-NEXT:    lwz r6, 4(r5)
335; LARGE32-NEXT:    lwz r5, 0(r5)
336; LARGE32-NEXT:    addc r4, r6, r4
337; LARGE32-NEXT:    adde r3, r5, r3
338; LARGE32-NEXT:    addi r1, r1, 32
339; LARGE32-NEXT:    lwz r0, 8(r1)
340; LARGE32-NEXT:    mtlr r0
341; LARGE32-NEXT:    blr
342entry:
343  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit)
344  %1 = load i64, ptr %0, align 8
345  %2 = load i64, ptr @VarInit, align 8
346  %add = add nsw i64 %2, %1
347  ret i64 %add
348}
349
350define i64 @loadITLInit() {
351; SMALL64-LABEL: loadITLInit:
352; SMALL64:       # %bb.0: # %entry
353; SMALL64-NEXT:    ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit
354; SMALL64-NEXT:    ldx r3, r13, r3
355; SMALL64-NEXT:    blr
356;
357; LARGE64-LABEL: loadITLInit:
358; LARGE64:       # %bb.0: # %entry
359; LARGE64-NEXT:    addis r3, L..C1@u(r2)
360; LARGE64-NEXT:    ld r3, L..C1@l(r3)
361; LARGE64-NEXT:    ldx r3, r13, r3
362; LARGE64-NEXT:    blr
363;
364; SMALL32-LABEL: loadITLInit:
365; SMALL32:       # %bb.0: # %entry
366; SMALL32-NEXT:    mflr r0
367; SMALL32-NEXT:    stwu r1, -32(r1)
368; SMALL32-NEXT:    lwz r4, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit
369; SMALL32-NEXT:    bla .__get_tpointer[PR]
370; SMALL32-NEXT:    stw r0, 40(r1)
371; SMALL32-NEXT:    add r4, r3, r4
372; SMALL32-NEXT:    lwz r3, 0(r4)
373; SMALL32-NEXT:    lwz r4, 4(r4)
374; SMALL32-NEXT:    addi r1, r1, 32
375; SMALL32-NEXT:    lwz r0, 8(r1)
376; SMALL32-NEXT:    mtlr r0
377; SMALL32-NEXT:    blr
378;
379; LARGE32-LABEL: loadITLInit:
380; LARGE32:       # %bb.0: # %entry
381; LARGE32-NEXT:    mflr r0
382; LARGE32-NEXT:    stwu r1, -32(r1)
383; LARGE32-NEXT:    stw r0, 40(r1)
384; LARGE32-NEXT:    addis r3, L..C1@u(r2)
385; LARGE32-NEXT:    lwz r4, L..C1@l(r3)
386; LARGE32-NEXT:    bla .__get_tpointer[PR]
387; LARGE32-NEXT:    add r4, r3, r4
388; LARGE32-NEXT:    lwz r3, 0(r4)
389; LARGE32-NEXT:    lwz r4, 4(r4)
390; LARGE32-NEXT:    addi r1, r1, 32
391; LARGE32-NEXT:    lwz r0, 8(r1)
392; LARGE32-NEXT:    mtlr r0
393; LARGE32-NEXT:    blr
394entry:
395  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit)
396  %1 = load i64, ptr %0, align 8
397  ret i64 %1
398}
399
400define i64 @loadITLInit2() {
401; SMALL64-LABEL: loadITLInit2:
402; SMALL64:       # %bb.0: # %entry
403; SMALL64-NEXT:    ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit
404; SMALL64-NEXT:    ld r4, L..C4(r2) # @VarInit
405; SMALL64-NEXT:    ldx r3, r13, r3
406; SMALL64-NEXT:    ld r4, 0(r4)
407; SMALL64-NEXT:    add r3, r4, r3
408; SMALL64-NEXT:    blr
409;
410; LARGE64-LABEL: loadITLInit2:
411; LARGE64:       # %bb.0: # %entry
412; LARGE64-NEXT:    addis r3, L..C1@u(r2)
413; LARGE64-NEXT:    addis r4, L..C4@u(r2)
414; LARGE64-NEXT:    ld r3, L..C1@l(r3)
415; LARGE64-NEXT:    ld r4, L..C4@l(r4)
416; LARGE64-NEXT:    ldx r3, r13, r3
417; LARGE64-NEXT:    ld r4, 0(r4)
418; LARGE64-NEXT:    add r3, r4, r3
419; LARGE64-NEXT:    blr
420;
421; SMALL32-LABEL: loadITLInit2:
422; SMALL32:       # %bb.0: # %entry
423; SMALL32-NEXT:    mflr r0
424; SMALL32-NEXT:    stwu r1, -32(r1)
425; SMALL32-NEXT:    lwz r4, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit
426; SMALL32-NEXT:    bla .__get_tpointer[PR]
427; SMALL32-NEXT:    lwz r5, L..C4(r2) # @VarInit
428; SMALL32-NEXT:    stw r0, 40(r1)
429; SMALL32-NEXT:    add r3, r3, r4
430; SMALL32-NEXT:    lwz r6, 4(r5)
431; SMALL32-NEXT:    lwz r5, 0(r5)
432; SMALL32-NEXT:    lwz r4, 4(r3)
433; SMALL32-NEXT:    lwz r3, 0(r3)
434; SMALL32-NEXT:    addc r4, r6, r4
435; SMALL32-NEXT:    adde r3, r5, r3
436; SMALL32-NEXT:    addi r1, r1, 32
437; SMALL32-NEXT:    lwz r0, 8(r1)
438; SMALL32-NEXT:    mtlr r0
439; SMALL32-NEXT:    blr
440;
441; LARGE32-LABEL: loadITLInit2:
442; LARGE32:       # %bb.0: # %entry
443; LARGE32-NEXT:    mflr r0
444; LARGE32-NEXT:    stwu r1, -32(r1)
445; LARGE32-NEXT:    stw r0, 40(r1)
446; LARGE32-NEXT:    addis r3, L..C1@u(r2)
447; LARGE32-NEXT:    lwz r4, L..C1@l(r3)
448; LARGE32-NEXT:    bla .__get_tpointer[PR]
449; LARGE32-NEXT:    add r3, r3, r4
450; LARGE32-NEXT:    lwz r4, 4(r3)
451; LARGE32-NEXT:    lwz r3, 0(r3)
452; LARGE32-NEXT:    addis r5, L..C4@u(r2)
453; LARGE32-NEXT:    lwz r5, L..C4@l(r5)
454; LARGE32-NEXT:    lwz r6, 4(r5)
455; LARGE32-NEXT:    lwz r5, 0(r5)
456; LARGE32-NEXT:    addc r4, r6, r4
457; LARGE32-NEXT:    adde r3, r5, r3
458; LARGE32-NEXT:    addi r1, r1, 32
459; LARGE32-NEXT:    lwz r0, 8(r1)
460; LARGE32-NEXT:    mtlr r0
461; LARGE32-NEXT:    blr
462entry:
463  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit)
464  %1 = load i64, ptr %0, align 8
465  %2 = load i64, ptr @VarInit, align 8
466  %add = add nsw i64 %2, %1
467  ret i64 %add
468}
469
470define i64 @loadTLUninit() {
471; SMALL64-LABEL: loadTLUninit:
472; SMALL64:       # %bb.0: # %entry
473; SMALL64-NEXT:    ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit
474; SMALL64-NEXT:    ldx r3, r13, r3
475; SMALL64-NEXT:    blr
476;
477; LARGE64-LABEL: loadTLUninit:
478; LARGE64:       # %bb.0: # %entry
479; LARGE64-NEXT:    addis r3, L..C2@u(r2)
480; LARGE64-NEXT:    ld r3, L..C2@l(r3)
481; LARGE64-NEXT:    ldx r3, r13, r3
482; LARGE64-NEXT:    blr
483;
484; SMALL32-LABEL: loadTLUninit:
485; SMALL32:       # %bb.0: # %entry
486; SMALL32-NEXT:    mflr r0
487; SMALL32-NEXT:    stwu r1, -32(r1)
488; SMALL32-NEXT:    lwz r4, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit
489; SMALL32-NEXT:    bla .__get_tpointer[PR]
490; SMALL32-NEXT:    stw r0, 40(r1)
491; SMALL32-NEXT:    add r4, r3, r4
492; SMALL32-NEXT:    lwz r3, 0(r4)
493; SMALL32-NEXT:    lwz r4, 4(r4)
494; SMALL32-NEXT:    addi r1, r1, 32
495; SMALL32-NEXT:    lwz r0, 8(r1)
496; SMALL32-NEXT:    mtlr r0
497; SMALL32-NEXT:    blr
498;
499; LARGE32-LABEL: loadTLUninit:
500; LARGE32:       # %bb.0: # %entry
501; LARGE32-NEXT:    mflr r0
502; LARGE32-NEXT:    stwu r1, -32(r1)
503; LARGE32-NEXT:    stw r0, 40(r1)
504; LARGE32-NEXT:    addis r3, L..C2@u(r2)
505; LARGE32-NEXT:    lwz r4, L..C2@l(r3)
506; LARGE32-NEXT:    bla .__get_tpointer[PR]
507; LARGE32-NEXT:    add r4, r3, r4
508; LARGE32-NEXT:    lwz r3, 0(r4)
509; LARGE32-NEXT:    lwz r4, 4(r4)
510; LARGE32-NEXT:    addi r1, r1, 32
511; LARGE32-NEXT:    lwz r0, 8(r1)
512; LARGE32-NEXT:    mtlr r0
513; LARGE32-NEXT:    blr
514entry:
515  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit)
516  %1 = load i64, ptr %0, align 8
517  ret i64 %1
518}
519
520define i64 @loadTLUninit2() {
521; SMALL64-LABEL: loadTLUninit2:
522; SMALL64:       # %bb.0: # %entry
523; SMALL64-NEXT:    ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit
524; SMALL64-NEXT:    ld r4, L..C4(r2) # @VarInit
525; SMALL64-NEXT:    ldx r3, r13, r3
526; SMALL64-NEXT:    ld r4, 0(r4)
527; SMALL64-NEXT:    add r3, r4, r3
528; SMALL64-NEXT:    blr
529;
530; LARGE64-LABEL: loadTLUninit2:
531; LARGE64:       # %bb.0: # %entry
532; LARGE64-NEXT:    addis r3, L..C2@u(r2)
533; LARGE64-NEXT:    addis r4, L..C4@u(r2)
534; LARGE64-NEXT:    ld r3, L..C2@l(r3)
535; LARGE64-NEXT:    ld r4, L..C4@l(r4)
536; LARGE64-NEXT:    ldx r3, r13, r3
537; LARGE64-NEXT:    ld r4, 0(r4)
538; LARGE64-NEXT:    add r3, r4, r3
539; LARGE64-NEXT:    blr
540;
541; SMALL32-LABEL: loadTLUninit2:
542; SMALL32:       # %bb.0: # %entry
543; SMALL32-NEXT:    mflr r0
544; SMALL32-NEXT:    stwu r1, -32(r1)
545; SMALL32-NEXT:    lwz r4, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit
546; SMALL32-NEXT:    bla .__get_tpointer[PR]
547; SMALL32-NEXT:    lwz r5, L..C4(r2) # @VarInit
548; SMALL32-NEXT:    stw r0, 40(r1)
549; SMALL32-NEXT:    add r3, r3, r4
550; SMALL32-NEXT:    lwz r6, 4(r5)
551; SMALL32-NEXT:    lwz r5, 0(r5)
552; SMALL32-NEXT:    lwz r4, 4(r3)
553; SMALL32-NEXT:    lwz r3, 0(r3)
554; SMALL32-NEXT:    addc r4, r6, r4
555; SMALL32-NEXT:    adde r3, r5, r3
556; SMALL32-NEXT:    addi r1, r1, 32
557; SMALL32-NEXT:    lwz r0, 8(r1)
558; SMALL32-NEXT:    mtlr r0
559; SMALL32-NEXT:    blr
560;
561; LARGE32-LABEL: loadTLUninit2:
562; LARGE32:       # %bb.0: # %entry
563; LARGE32-NEXT:    mflr r0
564; LARGE32-NEXT:    stwu r1, -32(r1)
565; LARGE32-NEXT:    stw r0, 40(r1)
566; LARGE32-NEXT:    addis r3, L..C2@u(r2)
567; LARGE32-NEXT:    lwz r4, L..C2@l(r3)
568; LARGE32-NEXT:    bla .__get_tpointer[PR]
569; LARGE32-NEXT:    add r3, r3, r4
570; LARGE32-NEXT:    lwz r4, 4(r3)
571; LARGE32-NEXT:    lwz r3, 0(r3)
572; LARGE32-NEXT:    addis r5, L..C4@u(r2)
573; LARGE32-NEXT:    lwz r5, L..C4@l(r5)
574; LARGE32-NEXT:    lwz r6, 4(r5)
575; LARGE32-NEXT:    lwz r5, 0(r5)
576; LARGE32-NEXT:    addc r4, r6, r4
577; LARGE32-NEXT:    adde r3, r5, r3
578; LARGE32-NEXT:    addi r1, r1, 32
579; LARGE32-NEXT:    lwz r0, 8(r1)
580; LARGE32-NEXT:    mtlr r0
581; LARGE32-NEXT:    blr
582entry:
583  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit)
584  %1 = load i64, ptr %0, align 8
585  %2 = load i64, ptr @VarInit, align 8
586  %add = add nsw i64 %2, %1
587  ret i64 %add
588}
589
590define i64 @loadTLInit() {
591; SMALL64-LABEL: loadTLInit:
592; SMALL64:       # %bb.0: # %entry
593; SMALL64-NEXT:    ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit
594; SMALL64-NEXT:    ldx r3, r13, r3
595; SMALL64-NEXT:    blr
596;
597; LARGE64-LABEL: loadTLInit:
598; LARGE64:       # %bb.0: # %entry
599; LARGE64-NEXT:    addis r3, L..C3@u(r2)
600; LARGE64-NEXT:    ld r3, L..C3@l(r3)
601; LARGE64-NEXT:    ldx r3, r13, r3
602; LARGE64-NEXT:    blr
603;
604; SMALL32-LABEL: loadTLInit:
605; SMALL32:       # %bb.0: # %entry
606; SMALL32-NEXT:    mflr r0
607; SMALL32-NEXT:    stwu r1, -32(r1)
608; SMALL32-NEXT:    lwz r4, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit
609; SMALL32-NEXT:    bla .__get_tpointer[PR]
610; SMALL32-NEXT:    stw r0, 40(r1)
611; SMALL32-NEXT:    add r4, r3, r4
612; SMALL32-NEXT:    lwz r3, 0(r4)
613; SMALL32-NEXT:    lwz r4, 4(r4)
614; SMALL32-NEXT:    addi r1, r1, 32
615; SMALL32-NEXT:    lwz r0, 8(r1)
616; SMALL32-NEXT:    mtlr r0
617; SMALL32-NEXT:    blr
618;
619; LARGE32-LABEL: loadTLInit:
620; LARGE32:       # %bb.0: # %entry
621; LARGE32-NEXT:    mflr r0
622; LARGE32-NEXT:    stwu r1, -32(r1)
623; LARGE32-NEXT:    stw r0, 40(r1)
624; LARGE32-NEXT:    addis r3, L..C3@u(r2)
625; LARGE32-NEXT:    lwz r4, L..C3@l(r3)
626; LARGE32-NEXT:    bla .__get_tpointer[PR]
627; LARGE32-NEXT:    add r4, r3, r4
628; LARGE32-NEXT:    lwz r3, 0(r4)
629; LARGE32-NEXT:    lwz r4, 4(r4)
630; LARGE32-NEXT:    addi r1, r1, 32
631; LARGE32-NEXT:    lwz r0, 8(r1)
632; LARGE32-NEXT:    mtlr r0
633; LARGE32-NEXT:    blr
634entry:
635  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit)
636  %1 = load i64, ptr %0, align 8
637  ret i64 %1
638}
639
640define i64 @loadTLInit2() {
641; SMALL64-LABEL: loadTLInit2:
642; SMALL64:       # %bb.0: # %entry
643; SMALL64-NEXT:    ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit
644; SMALL64-NEXT:    ld r4, L..C4(r2) # @VarInit
645; SMALL64-NEXT:    ldx r3, r13, r3
646; SMALL64-NEXT:    ld r4, 0(r4)
647; SMALL64-NEXT:    add r3, r4, r3
648; SMALL64-NEXT:    blr
649;
650; LARGE64-LABEL: loadTLInit2:
651; LARGE64:       # %bb.0: # %entry
652; LARGE64-NEXT:    addis r3, L..C3@u(r2)
653; LARGE64-NEXT:    addis r4, L..C4@u(r2)
654; LARGE64-NEXT:    ld r3, L..C3@l(r3)
655; LARGE64-NEXT:    ld r4, L..C4@l(r4)
656; LARGE64-NEXT:    ldx r3, r13, r3
657; LARGE64-NEXT:    ld r4, 0(r4)
658; LARGE64-NEXT:    add r3, r4, r3
659; LARGE64-NEXT:    blr
660;
661; SMALL32-LABEL: loadTLInit2:
662; SMALL32:       # %bb.0: # %entry
663; SMALL32-NEXT:    mflr r0
664; SMALL32-NEXT:    stwu r1, -32(r1)
665; SMALL32-NEXT:    lwz r4, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit
666; SMALL32-NEXT:    bla .__get_tpointer[PR]
667; SMALL32-NEXT:    lwz r5, L..C4(r2) # @VarInit
668; SMALL32-NEXT:    stw r0, 40(r1)
669; SMALL32-NEXT:    add r3, r3, r4
670; SMALL32-NEXT:    lwz r6, 4(r5)
671; SMALL32-NEXT:    lwz r5, 0(r5)
672; SMALL32-NEXT:    lwz r4, 4(r3)
673; SMALL32-NEXT:    lwz r3, 0(r3)
674; SMALL32-NEXT:    addc r4, r6, r4
675; SMALL32-NEXT:    adde r3, r5, r3
676; SMALL32-NEXT:    addi r1, r1, 32
677; SMALL32-NEXT:    lwz r0, 8(r1)
678; SMALL32-NEXT:    mtlr r0
679; SMALL32-NEXT:    blr
680;
681; LARGE32-LABEL: loadTLInit2:
682; LARGE32:       # %bb.0: # %entry
683; LARGE32-NEXT:    mflr r0
684; LARGE32-NEXT:    stwu r1, -32(r1)
685; LARGE32-NEXT:    stw r0, 40(r1)
686; LARGE32-NEXT:    addis r3, L..C3@u(r2)
687; LARGE32-NEXT:    lwz r4, L..C3@l(r3)
688; LARGE32-NEXT:    bla .__get_tpointer[PR]
689; LARGE32-NEXT:    add r3, r3, r4
690; LARGE32-NEXT:    lwz r4, 4(r3)
691; LARGE32-NEXT:    lwz r3, 0(r3)
692; LARGE32-NEXT:    addis r5, L..C4@u(r2)
693; LARGE32-NEXT:    lwz r5, L..C4@l(r5)
694; LARGE32-NEXT:    lwz r6, 4(r5)
695; LARGE32-NEXT:    lwz r5, 0(r5)
696; LARGE32-NEXT:    addc r4, r6, r4
697; LARGE32-NEXT:    adde r3, r5, r3
698; LARGE32-NEXT:    addi r1, r1, 32
699; LARGE32-NEXT:    lwz r0, 8(r1)
700; LARGE32-NEXT:    mtlr r0
701; LARGE32-NEXT:    blr
702entry:
703  %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit)
704  %1 = load i64, ptr %0, align 8
705  %2 = load i64, ptr @VarInit, align 8
706  %add = add nsw i64 %2, %1
707  ret i64 %add
708}
709
710; TOC Entry Checks.
711
712; SMALL64-LABEL: .toc
713; SMALL64-LABEL: L..C0:
714; SMALL64-NEXT: .tc IThreadLocalVarUninit[TC],IThreadLocalVarUninit[UL]@le
715; SMALL64-LABEL: L..C1:
716; SMALL64-NEXT: .tc IThreadLocalVarInit[TC],IThreadLocalVarInit[TL]@le
717; SMALL64-LABEL: L..C2:
718; SMALL64-NEXT: .tc ThreadLocalVarUninit[TC],ThreadLocalVarUninit[TL]@le
719; SMALL64-LABEL: L..C3:
720; SMALL64-NEXT: .tc ThreadLocalVarInit[TC],ThreadLocalVarInit[TL]@le
721; SMALL64-LABEL: L..C4:
722; SMALL64-NEXT: .tc VarInit[TC],VarInit[RW]
723
724; LARGE64-LABEL: .toc
725; LARGE64-LABEL: L..C0:
726; LARGE64-NEXT: .tc IThreadLocalVarUninit[TE],IThreadLocalVarUninit[UL]@le
727; LARGE64-LABEL: L..C1:
728; LARGE64-NEXT: .tc IThreadLocalVarInit[TE],IThreadLocalVarInit[TL]@le
729; LARGE64-LABEL: L..C2:
730; LARGE64-NEXT: .tc ThreadLocalVarUninit[TE],ThreadLocalVarUninit[TL]@le
731; LARGE64-LABEL: L..C3:
732; LARGE64-NEXT: .tc ThreadLocalVarInit[TE],ThreadLocalVarInit[TL]@le
733; LARGE64-LABEL: L..C4:
734; LARGE64-NEXT: .tc VarInit[TE],VarInit[RW]
735
736; SMALL32-LABEL: .toc
737; SMALL32-LABEL: L..C0:
738; SMALL32-NEXT: .tc IThreadLocalVarUninit[TC],IThreadLocalVarUninit[UL]@le
739; SMALL32-LABEL: L..C1:
740; SMALL32-NEXT: .tc IThreadLocalVarInit[TC],IThreadLocalVarInit[TL]@le
741; SMALL32-LABEL: L..C2:
742; SMALL32-NEXT: .tc ThreadLocalVarUninit[TC],ThreadLocalVarUninit[TL]@le
743; SMALL32-LABEL: L..C3:
744; SMALL32-NEXT: .tc ThreadLocalVarInit[TC],ThreadLocalVarInit[TL]@le
745; SMALL32-LABEL: L..C4:
746; SMALL32-NEXT: .tc VarInit[TC],VarInit[RW]
747
748; LARGE32-LABEL: .toc
749; LARGE32-LABEL: L..C0:
750; LARGE32-NEXT: .tc IThreadLocalVarUninit[TE],IThreadLocalVarUninit[UL]@le
751; LARGE32-LABEL: L..C1:
752; LARGE32-NEXT: .tc IThreadLocalVarInit[TE],IThreadLocalVarInit[TL]@le
753; LARGE32-LABEL: L..C2:
754; LARGE32-NEXT: .tc ThreadLocalVarUninit[TE],ThreadLocalVarUninit[TL]@le
755; LARGE32-LABEL: L..C3:
756; LARGE32-NEXT: .tc ThreadLocalVarInit[TE],ThreadLocalVarInit[TL]@le
757; LARGE32-LABEL: L..C4:
758; LARGE32-NEXT: .tc VarInit[TE],VarInit[RW]
759