xref: /llvm-project/llvm/test/CodeGen/PowerPC/tls-pie-xform.ll (revision b922a3621116b404d868af8b74cab25ab78555be)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-gnu-linux < %s | FileCheck %s -check-prefix=CHECK
3
4@var_char = external thread_local local_unnamed_addr global i8, align 1
5@var_short = external thread_local local_unnamed_addr global i16, align 2
6@var_int = external thread_local local_unnamed_addr global i32, align 4
7@var_long_long = external thread_local local_unnamed_addr global i64, align 8
8@var_float = external thread_local local_unnamed_addr global float, align 4
9@var_double = external thread_local local_unnamed_addr global double, align 8
10
11define dso_local zeroext i8 @test_char_one() {
12; CHECK-LABEL: test_char_one:
13; CHECK:       # %bb.0: # %entry
14; CHECK-NEXT:    addis 3, 2, var_char@got@tprel@ha
15; CHECK-NEXT:    ld 3, var_char@got@tprel@l(3)
16; CHECK-NEXT:    lbzx 3, 3, var_char@tls
17; CHECK-NEXT:    blr
18entry:
19  %0 = load i8, ptr @var_char, align 1, !tbaa !4
20  ret i8 %0
21}
22
23define dso_local void @test_char_two(i32 signext %a) {
24; CHECK-LABEL: test_char_two:
25; CHECK:       # %bb.0: # %entry
26; CHECK-NEXT:    addis 4, 2, var_char@got@tprel@ha
27; CHECK-NEXT:    ld 4, var_char@got@tprel@l(4)
28; CHECK-NEXT:    stbx 3, 4, var_char@tls
29; CHECK-NEXT:    blr
30entry:
31  %conv = trunc i32 %a to i8
32  store i8 %conv, ptr @var_char, align 1, !tbaa !4
33  ret void
34}
35
36define dso_local zeroext i8 @test_char_three(i8 zeroext %a) {
37; CHECK-LABEL: test_char_three:
38; CHECK:       # %bb.0: # %entry
39; CHECK-NEXT:    addis 4, 2, var_char@got@tprel@ha
40; CHECK-NEXT:    ld 4, var_char@got@tprel@l(4)
41; CHECK-NEXT:    lbzx 5, 4, var_char@tls
42; CHECK-NEXT:    add 3, 5, 3
43; CHECK-NEXT:    stbx 3, 4, var_char@tls
44; CHECK-NEXT:    clrldi 3, 3, 56
45; CHECK-NEXT:    blr
46entry:
47  %0 = load i8, ptr @var_char, align 1, !tbaa !4
48  %add = add i8 %0, %a
49  store i8 %add, ptr @var_char, align 1, !tbaa !4
50  ret i8 %add
51}
52
53define dso_local signext i16 @test_short_one() {
54; CHECK-LABEL: test_short_one:
55; CHECK:       # %bb.0: # %entry
56; CHECK-NEXT:    addis 3, 2, var_short@got@tprel@ha
57; CHECK-NEXT:    ld 3, var_short@got@tprel@l(3)
58; CHECK-NEXT:    lhax 3, 3, var_short@tls
59; CHECK-NEXT:    blr
60entry:
61  %0 = load i16, ptr @var_short, align 2, !tbaa !7
62  ret i16 %0
63}
64
65define dso_local zeroext i16 @test_short_one_zeroext() {
66; CHECK-LABEL: test_short_one_zeroext:
67; CHECK:       # %bb.0: # %entry
68; CHECK-NEXT:    addis 3, 2, var_short@got@tprel@ha
69; CHECK-NEXT:    ld 3, var_short@got@tprel@l(3)
70; CHECK-NEXT:    lhzx 3, 3, var_short@tls
71; CHECK-NEXT:    blr
72entry:
73  %0 = load i16, ptr @var_short, align 2, !tbaa !7
74  ret i16 %0
75}
76
77define dso_local void @test_short_two(i32 signext %a) {
78; CHECK-LABEL: test_short_two:
79; CHECK:       # %bb.0: # %entry
80; CHECK-NEXT:    addis 4, 2, var_short@got@tprel@ha
81; CHECK-NEXT:    ld 4, var_short@got@tprel@l(4)
82; CHECK-NEXT:    sthx 3, 4, var_short@tls
83; CHECK-NEXT:    blr
84entry:
85  %conv = trunc i32 %a to i16
86  store i16 %conv, ptr @var_short, align 2, !tbaa !7
87  ret void
88}
89
90define dso_local signext i16 @test_short_three(i16 signext %a) {
91; CHECK-LABEL: test_short_three:
92; CHECK:       # %bb.0: # %entry
93; CHECK-NEXT:    addis 4, 2, var_short@got@tprel@ha
94; CHECK-NEXT:    ld 4, var_short@got@tprel@l(4)
95; CHECK-NEXT:    lhzx 5, 4, var_short@tls
96; CHECK-NEXT:    add 3, 5, 3
97; CHECK-NEXT:    sthx 3, 4, var_short@tls
98; CHECK-NEXT:    extsh 3, 3
99; CHECK-NEXT:    blr
100entry:
101  %0 = load i16, ptr @var_short, align 2, !tbaa !7
102  %add = add i16 %0, %a
103  store i16 %add, ptr @var_short, align 2, !tbaa !7
104  ret i16 %add
105}
106
107define dso_local signext i32 @test_int_one() {
108; CHECK-LABEL: test_int_one:
109; CHECK:       # %bb.0: # %entry
110; CHECK-NEXT:    addis 3, 2, var_int@got@tprel@ha
111; CHECK-NEXT:    ld 3, var_int@got@tprel@l(3)
112; CHECK-NEXT:    lwax 3, 3, var_int@tls
113; CHECK-NEXT:    blr
114entry:
115  %0 = load i32, ptr @var_int, align 4, !tbaa !9
116  ret i32 %0
117}
118
119define dso_local zeroext i32 @test_int_one_zeroext() {
120; CHECK-LABEL: test_int_one_zeroext:
121; CHECK:       # %bb.0: # %entry
122; CHECK-NEXT:    addis 3, 2, var_int@got@tprel@ha
123; CHECK-NEXT:    ld 3, var_int@got@tprel@l(3)
124; CHECK-NEXT:    lwzx 3, 3, var_int@tls
125; CHECK-NEXT:    blr
126entry:
127  %0 = load i32, ptr @var_int, align 4, !tbaa !9
128  ret i32 %0
129}
130
131define dso_local void @test_int_two(i32 signext %a) {
132; CHECK-LABEL: test_int_two:
133; CHECK:       # %bb.0: # %entry
134; CHECK-NEXT:    addis 4, 2, var_int@got@tprel@ha
135; CHECK-NEXT:    ld 4, var_int@got@tprel@l(4)
136; CHECK-NEXT:    stwx 3, 4, var_int@tls
137; CHECK-NEXT:    blr
138entry:
139  store i32 %a, ptr @var_int, align 4, !tbaa !9
140  ret void
141}
142
143define dso_local signext i32 @test_int_three(i32 signext %a) {
144; CHECK-LABEL: test_int_three:
145; CHECK:       # %bb.0: # %entry
146; CHECK-NEXT:    addis 4, 2, var_int@got@tprel@ha
147; CHECK-NEXT:    ld 4, var_int@got@tprel@l(4)
148; CHECK-NEXT:    lwzx 5, 4, var_int@tls
149; CHECK-NEXT:    add 3, 5, 3
150; CHECK-NEXT:    stwx 3, 4, var_int@tls
151; CHECK-NEXT:    extsw 3, 3
152; CHECK-NEXT:    blr
153entry:
154  %0 = load i32, ptr @var_int, align 4, !tbaa !9
155  %add = add nsw i32 %0, %a
156  store i32 %add, ptr @var_int, align 4, !tbaa !9
157  ret i32 %add
158}
159
160define dso_local i64 @test_longlong_one() {
161; CHECK-LABEL: test_longlong_one:
162; CHECK:       # %bb.0: # %entry
163; CHECK-NEXT:    addis 3, 2, var_long_long@got@tprel@ha
164; CHECK-NEXT:    ld 3, var_long_long@got@tprel@l(3)
165; CHECK-NEXT:    ldx 3, 3, var_long_long@tls
166; CHECK-NEXT:    blr
167entry:
168  %0 = load i64, ptr @var_long_long, align 8, !tbaa !11
169  ret i64 %0
170}
171
172define dso_local void @test_longlong_two(i32 signext %a) {
173; CHECK-LABEL: test_longlong_two:
174; CHECK:       # %bb.0: # %entry
175; CHECK-NEXT:    addis 4, 2, var_long_long@got@tprel@ha
176; CHECK-NEXT:    ld 4, var_long_long@got@tprel@l(4)
177; CHECK-NEXT:    stdx 3, 4, var_long_long@tls
178; CHECK-NEXT:    blr
179entry:
180  %conv = sext i32 %a to i64
181  store i64 %conv, ptr @var_long_long, align 8, !tbaa !11
182  ret void
183}
184
185define dso_local i64 @test_longlong_three(i64 %a) {
186; CHECK-LABEL: test_longlong_three:
187; CHECK:       # %bb.0: # %entry
188; CHECK-NEXT:    addis 4, 2, var_long_long@got@tprel@ha
189; CHECK-NEXT:    ld 4, var_long_long@got@tprel@l(4)
190; CHECK-NEXT:    ldx 5, 4, var_long_long@tls
191; CHECK-NEXT:    add 3, 5, 3
192; CHECK-NEXT:    stdx 3, 4, var_long_long@tls
193; CHECK-NEXT:    blr
194entry:
195  %0 = load i64, ptr @var_long_long, align 8, !tbaa !11
196  %add = add nsw i64 %0, %a
197  store i64 %add, ptr @var_long_long, align 8, !tbaa !11
198  ret i64 %add
199}
200
201define float @test_float_one() {
202; CHECK-LABEL: test_float_one:
203; CHECK:       # %bb.0: # %entry
204; CHECK-NEXT:    addis 3, 2, var_float@got@tprel@ha
205; CHECK-NEXT:    ld 3, var_float@got@tprel@l(3)
206; CHECK-NEXT:    lfsx 1, 3, var_float@tls
207; CHECK-NEXT:    blr
208entry:
209  %0 = load float, ptr @var_float, align 4
210  ret float %0
211}
212
213define void @test_float_two(float %a) {
214; CHECK-LABEL: test_float_two:
215; CHECK:       # %bb.0: # %entry
216; CHECK-NEXT:    addis 3, 2, var_float@got@tprel@ha
217; CHECK-NEXT:    ld 3, var_float@got@tprel@l(3)
218; CHECK-NEXT:    stfsx 1, 3, var_float@tls
219; CHECK-NEXT:    blr
220entry:
221  store float %a, ptr @var_float, align 4
222  ret void
223}
224
225define double @test_double_one() {
226; CHECK-LABEL: test_double_one:
227; CHECK:       # %bb.0: # %entry
228; CHECK-NEXT:    addis 3, 2, var_double@got@tprel@ha
229; CHECK-NEXT:    ld 3, var_double@got@tprel@l(3)
230; CHECK-NEXT:    lfdx 1, 3, var_double@tls
231; CHECK-NEXT:    blr
232entry:
233  %0 = load double, ptr @var_double, align 8
234  ret double %0
235}
236
237define void @test_double_two(double %a) {
238; CHECK-LABEL: test_double_two:
239; CHECK:       # %bb.0: # %entry
240; CHECK-NEXT:    addis 3, 2, var_double@got@tprel@ha
241; CHECK-NEXT:    ld 3, var_double@got@tprel@l(3)
242; CHECK-NEXT:    stfdx 1, 3, var_double@tls
243; CHECK-NEXT:    blr
244entry:
245  store double %a, ptr @var_double, align 8
246  ret void
247}
248
249!llvm.module.flags = !{!0, !1, !2}
250
251!0 = !{i32 1, !"wchar_size", i32 4}
252!1 = !{i32 7, !"PIC Level", i32 1}
253!2 = !{i32 7, !"PIE Level", i32 1}
254!4 = !{!5, !5, i64 0}
255!5 = !{!"omnipotent char", !6, i64 0}
256!6 = !{!"Simple C/C++ TBAA"}
257!7 = !{!8, !8, i64 0}
258!8 = !{!"short", !5, i64 0}
259!9 = !{!10, !10, i64 0}
260!10 = !{!"int", !5, i64 0}
261!11 = !{!12, !12, i64 0}
262!12 = !{!"long long", !5, i64 0}
263