1; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr10 -ppc-asm-full-reg-names \
2; RUN:   < %s | FileCheck %s --check-prefix=CHECK-S
3; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
4; RUN:   -mcpu=pwr10 -ppc-asm-full-reg-names \
5; RUN:   --filetype=obj < %s | llvm-objdump --no-show-raw-insn --mcpu=pwr10 -dr - \
6; RUN:   | FileCheck %s --check-prefix=CHECK-O
7
8; These test cases are to ensure that when using pc relative memory operations
9; ABI correct code and relocations are produced for the Local Exec TLS Model.
10
11@x = thread_local global i32 0, align 4
12@y = thread_local global [5 x i32] [i32 0, i32 0, i32 0, i32 0, i32 0], align 4
13
14define i32* @LocalExecAddressLoad() {
15; CHECK-S-LABEL: LocalExecAddressLoad:
16; CHECK-S:       # %bb.0: # %entry
17; CHECK-S-NEXT:    paddi r3, r13, x@TPREL, 0
18; CHECK-S-NEXT:    blr
19; CHECK-O-LABEL: <LocalExecAddressLoad>:
20; CHECK-O:         0: paddi 3, 13, 0, 0
21; CHECK-O-NEXT:    0000000000000000:  R_PPC64_TPREL34 x
22; CHECK-O-NEXT:    8: blr
23entry:
24  ret i32* @x
25}
26
27define i32 @LocalExecValueLoad() {
28; CHECK-S-LABEL: LocalExecValueLoad:
29; CHECK-S:       # %bb.0: # %entry
30; CHECK-S-NEXT:    paddi r3, r13, x@TPREL, 0
31; CHECK-S-NEXT:    lwz r3, 0(r3)
32; CHECK-S-NEXT:    blr
33; CHECK-O-LABEL: <LocalExecValueLoad>:
34; CHECK-O:         20: paddi 3, 13, 0, 0
35; CHECK-O-NEXT:    0000000000000020:  R_PPC64_TPREL34 x
36; CHECK-O-NEXT:    28: lwz 3, 0(3)
37; CHECK-O-NEXT:    2c: blr
38entry:
39  %0 = load i32, i32* @x, align 4
40  ret i32 %0
41}
42
43define void @LocalExecValueStore(i32 %in) {
44; CHECK-S-LABEL: LocalExecValueStore:
45; CHECK-S:       # %bb.0: # %entry
46; CHECK-S-NEXT:    paddi r4, r13, x@TPREL, 0
47; CHECK-S-NEXT:    stw r3, 0(r4)
48; CHECK-S-NEXT:    blr
49; CHECK-O-LABEL: <LocalExecValueStore>:
50; CHECK-O:         40: paddi 4, 13, 0, 0
51; CHECK-O-NEXT:    0000000000000040:  R_PPC64_TPREL34 x
52; CHECK-O-NEXT:    48: stw 3, 0(4)
53; CHECK-O-NEXT:    4c: blr
54entry:
55  store i32 %in, i32* @x, align 4
56  ret void
57}
58
59define i32 @LocalExecValueLoadOffset() {
60; CHECK-S-LABEL: LocalExecValueLoadOffset:
61; CHECK-S:       # %bb.0: # %entry
62; CHECK-S-NEXT:    paddi r3, r13, y@TPREL, 0
63; CHECK-S-NEXT:    lwz r3, 12(r3)
64; CHECK-S-NEXT:    blr
65; CHECK-O-LABEL: <LocalExecValueLoadOffset>:
66; CHECK-O:         60: paddi 3, 13, 0, 0
67; CHECK-O-NEXT:    0000000000000060:  R_PPC64_TPREL34 y
68; CHECK-O-NEXT:    68: lwz 3, 12(3)
69; CHECK-O-NEXT:    6c: blr
70entry:
71  %0 = load i32, i32* getelementptr inbounds ([5 x i32], [5 x i32]* @y, i64 0, i64 3), align 4
72  ret i32 %0
73}
74
75
76define i32* @LocalExecValueLoadOffsetNoLoad() {
77; CHECK-S-LABEL: LocalExecValueLoadOffsetNoLoad:
78; CHECK-S:       # %bb.0: # %entry
79; CHECK-S-NEXT:    paddi r3, r13, y@TPREL, 0
80; CHECK-S-NEXT:    addi r3, r3, 12
81; CHECK-S-NEXT:    blr
82; CHECK-O-LABEL: <LocalExecValueLoadOffsetNoLoad>:
83; CHECK-O:         80: paddi 3, 13, 0, 0
84; CHECK-O-NEXT:    0000000000000080:  R_PPC64_TPREL34 y
85; CHECK-O-NEXT:    88: addi 3, 3, 12
86; CHECK-O-NEXT:    8c: blr
87entry:
88  ret i32* getelementptr inbounds ([5 x i32], [5 x i32]* @y, i64 0, i64 3)
89}
90