1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -asm-verbose=false | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; These tests check for loop branching structure, and that the loop align 4*9880d681SAndroid Build Coastguard Worker; directive is placed in the expected place. 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; CodeGen should insert a branch into the middle of the loop in 7*9880d681SAndroid Build Coastguard Worker; order to avoid a branch within the loop. 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: simple: 10*9880d681SAndroid Build Coastguard Worker; CHECK: jmp .LBB0_1 11*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: align 12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB0_2: 13*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq loop_latch 14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB0_1: 15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq loop_header 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerdefine void @simple() nounwind { 18*9880d681SAndroid Build Coastguard Workerentry: 19*9880d681SAndroid Build Coastguard Worker br label %loop 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Workerloop: 22*9880d681SAndroid Build Coastguard Worker call void @loop_header() 23*9880d681SAndroid Build Coastguard Worker %t0 = tail call i32 @get() 24*9880d681SAndroid Build Coastguard Worker %t1 = icmp slt i32 %t0, 0 25*9880d681SAndroid Build Coastguard Worker br i1 %t1, label %done, label %bb 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Workerbb: 28*9880d681SAndroid Build Coastguard Worker call void @loop_latch() 29*9880d681SAndroid Build Coastguard Worker br label %loop 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Workerdone: 32*9880d681SAndroid Build Coastguard Worker call void @exit() 33*9880d681SAndroid Build Coastguard Worker ret void 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker; CodeGen should move block_a to the top of the loop so that it 37*9880d681SAndroid Build Coastguard Worker; falls through into the loop, avoiding a branch within the loop. 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: slightly_more_involved: 40*9880d681SAndroid Build Coastguard Worker; CHECK: jmp .LBB1_1 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: align 42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB1_4: 43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq bar99 44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB1_1: 45*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq body 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerdefine void @slightly_more_involved() nounwind { 48*9880d681SAndroid Build Coastguard Workerentry: 49*9880d681SAndroid Build Coastguard Worker br label %loop 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Workerloop: 52*9880d681SAndroid Build Coastguard Worker call void @body() 53*9880d681SAndroid Build Coastguard Worker %t0 = call i32 @get() 54*9880d681SAndroid Build Coastguard Worker %t1 = icmp slt i32 %t0, 2 55*9880d681SAndroid Build Coastguard Worker br i1 %t1, label %block_a, label %bb 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Workerbb: 58*9880d681SAndroid Build Coastguard Worker %t2 = call i32 @get() 59*9880d681SAndroid Build Coastguard Worker %t3 = icmp slt i32 %t2, 99 60*9880d681SAndroid Build Coastguard Worker br i1 %t3, label %exit, label %loop 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerblock_a: 63*9880d681SAndroid Build Coastguard Worker call void @bar99() 64*9880d681SAndroid Build Coastguard Worker br label %loop 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerexit: 67*9880d681SAndroid Build Coastguard Worker call void @exit() 68*9880d681SAndroid Build Coastguard Worker ret void 69*9880d681SAndroid Build Coastguard Worker} 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker; Same as slightly_more_involved, but block_a is now a CFG diamond with 72*9880d681SAndroid Build Coastguard Worker; fallthrough edges which should be preserved. 73*9880d681SAndroid Build Coastguard Worker; "callq block_a_merge_func" is tail duped. 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: yet_more_involved: 76*9880d681SAndroid Build Coastguard Worker; CHECK: jmp .LBB2_1 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: align 78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB2_5: 79*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq block_a_true_func 80*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq block_a_merge_func 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB2_1: 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq body 83*9880d681SAndroid Build Coastguard Worker; 84*9880d681SAndroid Build Coastguard Worker; LBB2_4 85*9880d681SAndroid Build Coastguard Worker; CHECK: callq bar99 86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq get 87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmpl $2999, %eax 88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jle .LBB2_5 89*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq block_a_false_func 90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq block_a_merge_func 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp .LBB2_1 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerdefine void @yet_more_involved() nounwind { 94*9880d681SAndroid Build Coastguard Workerentry: 95*9880d681SAndroid Build Coastguard Worker br label %loop 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Workerloop: 98*9880d681SAndroid Build Coastguard Worker call void @body() 99*9880d681SAndroid Build Coastguard Worker %t0 = call i32 @get() 100*9880d681SAndroid Build Coastguard Worker %t1 = icmp slt i32 %t0, 2 101*9880d681SAndroid Build Coastguard Worker br i1 %t1, label %block_a, label %bb 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Workerbb: 104*9880d681SAndroid Build Coastguard Worker %t2 = call i32 @get() 105*9880d681SAndroid Build Coastguard Worker %t3 = icmp slt i32 %t2, 99 106*9880d681SAndroid Build Coastguard Worker br i1 %t3, label %exit, label %loop 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerblock_a: 109*9880d681SAndroid Build Coastguard Worker call void @bar99() 110*9880d681SAndroid Build Coastguard Worker %z0 = call i32 @get() 111*9880d681SAndroid Build Coastguard Worker %z1 = icmp slt i32 %z0, 3000 112*9880d681SAndroid Build Coastguard Worker br i1 %z1, label %block_a_true, label %block_a_false 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Workerblock_a_true: 115*9880d681SAndroid Build Coastguard Worker call void @block_a_true_func() 116*9880d681SAndroid Build Coastguard Worker br label %block_a_merge 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workerblock_a_false: 119*9880d681SAndroid Build Coastguard Worker call void @block_a_false_func() 120*9880d681SAndroid Build Coastguard Worker br label %block_a_merge 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerblock_a_merge: 123*9880d681SAndroid Build Coastguard Worker call void @block_a_merge_func() 124*9880d681SAndroid Build Coastguard Worker br label %loop 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerexit: 127*9880d681SAndroid Build Coastguard Worker call void @exit() 128*9880d681SAndroid Build Coastguard Worker ret void 129*9880d681SAndroid Build Coastguard Worker} 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker; CodeGen should move the CFG islands that are part of the loop but don't 132*9880d681SAndroid Build Coastguard Worker; conveniently fit anywhere so that they are at least contiguous with the 133*9880d681SAndroid Build Coastguard Worker; loop. 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cfg_islands: 136*9880d681SAndroid Build Coastguard Worker; CHECK: jmp .LBB3_1 137*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: align 138*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB3_7: 139*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq bar100 140*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB3_1: 141*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq loop_header 142*9880d681SAndroid Build Coastguard Worker; CHECK: jl .LBB3_7 143*9880d681SAndroid Build Coastguard Worker; CHECK: jge .LBB3_3 144*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq bar101 145*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp .LBB3_1 146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: align 147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB3_3: 148*9880d681SAndroid Build Coastguard Worker; CHECK: jge .LBB3_4 149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq bar102 150*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp .LBB3_1 151*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB3_4: 152*9880d681SAndroid Build Coastguard Worker; CHECK: jl .LBB3_6 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq loop_latch 154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp .LBB3_1 155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB3_6: 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Workerdefine void @cfg_islands() nounwind { 158*9880d681SAndroid Build Coastguard Workerentry: 159*9880d681SAndroid Build Coastguard Worker br label %loop 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Workerloop: 162*9880d681SAndroid Build Coastguard Worker call void @loop_header() 163*9880d681SAndroid Build Coastguard Worker %t0 = call i32 @get() 164*9880d681SAndroid Build Coastguard Worker %t1 = icmp slt i32 %t0, 100 165*9880d681SAndroid Build Coastguard Worker br i1 %t1, label %block100, label %bb 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Workerbb: 168*9880d681SAndroid Build Coastguard Worker %t2 = call i32 @get() 169*9880d681SAndroid Build Coastguard Worker %t3 = icmp slt i32 %t2, 101 170*9880d681SAndroid Build Coastguard Worker br i1 %t3, label %block101, label %bb1 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Workerbb1: 173*9880d681SAndroid Build Coastguard Worker %t4 = call i32 @get() 174*9880d681SAndroid Build Coastguard Worker %t5 = icmp slt i32 %t4, 102 175*9880d681SAndroid Build Coastguard Worker br i1 %t5, label %block102, label %bb2 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Workerbb2: 178*9880d681SAndroid Build Coastguard Worker %t6 = call i32 @get() 179*9880d681SAndroid Build Coastguard Worker %t7 = icmp slt i32 %t6, 103 180*9880d681SAndroid Build Coastguard Worker br i1 %t7, label %exit, label %bb3 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerbb3: 183*9880d681SAndroid Build Coastguard Worker call void @loop_latch() 184*9880d681SAndroid Build Coastguard Worker br label %loop 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Workerexit: 187*9880d681SAndroid Build Coastguard Worker call void @exit() 188*9880d681SAndroid Build Coastguard Worker ret void 189*9880d681SAndroid Build Coastguard Worker 190*9880d681SAndroid Build Coastguard Workerblock100: 191*9880d681SAndroid Build Coastguard Worker call void @bar100() 192*9880d681SAndroid Build Coastguard Worker br label %loop 193*9880d681SAndroid Build Coastguard Worker 194*9880d681SAndroid Build Coastguard Workerblock101: 195*9880d681SAndroid Build Coastguard Worker call void @bar101() 196*9880d681SAndroid Build Coastguard Worker br label %loop 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerblock102: 199*9880d681SAndroid Build Coastguard Worker call void @bar102() 200*9880d681SAndroid Build Coastguard Worker br label %loop 201*9880d681SAndroid Build Coastguard Worker} 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: check_minsize: 204*9880d681SAndroid Build Coastguard Worker; CHECK: jmp .LBB4_1 205*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: align 206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB4_2: 207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq loop_latch 208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB4_1: 209*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq loop_header 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker 212*9880d681SAndroid Build Coastguard Workerdefine void @check_minsize() minsize nounwind { 213*9880d681SAndroid Build Coastguard Workerentry: 214*9880d681SAndroid Build Coastguard Worker br label %loop 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Workerloop: 217*9880d681SAndroid Build Coastguard Worker call void @loop_header() 218*9880d681SAndroid Build Coastguard Worker %t0 = tail call i32 @get() 219*9880d681SAndroid Build Coastguard Worker %t1 = icmp slt i32 %t0, 0 220*9880d681SAndroid Build Coastguard Worker br i1 %t1, label %done, label %bb 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Workerbb: 223*9880d681SAndroid Build Coastguard Worker call void @loop_latch() 224*9880d681SAndroid Build Coastguard Worker br label %loop 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Workerdone: 227*9880d681SAndroid Build Coastguard Worker call void @exit() 228*9880d681SAndroid Build Coastguard Worker ret void 229*9880d681SAndroid Build Coastguard Worker} 230*9880d681SAndroid Build Coastguard Worker 231*9880d681SAndroid Build Coastguard Workerdeclare void @bar99() nounwind 232*9880d681SAndroid Build Coastguard Workerdeclare void @bar100() nounwind 233*9880d681SAndroid Build Coastguard Workerdeclare void @bar101() nounwind 234*9880d681SAndroid Build Coastguard Workerdeclare void @bar102() nounwind 235*9880d681SAndroid Build Coastguard Workerdeclare void @body() nounwind 236*9880d681SAndroid Build Coastguard Workerdeclare void @exit() nounwind 237*9880d681SAndroid Build Coastguard Workerdeclare void @loop_header() nounwind 238*9880d681SAndroid Build Coastguard Workerdeclare void @loop_latch() nounwind 239*9880d681SAndroid Build Coastguard Workerdeclare i32 @get() nounwind 240*9880d681SAndroid Build Coastguard Workerdeclare void @block_a_true_func() nounwind 241*9880d681SAndroid Build Coastguard Workerdeclare void @block_a_false_func() nounwind 242*9880d681SAndroid Build Coastguard Workerdeclare void @block_a_merge_func() nounwind 243