• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
9target 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"
10target 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]])
61define void @test_b4() nounwind {
62entry:
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]])
95define void @test_h2() nounwind {
96entry:
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]])
114define void @test_h2_optsize() optsize nounwind {
115entry:
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]])
178define void @test_b8() nounwind {
179entry:
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]])
236define void @test_h4() nounwind {
237entry:
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]])
270define void @test_w2() nounwind {
271entry:
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]])
298define void @test_d2() nounwind {
299entry:
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)
315define i64 @test_singleuse() nounwind {
316entry:
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]]
329define void @test_misalign() nounwind {
330entry:
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}
336