1; RUN: llc < %s -march=avr -mattr=avr6 | FileCheck %s
2
3declare i16 @allocate(i16*, i16*)
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], [14 x i16]* %k, i16 0, i16 8
22  %arrayidx1 = getelementptr inbounds [18 x i16], [18 x i16]* %p, i16 0, i16 5
23  %call = call i16 @allocate(i16* %arrayidx, i16* %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], [14 x i16]* %k, i16 0, i16 8
39  %arrayidx1 = getelementptr inbounds [55 x i16], [55 x i16]* %p, i16 0, i16 41
40  %call = call i16 @allocate(i16* %arrayidx, i16* %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+23, {{.*}}
50; CHECK: std Y+24, {{.*}}
51; Big offset here
52; CHECK: adiw r28, 57
53; CHECK: std Y+62, {{.*}}
54; CHECK: std Y+63, {{.*}}
55; CHECK: sbiw r28, 57
56  %p = alloca [15 x i16]
57  %k = alloca [14 x i16]
58  %arrayidx = getelementptr inbounds [15 x i16], [15 x i16]* %p, i16 0, i16 45
59  store i16 22, i16* %arrayidx
60  %arrayidx1 = getelementptr inbounds [14 x i16], [14 x i16]* %k, i16 0, i16 11
61  store i16 42, i16* %arrayidx1
62  %arrayidx2 = getelementptr inbounds [14 x i16], [14 x i16]* %k, i16 0, i16 0
63  %arrayidx3 = getelementptr inbounds [15 x i16], [15 x i16]* %p, i16 0, i16 0
64  %call = call i16 @allocate(i16* %arrayidx2, i16* %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+62, {{.*}}
75; CHECK: std Y+63, {{.*}}
76; CHECK: subi r28, 215
77; CHECK: sbci r29, 0
78  %k = alloca [140 x i16]
79  %arrayidx = getelementptr inbounds [140 x i16], [140 x i16]* %k, i16 0, i16 138
80  store i16 22, i16* %arrayidx
81  %arraydecay = getelementptr inbounds [140 x i16], [140 x i16]* %k, i16 0, i16 0
82  call i16 @allocate(i16* %arraydecay, i16* null)
83  ret void
84}
85