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 bitcast (i32 (...)* @bar0 to i32 ()*)() #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 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %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 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %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 %t1 = getelementptr [16384 x i32], [16384 x i32]* %t0, i32 0, i32 0 72 %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t1) #0 73 ret i32 %t2 74} 75 76; Combinations. 77 78; CHECK-LABEL: test_ad: 79; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 80; CHECK: stwux 1, 1, {{[0-9]+}} 81; CHECK: mr 1, {{[0-9]+}} 82; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 83define i32 @test_ad(i32 %p0) local_unnamed_addr #0 { 84 %t0 = alloca i32, align 128 85 %t1 = alloca i32, i32 %p0, align 4 86 %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0 87 %t3 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t1) #0 88 %t4 = add i32 %t2, %t3 89 ret i32 %t4 90} 91 92; CHECK-LABEL: test_as: 93; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 94; CHECK: stwux 1, 1, {{[0-9]+}} 95; CHECK: mr 1, {{[0-9]+}} 96; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 97define i32 @test_as() local_unnamed_addr #0 { 98 %t0 = alloca i32, align 128 99 %t1 = alloca [16384 x i32] 100 %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0 101 %t3 = getelementptr [16384 x i32], [16384 x i32]* %t1, i32 0, i32 0 102 %t4 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t3) #0 103 %t5 = add i32 %t2, %t4 104 ret i32 %t5 105} 106 107; CHECK-LABEL: test_ds: 108; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 109; CHECK: stwux 1, 1, {{[0-9]+}} 110; CHECK: mr 1, {{[0-9]+}} 111; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 112define i32 @test_ds(i32 %p0) local_unnamed_addr #0 { 113 %t0 = alloca i32, i32 %p0, align 4 114 %t1 = alloca [16384 x i32] 115 %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0 116 %t3 = getelementptr [16384 x i32], [16384 x i32]* %t1, i32 0, i32 0 117 %t4 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t3) #0 118 %t5 = add i32 %t2, %t4 119 ret i32 %t5 120} 121 122; CHECK-LABEL: test_ads: 123; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1) 124; CHECK: stwux 1, 1, {{[0-9]+}} 125; CHECK: mr 1, {{[0-9]+}} 126; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1) 127define i32 @test_ads(i32 %p0) local_unnamed_addr #0 { 128 %t0 = alloca i32, align 128 129 %t1 = alloca i32, i32 %p0, align 4 130 %t2 = alloca [16384 x i32] 131 132 %t3 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0 133 %t4 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t1) #0 134 %t5 = add i32 %t3, %t4 135 136 %t6 = getelementptr [16384 x i32], [16384 x i32]* %t2, i32 0, i32 0 137 %t7 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t6) #0 138 %t8 = add i32 %t5, %t7 139 ret i32 %t7 140} 141 142 143declare i32 @bar0(...) local_unnamed_addr #0 144declare i32 @bar1(...) local_unnamed_addr #0 145 146attributes #0 = { nounwind } 147