diff options
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/CodeGen/AVR/high-pressure-on-ptrregs.ll | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AVR/high-pressure-on-ptrregs.ll b/llvm/test/CodeGen/AVR/high-pressure-on-ptrregs.ll new file mode 100644 index 00000000000..9330ce1eb2a --- /dev/null +++ b/llvm/test/CodeGen/AVR/high-pressure-on-ptrregs.ll @@ -0,0 +1,78 @@ +; RUN: llc < %s -march=avr | FileCheck %s + +; This tests how LLVM handles IR which puts very high +; presure on the PTRREGS class for the register allocator. +; +; This causes a problem because we only have one small register +; class for loading and storing from pointers - 'PTRREGS'. +; One of these registers is also used for the frame pointer, meaning +; that we only ever have two registers available for these operations. +; +; There is an existing bug filed for this issue - PR14879. +; +; The specific failure: +; LLVM ERROR: ran out of registers during register allocation +; +; It has been assembled from the following c code: +; +; struct ss +; { +; int a; +; int b; +; int c; +; }; +; +; void loop(struct ss *x, struct ss **y, int z) +; { +; int i; +; for (i=0; i<z; ++i) +; { +; x->c += y[i]->b; +; } +; } + +%struct.ss = type { i16, i16, i16 } + +; CHECK-LABEL: loop +define void @loop(%struct.ss* %x, %struct.ss** %y, i16 %z) #0 { +entry: + %x.addr = alloca %struct.ss*, align 2 + %y.addr = alloca %struct.ss**, align 2 + %z.addr = alloca i16, align 2 + %i = alloca i16, align 2 + store %struct.ss* %x, %struct.ss** %x.addr, align 2 + store %struct.ss** %y, %struct.ss*** %y.addr, align 2 + store i16 %z, i16* %z.addr, align 2 + store i16 0, i16* %i, align 2 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %tmp = load i16, i16* %i, align 2 + %tmp1 = load i16, i16* %z.addr, align 2 + %cmp = icmp slt i16 %tmp, %tmp1 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %tmp2 = load %struct.ss**, %struct.ss*** %y.addr, align 2 + %tmp3 = load i16, i16* %i, align 2 + %arrayidx = getelementptr inbounds %struct.ss*, %struct.ss** %tmp2, i16 %tmp3 + %tmp4 = load %struct.ss*, %struct.ss** %arrayidx, align 2 + %b = getelementptr inbounds %struct.ss, %struct.ss* %tmp4, i32 0, i32 1 + %tmp5 = load i16, i16* %b, align 2 + %tmp6 = load %struct.ss*, %struct.ss** %x.addr, align 2 + %c = getelementptr inbounds %struct.ss, %struct.ss* %tmp6, i32 0, i32 2 + %tmp7 = load i16, i16* %c, align 2 + %add = add nsw i16 %tmp7, %tmp5 + store i16 %add, i16* %c, align 2 + br label %for.inc + +for.inc: ; preds = %for.body + %tmp8 = load i16, i16* %i, align 2 + %inc = add nsw i16 %tmp8, 1 + store i16 %inc, i16* %i, align 2 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} + |