xref: /llvm-project/llvm/test/CodeGen/PowerPC/toc-data.ll (revision a51712751c184ebe056718c938d2526693a31564)
1; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s \
2; RUN:     -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32
3; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s \
4; RUN:     -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK64
5; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32
6; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST64
7
8; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s \
9; RUN:     -stop-before=ppc-vsx-copy -O0  | FileCheck %s --check-prefix CHECK32
10; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s \
11; RUN:     -stop-before=ppc-vsx-copy -O0 | FileCheck %s --check-prefix CHECK64-NOOPT
12; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST32
13; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST64
14
15; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s \
16; RUN:     -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32LARGE
17; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32LARGE
18
19; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s \
20; RUN:     -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK64LARGE
21; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST64LARGE
22
23; Global variables i and f have the toc-data attribute.
24; In the following functions, those writing to or reading from
25; variables i and f should use the toc-data access pattern.
26; All remaining variables should use the regular toc access sequence.
27@i = dso_local global i32 0, align 4 #0
28@d = dso_local local_unnamed_addr global double 3.141590e+00, align 8
29@f = dso_local local_unnamed_addr global float 0x4005BE76C0000000, align 4 #0
30@ll = dso_local local_unnamed_addr global i64 55, align 8
31@ilocal = internal global i32 0, align 4
32
33define dso_local void @write_int(i32 signext %in) {
34  entry:
35    store i32 %in, ptr @i, align 4
36    ret void
37}
38; CHECK32: name:            write_int
39; CHECK32:      %[[SCRATCH:[0-9]+]]:gprc_and_gprc_nor0 = ADDItoc $r2, @i
40; CHECK32-NEXT: STW %{{[0-9]+}}, 0, killed %[[SCRATCH]] :: (store (s32) into @i)
41
42; TEST32:         .write_int:
43; TEST32:           la 4, i[TD](2)
44; TEST32-NEXT:      stw 3, 0(4)
45
46; CHECK64: name:            write_int
47; CHECK64:      %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @i
48; CHECK64-NEXT: STW8 %{{[0-9]+}}, 0, killed %[[SCRATCH]] :: (store (s32) into @i)
49
50; CHECK64-NOOPT:  name: write_int
51; CHECK64-NOOPT:    %[[SUBREG:[0-9]+]]:gprc = COPY %{{[0-9]}}.sub_32
52; CHECK64-NOOPT:    %[[ADDR:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @i
53; CHECK64-NOOPT:    STW %[[SUBREG]], 0, %[[ADDR]]
54
55; TEST64:         .write_int:
56; TEST64:           la 4, i[TD](2)
57; TEST64-NEXT:      stw 3, 0(4)
58
59; CHECK32LARGE: name:            write_int
60; CHECK32LARGE:      %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @i
61; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc_and_gprc_nor0 = ADDItocL killed %[[SCRATCH1]], @i
62; CHECK32LARGE-NEXT: STW %{{[0-9]+}}, 0, killed %[[SCRATCH2]] :: (store (s32) into @i)
63
64; FIXME: peephole optimization opportunity for lower part relocation @l to the consuming stw
65; TEST32LARGE:         .write_int:
66; TEST32LARGE:          addis 4, i[TD]@u(2)
67; TEST32LARGE-NEXT:	la 4, i[TD]@l(4)
68; TEST32LARGE-NEXT:	stw 3, 0(4)
69
70
71; CHECK64LARGE: name:            write_int
72; CHECK64LARGE:      %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @i
73; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItocL8 killed %[[SCRATCH1]], @i
74; CHECK64LARGE-NEXT: STW8 %{{[0-9]+}}, 0, killed %[[SCRATCH2]] :: (store (s32) into @i)
75
76; TEST64LARGE:         .write_int:
77; TEST64LARGE:          addis 4, i[TD]@u(2)
78; TEST64LARGE-NEXT:	la 4, i[TD]@l(4)
79; TEST64LARGE-NEXT:	stw 3, 0(4)
80
81define dso_local i64 @read_ll() {
82  entry:
83    %0 = load i64, ptr @ll, align 8
84    ret i64 %0
85}
86; CHECK32: name:            read_ll
87; CHECK32: LWZtoc @ll, $r2 :: (load (s32) from got)
88
89; TEST32:       .read_ll:
90; TEST32:         lwz 4, L..C0(2)
91; TEST32-NEXT:    lwz 3, 0(4)
92; TEST32-NEXT:    lwz 4, 4(4)
93
94; CHECK64: name:            read_ll
95; CHECK64:   %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @ll, $x2 :: (load (s64) from got)
96; CHECK64:   LD 0, killed %[[SCRATCH]]
97
98; CHECK64-NOOPT: name:            read_ll
99; CHECK64-NOOPT:   %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @ll, $x2
100; CHECK64-NOOPT:   LD 0, %[[SCRATCH]]
101
102; TEST64:       .read_ll:
103; TEST64:         ld 3, L..C0(2)
104; TEST64-NEXT:    ld 3, 0(3)
105
106; CHECK32LARGE: name:            read_ll
107; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @ll
108; CHECK32LARGE: LWZtocL @ll, killed %[[SCRATCH1]] :: (load (s32) from got)
109
110; TEST32LARGE:         .read_ll:
111; TEST32LARGE:          addis 3, L..C0@u(2)
112; TEST32LARGE-NEXT:	lwz 4, L..C0@l(3)
113; TEST32LARGE-NEXT:	lwz 3, 0(4)
114; TEST32LARGE-NEXT:	lwz 4, 4(4)
115
116; CHECK64LARGE: name:            read_ll
117; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @ll
118; CHECK64LARGE: LDtocL @ll, killed %[[SCRATCH1]] :: (load (s64) from got)
119
120; TEST64LARGE:         .read_ll:
121; TEST64LARGE:          addis 3, L..C0@u(2)
122; TEST64LARGE-NEXT:	ld 3, L..C0@l(3)
123; TEST64LARGE-NEXT:	ld 3, 0(3)
124
125define dso_local float @read_float() {
126  entry:
127    %0 = load float, ptr @f, align 4
128    ret float %0
129}
130; CHECK32: name:            read_float
131; CHECK32: %[[SCRATCH:[0-9]+]]:gprc_and_gprc_nor0 = ADDItoc $r2, @f
132; CHECK32: %{{[0-9]+}}:f4rc = LFS 0, killed %[[SCRATCH]] :: (dereferenceable load (s32) from @f)
133
134; TEST32:       .read_float:
135; TEST32:         la 3, f[TD](2)
136; TEST32-NEXT:    lfs 1, 0(3)
137
138; CHECK64: name:            read_float
139; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @f
140; CHECK64: %{{[0-9]+}}:f4rc = LFS 0, killed %[[SCRATCH]] :: (dereferenceable load (s32) from @f)
141
142; CHECK64-NOOPT: name:            read_float
143; CHECK64-NOOPT:   %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @f
144; CHECK64-NOOPT:   %{{[0-9]+}}:f4rc = LFS 0, %[[SCRATCH]]
145
146; TEST64:       .read_float:
147; TEST64:         la 3, f[TD](2)
148; TEST64-NEXT:    lfs 1, 0(3)
149
150; CHECK32LARGE: name:            read_float
151; CHECK32LARGE:      %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @f
152; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc_and_gprc_nor0 = ADDItocL killed %[[SCRATCH1]], @f
153; CHECK32LARGE-NEXT: LFS 0, killed %[[SCRATCH2]] :: (dereferenceable load (s32) from @f)
154
155; FIXME: peephole optimization opportunity for lower part relocation @l to the consuming lfs
156; TEST32LARGE:         .read_float:
157; TEST32LARGE:          addis 3, f[TD]@u(2)
158; TEST32LARGE-NEXT:	la 3, f[TD]@l(3)
159; TEST32LARGE-NEXT:	lfs 1, 0(3)
160
161
162; CHECK64LARGE: name:            read_float
163; CHECK64LARGE:      %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @f
164; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItocL8 killed %[[SCRATCH1]], @f
165; CHECK64LARGE-NEXT: LFS 0, killed %[[SCRATCH2]] :: (dereferenceable load (s32) from @f)
166
167
168; TEST64LARGE:         .read_float:
169; TEST64LARGE:          addis 3, f[TD]@u(2)
170; TEST64LARGE-NEXT:	la 3, f[TD]@l(3)
171; TEST64LARGE-NEXT:	lfs 1, 0(3)
172
173define dso_local void @write_double(double %in) {
174  entry:
175    store double %in, ptr @d, align 8
176    ret void
177}
178; CHECK32: name:            write_double
179; CHECK32: LWZtoc @d, $r2 :: (load (s32) from got)
180
181; TEST32:       .write_double
182; TEST32:         lwz 3, L..C1(2)
183; TEST32-NEXT:    stfd 1, 0(3)
184
185; CHECK64: name:            write_double
186; CHECK64:   %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @d, $x2 :: (load (s64) from got)
187; CHECK64:   STFD %{{[0-9]+}}, 0, killed %[[SCRATCH]]
188
189; CHECK64-NOOPT: name:            write_double
190; CHECK64-NOOPT:   %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @d, $x2
191; CHECK64-NOOPT    STFD %{{[0-9]+}}, 0 %[[SCRATCH]]
192
193; TEST64:       .write_double
194; TEST64:         ld 3, L..C1(2)
195; TEST64-NEXT:    stfd 1, 0(3)
196
197; CHECK32LARGE: name:            write_double
198; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @d
199; CHECK32LARGE: LWZtocL @d, killed %[[SCRATCH1]] :: (load (s32) from got)
200
201; TEST32LARGE:         .write_double:
202; TEST32LARGE:          addis 3, L..C1@u(2)
203; TEST32LARGE-NEXT:	lwz 3, L..C1@l(3)
204; TEST32LARGE-NEXT:	stfd 1, 0(3)
205
206; CHECK64LARGE: name:            write_double
207; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @d
208; CHECK64LARGE: LDtocL @d, killed %[[SCRATCH1]] :: (load (s64) from got)
209
210; TEST64LARGE:         .write_double:
211; TEST64LARGE:          addis 3, L..C1@u(2)
212; TEST64LARGE-NEXT:	ld 3, L..C1@l(3)
213; TEST64LARGE-NEXT:	stfd 1, 0(3)
214
215define dso_local nonnull ptr @addr() {
216  entry:
217    ret ptr @i
218}
219; CHECK32: name:            addr
220; CHECK32:       %[[SCRATCH:[0-9]+]]:gprc = ADDItoc $r2, @i
221; CHECK32-NEXT:  $r3 = COPY %[[SCRATCH]]
222
223; TEST32:       .addr
224; TEST32:         la 3, i[TD](2)
225
226; CHECK64: name:            addr
227; CHECK64:       %[[SCRATCH:[0-9]+]]:g8rc = ADDItoc8 $x2, @i
228; CHECK64-NEXT:  $x3 = COPY %[[SCRATCH]]
229
230; CHECK64-NOOPT: name:            addr
231; CHECK64-NOOPT:   %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @i
232; CHECK64-NOOPT:   $x3 = COPY %[[SCRATCH]]
233
234; TEST64:       .addr
235; TEST64:         la 3, i[TD](2)
236
237; CHECK32LARGE: name:            addr
238; CHECK32LARGE:      %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @i
239; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc = ADDItocL killed %[[SCRATCH1]], @i
240; CHECK32LARGE-NEXT: $r3 = COPY %[[SCRATCH2]]
241
242; TEST32LARGE:         .addr:
243; TEST32LARGE:          addis 3, i[TD]@u(2)
244; TEST32LARGE-NEXT:	la 3, i[TD]@l(3)
245
246; TEST32:         .toc
247; TEST32:           .tc ll[TC],ll[RW]
248; TEST32-NOT:       .csect ll[TD]
249; TEST32:           .tc d[TC],d[RW]
250; TEST32-NOT:       .csect d[TD],2
251; TEST32:           .csect i[TD],2
252; TEST32-NEXT:      .globl  i[TD]
253; TEST32-NEXT:      .align  2
254; TEST32-NOT:       .tc i[TC],i[RW]
255; TEST32:           .csect f[TD],2
256; TEST32-NEXT:      .globl f[TD]
257; TEST32-NOT:       .tc f[TD],f[RW]
258
259; TEST64:         .toc
260; TEST64:           .tc ll[TC],ll[RW]
261; TEST64-NOT:       .csect ll[TD]
262; TEST64:           .tc d[TC],d[RW]
263; TEST64-NOT:       .csect d[TD],2
264; TEST64:           .csect i[TD],2
265; TEST64-NEXT:      .globl  i[TD]
266; TEST64-NEXT:      .align  2
267; TEST64-NOT:       .tc i[TC],i[RW]
268; TEST64:           .csect f[TD],2
269; TEST64-NEXT:      .globl f[TD]
270; TEST64-NOT:       .tc f[TD],f[RW]
271
272; TEST32LARGE:         .toc
273; TEST32LARGE:           .tc ll[TE],ll[RW]
274; TEST32LARGE-NOT:       .csect ll[TD]
275; TEST32LARGE:           .tc d[TE],d[RW]
276; TEST32LARGE-NOT:       .csect d[TD],2
277; TEST32LARGE:           .csect i[TD],2
278; TEST32LARGE-NEXT:      .globl  i[TD]
279; TEST32LARGE-NEXT:      .align  2
280; TEST32LARGE-NOT:       .tc i[TE],i[RW]
281; TEST32LARGE:           .csect f[TD],2
282; TEST32LARGE-NEXT:      .globl f[TD]
283; TEST32LARGE-NOT:       .tc f[TE],f[RW]
284
285; CHECK64LARGE: name:            addr
286; CHECK64LARGE:      %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @i
287; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc = ADDItocL8 killed %[[SCRATCH1]], @i
288; CHECK64LARGE-NEXT: $x3 = COPY %[[SCRATCH2]]
289
290; TEST64LARGE:         .addr:
291; TEST64LARGE:          addis 3, i[TD]@u(2)
292; TEST64LARGE:          la 3, i[TD]@l(3)
293
294; TEST64LARGE:         .toc
295; TEST64LARGE:           .tc ll[TE],ll[RW]
296; TEST64LARGE-NOT:       .csect ll[TD]
297; TEST64LARGE:           .tc d[TE],d[RW]
298; TEST64LARGE-NOT:       .csect d[TD],2
299; TEST64LARGE:           .csect i[TD],2
300; TEST64LARGE-NEXT:      .globl  i[TD]
301; TEST64LARGE-NEXT:      .align  2
302; TEST64LARGE-NOT:       .tc i[TE],i[RW]
303; TEST64LARGE:           .csect f[TD],2
304; TEST64LARGE-NEXT:      .globl f[TD]
305; TEST64LARGE-NOT:       .tc f[TE],f[RW]
306
307attributes #0 = { "toc-data" }
308