xref: /aosp_15_r20/external/llvm/test/CodeGen/Thumb/stack-access.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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