[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / CodeGen / ARM / indexed-mem.ll
blobb318c7642566013e0c7a2f04c383b0a94559e9d5
1 ; RUN: llc -mtriple=thumbv8m.main %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V8M
2 ; RUN: llc -mtriple=armv8 %s -o - | FileCheck %s --check-prefix=CHECK-V8
4 ; CHECK-LABEL: pre_inc_ldr
5 ; CHECK: ldr{{.*}}, [r0, #4]!
6 define i32* @pre_inc_ldr(i32* %base, i32 %a) {
7   %addr = getelementptr i32, i32* %base, i32 1
8   %ld = load i32, i32* %addr
9   %addr.1 = getelementptr i32, i32* %base, i32 2
10   %res = add i32 %ld, %a
11   store i32 %res, i32* %addr.1
12   ret i32* %addr
15 ; CHECK-LABEL: pre_dec_ldr
16 ; CHECK: ldr{{.*}}, [r0, #-4]!
17 define i32* @pre_dec_ldr(i32* %base, i32 %a) {
18   %addr = getelementptr i32, i32* %base, i32 -1
19   %ld = load i32, i32* %addr
20   %addr.1 = getelementptr i32, i32* %base, i32 2
21   %res = add i32 %ld, %a
22   store i32 %res, i32* %addr.1
23   ret i32* %addr
26 ; CHECK-LABEL: post_inc_ldr
27 ; CHECK: ldr{{.*}}, [r0], #4
28 define i32* @post_inc_ldr(i32* %base, i32* %addr.2, i32 %a) {
29   %addr = getelementptr i32, i32* %base, i32 0
30   %ld = load i32, i32* %addr
31   %addr.1 = getelementptr i32, i32* %base, i32 1
32   %res = add i32 %ld, %a
33   store i32 %res, i32* %addr.2
34   ret i32* %addr.1
37 ; CHECK-LABEL: post_dec_ldr
38 ; CHECK: ldr{{.*}}, [r0], #-4
39 define i32* @post_dec_ldr(i32* %base, i32* %addr.2, i32 %a) {
40   %addr = getelementptr i32, i32* %base, i32 0
41   %ld = load i32, i32* %addr
42   %addr.1 = getelementptr i32, i32* %base, i32 -1
43   %res = add i32 %ld, %a
44   store i32 %res, i32* %addr.2
45   ret i32* %addr.1
48 ; CHECK-LABEL: pre_inc_str
49 ; CHECK: str{{.*}}, [r0, #4]!
50 define i32* @pre_inc_str(i32* %base, i32 %a, i32 %b) {
51   %addr.1 = getelementptr i32, i32* %base, i32 1
52   %res = add i32 %a, %b
53   store i32 %res, i32* %addr.1
54   ret i32* %addr.1
57 ; CHECK-LABEL: pre_dec_str
58 ; CHECK: str{{.*}}, [r0, #-4]!
59 define i32* @pre_dec_str(i32* %base, i32 %a, i32 %b) {
60   %res = add i32 %a, %b
61   %addr.1 = getelementptr i32, i32* %base, i32 -1
62   store i32 %res, i32* %addr.1
63   ret i32* %addr.1
66 ; CHECK-LABEL: post_inc_str
67 ; CHECK: str{{.*}}, [r0], #4
68 define i32* @post_inc_str(i32* %base, i32 %a, i32 %b) {
69   %addr.1 = getelementptr i32, i32* %base, i32 1
70   %res = add i32 %a, %b
71   store i32 %res, i32* %base
72   ret i32* %addr.1
75 ; CHECK-LABEL: post_dec_str
76 ; CHECK: str{{.*}}, [r0], #-4
77 define i32* @post_dec_str(i32* %base, i32 %a, i32 %b) {
78   %addr.1 = getelementptr i32, i32* %base, i32 -1
79   %res = add i32 %a, %b
80   store i32 %res, i32* %base
81   ret i32* %addr.1
84 ; TODO: Generate ldrd
85 ; CHECK-LABEL: pre_inc_ldrd
86 ; CHECK: ldr{{.*}}, #4]!
87 define i32* @pre_inc_ldrd(i32* %base) {
88   %addr = getelementptr i32, i32* %base, i32 1
89   %addr.1 = getelementptr i32, i32* %base, i32 2
90   %addr.2 = getelementptr i32, i32* %base, i32 3
91   %ld = load i32, i32* %addr
92   %ld.1 = load i32, i32* %addr.1
93   %res = add i32 %ld, %ld.1
94   store i32 %res, i32* %addr.2
95   ret i32* %addr
98 ; TODO: Generate ldrd
99 ; CHECK-LABEL: pre_dec_ldrd
100 ; CHECK: ldr{{.*}}, #-4]!
101 define i32* @pre_dec_ldrd(i32* %base) {
102   %addr = getelementptr i32, i32* %base, i32 -1
103   %addr.1 = getelementptr i32, i32* %base, i32 -2
104   %addr.2 = getelementptr i32, i32* %base, i32 -3
105   %ld = load i32, i32* %addr
106   %ld.1 = load i32, i32* %addr.1
107   %res = add i32 %ld, %ld.1
108   store i32 %res, i32* %addr.2
109   ret i32* %addr
112 ; TODO: Generate post inc
113 ; CHECK-LABEL: post_inc_ldrd
114 ; CHECK-V8M: ldrd{{.*}}, [r0]
115 ; CHECK-V8: ldm
116 ; CHECK: add{{.*}}, #8
117 define i32* @post_inc_ldrd(i32* %base, i32* %addr.3) {
118   %addr = getelementptr i32, i32* %base, i32 0
119   %ld = load i32, i32* %addr
120   %addr.1 = getelementptr i32, i32* %base, i32 1
121   %ld.1 = load i32, i32* %addr.1
122   %addr.2 = getelementptr i32, i32* %base, i32 2
123   %res = add i32 %ld, %ld.1
124   store i32 %res, i32* %addr.3
125   ret i32* %addr.2
128 ; CHECK-LABEL: pre_inc_str_multi
129 ; CHECK: str{{.*}}, #8]!
130 define i32* @pre_inc_str_multi(i32* %base) {
131   %addr = getelementptr i32, i32* %base, i32 0
132   %addr.1 = getelementptr i32, i32* %base, i32 1
133   %ld = load i32, i32* %addr
134   %ld.1 = load i32, i32* %addr.1
135   %res = add i32 %ld, %ld.1
136   %addr.2 = getelementptr i32, i32* %base, i32 2
137   store i32 %res, i32* %addr.2
138   ret i32* %addr.2
141 ; CHECK-LABEL: pre_dec_str_multi
142 ; CHECK: str{{.*}}, #-4]!
143 define i32* @pre_dec_str_multi(i32* %base) {
144   %addr = getelementptr i32, i32* %base, i32 0
145   %addr.1 = getelementptr i32, i32* %base, i32 1
146   %ld = load i32, i32* %addr
147   %ld.1 = load i32, i32* %addr.1
148   %res = add i32 %ld, %ld.1
149   %addr.2 = getelementptr i32, i32* %base, i32 -1
150   store i32 %res, i32* %addr.2
151   ret i32* %addr.2
154 ; CHECK-LABEL: illegal_pre_inc_store_1
155 ; CHECK-NOT: str{{.*}} ]!
156 define i32* @illegal_pre_inc_store_1(i32* %base) {
157 entry:
158   %ptr.to.use = getelementptr i32, i32* %base, i32 2
159   %ptr.to.store = ptrtoint i32* %base to i32
160   store i32 %ptr.to.store, i32* %ptr.to.use, align 4
161   ret i32* %ptr.to.use
164 ; TODO: The mov should be unecessary
165 ; CHECK-LABEL: legal_pre_inc_store_needs_copy_1
166 ; CHECK: add{{.*}}, #8
167 ; CHECK-NOT: str{{.*}}]!
168 ; CHECK: mov
169 define i32* @legal_pre_inc_store_needs_copy_1(i32* %base) {
170 entry:
171   %ptr.to.use = getelementptr i32, i32* %base, i32 2
172   %ptr.to.store = ptrtoint i32* %ptr.to.use to i32
173   store i32 %ptr.to.store, i32* %ptr.to.use, align 4
174   ret i32* %ptr.to.use
177 ; CHECK-LABEL: legal_pre_inc_store_needs_copy_2
178 ; CHECK-NOT: mov
179 ; CHECK-NOT: str{{.*}}]!
180 define i32* @legal_pre_inc_store_needs_copy_2(i32 %base) {
181 entry:
182   %ptr = inttoptr i32 %base to i32*
183   %ptr.to.use = getelementptr i32, i32* %ptr, i32 2
184   store i32 %base, i32* %ptr.to.use, align 4
185   ret i32* %ptr.to.use