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
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
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
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
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
53 store i32 %res, 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) {
61 %addr.1 = getelementptr i32, i32* %base, i32 -1
62 store i32 %res, 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
71 store i32 %res, i32* %base
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
80 store i32 %res, i32* %base
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
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
112 ; TODO: Generate post inc
113 ; CHECK-LABEL: post_inc_ldrd
114 ; CHECK-V8M: ldrd{{.*}}, [r0]
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
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
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
154 ; CHECK-LABEL: illegal_pre_inc_store_1
155 ; CHECK-NOT: str{{.*}} ]!
156 define i32* @illegal_pre_inc_store_1(i32* %base) {
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
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{{.*}}]!
169 define i32* @legal_pre_inc_store_needs_copy_1(i32* %base) {
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
177 ; CHECK-LABEL: legal_pre_inc_store_needs_copy_2
179 ; CHECK-NOT: str{{.*}}]!
180 define i32* @legal_pre_inc_store_needs_copy_2(i32 %base) {
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