xref: /llvm-project/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-load-store.mir (revision fd3eaf76ba3392a4406247d996e757ef49f7a8b2)
1# RUN: llc -mtriple arm-- -run-pass=legalizer %s -o - | FileCheck %s
2# RUN: llc -mtriple thumbv7-- -run-pass=legalizer %s -o - | FileCheck %s
3--- |
4  define void @test_legal_loads_stores() { ret void }
5  define void @test_load_store_s1() { ret void }
6  define void @test_load_from_stack() { ret void }
7
8  define void @test_load_store_64_vfp() #0 { ret void }
9  define void @test_load_store_64_novfp() #1 { ret void }
10
11  define void @test_gep_s32() { ret void }
12
13  attributes #0 = { "target-features"="+vfp2" }
14  attributes #1 = { "target-features"="-vfp2sp" }
15...
16---
17name:            test_legal_loads_stores
18# CHECK-LABEL: name: test_legal_loads_stores
19legalized:       false
20# CHECK: legalized: true
21regBankSelected: false
22selected:        false
23tracksRegLiveness: true
24registers:
25  - { id: 0, class: _ }
26  - { id: 1, class: _ }
27  - { id: 2, class: _ }
28  - { id: 3, class: _ }
29  - { id: 4, class: _ }
30  - { id: 5, class: _ }
31  - { id: 6, class: _ }
32body:             |
33  bb.0:
34    liveins: $r0
35
36    ; These are all legal, so we should find them unchanged in the output
37    ; CHECK-DAG: G_STORE {{%[0-9]+}}(s32), %0(p0) :: (store (s32))
38    ; CHECK-DAG: G_STORE {{%[0-9]+}}(s16), %0(p0) :: (store (s16))
39    ; CHECK-DAG: G_STORE {{%[0-9]+}}(s8), %0(p0) :: (store (s8))
40    ; CHECK-DAG: G_STORE {{%[0-9]+}}(p0), %0(p0)
41    ; CHECK-DAG: {{%[0-9]+}}:_(s32) = G_LOAD %0(p0) :: (load (s32))
42    ; CHECK-DAG: {{%[0-9]+}}:_(s16) = G_LOAD %0(p0) :: (load (s16))
43    ; CHECK-DAG: {{%[0-9]+}}:_(s8) = G_LOAD %0(p0) :: (load (s8))
44    ; CHECK-DAG: {{%[0-9]+}}:_(p0) = G_LOAD %0(p0) :: (load (p0))
45    %0(p0) = COPY $r0
46    %2(s32) = G_LOAD %0(p0) :: (load (s32))
47    G_STORE %2(s32), %0(p0) :: (store (s32))
48    %3(s16) = G_LOAD %0(p0) :: (load (s16))
49    G_STORE %3(s16), %0(p0) :: (store (s16))
50    %4(s8) = G_LOAD %0(p0) :: (load (s8))
51    G_STORE %4(s8), %0(p0) :: (store (s8))
52    %6(p0) = G_LOAD %0(p0) :: (load (p0))
53    G_STORE %6(p0), %0(p0) :: (store (p0))
54    BX_RET 14, $noreg
55...
56
57---
58name:            test_load_store_s1
59legalized:       false
60# CHECK: legalized: true
61regBankSelected: false
62selected:        false
63tracksRegLiveness: true
64body:             |
65  bb.0:
66    liveins: $r0
67
68    ; CHECK: [[LD:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load (s8))
69    ; CHECK: [[ASSERTZ:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[LD]], 1
70    ; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
71    ; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ASSERTZ]]
72    ; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[EXT]], [[ONE]]
73    ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[AND]]
74    ; CHECK: G_STORE [[TRUNC]](s8), {{%[0-9]+}}(p0) :: (store (s8))
75    %0:_(p0) = COPY $r0
76    %5:_(s1) = G_LOAD %0(p0) :: (load (s1))
77    G_STORE %5(s1), %0(p0) :: (store (s1))
78    BX_RET 14, $noreg
79...
80---
81name:            test_load_from_stack
82# CHECK-LABEL: name: test_load_from_stack
83legalized:       false
84# CHECK: legalized: true
85regBankSelected: false
86selected:        false
87tracksRegLiveness: true
88registers:
89  - { id: 0, class: _ }
90  - { id: 1, class: _ }
91  - { id: 2, class: _ }
92  - { id: 3, class: _ }
93fixedStack:
94  - { id: 0, offset: 0, size: 4, alignment: 4, isImmutable: true, isAliased: false }
95  - { id: 1, offset: 4, size: 4, alignment: 4, isImmutable: true, isAliased: false }
96  - { id: 2, offset: 8, size: 4, alignment: 4, isImmutable: true, isAliased: false }
97  # CHECK: id: [[FRAME_INDEX:[0-9]+]], type: default, offset: 8
98body:             |
99  bb.0:
100    liveins: $r0, $r1, $r2, $r3
101
102    ; This is legal, so we should find it unchanged in the output
103    ; CHECK: [[FIVREG:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FRAME_INDEX]]
104    ; CHECK: {{%[0-9]+}}:_(s32) = G_LOAD [[FIVREG]](p0) :: (load (s32))
105    %0(p0) = G_FRAME_INDEX %fixed-stack.2
106    %1(s32) = G_LOAD %0(p0) :: (load (s32))
107    $r0 = COPY %1(s32)
108    BX_RET 14, $noreg, implicit $r0
109...
110---
111name:            test_load_store_64_vfp
112# CHECK-LABEL: name: test_load_store_64_vfp
113legalized:       false
114# CHECK: legalized: true
115regBankSelected: false
116selected:        false
117tracksRegLiveness: true
118registers:
119  - { id: 0, class: _ }
120  - { id: 1, class: _ }
121  - { id: 2, class: _ }
122body:             |
123  bb.0:
124    liveins: $r0
125
126    ; Can't use the VFP support for unaligned operations, we need to use 32-bits
127    ; operations instead.
128    ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
129    ; CHECK-NEXT: [[V1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load (s32), align 1)
130    ; CHECK-NEXT: [[OFF:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
131    ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR1]], [[OFF]]
132    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[ADDR2]]
133    ; CHECK-NEXT: [[V2:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from unknown-address + 4, align 1)
134    ; CHECK-NEXT: G_STORE [[V1]](s32), [[ADDR1]](p0) :: (store (s32), align 1)
135    ; CHECK-NEXT: G_STORE [[V2]](s32), [[ADDR2]](p0) :: (store (s32) into unknown-address + 4, align 1)
136    %0(p0) = COPY $r0
137    %1(s64) = G_LOAD %0(p0) :: (load (s64), align 1)
138    G_STORE %1(s64), %0(p0) :: (store (s64), align 1)
139
140    ; For word-aligned we can use VFP operations.
141    ; CHECK: [[V:%[0-9]+]]:_(s64) = G_LOAD %0(p0) :: (load (s64), align 4)
142    ; CHECK: G_STORE [[V]](s64), %0(p0) :: (store (s64), align 4)
143    %2(s64) = G_LOAD %0(p0) :: (load (s64), align 4)
144    G_STORE %2(s64), %0(p0) :: (store (s64), align 4)
145
146    BX_RET 14, $noreg
147...
148---
149name:            test_load_store_64_novfp
150# CHECK-LABEL: name: test_load_store_64_novfp
151legalized:       false
152# CHECK: legalized: true
153regBankSelected: false
154selected:        false
155tracksRegLiveness: true
156registers:
157  - { id: 0, class: _ }
158  - { id: 1, class: _ }
159  - { id: 2, class: _ }
160body:             |
161  bb.0:
162    liveins: $r0
163
164    ; When we don't have VFP support, we need to use 32-bit operations.
165    ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
166    ; CHECK-NEXT: [[V1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load (s32), align 1)
167    ; CHECK-NEXT: [[OFF:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
168    ; CHECK-NEXT: [[ADDR2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR1]], [[OFF]]
169    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[ADDR2]]
170    ; CHECK-NEXT: [[V2:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from unknown-address + 4, align 1)
171    ; CHECK-NEXT: G_STORE [[V1]](s32), [[ADDR1]](p0) :: (store (s32), align 1)
172    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY [[ADDR2]]
173    ; CHECK-NEXT: G_STORE [[V2]](s32), [[COPY2]](p0) :: (store (s32) into unknown-address + 4, align 1)
174    %0(p0) = COPY $r0
175    %1(s64) = G_LOAD %0(p0) :: (load (s64), align 1)
176    G_STORE %1(s64), %0(p0) :: (store (s64), align 1)
177
178    ; CHECK: [[V1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load (s32))
179    ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(p0) = COPY [[ADDR2]]
180    ; CHECK-NEXT: [[V2:%[0-9]+]]:_(s32) = G_LOAD [[COPY3]](p0) :: (load (s32) from unknown-address + 4)
181    ; CHECK-NEXT: G_STORE [[V1]](s32), [[ADDR1]](p0) :: (store (s32))
182    ; CHECK-NEXT: G_STORE [[V2]](s32), [[ADDR2]](p0) :: (store (s32) into unknown-address + 4)
183    %2(s64) = G_LOAD %0(p0) :: (load (s64), align 4)
184    G_STORE %2(s64), %0(p0) :: (store (s64), align 4)
185
186    BX_RET 14, $noreg
187...
188---
189name:            test_gep_s32
190# CHECK-LABEL: name: test_gep_s32
191legalized:       false
192# CHECK: legalized: true
193regBankSelected: false
194selected:        false
195tracksRegLiveness: true
196registers:
197  - { id: 0, class: _ }
198  - { id: 1, class: _ }
199  - { id: 2, class: _ }
200body:             |
201  bb.0:
202    liveins: $r0, $r1
203
204    %0(p0) = COPY $r0
205    %1(s32) = COPY $r1
206
207    ; CHECK: {{%[0-9]+}}:_(p0) = G_PTR_ADD {{%[0-9]+}}, {{%[0-9]+}}(s32)
208    %2(p0) = G_PTR_ADD %0, %1(s32)
209
210    $r0 = COPY %2(p0)
211    BX_RET 14, $noreg, implicit $r0
212...
213