[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / CodeGen / PowerPC / peephole-align.ll
blobe866b3e28b25f38da9290c8a7401f90206af7c31
1 ; RUN: llc -relocation-model=static -verify-machineinstrs -mcpu=pwr7 -O1 -code-model=medium <%s | FileCheck %s
2 ; RUN: llc -relocation-model=static -verify-machineinstrs -mcpu=pwr8 -O1 -code-model=medium <%s | FileCheck %s
4 ; Test peephole optimization for medium code model (32-bit TOC offsets)
5 ; for loading and storing small offsets within aligned values.
7 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"
8 target triple = "powerpc64-unknown-linux-gnu"
10 %struct.b4 = type<{ i8, i8, i8, i8 }>
11 %struct.h2 = type<{ i16, i16 }>
13 %struct.b8 = type<{ i8, i8, i8, i8, i8, i8, i8, i8 }>
14 %struct.h4 = type<{ i16, i16, i16, i16 }>
15 %struct.w2 = type<{ i32, i32 }>
17 %struct.d2 = type<{ i64, i64 }>
18 %struct.misalign = type<{ i8, i64 }>
20 @b4v = global %struct.b4 <{ i8 1, i8 2, i8 3, i8 4 }>, align 4
21 @h2v = global %struct.h2 <{ i16 1, i16 2 }>, align 4
23 @b8v = global %struct.b8 <{ i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8 }>, align 8
24 @h4v = global %struct.h4 <{ i16 1, i16 2, i16 3, i16 4 }>, align 8
25 @w2v = global %struct.w2 <{ i32 1, i32 2 }>, align 8
27 @d2v = global %struct.d2 <{ i64 1, i64 2 }>, align 16
28 @misalign_v = global %struct.misalign <{ i8 1, i64 2 }>, align 16
30 ; CHECK-LABEL: test_b4:
31 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, b4v@toc@ha
32 ; CHECK-DAG: lbz [[REG0_0:[0-9]+]], b4v@toc@l([[REGSTRUCT]])
33 ; CHECK-DAG: lbz [[REG1_0:[0-9]+]], b4v@toc@l+1([[REGSTRUCT]])
34 ; CHECK-DAG: lbz [[REG2_0:[0-9]+]], b4v@toc@l+2([[REGSTRUCT]])
35 ; CHECK-DAG: lbz [[REG3_0:[0-9]+]], b4v@toc@l+3([[REGSTRUCT]])
36 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
37 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
38 ; CHECK-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
39 ; CHECK-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
40 ; CHECK-DAG: stb [[REG0_1]], b4v@toc@l([[REGSTRUCT]])
41 ; CHECK-DAG: stb [[REG1_1]], b4v@toc@l+1([[REGSTRUCT]])
42 ; CHECK-DAG: stb [[REG2_1]], b4v@toc@l+2([[REGSTRUCT]])
43 ; CHECK-DAG: stb [[REG3_1]], b4v@toc@l+3([[REGSTRUCT]])
45 define void @test_b4() nounwind {
46 entry:
47   %0 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 0), align 1
48   %inc0 = add nsw i8 %0, 1
49   store i8 %inc0, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 0), align 1
50   %1 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 1), align 1
51   %inc1 = add nsw i8 %1, 2
52   store i8 %inc1, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 1), align 1
53   %2 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 2), align 1
54   %inc2 = add nsw i8 %2, 3
55   store i8 %inc2, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 2), align 1
56   %3 = load i8, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 3), align 1
57   %inc3 = add nsw i8 %3, 4
58   store i8 %inc3, i8* getelementptr inbounds (%struct.b4, %struct.b4* @b4v, i32 0, i32 3), align 1
59   ret void
62 ; CHECK-LABEL: test_h2:
63 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
64 ; CHECK-DAG: lhz [[REG0_0:[0-9]+]], h2v@toc@l([[REGSTRUCT]])
65 ; CHECK-DAG: lhz [[REG1_0:[0-9]+]], h2v@toc@l+2([[REGSTRUCT]])
66 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
67 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
68 ; CHECK-DAG: sth [[REG0_1]], h2v@toc@l([[REGSTRUCT]])
69 ; CHECK-DAG: sth [[REG1_1]], h2v@toc@l+2([[REGSTRUCT]])
71 define void @test_h2() nounwind {
72 entry:
73   %0 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
74   %inc0 = add nsw i16 %0, 1
75   store i16 %inc0, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
76   %1 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
77   %inc1 = add nsw i16 %1, 2
78   store i16 %inc1, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
79   ret void
82 ; CHECK-LABEL: test_h2_optsize:
83 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, h2v@toc@ha
84 ; CHECK-DAG: lhz [[REG0_0:[0-9]+]], h2v@toc@l([[REGSTRUCT]])
85 ; CHECK-DAG: lhz [[REG1_0:[0-9]+]], h2v@toc@l+2([[REGSTRUCT]])
86 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
87 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
88 ; CHECK-DAG: sth [[REG0_1]], h2v@toc@l([[REGSTRUCT]])
89 ; CHECK-DAG: sth [[REG1_1]], h2v@toc@l+2([[REGSTRUCT]])
90 define void @test_h2_optsize() optsize nounwind {
91 entry:
92   %0 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
93   %inc0 = add nsw i16 %0, 1
94   store i16 %inc0, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 0), align 2
95   %1 = load i16, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
96   %inc1 = add nsw i16 %1, 2
97   store i16 %inc1, i16* getelementptr inbounds (%struct.h2, %struct.h2* @h2v, i32 0, i32 1), align 2
98   ret void
101 ; CHECK-LABEL: test_b8:
102 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, b8v@toc@ha
103 ; CHECK-DAG: lbz [[REG0_0:[0-9]+]], b8v@toc@l([[REGSTRUCT]])
104 ; CHECK-DAG: lbz [[REG1_0:[0-9]+]], b8v@toc@l+1([[REGSTRUCT]])
105 ; CHECK-DAG: lbz [[REG2_0:[0-9]+]], b8v@toc@l+2([[REGSTRUCT]])
106 ; CHECK-DAG: lbz [[REG3_0:[0-9]+]], b8v@toc@l+3([[REGSTRUCT]])
107 ; CHECK-DAG: lbz [[REG4_0:[0-9]+]], b8v@toc@l+4([[REGSTRUCT]])
108 ; CHECK-DAG: lbz [[REG5_0:[0-9]+]], b8v@toc@l+5([[REGSTRUCT]])
109 ; CHECK-DAG: lbz [[REG6_0:[0-9]+]], b8v@toc@l+6([[REGSTRUCT]])
110 ; CHECK-DAG: lbz [[REG7_0:[0-9]+]], b8v@toc@l+7([[REGSTRUCT]])
111 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
112 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
113 ; CHECK-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
114 ; CHECK-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
115 ; CHECK-DAG: addi [[REG4_1:[0-9]+]], [[REG4_0]], 5
116 ; CHECK-DAG: addi [[REG5_1:[0-9]+]], [[REG5_0]], 6
117 ; CHECK-DAG: addi [[REG6_1:[0-9]+]], [[REG6_0]], 7
118 ; CHECK-DAG: addi [[REG7_1:[0-9]+]], [[REG7_0]], 8
119 ; CHECK-DAG: stb [[REG0_1]], b8v@toc@l([[REGSTRUCT]])
120 ; CHECK-DAG: stb [[REG1_1]], b8v@toc@l+1([[REGSTRUCT]])
121 ; CHECK-DAG: stb [[REG2_1]], b8v@toc@l+2([[REGSTRUCT]])
122 ; CHECK-DAG: stb [[REG3_1]], b8v@toc@l+3([[REGSTRUCT]])
123 ; CHECK-DAG: stb [[REG4_1]], b8v@toc@l+4([[REGSTRUCT]])
124 ; CHECK-DAG: stb [[REG5_1]], b8v@toc@l+5([[REGSTRUCT]])
125 ; CHECK-DAG: stb [[REG6_1]], b8v@toc@l+6([[REGSTRUCT]])
126 ; CHECK-DAG: stb [[REG7_1]], b8v@toc@l+7([[REGSTRUCT]])
128 define void @test_b8() nounwind {
129 entry:
130   %0 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 0), align 1
131   %inc0 = add nsw i8 %0, 1
132   store i8 %inc0, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 0), align 1
133   %1 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 1), align 1
134   %inc1 = add nsw i8 %1, 2
135   store i8 %inc1, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 1), align 1
136   %2 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 2), align 1
137   %inc2 = add nsw i8 %2, 3
138   store i8 %inc2, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 2), align 1
139   %3 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 3), align 1
140   %inc3 = add nsw i8 %3, 4
141   store i8 %inc3, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 3), align 1
142   %4 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 4), align 1
143   %inc4 = add nsw i8 %4, 5
144   store i8 %inc4, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 4), align 1
145   %5 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 5), align 1
146   %inc5 = add nsw i8 %5, 6
147   store i8 %inc5, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 5), align 1
148   %6 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 6), align 1
149   %inc6 = add nsw i8 %6, 7
150   store i8 %inc6, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 6), align 1
151   %7 = load i8, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 7), align 1
152   %inc7 = add nsw i8 %7, 8
153   store i8 %inc7, i8* getelementptr inbounds (%struct.b8, %struct.b8* @b8v, i32 0, i32 7), align 1
154   ret void
157 ; CHECK-LABEL: test_h4:
158 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, h4v@toc@ha
159 ; CHECK-DAG: lhz [[REG0_0:[0-9]+]], h4v@toc@l([[REGSTRUCT]])
160 ; CHECK-DAG: lhz [[REG1_0:[0-9]+]], h4v@toc@l+2([[REGSTRUCT]])
161 ; CHECK-DAG: lhz [[REG2_0:[0-9]+]], h4v@toc@l+4([[REGSTRUCT]])
162 ; CHECK-DAG: lhz [[REG3_0:[0-9]+]], h4v@toc@l+6([[REGSTRUCT]])
163 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
164 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
165 ; CHECK-DAG: addi [[REG2_1:[0-9]+]], [[REG2_0]], 3
166 ; CHECK-DAG: addi [[REG3_1:[0-9]+]], [[REG3_0]], 4
167 ; CHECK-DAG: sth [[REG0_1]], h4v@toc@l([[REGSTRUCT]])
168 ; CHECK-DAG: sth [[REG1_1]], h4v@toc@l+2([[REGSTRUCT]])
169 ; CHECK-DAG: sth [[REG2_1]], h4v@toc@l+4([[REGSTRUCT]])
170 ; CHECK-DAG: sth [[REG3_1]], h4v@toc@l+6([[REGSTRUCT]])
172 define void @test_h4() nounwind {
173 entry:
174   %0 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 0), align 2
175   %inc0 = add nsw i16 %0, 1
176   store i16 %inc0, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 0), align 2
177   %1 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 1), align 2
178   %inc1 = add nsw i16 %1, 2
179   store i16 %inc1, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 1), align 2
180   %2 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 2), align 2
181   %inc2 = add nsw i16 %2, 3
182   store i16 %inc2, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 2), align 2
183   %3 = load i16, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 3), align 2
184   %inc3 = add nsw i16 %3, 4
185   store i16 %inc3, i16* getelementptr inbounds (%struct.h4, %struct.h4* @h4v, i32 0, i32 3), align 2
186   ret void
189 ; CHECK-LABEL: test_w2:
190 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, w2v@toc@ha
191 ; CHECK-DAG: lwz [[REG0_0:[0-9]+]], w2v@toc@l([[REGSTRUCT]])
192 ; CHECK-DAG: lwz [[REG1_0:[0-9]+]], w2v@toc@l+4([[REGSTRUCT]])
193 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
194 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
195 ; CHECK-DAG: stw [[REG0_1]], w2v@toc@l([[REGSTRUCT]])
196 ; CHECK-DAG: stw [[REG1_1]], w2v@toc@l+4([[REGSTRUCT]])
198 define void @test_w2() nounwind {
199 entry:
200   %0 = load i32, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 0), align 4
201   %inc0 = add nsw i32 %0, 1
202   store i32 %inc0, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 0), align 4
203   %1 = load i32, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 1), align 4
204   %inc1 = add nsw i32 %1, 2
205   store i32 %inc1, i32* getelementptr inbounds (%struct.w2, %struct.w2* @w2v, i32 0, i32 1), align 4
206   ret void
209 ; CHECK-LABEL: test_d2:
210 ; CHECK: addis [[REGSTRUCT:[0-9]+]], 2, d2v@toc@ha
211 ; CHECK: addi [[BASEV:[0-9]+]], [[REGSTRUCT]], d2v@toc@l
212 ; CHECK-DAG: ld [[REG0_0:[0-9]+]], d2v@toc@l([[REGSTRUCT]])
213 ; CHECK-DAG: ld [[REG1_0:[0-9]+]], 8([[BASEV]])
214 ; CHECK-DAG: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
215 ; CHECK-DAG: addi [[REG1_1:[0-9]+]], [[REG1_0]], 2
216 ; CHECK-DAG: std [[REG0_1]], d2v@toc@l([[REGSTRUCT]])
217 ; CHECK-DAG: std [[REG1_1]], 8([[BASEV]])
219 define void @test_d2() nounwind {
220 entry:
221   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 0), align 8
222   %inc0 = add nsw i64 %0, 1
223   store i64 %inc0, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 0), align 8
224   %1 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
225   %inc1 = add nsw i64 %1, 2
226   store i64 %inc1, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
227   ret void
230 ; CHECK-LABEL: test_singleuse:
231 ; CHECK: addis [[REG:[0-9]+]], 2, d2v@toc@ha+8
232 ; CHECK: ld 3, d2v@toc@l+8([[REG]])
233 define i64 @test_singleuse() nounwind {
234 entry:
235   %0 = load i64, i64* getelementptr inbounds (%struct.d2, %struct.d2* @d2v, i32 0, i32 1), align 8
236   ret i64 %0
239 ; Make sure the optimization fails to fire if the symbol is aligned, but the offset is not.
240 ; CHECK-LABEL: test_misalign
241 ; CHECK: addis [[REGSTRUCT_0:[0-9]+]], 2, misalign_v@toc@ha
242 ; CHECK-DAG: addi [[REGSTRUCT:[0-9]+]], [[REGSTRUCT_0]], misalign_v@toc@l
243 ; CHECK-DAG: li [[OFFSET_REG:[0-9]+]], 1
244 ; CHECK: ldx [[REG0_0:[0-9]+]], [[REGSTRUCT]], [[OFFSET_REG]]
245 ; CHECK: addi [[REG0_1:[0-9]+]], [[REG0_0]], 1
246 ; CHECK: stdx [[REG0_1]], [[REGSTRUCT]], [[OFFSET_REG]]
247 define void @test_misalign() nounwind {
248 entry:
249   %0 = load i64, i64* getelementptr inbounds (%struct.misalign, %struct.misalign* @misalign_v, i32 0, i32 1), align 1
250   %inc0 = add nsw i64 %0, 1
251   store i64 %inc0, i64* getelementptr inbounds (%struct.misalign, %struct.misalign* @misalign_v, i32 0, i32 1), align 1
252   ret void