[PPC]: Peephole optimize small accesss to aligned globals.
[oota-llvm.git] / test / CodeGen / PowerPC / peephole-align.ll
1 ; RUN: llc -mcpu=pwr7 -O1 -code-model=medium <%s | FileCheck -check-prefix=POWER7 -check-prefix=CHECK %s
2 ; RUN: llc -mcpu=pwr8 -O1 -code-model=medium <%s | FileCheck -check-prefix=POWER8 -check-prefix=CHECK %s
3
4 ; Test peephole optimization for medium code model (32-bit TOC offsets)
5 ; for loading and storing small offsets within aligned values.
6 ; For power8, verify that the optimization doesn't fire, as it prevents fusion
7 ; opportunities.
8
9 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
10 target triple = "powerpc64-unknown-linux-gnu"
11
12 %struct.b4 = type<{ i8, i8, i8, i8 }>
13 %struct.h2 = type<{ i16, i16 }>
14
15 %struct.b8 = type<{ i8, i8, i8, i8, i8, i8, i8, i8 }>
16 %struct.h4 = type<{ i16, i16, i16, i16 }>
17 %struct.w2 = type<{ i32, i32 }>
18
19 %struct.d2 = type<{ i64, i64 }>
20 %struct.misalign = type<{ i8, i64 }>
21
22 @b4v = global %struct.b4 <{ i8 1, i8 2, i8 3, i8 4 }>, align 4
23 @h2v = global %struct.h2 <{ i16 1, i16 2 }>, align 4
24
25 @b8v = global %struct.b8 <{ i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8 }>, align 8
26 @h4v = global %struct.h4 <{ i16 1, i16 2, i16 3, i16 4 }>, align 8
27 @w2v = global %struct.w2 <{ i32 1, i32 2 }>, align 8
28
29 @d2v = global %struct.d2 <{ i64 1, i64 2 }>, align 16
30 @misalign_v = global %struct.misalign <{ i8 1, i64 2 }>, align 16
31
32 ; CHECK-LABEL: test_b4:
33 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, b4v@toc@ha
34 ; POWER7-DAG: lbz [[REG0_0:[0-9]+]], b4v@toc@l([[REGSTRUCT]])
35 ; POWER7-DAG: lbz [[REG1_0:[0-9]+]], b4v@toc@l+1([[REGSTRUCT]])
36 ; POWER7-DAG: lbz [[REG2_0:[0-9]+]], b4v@toc@l+2([[REGSTRUCT]])
37 ; POWER7-DAG: lbz [[REG3_0:[0-9]+]], b4v@toc@l+3([[REGSTRUCT]])
38 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
39 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
40 ; POWER7-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
41 ; POWER7-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
42 ; POWER7-DAG: stb [[REG0_1]], b4v@toc@l([[REGSTRUCT]])
43 ; POWER7-DAG: stb [[REG1_1]], b4v@toc@l+1([[REGSTRUCT]])
44 ; POWER7-DAG: stb [[REG2_1]], b4v@toc@l+2([[REGSTRUCT]])
45 ; POWER7-DAG: stb [[REG3_1]], b4v@toc@l+3([[REGSTRUCT]])
46
47 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, b4v@toc@ha
48 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], b4v@toc@l
49 ; POWER8-DAG: lbz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
50 ; POWER8-DAG: lbz [[REG1_0:[0-9]+]], 1([[REGSTRUCT]])
51 ; POWER8-DAG: lbz [[REG2_0:[0-9]+]], 2([[REGSTRUCT]])
52 ; POWER8-DAG: lbz [[REG3_0:[0-9]+]], 3([[REGSTRUCT]])
53 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
54 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
55 ; POWER8-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
56 ; POWER8-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
57 ; POWER8-DAG: stb [[REG0_1]], 0([[REGSTRUCT]])
58 ; POWER8-DAG: stb [[REG1_1]], 1([[REGSTRUCT]])
59 ; POWER8-DAG: stb [[REG2_1]], 2([[REGSTRUCT]])
60 ; POWER8-DAG: stb [[REG3_1]], 3([[REGSTRUCT]])
61 define void @test_b4() nounwind {
62 entry:
63   %0 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 0), align 1
64   %inc0 = add nsw i8 %0, 1
65   store i8 %inc0, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 0), align 1
66   %1 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 1), align 1
67   %inc1 = add nsw i8 %1, 2
68   store i8 %inc1, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 1), align 1
69   %2 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 2), align 1
70   %inc2 = add nsw i8 %2, 3
71   store i8 %inc2, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 2), align 1
72   %3 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 3), align 1
73   %inc3 = add nsw i8 %3, 4
74   store i8 %inc3, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 3), align 1
75   ret void
76 }
77
78 ; CHECK-LABEL: test_h2:
79 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
80 ; POWER7-DAG: lhz [[REG0_0:[0-9]+]], h2v@toc@l([[REGSTRUCT]])
81 ; POWER7-DAG: lhz [[REG1_0:[0-9]+]], h2v@toc@l+2([[REGSTRUCT]])
82 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
83 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
84 ; POWER7-DAG: sth [[REG0_1]], h2v@toc@l([[REGSTRUCT]])
85 ; POWER7-DAG: sth [[REG1_1]], h2v@toc@l+2([[REGSTRUCT]])
86
87 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
88 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], h2v@toc@l
89 ; POWER8-DAG: lhz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
90 ; POWER8-DAG: lhz [[REG1_0:[0-9]+]], 2([[REGSTRUCT]])
91 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
92 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
93 ; POWER8-DAG: sth [[REG0_1]], 0([[REGSTRUCT]])
94 ; POWER8-DAG: sth [[REG1_1]], 2([[REGSTRUCT]])
95 define void @test_h2() nounwind {
96 entry:
97   %0 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
98   %inc0 = add nsw i16 %0, 1
99   store i16 %inc0, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
100   %1 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
101   %inc1 = add nsw i16 %1, 2
102   store i16 %inc1, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
103   ret void
104 }
105
106 ; CHECK-LABEL: test_h2_optsize:
107 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
108 ; CHECK-DAG: lhz [[REG0_0:[0-9]+]], h2v@toc@l([[REGSTRUCT]])
109 ; CHECK-DAG: lhz [[REG1_0:[0-9]+]], h2v@toc@l+2([[REGSTRUCT]])
110 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
111 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
112 ; CHECK-DAG: sth [[REG0_1]], h2v@toc@l([[REGSTRUCT]])
113 ; CHECK-DAG: sth [[REG1_1]], h2v@toc@l+2([[REGSTRUCT]])
114 define void @test_h2_optsize() optsize nounwind {
115 entry:
116   %0 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
117   %inc0 = add nsw i16 %0, 1
118   store i16 %inc0, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
119   %1 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
120   %inc1 = add nsw i16 %1, 2
121   store i16 %inc1, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
122   ret void
123 }
124
125 ; CHECK-LABEL: test_b8:
126 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, b8v@toc@ha
127 ; POWER7-DAG: lbz [[REG0_0:[0-9]+]], b8v@toc@l([[REGSTRUCT]])
128 ; POWER7-DAG: lbz [[REG1_0:[0-9]+]], b8v@toc@l+1([[REGSTRUCT]])
129 ; POWER7-DAG: lbz [[REG2_0:[0-9]+]], b8v@toc@l+2([[REGSTRUCT]])
130 ; POWER7-DAG: lbz [[REG3_0:[0-9]+]], b8v@toc@l+3([[REGSTRUCT]])
131 ; POWER7-DAG: lbz [[REG4_0:[0-9]+]], b8v@toc@l+4([[REGSTRUCT]])
132 ; POWER7-DAG: lbz [[REG5_0:[0-9]+]], b8v@toc@l+5([[REGSTRUCT]])
133 ; POWER7-DAG: lbz [[REG6_0:[0-9]+]], b8v@toc@l+6([[REGSTRUCT]])
134 ; POWER7-DAG: lbz [[REG7_0:[0-9]+]], b8v@toc@l+7([[REGSTRUCT]])
135 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
136 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
137 ; POWER7-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
138 ; POWER7-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
139 ; POWER7-DAG: addi [[REG4_1:[0-9]+]], [[REG4_0]], 5
140 ; POWER7-DAG: addi [[REG5_1:[0-9]+]], [[REG5_0]], 6
141 ; POWER7-DAG: addi [[REG6_1:[0-9]+]], [[REG6_0]], 7
142 ; POWER7-DAG: addi [[REG7_1:[0-9]+]], [[REG7_0]], 8
143 ; POWER7-DAG: stb [[REG0_1]], b8v@toc@l([[REGSTRUCT]])
144 ; POWER7-DAG: stb [[REG1_1]], b8v@toc@l+1([[REGSTRUCT]])
145 ; POWER7-DAG: stb [[REG2_1]], b8v@toc@l+2([[REGSTRUCT]])
146 ; POWER7-DAG: stb [[REG3_1]], b8v@toc@l+3([[REGSTRUCT]])
147 ; POWER7-DAG: stb [[REG4_1]], b8v@toc@l+4([[REGSTRUCT]])
148 ; POWER7-DAG: stb [[REG5_1]], b8v@toc@l+5([[REGSTRUCT]])
149 ; POWER7-DAG: stb [[REG6_1]], b8v@toc@l+6([[REGSTRUCT]])
150 ; POWER7-DAG: stb [[REG7_1]], b8v@toc@l+7([[REGSTRUCT]])
151
152 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, b8v@toc@ha
153 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], b8v@toc@l
154 ; POWER8-DAG: lbz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
155 ; POWER8-DAG: lbz [[REG1_0:[0-9]+]], 1([[REGSTRUCT]])
156 ; POWER8-DAG: lbz [[REG2_0:[0-9]+]], 2([[REGSTRUCT]])
157 ; POWER8-DAG: lbz [[REG3_0:[0-9]+]], 3([[REGSTRUCT]])
158 ; POWER8-DAG: lbz [[REG4_0:[0-9]+]], 4([[REGSTRUCT]])
159 ; POWER8-DAG: lbz [[REG5_0:[0-9]+]], 5([[REGSTRUCT]])
160 ; POWER8-DAG: lbz [[REG6_0:[0-9]+]], 6([[REGSTRUCT]])
161 ; POWER8-DAG: lbz [[REG7_0:[0-9]+]], 7([[REGSTRUCT]])
162 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
163 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
164 ; POWER8-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
165 ; POWER8-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
166 ; POWER8-DAG: addi [[REG4_1:[0-9]+]], [[REG4_0]], 5
167 ; POWER8-DAG: addi [[REG5_1:[0-9]+]], [[REG5_0]], 6
168 ; POWER8-DAG: addi [[REG6_1:[0-9]+]], [[REG6_0]], 7
169 ; POWER8-DAG: addi [[REG7_1:[0-9]+]], [[REG7_0]], 8
170 ; POWER8-DAG: stb [[REG0_1]], 0([[REGSTRUCT]])
171 ; POWER8-DAG: stb [[REG1_1]], 1([[REGSTRUCT]])
172 ; POWER8-DAG: stb [[REG2_1]], 2([[REGSTRUCT]])
173 ; POWER8-DAG: stb [[REG3_1]], 3([[REGSTRUCT]])
174 ; POWER8-DAG: stb [[REG4_1]], 4([[REGSTRUCT]])
175 ; POWER8-DAG: stb [[REG5_1]], 5([[REGSTRUCT]])
176 ; POWER8-DAG: stb [[REG6_1]], 6([[REGSTRUCT]])
177 ; POWER8-DAG: stb [[REG7_1]], 7([[REGSTRUCT]])
178 define void @test_b8() nounwind {
179 entry:
180   %0 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 0), align 1
181   %inc0 = add nsw i8 %0, 1
182   store i8 %inc0, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 0), align 1
183   %1 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 1), align 1
184   %inc1 = add nsw i8 %1, 2
185   store i8 %inc1, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 1), align 1
186   %2 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 2), align 1
187   %inc2 = add nsw i8 %2, 3
188   store i8 %inc2, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 2), align 1
189   %3 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 3), align 1
190   %inc3 = add nsw i8 %3, 4
191   store i8 %inc3, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 3), align 1
192   %4 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 4), align 1
193   %inc4 = add nsw i8 %4, 5
194   store i8 %inc4, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 4), align 1
195   %5 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 5), align 1
196   %inc5 = add nsw i8 %5, 6
197   store i8 %inc5, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 5), align 1
198   %6 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 6), align 1
199   %inc6 = add nsw i8 %6, 7
200   store i8 %inc6, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 6), align 1
201   %7 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 7), align 1
202   %inc7 = add nsw i8 %7, 8
203   store i8 %inc7, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 7), align 1
204   ret void
205 }
206
207 ; CHECK-LABEL: test_h4:
208 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, h4v@toc@ha
209 ; POWER7-DAG: lhz [[REG0_0:[0-9]+]], h4v@toc@l([[REGSTRUCT]])
210 ; POWER7-DAG: lhz [[REG1_0:[0-9]+]], h4v@toc@l+2([[REGSTRUCT]])
211 ; POWER7-DAG: lhz [[REG2_0:[0-9]+]], h4v@toc@l+4([[REGSTRUCT]])
212 ; POWER7-DAG: lhz [[REG3_0:[0-9]+]], h4v@toc@l+6([[REGSTRUCT]])
213 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
214 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
215 ; POWER7-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
216 ; POWER7-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
217 ; POWER7-DAG: sth [[REG0_1]], h4v@toc@l([[REGSTRUCT]])
218 ; POWER7-DAG: sth [[REG1_1]], h4v@toc@l+2([[REGSTRUCT]])
219 ; POWER7-DAG: sth [[REG2_1]], h4v@toc@l+4([[REGSTRUCT]])
220 ; POWER7-DAG: sth [[REG3_1]], h4v@toc@l+6([[REGSTRUCT]])
221
222 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, h4v@toc@ha
223 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], h4v@toc@l
224 ; POWER8-DAG: lhz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
225 ; POWER8-DAG: lhz [[REG1_0:[0-9]+]], 2([[REGSTRUCT]])
226 ; POWER8-DAG: lhz [[REG2_0:[0-9]+]], 4([[REGSTRUCT]])
227 ; POWER8-DAG: lhz [[REG3_0:[0-9]+]], 6([[REGSTRUCT]])
228 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
229 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
230 ; POWER8-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
231 ; POWER8-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
232 ; POWER8-DAG: sth [[REG0_1]], 0([[REGSTRUCT]])
233 ; POWER8-DAG: sth [[REG1_1]], 2([[REGSTRUCT]])
234 ; POWER8-DAG: sth [[REG2_1]], 4([[REGSTRUCT]])
235 ; POWER8-DAG: sth [[REG3_1]], 6([[REGSTRUCT]])
236 define void @test_h4() nounwind {
237 entry:
238   %0 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 0), align 2
239   %inc0 = add nsw i16 %0, 1
240   store i16 %inc0, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 0), align 2
241   %1 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 1), align 2
242   %inc1 = add nsw i16 %1, 2
243   store i16 %inc1, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 1), align 2
244   %2 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 2), align 2
245   %inc2 = add nsw i16 %2, 3
246   store i16 %inc2, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 2), align 2
247   %3 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 3), align 2
248   %inc3 = add nsw i16 %3, 4
249   store i16 %inc3, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 3), align 2
250   ret void
251 }
252
253 ; CHECK-LABEL: test_w2:
254 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, w2v@toc@ha
255 ; POWER7-DAG: lwz [[REG0_0:[0-9]+]], w2v@toc@l([[REGSTRUCT]])
256 ; POWER7-DAG: lwz [[REG1_0:[0-9]+]], w2v@toc@l+4([[REGSTRUCT]])
257 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
258 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
259 ; POWER7-DAG: stw [[REG0_1]], w2v@toc@l([[REGSTRUCT]])
260 ; POWER7-DAG: stw [[REG1_1]], w2v@toc@l+4([[REGSTRUCT]])
261
262 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, w2v@toc@ha
263 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], w2v@toc@l
264 ; POWER8-DAG: lwz [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
265 ; POWER8-DAG: lwz [[REG1_0:[0-9]+]], 4([[REGSTRUCT]])
266 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
267 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
268 ; POWER8-DAG: stw [[REG0_1]], 0([[REGSTRUCT]])
269 ; POWER8-DAG: stw [[REG1_1]], 4([[REGSTRUCT]])
270 define void @test_w2() nounwind {
271 entry:
272   %0 = load i32, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 0), align 4
273   %inc0 = add nsw i32 %0, 1
274   store i32 %inc0, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 0), align 4
275   %1 = load i32, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 1), align 4
276   %inc1 = add nsw i32 %1, 2
277   store i32 %inc1, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 1), align 4
278   ret void
279 }
280
281 ; CHECK-LABEL: test_d2:
282 ; POWER7: addis [[REGSTRUCT:[0-9]+]], 2, d2v@toc@ha
283 ; POWER7-DAG: ld [[REG0_0:[0-9]+]], d2v@toc@l([[REGSTRUCT]])
284 ; POWER7-DAG: ld [[REG1_0:[0-9]+]], d2v@toc@l+8([[REGSTRUCT]])
285 ; POWER7-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
286 ; POWER7-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
287 ; POWER7-DAG: std [[REG0_1]], d2v@toc@l([[REGSTRUCT]])
288 ; POWER7-DAG: std [[REG1_1]], d2v@toc@l+8([[REGSTRUCT]])
289
290 ; POWER8: addis [[REGSTRUCT:[0-9]+]], 2, d2v@toc@ha
291 ; POWER8-NEXT: addi [[REGSTRUCT]], [[REGSTRUCT]], d2v@toc@l
292 ; POWER8-DAG: ld [[REG0_0:[0-9]+]], 0([[REGSTRUCT]])
293 ; POWER8-DAG: ld [[REG1_0:[0-9]+]], 8([[REGSTRUCT]])
294 ; POWER8-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
295 ; POWER8-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
296 ; POWER8-DAG: std [[REG0_1]], 0([[REGSTRUCT]])
297 ; POWER8-DAG: std [[REG1_1]], 8([[REGSTRUCT]])
298 define void @test_d2() nounwind {
299 entry:
300   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 0), align 8
301   %inc0 = add nsw i64 %0, 1
302   store i64 %inc0, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 0), align 8
303   %1 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
304   %inc1 = add nsw i64 %1, 2
305   store i64 %inc1, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
306   ret void
307 }
308
309 ; Make sure the optimization fires on power8 if there is a single use resulting
310 ; in a better fusion opportunity.
311 ; register 3 is the return value, so it should be chosen
312 ; CHECK-LABEL: test_singleuse:
313 ; CHECK: addis 3, 2, d2v@toc@ha
314 ; CHECK: ld 3, d2v@toc@l+8(3)
315 define i64 @test_singleuse() nounwind {
316 entry:
317   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
318   ret i64 %0
319 }
320
321 ; Make sure the optimization fails to fire if the symbol is aligned, but the offset is not.
322 ; CHECK-LABEL: test_misalign
323 ; POWER7: addis [[REGSTRUCT_0:[0-9]+]], 2, misalign_v@toc@ha
324 ; POWER7: addi [[REGSTRUCT:[0-9]+]], [[REGSTRUCT_0]], misalign_v@toc@l
325 ; POWER7: li [[OFFSET_REG:[0-9]+]], 1
326 ; POWER7: ldx [[REG0_0:[0-9]+]], [[REGSTRUCT]], [[OFFSET_REG]]
327 ; POWER7: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
328 ; POWER7: stdx [[REG0_1]], [[REGSTRUCT]], [[OFFSET_REG]]
329 define void @test_misalign() nounwind {
330 entry:
331   %0 = load i64, i64* getelementptr inbounds (%struct.misalign, %struct.misalign* @misalign_v, i32 0, i32 1), align 1
332   %inc0 = add nsw i64 %0, 1
333   store i64 %inc0, i64* getelementptr inbounds (%struct.misalign, %struct.misalign* @misalign_v, i32 0, i32 1), align 1
334   ret void
335 }