1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumb-eabi < %s -o - | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Check that stack addresses are generated using a single ADD 4*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8** %p) { 5*9880d681SAndroid Build Coastguard Worker %x = alloca i8, align 1 6*9880d681SAndroid Build Coastguard Worker %y = alloca i8, align 1 7*9880d681SAndroid Build Coastguard Worker %z = alloca i8, align 1 8*9880d681SAndroid Build Coastguard Worker; CHECK: add r1, sp, #8 9*9880d681SAndroid Build Coastguard Worker; CHECK: str r1, [r0] 10*9880d681SAndroid Build Coastguard Worker store i8* %x, i8** %p, align 4 11*9880d681SAndroid Build Coastguard Worker; CHECK: add r1, sp, #4 12*9880d681SAndroid Build Coastguard Worker; CHECK: str r1, [r0] 13*9880d681SAndroid Build Coastguard Worker store i8* %y, i8** %p, align 4 14*9880d681SAndroid Build Coastguard Worker; CHECK: mov r1, sp 15*9880d681SAndroid Build Coastguard Worker; CHECK: str r1, [r0] 16*9880d681SAndroid Build Coastguard Worker store i8* %z, i8** %p, align 4 17*9880d681SAndroid Build Coastguard Worker ret void 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; Stack offsets larger than 1020 still need two ADDs 21*9880d681SAndroid Build Coastguard Workerdefine void @test2([1024 x i8]** %p) { 22*9880d681SAndroid Build Coastguard Worker %arr1 = alloca [1024 x i8], align 1 23*9880d681SAndroid Build Coastguard Worker %arr2 = alloca [1024 x i8], align 1 24*9880d681SAndroid Build Coastguard Worker; CHECK: add r1, sp, #1020 25*9880d681SAndroid Build Coastguard Worker; CHECK: adds r1, #4 26*9880d681SAndroid Build Coastguard Worker; CHECK: str r1, [r0] 27*9880d681SAndroid Build Coastguard Worker store [1024 x i8]* %arr1, [1024 x i8]** %p, align 4 28*9880d681SAndroid Build Coastguard Worker; CHECK: mov r1, sp 29*9880d681SAndroid Build Coastguard Worker; CHECK: str r1, [r0] 30*9880d681SAndroid Build Coastguard Worker store [1024 x i8]* %arr2, [1024 x i8]** %p, align 4 31*9880d681SAndroid Build Coastguard Worker ret void 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; If possible stack-based lrdb/ldrh are widened to use SP-based addressing 35*9880d681SAndroid Build Coastguard Workerdefine i32 @test3() #0 { 36*9880d681SAndroid Build Coastguard Worker %x = alloca i8, align 1 37*9880d681SAndroid Build Coastguard Worker %y = alloca i8, align 1 38*9880d681SAndroid Build Coastguard Worker; CHECK: ldr r0, [sp] 39*9880d681SAndroid Build Coastguard Worker %1 = load i8, i8* %x, align 1 40*9880d681SAndroid Build Coastguard Worker; CHECK: ldr r1, [sp, #4] 41*9880d681SAndroid Build Coastguard Worker %2 = load i8, i8* %y, align 1 42*9880d681SAndroid Build Coastguard Worker %3 = add nsw i8 %1, %2 43*9880d681SAndroid Build Coastguard Worker %4 = zext i8 %3 to i32 44*9880d681SAndroid Build Coastguard Worker ret i32 %4 45*9880d681SAndroid Build Coastguard Worker} 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerdefine i32 @test4() #0 { 48*9880d681SAndroid Build Coastguard Worker %x = alloca i16, align 2 49*9880d681SAndroid Build Coastguard Worker %y = alloca i16, align 2 50*9880d681SAndroid Build Coastguard Worker; CHECK: ldr r0, [sp] 51*9880d681SAndroid Build Coastguard Worker %1 = load i16, i16* %x, align 2 52*9880d681SAndroid Build Coastguard Worker; CHECK: ldr r1, [sp, #4] 53*9880d681SAndroid Build Coastguard Worker %2 = load i16, i16* %y, align 2 54*9880d681SAndroid Build Coastguard Worker %3 = add nsw i16 %1, %2 55*9880d681SAndroid Build Coastguard Worker %4 = zext i16 %3 to i32 56*9880d681SAndroid Build Coastguard Worker ret i32 %4 57*9880d681SAndroid Build Coastguard Worker} 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; Don't widen if the value needs to be zero-extended 60*9880d681SAndroid Build Coastguard Workerdefine zeroext i8 @test5() { 61*9880d681SAndroid Build Coastguard Worker %x = alloca i8, align 1 62*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, sp 63*9880d681SAndroid Build Coastguard Worker; CHECK: ldrb r0, [r0] 64*9880d681SAndroid Build Coastguard Worker %1 = load i8, i8* %x, align 1 65*9880d681SAndroid Build Coastguard Worker ret i8 %1 66*9880d681SAndroid Build Coastguard Worker} 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workerdefine zeroext i16 @test6() { 69*9880d681SAndroid Build Coastguard Worker %x = alloca i16, align 2 70*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, sp 71*9880d681SAndroid Build Coastguard Worker; CHECK: ldrh r0, [r0] 72*9880d681SAndroid Build Coastguard Worker %1 = load i16, i16* %x, align 2 73*9880d681SAndroid Build Coastguard Worker ret i16 %1 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; Accessing the bottom of a large array shouldn't require materializing a base 77*9880d681SAndroid Build Coastguard Workerdefine void @test7() { 78*9880d681SAndroid Build Coastguard Worker %arr = alloca [200 x i32], align 4 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker ; CHECK: movs [[REG:r[0-9]+]], #1 81*9880d681SAndroid Build Coastguard Worker ; CHECK: str [[REG]], [sp, #4] 82*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds [200 x i32], [200 x i32]* %arr, i32 0, i32 1 83*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arrayidx, align 4 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker ; CHECK: str [[REG]], [sp, #16] 86*9880d681SAndroid Build Coastguard Worker %arrayidx1 = getelementptr inbounds [200 x i32], [200 x i32]* %arr, i32 0, i32 4 87*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arrayidx1, align 4 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker ret void 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; Check that loads/stores with out-of-range offsets are handled correctly 93*9880d681SAndroid Build Coastguard Workerdefine void @test8() { 94*9880d681SAndroid Build Coastguard Worker %arr3 = alloca [224 x i32], align 4 95*9880d681SAndroid Build Coastguard Worker %arr2 = alloca [224 x i32], align 4 96*9880d681SAndroid Build Coastguard Worker %arr1 = alloca [224 x i32], align 4 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[REG:r[0-9]+]], #1 99*9880d681SAndroid Build Coastguard Worker; CHECK: str [[REG]], [sp] 100*9880d681SAndroid Build Coastguard Worker %arr1idx1 = getelementptr inbounds [224 x i32], [224 x i32]* %arr1, i32 0, i32 0 101*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arr1idx1, align 4 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; Offset in range for sp-based store, but not for non-sp-based store 104*9880d681SAndroid Build Coastguard Worker; CHECK: str [[REG]], [sp, #128] 105*9880d681SAndroid Build Coastguard Worker %arr1idx2 = getelementptr inbounds [224 x i32], [224 x i32]* %arr1, i32 0, i32 32 106*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arr1idx2, align 4 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker; CHECK: str [[REG]], [sp, #896] 109*9880d681SAndroid Build Coastguard Worker %arr2idx1 = getelementptr inbounds [224 x i32], [224 x i32]* %arr2, i32 0, i32 0 110*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arr2idx1, align 4 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker; %arr2 is in range, but this element of it is not 113*9880d681SAndroid Build Coastguard Worker; CHECK: str [[REG]], [{{r[0-9]+}}] 114*9880d681SAndroid Build Coastguard Worker %arr2idx2 = getelementptr inbounds [224 x i32], [224 x i32]* %arr2, i32 0, i32 32 115*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arr2idx2, align 4 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker; %arr3 is not in range 118*9880d681SAndroid Build Coastguard Worker; CHECK: str [[REG]], [{{r[0-9]+}}] 119*9880d681SAndroid Build Coastguard Worker %arr3idx1 = getelementptr inbounds [224 x i32], [224 x i32]* %arr3, i32 0, i32 0 120*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arr3idx1, align 4 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker; CHECK: str [[REG]], [{{r[0-9]+}}] 123*9880d681SAndroid Build Coastguard Worker %arr3idx2 = getelementptr inbounds [224 x i32], [224 x i32]* %arr3, i32 0, i32 32 124*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arr3idx2, align 4 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker ret void 127*9880d681SAndroid Build Coastguard Worker} 128