|  | ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s | 
|  | ; RUN: llc < %s -mtriple=i686-pc-win32 -O0 | 
|  |  | 
|  | %struct.S = type { [1024 x i8] } | 
|  | %struct.T = type { [3000 x i8] } | 
|  | %struct.U = type { [10000 x i8] } | 
|  |  | 
|  | define void @basics() { | 
|  | ; CHECK-LABEL: basics: | 
|  | entry: | 
|  | br label %bb1 | 
|  |  | 
|  | ; Allocation move sizes should have been removed. | 
|  | ; CHECK-NOT: movl $1024 | 
|  | ; CHECK-NOT: movl $3000 | 
|  |  | 
|  | bb1: | 
|  | %p0 = alloca %struct.S | 
|  | ; The allocation is small enough not to require stack probing, but the %esp | 
|  | ; offset after the prologue is not known, so the stack must be touched before | 
|  | ; the pointer is adjusted. | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $1020, %esp | 
|  |  | 
|  | %saved_stack = tail call i8* @llvm.stacksave() | 
|  |  | 
|  | %p1 = alloca %struct.S | 
|  | ; We know the %esp offset from above, so there is no need to touch the stack | 
|  | ; before adjusting it. | 
|  | ; CHECK: subl $1024, %esp | 
|  |  | 
|  | %p2 = alloca %struct.T | 
|  | ; The offset is now 2048 bytes, so allocating a T must touch the stack again. | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $2996, %esp | 
|  |  | 
|  | call void @f(%struct.S* %p0) | 
|  | ; CHECK: calll | 
|  |  | 
|  | %p3 = alloca %struct.T | 
|  | ; The call above touched the stack, so there is room for a T object. | 
|  | ; CHECK: subl $3000, %esp | 
|  |  | 
|  | %p4 = alloca %struct.U | 
|  | ; The U object is large enough to require stack probing. | 
|  | ; CHECK: movl $10000, %eax | 
|  | ; CHECK: calll __chkstk | 
|  |  | 
|  | %p5 = alloca %struct.T | 
|  | ; The stack probing above touched the tip of the stack, so there's room for a T. | 
|  | ; CHECK: subl $3000, %esp | 
|  |  | 
|  | call void @llvm.stackrestore(i8* %saved_stack) | 
|  | %p6 = alloca %struct.S | 
|  | ; The stack restore means we lose track of the stack pointer and must probe. | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $1020, %esp | 
|  |  | 
|  | ; Use the pointers so they're not optimized away. | 
|  | call void @f(%struct.S* %p1) | 
|  | call void @g(%struct.T* %p2) | 
|  | call void @g(%struct.T* %p3) | 
|  | call void @h(%struct.U* %p4) | 
|  | call void @g(%struct.T* %p5) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define void @loop() { | 
|  | ; CHECK-LABEL: loop: | 
|  | entry: | 
|  | br label %bb1 | 
|  |  | 
|  | bb1: | 
|  | %p1 = alloca %struct.S | 
|  | ; The entry offset is unknown; touch-and-sub. | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $1020, %esp | 
|  | br label %loop1 | 
|  |  | 
|  | loop1: | 
|  | %i1 = phi i32 [ 10, %bb1 ], [ %dec1, %loop1 ] | 
|  | %p2 = alloca %struct.S | 
|  | ; We know the incoming offset from bb1, but from the back-edge, we assume the | 
|  | ; worst, and therefore touch-and-sub to allocate. | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $1020, %esp | 
|  | %dec1 = sub i32 %i1, 1 | 
|  | %cmp1 = icmp sgt i32 %i1, 0 | 
|  | br i1 %cmp1, label %loop1, label %end | 
|  | ; CHECK: decl | 
|  | ; CHECK: jg | 
|  |  | 
|  | end: | 
|  | call void @f(%struct.S* %p1) | 
|  | call void @f(%struct.S* %p2) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define void @probe_size_attribute() "stack-probe-size"="512" { | 
|  | ; CHECK-LABEL: probe_size_attribute: | 
|  | entry: | 
|  | br label %bb1 | 
|  |  | 
|  | bb1: | 
|  | %p0 = alloca %struct.S | 
|  | ; The allocation would be small enough not to require probing, if it wasn't | 
|  | ; for the stack-probe-size attribute. | 
|  | ; CHECK: movl $1024, %eax | 
|  | ; CHECK: calll __chkstk | 
|  | call void @f(%struct.S* %p0) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define void @cfg(i1 %x, i1 %y) { | 
|  | ; Test that the blocks are analyzed in the correct order. | 
|  | ; CHECK-LABEL: cfg: | 
|  | entry: | 
|  | br i1 %x, label %bb1, label %bb3 | 
|  |  | 
|  | bb1: | 
|  | %p1 = alloca %struct.S | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $1020, %esp | 
|  | br label %bb4 | 
|  |  | 
|  | bb2: | 
|  | %p5 = alloca %struct.T | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $2996, %esp | 
|  | call void @g(%struct.T* %p5) | 
|  | ret void | 
|  |  | 
|  | bb3: | 
|  | %p2 = alloca %struct.T | 
|  | ; CHECK: pushl %eax | 
|  | ; CHECK: subl $2996, %esp | 
|  | br label %bb4 | 
|  |  | 
|  | bb4: | 
|  | br i1 %y, label %bb5, label %bb2 | 
|  |  | 
|  | bb5: | 
|  | %p4 = alloca %struct.S | 
|  | ; CHECK: subl $1024, %esp | 
|  | call void @f(%struct.S* %p4) | 
|  | ret void | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | declare void @f(%struct.S*) | 
|  | declare void @g(%struct.T*) | 
|  | declare void @h(%struct.U*) | 
|  |  | 
|  | declare i8* @llvm.stacksave() | 
|  | declare void @llvm.stackrestore(i8*) |