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