1; Test that accesses of the stack remain within the range defined by R1, 2; i.e. that loads and stores only access the allocated stack. This does not 3; have to be the case when red zone is present. 4 5; Make sure that there is no red zone, i.e. ppc32 and SVR4 ABI. 6; RUN: llc -mtriple=powerpc--freebsd-elf < %s | FileCheck %s 7 8; There are two ways that the stack pointer can be adjusted in the prologue: 9; - by adding an immediate value: 10; stwu r1, -imm(r1) 11; - by adding another register: 12; stwux r1, rx, r1 13; 14; The restoring of the stack pointer can be done: 15; - by adding an immediate value to it: 16; addi r1, r1, imm 17; - by copying the value from another register: 18; mr r1, rx 19 20 21; Nothing (no special features). 22; 23; CHECK-LABEL: test_n: 24; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 25; CHECK: stwu 1, -[[SIZE:[0-9]+]](1) 26; CHECK: addi 1, 1, [[SIZE]] 27; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 28define i32 @test_n() local_unnamed_addr #0 { 29entry: 30 %t0 = tail call i32 @bar0() #0 31 ret i32 %t0 32} 33 34; Aligned object on the stack. 35; 36; CHECK-LABEL: test_a: 37; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 38; CHECK: stwux 1, 1, {{[0-9]+}} 39; CHECK: mr 1, {{[0-9]+}} 40; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 41 42define i32 @test_a() local_unnamed_addr #0 { 43entry: 44 %t0 = alloca i32, align 128 45 %t1 = tail call i32 @bar1(ptr %t0) #0 46 ret i32 %t1 47} 48 49; Dynamic allocation on the stack. 50; 51; CHECK-LABEL: test_d: 52; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 53; CHECK: stwu 1, -[[SIZE:[0-9]+]](1) 54; CHECK: mr 1, {{[0-9]+}} 55; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 56define i32 @test_d(i32 %p0) local_unnamed_addr #0 { 57 %t0 = alloca i32, i32 %p0, align 4 58 %t1 = tail call i32 @bar1(ptr %t0) #0 59 ret i32 %t1 60} 61 62; Large stack (exceeds size of D-field). 63; CHECK-LABEL: test_s: 64; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 65; CHECK: stwux 1, 1, {{[0-9]+}} 66; CHECK: mr 1, {{[0-9]+}} 67; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 68define i32 @test_s(i32 %p0) local_unnamed_addr #0 { 69entry: 70 %t0 = alloca [16384 x i32] 71 %t2 = tail call i32 @bar1(ptr %t0) #0 72 ret i32 %t2 73} 74 75; Combinations. 76 77; CHECK-LABEL: test_ad: 78; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 79; CHECK: stwux 1, 1, {{[0-9]+}} 80; CHECK: mr 1, {{[0-9]+}} 81; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 82define i32 @test_ad(i32 %p0) local_unnamed_addr #0 { 83 %t0 = alloca i32, align 128 84 %t1 = alloca i32, i32 %p0, align 4 85 %t2 = tail call i32 @bar1(ptr %t0) #0 86 %t3 = tail call i32 @bar1(ptr %t1) #0 87 %t4 = add i32 %t2, %t3 88 ret i32 %t4 89} 90 91; CHECK-LABEL: test_as: 92; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 93; CHECK: stwux 1, 1, {{[0-9]+}} 94; CHECK: mr 1, {{[0-9]+}} 95; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 96define i32 @test_as() local_unnamed_addr #0 { 97 %t0 = alloca i32, align 128 98 %t1 = alloca [16384 x i32] 99 %t2 = tail call i32 @bar1(ptr %t0) #0 100 %t4 = tail call i32 @bar1(ptr %t1) #0 101 %t5 = add i32 %t2, %t4 102 ret i32 %t5 103} 104 105; CHECK-LABEL: test_ds: 106; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 107; CHECK: stwux 1, 1, {{[0-9]+}} 108; CHECK: mr 1, {{[0-9]+}} 109; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 110define i32 @test_ds(i32 %p0) local_unnamed_addr #0 { 111 %t0 = alloca i32, i32 %p0, align 4 112 %t1 = alloca [16384 x i32] 113 %t2 = tail call i32 @bar1(ptr %t0) #0 114 %t4 = tail call i32 @bar1(ptr %t1) #0 115 %t5 = add i32 %t2, %t4 116 ret i32 %t5 117} 118 119; CHECK-LABEL: test_ads: 120; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 121; CHECK: stwux 1, 1, {{[0-9]+}} 122; CHECK: mr 1, {{[0-9]+}} 123; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 124define i32 @test_ads(i32 %p0) local_unnamed_addr #0 { 125 %t0 = alloca i32, align 128 126 %t1 = alloca i32, i32 %p0, align 4 127 %t2 = alloca [16384 x i32] 128 129 %t3 = tail call i32 @bar1(ptr %t0) #0 130 %t4 = tail call i32 @bar1(ptr %t1) #0 131 %t5 = add i32 %t3, %t4 132 133 %t7 = tail call i32 @bar1(ptr %t2) #0 134 %t8 = add i32 %t5, %t7 135 ret i32 %t7 136} 137 138 139declare i32 @bar0(...) local_unnamed_addr #0 140declare i32 @bar1(...) local_unnamed_addr #0 141 142attributes #0 = { nounwind } 143