xref: /llvm-project/llvm/test/CodeGen/AVR/alloca.ll (revision 9ef1d37ffb5f56a9b949a6307bbb16c2ea0130e3)
1; RUN: llc < %s -mtriple=avr -mattr=avr6 | FileCheck %s
2
3declare i16 @allocate(ptr, ptr)
4
5; Test taking an address of an alloca with a small offset (adiw)
6define i16 @alloca_addressof_small() {
7entry:
8; CHECK-LABEL: alloca_addressof_small:
9; Test that Y is saved
10; CHECK: push r28
11; CHECK: push r29
12; CHECK: movw r24, r28
13; CHECK: adiw r24, 17
14; CHECK: movw {{.*}}, r28
15; CHECK: adiw {{.*}}, 39
16; CHECK: movw r22, {{.*}}
17; CHECK: pop r29
18; CHECK: pop r28
19  %p = alloca [18 x i16]
20  %k = alloca [14 x i16]
21  %arrayidx = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 8
22  %arrayidx1 = getelementptr inbounds [18 x i16], ptr %p, i16 0, i16 5
23  %call = call i16 @allocate(ptr %arrayidx, ptr %arrayidx1)
24  ret i16 %call
25}
26
27; Test taking an address of an alloca with a big offset (subi/sbci pair)
28define i16 @alloca_addressof_big() {
29entry:
30; CHECK-LABEL: alloca_addressof_big:
31; CHECK: movw r24, r28
32; CHECK: adiw r24, 17
33; CHECK: movw r22, r28
34; CHECK: subi r22, 145
35; CHECK: sbci r23, 255
36  %p = alloca [55 x i16]
37  %k = alloca [14 x i16]
38  %arrayidx = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 8
39  %arrayidx1 = getelementptr inbounds [55 x i16], ptr %p, i16 0, i16 41
40  %call = call i16 @allocate(ptr %arrayidx, ptr %arrayidx1)
41  ret i16 %call
42}
43
44; Test writing to an allocated variable with a small and a big offset
45define i16 @alloca_write(i16 %x) {
46entry:
47; CHECK-LABEL: alloca_write:
48; Small offset here
49; CHECK: std Y+24, {{.*}}
50; CHECK: std Y+23, {{.*}}
51; Big offset here
52; CHECK: adiw r28, 57
53; CHECK: std Y+63, {{.*}}
54; CHECK: std Y+62, {{.*}}
55; CHECK: sbiw r28, 57
56  %p = alloca [15 x i16]
57  %k = alloca [14 x i16]
58  %arrayidx = getelementptr inbounds [15 x i16], ptr %p, i16 0, i16 45
59  store i16 22, ptr %arrayidx
60  %arrayidx1 = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 11
61  store i16 42, ptr %arrayidx1
62  %arrayidx2 = getelementptr inbounds [14 x i16], ptr %k, i16 0, i16 0
63  %arrayidx3 = getelementptr inbounds [15 x i16], ptr %p, i16 0, i16 0
64  %call = call i16 @allocate(ptr %arrayidx2, ptr %arrayidx3)
65  ret i16 %call
66}
67
68; Test writing to an allocated variable with a huge offset that cant be
69; materialized with adiw/sbiw but with a subi/sbci pair.
70define void @alloca_write_huge() {
71; CHECK-LABEL: alloca_write_huge:
72; CHECK: subi r28, 41
73; CHECK: sbci r29, 255
74; CHECK: std Y+63, {{.*}}
75; CHECK: std Y+62, {{.*}}
76; CHECK: subi r28, 215
77; CHECK: sbci r29, 0
78  %k = alloca [140 x i16]
79  %arrayidx = getelementptr inbounds [140 x i16], ptr %k, i16 0, i16 138
80  store i16 22, ptr %arrayidx
81  %arraydecay = getelementptr inbounds [140 x i16], ptr %k, i16 0, i16 0
82  call i16 @allocate(ptr %arraydecay, ptr null)
83  ret void
84}
85