1; RUN: llc < %s -march=avr | FileCheck %s
2
3; This tests how LLVM handles IR which puts very high
4; presure on the PTRREGS class for the register allocator.
5;
6; This causes a problem because we only have one small register
7; class for loading and storing from pointers - 'PTRREGS'.
8; One of these registers is also used for the frame pointer, meaning
9; that we only ever have two registers available for these operations.
10;
11; There is an existing bug filed for this issue - PR14879.
12;
13; The specific failure:
14; LLVM ERROR: ran out of registers during register allocation
15;
16; It has been assembled from the following c code:
17;
18; struct ss
19; {
20;   int a;
21;   int b;
22;   int c;
23; };
24;
25; void loop(struct ss *x, struct ss **y, int z)
26; {
27;   int i;
28;   for (i=0; i<z; ++i)
29;   {
30;     x->c += y[i]->b;
31;   }
32; }
33
34%struct.ss = type { i16, i16, i16 }
35
36; CHECK-LABEL: loop
37define void @loop(%struct.ss* %x, %struct.ss** %y, i16 %z) #0 {
38entry:
39  %x.addr = alloca %struct.ss*, align 2
40  %y.addr = alloca %struct.ss**, align 2
41  %z.addr = alloca i16, align 2
42  %i = alloca i16, align 2
43  store %struct.ss* %x, %struct.ss** %x.addr, align 2
44  store %struct.ss** %y, %struct.ss*** %y.addr, align 2
45  store i16 %z, i16* %z.addr, align 2
46  store i16 0, i16* %i, align 2
47  br label %for.cond
48
49for.cond:                                         ; preds = %for.inc, %entry
50  %tmp = load i16, i16* %i, align 2
51  %tmp1 = load i16, i16* %z.addr, align 2
52  %cmp = icmp slt i16 %tmp, %tmp1
53  br i1 %cmp, label %for.body, label %for.end
54
55for.body:                                         ; preds = %for.cond
56  %tmp2 = load %struct.ss**, %struct.ss*** %y.addr, align 2
57  %tmp3 = load i16, i16* %i, align 2
58  %arrayidx = getelementptr inbounds %struct.ss*, %struct.ss** %tmp2, i16 %tmp3
59  %tmp4 = load %struct.ss*, %struct.ss** %arrayidx, align 2
60  %b = getelementptr inbounds %struct.ss, %struct.ss* %tmp4, i32 0, i32 1
61  %tmp5 = load i16, i16* %b, align 2
62  %tmp6 = load %struct.ss*, %struct.ss** %x.addr, align 2
63  %c = getelementptr inbounds %struct.ss, %struct.ss* %tmp6, i32 0, i32 2
64  %tmp7 = load i16, i16* %c, align 2
65  %add = add nsw i16 %tmp7, %tmp5
66  store i16 %add, i16* %c, align 2
67  br label %for.inc
68
69for.inc:                                          ; preds = %for.body
70  %tmp8 = load i16, i16* %i, align 2
71  %inc = add nsw i16 %tmp8, 1
72  store i16 %inc, i16* %i, align 2
73  br label %for.cond
74
75for.end:                                          ; preds = %for.cond
76  ret void
77}
78
79