1; FIXME: FastISel currently returns false if it hits code that uses VSX
2; registers and with -fast-isel-abort=1 turned on the test case will then fail.
3; When fastisel better supports VSX fix up this test case.
4;
5; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel -fast-isel-abort=1 -mattr=-vsx -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s --check-prefix=ELF64
6
7; This test verifies that load/store instructions are properly generated,
8; and that they pass MI verification.
9
10@a = global i8 1, align 1
11@b = global i16 2, align 2
12@c = global i32 4, align 4
13@d = global i64 8, align 8
14@e = global float 1.25, align 4
15@f = global double 3.5, align 8
16
17%struct.s = type<{ i8, i32 }>
18%struct.t = type<{ i8, i64 }>
19
20@g = global %struct.s <{ i8 1, i32 2 }>, align 1
21@h = global %struct.t <{ i8 1, i64 2 }>, align 1
22
23@i = common global [8192 x i64] zeroinitializer, align 8
24
25; load
26
27define i8 @t1() nounwind {
28; ELF64: t1
29  %1 = load i8, i8* @a, align 1
30; ELF64: lbz
31  %2 = add nsw i8 %1, 1
32; ELF64: addi
33  ret i8 %2
34}
35
36define i16 @t2() nounwind {
37; ELF64: t2
38  %1 = load i16, i16* @b, align 2
39; ELF64: lhz
40  %2 = add nsw i16 %1, 1
41; ELF64: addi
42  ret i16 %2
43}
44
45define i32 @t3() nounwind {
46; ELF64: t3
47  %1 = load i32, i32* @c, align 4
48; ELF64: lwz
49  %2 = add nsw i32 %1, 1
50; ELF64: addi
51  ret i32 %2
52}
53
54define i64 @t4() nounwind {
55; ELF64: t4
56  %1 = load i64, i64* @d, align 4
57; ELF64: ld
58  %2 = add nsw i64 %1, 1
59; ELF64: addi
60  ret i64 %2
61}
62
63define float @t5() nounwind {
64; ELF64: t5
65  %1 = load float, float* @e, align 4
66; ELF64: lfs
67  %2 = fadd float %1, 1.0
68; ELF64: fadds
69  ret float %2
70}
71
72define double @t6() nounwind {
73; ELF64: t6
74  %1 = load double, double* @f, align 8
75; ELF64: lfd
76  %2 = fadd double %1, 1.0
77; ELF64: fadd
78  ret double %2
79}
80
81; store
82
83define void @t7(i8 %v) nounwind {
84; ELF64: t7
85  %1 = add nsw i8 %v, 1
86  store i8 %1, i8* @a, align 1
87; ELF64: addis
88; ELF64: addi
89; ELF64: addi
90; ELF64: stb
91  ret void
92}
93
94define void @t8(i16 %v) nounwind {
95; ELF64: t8
96  %1 = add nsw i16 %v, 1
97  store i16 %1, i16* @b, align 2
98; ELF64: addis
99; ELF64: addi
100; ELF64: addi
101; ELF64: sth
102  ret void
103}
104
105define void @t9(i32 %v) nounwind {
106; ELF64: t9
107  %1 = add nsw i32 %v, 1
108  store i32 %1, i32* @c, align 4
109; ELF64: addis
110; ELF64: addi
111; ELF64: addi
112; ELF64: stw
113  ret void
114}
115
116define void @t10(i64 %v) nounwind {
117; ELF64: t10
118  %1 = add nsw i64 %v, 1
119  store i64 %1, i64* @d, align 4
120; ELF64: addis
121; ELF64: addi
122; ELF64: addi
123; ELF64: std
124  ret void
125}
126
127define void @t11(float %v) nounwind {
128; ELF64: t11
129  %1 = fadd float %v, 1.0
130  store float %1, float* @e, align 4
131; ELF64: fadds
132; ELF64: stfs
133  ret void
134}
135
136define void @t12(double %v) nounwind {
137; ELF64: t12
138  %1 = fadd double %v, 1.0
139  store double %1, double* @f, align 8
140; ELF64: fadd
141; ELF64: stfd
142  ret void
143}
144
145;; lwa requires an offset divisible by 4, so we need lwax here.
146define i64 @t13() nounwind {
147; ELF64: t13
148  %1 = load i32, i32* getelementptr inbounds (%struct.s, %struct.s* @g, i32 0, i32 1), align 1
149  %2 = sext i32 %1 to i64
150; ELF64: li
151; ELF64: lwax
152  %3 = add nsw i64 %2, 1
153; ELF64: addi
154  ret i64 %3
155}
156
157;; ld requires an offset divisible by 4, so we need ldx here.
158define i64 @t14() nounwind {
159; ELF64: t14
160  %1 = load i64, i64* getelementptr inbounds (%struct.t, %struct.t* @h, i32 0, i32 1), align 1
161; ELF64: li
162; ELF64: ldx
163  %2 = add nsw i64 %1, 1
164; ELF64: addi
165  ret i64 %2
166}
167
168;; std requires an offset divisible by 4, so we need stdx here.
169define void @t15(i64 %v) nounwind {
170; ELF64: t15
171  %1 = add nsw i64 %v, 1
172  store i64 %1, i64* getelementptr inbounds (%struct.t, %struct.t* @h, i32 0, i32 1), align 1
173; ELF64: addis
174; ELF64: addi
175; ELF64: addi
176; ELF64: li
177; ELF64: stdx
178  ret void
179}
180
181;; ld requires an offset that fits in 16 bits, so we need ldx here.
182define i64 @t16() nounwind {
183; ELF64: t16
184  %1 = load i64, i64* getelementptr inbounds ([8192 x i64], [8192 x i64]* @i, i32 0, i64 5000), align 8
185; ELF64: lis
186; ELF64: ori
187; ELF64: ldx
188  %2 = add nsw i64 %1, 1
189; ELF64: addi
190  ret i64 %2
191}
192
193;; std requires an offset that fits in 16 bits, so we need stdx here.
194define void @t17(i64 %v) nounwind {
195; ELF64: t17
196  %1 = add nsw i64 %v, 1
197  store i64 %1, i64* getelementptr inbounds ([8192 x i64], [8192 x i64]* @i, i32 0, i64 5000), align 8
198; ELF64: addis
199; ELF64: ld
200; ELF64: addi
201; ELF64: lis
202; ELF64: ori
203; ELF64: stdx
204  ret void
205}
206
207