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