1 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s 2 ; RUN: llc < %s -mtriple=i686-pc-win32 -O0 3 4 %struct.S = type { [1024 x i8] } 5 %struct.T = type { [3000 x i8] } 6 %struct.U = type { [10000 x i8] } 7 8 define void @basics() { 9 ; CHECK-LABEL: basics: 10 entry: 11 br label %bb1 12 13 ; Allocation move sizes should have been removed. 14 ; CHECK-NOT: movl $1024 15 ; CHECK-NOT: movl $3000 16 17 bb1: 18 %p0 = alloca %struct.S 19 ; The allocation is small enough not to require stack probing, but the %esp 20 ; offset after the prologue is not known, so the stack must be touched before 21 ; the pointer is adjusted. 22 ; CHECK: pushl %eax 23 ; CHECK: subl $1020, %esp 24 25 %saved_stack = tail call i8* @llvm.stacksave() 26 27 %p1 = alloca %struct.S 28 ; We know the %esp offset from above, so there is no need to touch the stack 29 ; before adjusting it. 30 ; CHECK: subl $1024, %esp 31 32 %p2 = alloca %struct.T 33 ; The offset is now 2048 bytes, so allocating a T must touch the stack again. 34 ; CHECK: pushl %eax 35 ; CHECK: subl $2996, %esp 36 37 call void @f(%struct.S* %p0) 38 ; CHECK: calll 39 40 %p3 = alloca %struct.T 41 ; The call above touched the stack, so there is room for a T object. 42 ; CHECK: subl $3000, %esp 43 44 %p4 = alloca %struct.U 45 ; The U object is large enough to require stack probing. 46 ; CHECK: movl $10000, %eax 47 ; CHECK: calll __chkstk 48 49 %p5 = alloca %struct.T 50 ; The stack probing above touched the tip of the stack, so there's room for a T. 51 ; CHECK: subl $3000, %esp 52 53 call void @llvm.stackrestore(i8* %saved_stack) 54 %p6 = alloca %struct.S 55 ; The stack restore means we lose track of the stack pointer and must probe. 56 ; CHECK: pushl %eax 57 ; CHECK: subl $1020, %esp 58 59 ; Use the pointers so they're not optimized away. 60 call void @f(%struct.S* %p1) 61 call void @g(%struct.T* %p2) 62 call void @g(%struct.T* %p3) 63 call void @h(%struct.U* %p4) 64 call void @g(%struct.T* %p5) 65 ret void 66 } 67 68 define void @loop() { 69 ; CHECK-LABEL: loop: 70 entry: 71 br label %bb1 72 73 bb1: 74 %p1 = alloca %struct.S 75 ; The entry offset is unknown; touch-and-sub. 76 ; CHECK: pushl %eax 77 ; CHECK: subl $1020, %esp 78 br label %loop1 79 80 loop1: 81 %i1 = phi i32 [ 10, %bb1 ], [ %dec1, %loop1 ] 82 %p2 = alloca %struct.S 83 ; We know the incoming offset from bb1, but from the back-edge, we assume the 84 ; worst, and therefore touch-and-sub to allocate. 85 ; CHECK: pushl %eax 86 ; CHECK: subl $1020, %esp 87 %dec1 = sub i32 %i1, 1 88 %cmp1 = icmp sgt i32 %i1, 0 89 br i1 %cmp1, label %loop1, label %end 90 ; CHECK: decl 91 ; CHECK: jg 92 93 end: 94 call void @f(%struct.S* %p1) 95 call void @f(%struct.S* %p2) 96 ret void 97 } 98 99 define void @probe_size_attribute() "stack-probe-size"="512" { 100 ; CHECK-LABEL: probe_size_attribute: 101 entry: 102 br label %bb1 103 104 bb1: 105 %p0 = alloca %struct.S 106 ; The allocation would be small enough not to require probing, if it wasn't 107 ; for the stack-probe-size attribute. 108 ; CHECK: movl $1024, %eax 109 ; CHECK: calll __chkstk 110 call void @f(%struct.S* %p0) 111 ret void 112 } 113 114 define void @cfg(i1 %x, i1 %y) { 115 ; Test that the blocks are analyzed in the correct order. 116 ; CHECK-LABEL: cfg: 117 entry: 118 br i1 %x, label %bb1, label %bb2 119 120 bb1: 121 %p1 = alloca %struct.S 122 ; CHECK: pushl %eax 123 ; CHECK: subl $1020, %esp 124 br label %bb3 125 bb2: 126 %p2 = alloca %struct.T 127 ; CHECK: pushl %eax 128 ; CHECK: subl $2996, %esp 129 br label %bb3 130 131 bb3: 132 br i1 %y, label %bb4, label %bb5 133 134 bb4: 135 %p4 = alloca %struct.S 136 ; CHECK: subl $1024, %esp 137 call void @f(%struct.S* %p4) 138 ret void 139 140 bb5: 141 %p5 = alloca %struct.T 142 ; CHECK: pushl %eax 143 ; CHECK: subl $2996, %esp 144 call void @g(%struct.T* %p5) 145 ret void 146 } 147 148 149 declare void @f(%struct.S*) 150 declare void @g(%struct.T*) 151 declare void @h(%struct.U*) 152 153 declare i8* @llvm.stacksave() 154 declare void @llvm.stackrestore(i8*) 155