127 lines · plain
1; RUN: llc < %s -mtriple=avr | FileCheck %s2 3declare void @foo(ptr, ptr, ptr)4 5define void @test1(i16 %x) {6; CHECK-LABEL: test1:7; Frame setup, with frame pointer8; CHECK: in r28, 619; CHECK: in r29, 6210; CHECK: out 61, r2811; allocate first dynalloca12; CHECK: in {{.*}}, 6113; CHECK: in {{.*}}, 6214; CHECK: sub15; CHECK: sbc16; CHECK: in r0, 6317; CHECK-NEXT: cli18; CHECK-NEXT: out 62, {{.*}}19; CHECK-NEXT: out 63, r020; CHECK-NEXT: out 61, {{.*}}21; Test writes22; CHECK: std Z+13, {{.*}}23; CHECK: std Z+12, {{.*}}24; CHECK: std Z+7, {{.*}}25; CHECK-NOT: std26; Test SP restore27; CHECK: in r0, 6328; CHECK-NEXT: cli29; CHECK-NEXT: out 62, r2930; CHECK-NEXT: out 63, r031; CHECK-NEXT: out 61, r2832 %a = alloca [8 x i16]33 %vla = alloca i16, i16 %x34 %add = shl nsw i16 %x, 135 %vla1 = alloca i8, i16 %add36 %arrayidx = getelementptr inbounds [8 x i16], ptr %a, i16 0, i16 237 store i16 3, ptr %arrayidx38 %arrayidx2 = getelementptr inbounds i16, ptr %vla, i16 639 store i16 4, ptr %arrayidx240 %arrayidx3 = getelementptr inbounds i8, ptr %vla1, i16 741 store i8 44, ptr %arrayidx342 %arraydecay = getelementptr inbounds [8 x i16], ptr %a, i16 0, i16 043 call void @foo(ptr %arraydecay, ptr %vla, ptr %vla1)44 ret void45}46 47declare void @foo2(ptr, i64, i64, i64)48 49; Test that arguments are passed through pushes into the call instead of50; allocating the call frame space in the prologue. Also test that SP is restored51; after the call frame is restored and not before.52define void @dynalloca2(i16 %x) {53; CHECK-LABEL: dynalloca2:54; CHECK: in r28, 6155; CHECK: in r29, 6256; Allocate stack space for call57; CHECK: in {{.*}}, 6158; CHECK: in {{.*}}, 6259; CHECK: subi60; CHECK: sbci61; CHECK: in r0, 6362; CHECK-NEXT: cli63; CHECK-NEXT: out 62, {{.*}}64; CHECK-NEXT: out 63, r065; CHECK-NEXT: out 61, {{.*}}66; Store values on the stack67; CHECK: ldi [[REG1:r[0-9]+]], 068; CHECK: ldi [[REG2:r[0-9]+]], 069; CHECK: std Z+8, [[REG2]]70; CHECK: std Z+7, [[REG1]]71; CHECK: std Z+6, [[REG2]]72; CHECK: std Z+5, [[REG1]]73; CHECK: std Z+4, [[REG2]]74; CHECK: std Z+3, [[REG1]]75; CHECK: std Z+2, [[REG2]]76; CHECK: std Z+1, [[REG1]]77; CHECK: call78; Call frame restore79; CHECK-NEXT: in r30, 6180; CHECK-NEXT: in r31, 6281; CHECK-NEXT: adiw r30, 882; CHECK-NEXT: in r0, 6383; CHECK-NEXT: cli84; CHECK-NEXT: out 62, r3185; CHECK-NEXT: out 63, r086; CHECK-NEXT: out 61, r3087; SP restore88; CHECK: in r0, 6389; CHECK-NEXT: cli90; CHECK-NEXT: out 62, r2991; CHECK-NEXT: out 63, r092; CHECK-NEXT: out 61, r2893 %vla = alloca i16, i16 %x94 call void @foo2(ptr %vla, i64 0, i64 0, i64 0)95 ret void96}97 98; Test a function with a variable sized object but without any other need for a99; frame pointer.100; Allocas that are not placed in the entry block are considered variable sized101; (they could be in a loop).102define void @dynalloca3() {103; CHECK-LABEL: dynalloca3:104; Read frame pointer105; CHECK: in r28, 61106; CHECK-NEXT: in r29, 62107; Allocate memory for the alloca108; CHECK-NEXT: in r24, 61109; CHECK-NEXT: in r25, 62110; CHECK-NEXT: sbiw r24, 8111; CHECK-NEXT: in r0, 63112; CHECK-NEXT: cli113; CHECK-NEXT: out 62, r25114; CHECK-NEXT: out 63, r0115; CHECK-NEXT: out 61, r24116; Restore frame pointer117; CHECK-NEXT: in r0, 63118; CHECK-NEXT: cli119; CHECK-NEXT: out 62, r29120; CHECK-NEXT: out 63, r0121; CHECK-NEXT: out 61, r28122 br label %11231:124 %a = alloca i64125 ret void126}127