1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE 2*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE 3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 4*9880d681SAndroid Build Coastguard Workertarget triple = "arm64-apple-ios" 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Initial motivating example: Simple diamond with a call just on one side. 8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo: 9*9880d681SAndroid Build Coastguard Worker; 10*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit. 11*9880d681SAndroid Build Coastguard Worker; No prologue needed. 12*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp w0, w1 13*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: b.ge [[EXIT_LABEL:LBB[0-9_]+]] 14*9880d681SAndroid Build Coastguard Worker; 15*9880d681SAndroid Build Coastguard Worker; Prologue code. 16*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #32 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[SAVE_SP:x[0-9]+]], [[CSR:x[0-9]+]], [sp, #16] 18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SAVE_SP]], sp, #16 19*9880d681SAndroid Build Coastguard Worker; 20*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit. 21*9880d681SAndroid Build Coastguard Worker; After the prologue is set. 22*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp w0, w1 23*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: b.ge [[EXIT_LABEL:LBB[0-9_]+]] 24*9880d681SAndroid Build Coastguard Worker; 25*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca. 26*9880d681SAndroid Build Coastguard Worker; CHECK: stur w0, {{\[}}[[SAVE_SP]], #-4] 27*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument. 28*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub x1, [[SAVE_SP]], #4 29*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero. 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov w0, wzr 31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl _doSomething 32*9880d681SAndroid Build Coastguard Worker; 33*9880d681SAndroid Build Coastguard Worker; Without shrink-wrapping, epilogue is in the exit block. 34*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EXIT_LABEL]]: 35*9880d681SAndroid Build Coastguard Worker; Epilogue code. 36*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp x{{[0-9]+}}, [[CSR]], [sp, #16] 37*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add sp, sp, #32 38*9880d681SAndroid Build Coastguard Worker; 39*9880d681SAndroid Build Coastguard Worker; With shrink-wrapping, exit block is a simple return. 40*9880d681SAndroid Build Coastguard Worker; ENABLE: [[EXIT_LABEL]]: 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 42*9880d681SAndroid Build Coastguard Workerdefine i32 @foo(i32 %a, i32 %b) { 43*9880d681SAndroid Build Coastguard Worker %tmp = alloca i32, align 4 44*9880d681SAndroid Build Coastguard Worker %tmp2 = icmp slt i32 %a, %b 45*9880d681SAndroid Build Coastguard Worker br i1 %tmp2, label %true, label %false 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workertrue: 48*9880d681SAndroid Build Coastguard Worker store i32 %a, i32* %tmp, align 4 49*9880d681SAndroid Build Coastguard Worker %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 50*9880d681SAndroid Build Coastguard Worker br label %false 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerfalse: 53*9880d681SAndroid Build Coastguard Worker %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 54*9880d681SAndroid Build Coastguard Worker ret i32 %tmp.0 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; Function Attrs: optsize 58*9880d681SAndroid Build Coastguard Workerdeclare i32 @doSomething(i32, i32*) 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the restore inside the loop whereas the save 62*9880d681SAndroid Build Coastguard Worker; is outside. 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop: 64*9880d681SAndroid Build Coastguard Worker; 65*9880d681SAndroid Build Coastguard Worker; Shrink-wrapping allows to skip the prologue in the else case. 66*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 67*9880d681SAndroid Build Coastguard Worker; 68*9880d681SAndroid Build Coastguard Worker; Prologue code. 69*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! 70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 72*9880d681SAndroid Build Coastguard Worker; 73*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 74*9880d681SAndroid Build Coastguard Worker; 75*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w[0-9]+]], wzr 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 77*9880d681SAndroid Build Coastguard Worker; 78*9880d681SAndroid Build Coastguard Worker; Next BB. 79*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: ; %for.body 80*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]] 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1 83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP]] 84*9880d681SAndroid Build Coastguard Worker; 85*9880d681SAndroid Build Coastguard Worker; Next BB. 86*9880d681SAndroid Build Coastguard Worker; Copy SUM into the returned register + << 3. 87*9880d681SAndroid Build Coastguard Worker; CHECK: lsl w0, [[SUM]], #3 88*9880d681SAndroid Build Coastguard Worker; 89*9880d681SAndroid Build Coastguard Worker; Jump to epilogue. 90*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]] 91*9880d681SAndroid Build Coastguard Worker; 92*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else 93*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 94*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1 95*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: ; %if.end 96*9880d681SAndroid Build Coastguard Worker; 97*9880d681SAndroid Build Coastguard Worker; Epilogue code. 98*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[CSR3]], [[CSR4]], [sp, #16] 99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 101*9880d681SAndroid Build Coastguard Worker; 102*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else 103*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 104*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1 105*9880d681SAndroid Build Coastguard Worker; ENABLE: ret 106*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) { 107*9880d681SAndroid Build Coastguard Workerentry: 108*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 109*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.body 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 112*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 113*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ] 114*9880d681SAndroid Build Coastguard Worker %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() 115*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 116*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 117*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 118*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 121*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 122*9880d681SAndroid Build Coastguard Worker br label %if.end 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 125*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 126*9880d681SAndroid Build Coastguard Worker br label %if.end 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 129*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 130*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Workerdeclare i32 @something(...) 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the shrink-wrapping inside the loop even 136*9880d681SAndroid Build Coastguard Worker; though that would be legal. The cost model must prevent that. 137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop2: 138*9880d681SAndroid Build Coastguard Worker; Prologue code. 139*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! 140*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] 141*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 142*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w[0-9]+]], wzr 143*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 144*9880d681SAndroid Build Coastguard Worker; Next BB. 145*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body 146*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something 147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]] 148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1 149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]] 150*9880d681SAndroid Build Coastguard Worker; Next BB. 151*9880d681SAndroid Build Coastguard Worker; CHECK: ; %for.end 152*9880d681SAndroid Build Coastguard Worker; CHECK: mov w0, [[SUM]] 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR3]], [[CSR4]], [sp, #16] 154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 156*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) { 157*9880d681SAndroid Build Coastguard Workerentry: 158*9880d681SAndroid Build Coastguard Worker br label %for.body 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 161*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 162*9880d681SAndroid Build Coastguard Worker %sum.03 = phi i32 [ 0, %entry ], [ %add, %for.body ] 163*9880d681SAndroid Build Coastguard Worker %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() 164*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.03 165*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.04, 1 166*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 167*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 170*9880d681SAndroid Build Coastguard Worker ret i32 %add 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have save within the loop and 174*9880d681SAndroid Build Coastguard Worker; restore outside. 175*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoSaveOutsideLoop: 176*9880d681SAndroid Build Coastguard Worker; 177*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 178*9880d681SAndroid Build Coastguard Worker; 179*9880d681SAndroid Build Coastguard Worker; Prologue code. 180*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! 181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] 182*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 183*9880d681SAndroid Build Coastguard Worker; 184*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 185*9880d681SAndroid Build Coastguard Worker; 186*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w[0-9]+]], wzr 187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 188*9880d681SAndroid Build Coastguard Worker; 189*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body 190*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something 191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]] 192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1 193*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]] 194*9880d681SAndroid Build Coastguard Worker; Next BB. 195*9880d681SAndroid Build Coastguard Worker; CHECK: bl _somethingElse 196*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl w0, [[SUM]], #3 197*9880d681SAndroid Build Coastguard Worker; 198*9880d681SAndroid Build Coastguard Worker; Jump to epilogue. 199*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]] 200*9880d681SAndroid Build Coastguard Worker; 201*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else 202*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 203*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1 204*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: ; %if.end 205*9880d681SAndroid Build Coastguard Worker; Epilogue code. 206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR3]], [[CSR4]], [sp, #16] 207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 209*9880d681SAndroid Build Coastguard Worker; 210*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else 211*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 212*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1 213*9880d681SAndroid Build Coastguard Worker; ENABLE: ret 214*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) { 215*9880d681SAndroid Build Coastguard Workerentry: 216*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 217*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.body 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 220*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 221*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ] 222*9880d681SAndroid Build Coastguard Worker %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() 223*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 224*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 225*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 226*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 229*9880d681SAndroid Build Coastguard Worker tail call void bitcast (void (...)* @somethingElse to void ()*)() 230*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 231*9880d681SAndroid Build Coastguard Worker br label %if.end 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 234*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 235*9880d681SAndroid Build Coastguard Worker br label %if.end 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 238*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 239*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 240*9880d681SAndroid Build Coastguard Worker} 241*9880d681SAndroid Build Coastguard Worker 242*9880d681SAndroid Build Coastguard Workerdeclare void @somethingElse(...) 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have restore within the loop and 245*9880d681SAndroid Build Coastguard Worker; save outside. 246*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoRestoreOutsideLoop: 247*9880d681SAndroid Build Coastguard Worker; 248*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 249*9880d681SAndroid Build Coastguard Worker; 250*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! 251*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] 252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 253*9880d681SAndroid Build Coastguard Worker; 254*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 255*9880d681SAndroid Build Coastguard Worker; 256*9880d681SAndroid Build Coastguard Worker; CHECK: bl _somethingElse 257*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[SUM:w[0-9]+]], wzr 258*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 259*9880d681SAndroid Build Coastguard Worker; 260*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body 261*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something 262*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]] 263*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1 264*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]] 265*9880d681SAndroid Build Coastguard Worker; Next BB. 266*9880d681SAndroid Build Coastguard Worker; CHECK: lsl w0, [[SUM]], #3 267*9880d681SAndroid Build Coastguard Worker; 268*9880d681SAndroid Build Coastguard Worker; Jump to epilogue. 269*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]] 270*9880d681SAndroid Build Coastguard Worker; 271*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else 272*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 273*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1 274*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: ; %if.end 275*9880d681SAndroid Build Coastguard Worker; Epilogue code. 276*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[CSR3]], [[CSR4]], [sp, #16] 277*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 278*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 279*9880d681SAndroid Build Coastguard Worker; 280*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else 281*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 282*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1 283*9880d681SAndroid Build Coastguard Worker; ENABLE: ret 284*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 { 285*9880d681SAndroid Build Coastguard Workerentry: 286*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 287*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %if.then 288*9880d681SAndroid Build Coastguard Worker 289*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 290*9880d681SAndroid Build Coastguard Worker tail call void bitcast (void (...)* @somethingElse to void ()*)() 291*9880d681SAndroid Build Coastguard Worker br label %for.body 292*9880d681SAndroid Build Coastguard Worker 293*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %if.then 294*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ] 295*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 296*9880d681SAndroid Build Coastguard Worker %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() 297*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 298*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 299*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 300*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 301*9880d681SAndroid Build Coastguard Worker 302*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 303*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 304*9880d681SAndroid Build Coastguard Worker br label %if.end 305*9880d681SAndroid Build Coastguard Worker 306*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 307*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 308*9880d681SAndroid Build Coastguard Worker br label %if.end 309*9880d681SAndroid Build Coastguard Worker 310*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 311*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 312*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 313*9880d681SAndroid Build Coastguard Worker} 314*9880d681SAndroid Build Coastguard Worker 315*9880d681SAndroid Build Coastguard Worker; Check that we handle function with no frame information correctly. 316*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: emptyFrame: 317*9880d681SAndroid Build Coastguard Worker; CHECK: ; %entry 318*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov w0, wzr 319*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 320*9880d681SAndroid Build Coastguard Workerdefine i32 @emptyFrame() { 321*9880d681SAndroid Build Coastguard Workerentry: 322*9880d681SAndroid Build Coastguard Worker ret i32 0 323*9880d681SAndroid Build Coastguard Worker} 324*9880d681SAndroid Build Coastguard Worker 325*9880d681SAndroid Build Coastguard Worker; Check that we handle variadic function correctly. 326*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: variadicFunc: 327*9880d681SAndroid Build Coastguard Worker; 328*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 329*9880d681SAndroid Build Coastguard Worker; 330*9880d681SAndroid Build Coastguard Worker; Prologue code. 331*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #16 332*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 333*9880d681SAndroid Build Coastguard Worker; 334*9880d681SAndroid Build Coastguard Worker; Sum is merged with the returned register. 335*9880d681SAndroid Build Coastguard Worker; CHECK: add [[VA_BASE:x[0-9]+]], sp, #16 336*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[VA_BASE]], [sp, #8] 337*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w1, #1 338*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.lt [[IFEND_LABEL:LBB[0-9_]+]] 339*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w0]], wzr 340*9880d681SAndroid Build Coastguard Worker; 341*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body 342*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[VA_ADDR:x[0-9]+]], [sp, #8] 343*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEXT_VA_ADDR:x[0-9]+]], [[VA_ADDR]], #8 344*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[NEXT_VA_ADDR]], [sp, #8] 345*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr [[VA_VAL:w[0-9]+]], {{\[}}[[VA_ADDR]]] 346*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], [[SUM]], [[VA_VAL]] 347*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub w1, w1, #1 348*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz w1, [[LOOP_LABEL]] 349*9880d681SAndroid Build Coastguard Worker; 350*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: b 351*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else 352*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1 353*9880d681SAndroid Build Coastguard Worker; 354*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else 355*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1 356*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: ret 357*9880d681SAndroid Build Coastguard Worker; 358*9880d681SAndroid Build Coastguard Worker; CHECK: [[IFEND_LABEL]]: 359*9880d681SAndroid Build Coastguard Worker; Epilogue code. 360*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, sp, #16 361*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 362*9880d681SAndroid Build Coastguard Workerdefine i32 @variadicFunc(i32 %cond, i32 %count, ...) #0 { 363*9880d681SAndroid Build Coastguard Workerentry: 364*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 365*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 366*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %if.then 367*9880d681SAndroid Build Coastguard Worker 368*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 369*9880d681SAndroid Build Coastguard Worker %ap1 = bitcast i8** %ap to i8* 370*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap1) 371*9880d681SAndroid Build Coastguard Worker %cmp6 = icmp sgt i32 %count, 0 372*9880d681SAndroid Build Coastguard Worker br i1 %cmp6, label %for.body, label %for.end 373*9880d681SAndroid Build Coastguard Worker 374*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %if.then, %for.body 375*9880d681SAndroid Build Coastguard Worker %i.08 = phi i32 [ %inc, %for.body ], [ 0, %if.then ] 376*9880d681SAndroid Build Coastguard Worker %sum.07 = phi i32 [ %add, %for.body ], [ 0, %if.then ] 377*9880d681SAndroid Build Coastguard Worker %0 = va_arg i8** %ap, i32 378*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %sum.07, %0 379*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.08, 1 380*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, %count 381*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 382*9880d681SAndroid Build Coastguard Worker 383*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %if.then 384*9880d681SAndroid Build Coastguard Worker %sum.0.lcssa = phi i32 [ 0, %if.then ], [ %add, %for.body ] 385*9880d681SAndroid Build Coastguard Worker call void @llvm.va_end(i8* %ap1) 386*9880d681SAndroid Build Coastguard Worker br label %if.end 387*9880d681SAndroid Build Coastguard Worker 388*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 389*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %count, 1 390*9880d681SAndroid Build Coastguard Worker br label %if.end 391*9880d681SAndroid Build Coastguard Worker 392*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 393*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %sum.0.lcssa, %for.end ], [ %mul, %if.else ] 394*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 395*9880d681SAndroid Build Coastguard Worker} 396*9880d681SAndroid Build Coastguard Worker 397*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*) 398*9880d681SAndroid Build Coastguard Worker 399*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_end(i8*) 400*9880d681SAndroid Build Coastguard Worker 401*9880d681SAndroid Build Coastguard Worker; Check that we handle inline asm correctly. 402*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: inlineAsm: 403*9880d681SAndroid Build Coastguard Worker; 404*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 405*9880d681SAndroid Build Coastguard Worker; 406*9880d681SAndroid Build Coastguard Worker; Prologue code. 407*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: x19. 408*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x19]], [sp, #-16]! 409*9880d681SAndroid Build Coastguard Worker; 410*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 411*9880d681SAndroid Build Coastguard Worker; 412*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[IV:w[0-9]+]], #10 413*9880d681SAndroid Build Coastguard Worker; 414*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body 415*9880d681SAndroid Build Coastguard Worker; Inline asm statement. 416*9880d681SAndroid Build Coastguard Worker; CHECK: add x19, x19, #1 417*9880d681SAndroid Build Coastguard Worker; CHECK: sub [[IV]], [[IV]], #1 418*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]] 419*9880d681SAndroid Build Coastguard Worker; Next BB. 420*9880d681SAndroid Build Coastguard Worker; CHECK: mov w0, wzr 421*9880d681SAndroid Build Coastguard Worker; Epilogue code. 422*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #16 423*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 424*9880d681SAndroid Build Coastguard Worker; Next BB. 425*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: ; %if.else 426*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl w0, w1, #1 427*9880d681SAndroid Build Coastguard Worker; Epilogue code. 428*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #16 429*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 430*9880d681SAndroid Build Coastguard Workerdefine i32 @inlineAsm(i32 %cond, i32 %N) { 431*9880d681SAndroid Build Coastguard Workerentry: 432*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 433*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.body 434*9880d681SAndroid Build Coastguard Worker 435*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 436*9880d681SAndroid Build Coastguard Worker %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 437*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "add x19, x19, #1", "~{x19}"() 438*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.03, 1 439*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 440*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %if.end, label %for.body 441*9880d681SAndroid Build Coastguard Worker 442*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 443*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 444*9880d681SAndroid Build Coastguard Worker br label %if.end 445*9880d681SAndroid Build Coastguard Worker 446*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %for.body, %if.else 447*9880d681SAndroid Build Coastguard Worker %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.body ] 448*9880d681SAndroid Build Coastguard Worker ret i32 %sum.0 449*9880d681SAndroid Build Coastguard Worker} 450*9880d681SAndroid Build Coastguard Worker 451*9880d681SAndroid Build Coastguard Worker; Check that we handle calls to variadic functions correctly. 452*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: callVariadicFunc: 453*9880d681SAndroid Build Coastguard Worker; 454*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 455*9880d681SAndroid Build Coastguard Worker; 456*9880d681SAndroid Build Coastguard Worker; Prologue code. 457*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #64 458*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #48] 459*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #48 460*9880d681SAndroid Build Coastguard Worker; 461*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] 462*9880d681SAndroid Build Coastguard Worker; Setup of the varags. 463*9880d681SAndroid Build Coastguard Worker; CHECK: stp x1, x1, [sp, #32] 464*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp x1, x1, [sp, #16] 465*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp x1, x1, [sp] 466*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov w0, w1 467*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl _someVariadicFunc 468*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl w0, w0, #3 469*9880d681SAndroid Build Coastguard Worker; 470*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[IFEND_LABEL:LBB[0-9_]+]] 471*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else 472*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: lsl w0, w1, #1 473*9880d681SAndroid Build Coastguard Worker; DISABLE: [[IFEND_LABEL]]: ; %if.end 474*9880d681SAndroid Build Coastguard Worker; 475*9880d681SAndroid Build Coastguard Worker; Epilogue code. 476*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[CSR1]], [[CSR2]], [sp, #48] 477*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add sp, sp, #64 478*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 479*9880d681SAndroid Build Coastguard Worker; 480*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else 481*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: lsl w0, w1, #1 482*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: ret 483*9880d681SAndroid Build Coastguard Workerdefine i32 @callVariadicFunc(i32 %cond, i32 %N) { 484*9880d681SAndroid Build Coastguard Workerentry: 485*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 486*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %if.then 487*9880d681SAndroid Build Coastguard Worker 488*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 489*9880d681SAndroid Build Coastguard Worker %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N) 490*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %call, 3 491*9880d681SAndroid Build Coastguard Worker br label %if.end 492*9880d681SAndroid Build Coastguard Worker 493*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 494*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 495*9880d681SAndroid Build Coastguard Worker br label %if.end 496*9880d681SAndroid Build Coastguard Worker 497*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %if.then 498*9880d681SAndroid Build Coastguard Worker %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ] 499*9880d681SAndroid Build Coastguard Worker ret i32 %sum.0 500*9880d681SAndroid Build Coastguard Worker} 501*9880d681SAndroid Build Coastguard Worker 502*9880d681SAndroid Build Coastguard Workerdeclare i32 @someVariadicFunc(i32, ...) 503*9880d681SAndroid Build Coastguard Worker 504*9880d681SAndroid Build Coastguard Worker; Make sure we do not insert unreachable code after noreturn function. 505*9880d681SAndroid Build Coastguard Worker; Although this is not incorrect to insert such code, it is useless 506*9880d681SAndroid Build Coastguard Worker; and it hurts the binary size. 507*9880d681SAndroid Build Coastguard Worker; 508*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noreturn: 509*9880d681SAndroid Build Coastguard Worker; DISABLE: stp 510*9880d681SAndroid Build Coastguard Worker; 511*9880d681SAndroid Build Coastguard Worker; CHECK: and [[TEST:w[0-9]+]], w0, #0xff 512*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[TEST]], [[ABORT:LBB[0-9_]+]] 513*9880d681SAndroid Build Coastguard Worker; 514*9880d681SAndroid Build Coastguard Worker; CHECK: mov w0, #42 515*9880d681SAndroid Build Coastguard Worker; 516*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: ldp 517*9880d681SAndroid Build Coastguard Worker; 518*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 519*9880d681SAndroid Build Coastguard Worker; 520*9880d681SAndroid Build Coastguard Worker; CHECK: [[ABORT]]: ; %if.abort 521*9880d681SAndroid Build Coastguard Worker; 522*9880d681SAndroid Build Coastguard Worker; ENABLE: stp 523*9880d681SAndroid Build Coastguard Worker; 524*9880d681SAndroid Build Coastguard Worker; CHECK: bl _abort 525*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: ldp 526*9880d681SAndroid Build Coastguard Workerdefine i32 @noreturn(i8 signext %bad_thing) { 527*9880d681SAndroid Build Coastguard Workerentry: 528*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i8 %bad_thing, 0 529*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.end, label %if.abort 530*9880d681SAndroid Build Coastguard Worker 531*9880d681SAndroid Build Coastguard Workerif.abort: 532*9880d681SAndroid Build Coastguard Worker tail call void @abort() #0 533*9880d681SAndroid Build Coastguard Worker unreachable 534*9880d681SAndroid Build Coastguard Worker 535*9880d681SAndroid Build Coastguard Workerif.end: 536*9880d681SAndroid Build Coastguard Worker ret i32 42 537*9880d681SAndroid Build Coastguard Worker} 538*9880d681SAndroid Build Coastguard Worker 539*9880d681SAndroid Build Coastguard Workerdeclare void @abort() #0 540*9880d681SAndroid Build Coastguard Worker 541*9880d681SAndroid Build Coastguard Workerattributes #0 = { noreturn nounwind } 542*9880d681SAndroid Build Coastguard Worker 543*9880d681SAndroid Build Coastguard Worker; Make sure that we handle infinite loops properly When checking that the Save 544*9880d681SAndroid Build Coastguard Worker; and Restore blocks are control flow equivalent, the loop searches for the 545*9880d681SAndroid Build Coastguard Worker; immediate (post) dominator for the (restore) save blocks. When either the Save 546*9880d681SAndroid Build Coastguard Worker; or Restore block is located in an infinite loop the only immediate (post) 547*9880d681SAndroid Build Coastguard Worker; dominator is itself. In this case, we cannot perform shrink wrapping, but we 548*9880d681SAndroid Build Coastguard Worker; should return gracefully and continue compilation. 549*9880d681SAndroid Build Coastguard Worker; The only condition for this test is the compilation finishes correctly. 550*9880d681SAndroid Build Coastguard Worker; 551*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop 552*9880d681SAndroid Build Coastguard Worker; CHECK: ret 553*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop() { 554*9880d681SAndroid Build Coastguard Workerentry: 555*9880d681SAndroid Build Coastguard Worker br i1 undef, label %if.then, label %if.end 556*9880d681SAndroid Build Coastguard Worker 557*9880d681SAndroid Build Coastguard Workerif.then: 558*9880d681SAndroid Build Coastguard Worker %ptr = alloca i32, i32 4 559*9880d681SAndroid Build Coastguard Worker br label %for.body 560*9880d681SAndroid Build Coastguard Worker 561*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 562*9880d681SAndroid Build Coastguard Worker %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 563*9880d681SAndroid Build Coastguard Worker %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() 564*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.03 565*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %ptr 566*9880d681SAndroid Build Coastguard Worker br label %for.body 567*9880d681SAndroid Build Coastguard Worker 568*9880d681SAndroid Build Coastguard Workerif.end: 569*9880d681SAndroid Build Coastguard Worker ret void 570*9880d681SAndroid Build Coastguard Worker} 571*9880d681SAndroid Build Coastguard Worker 572*9880d681SAndroid Build Coastguard Worker; Another infinite loop test this time with a body bigger than just one block. 573*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop2 574*9880d681SAndroid Build Coastguard Worker; CHECK: ret 575*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop2() { 576*9880d681SAndroid Build Coastguard Workerentry: 577*9880d681SAndroid Build Coastguard Worker br i1 undef, label %if.then, label %if.end 578*9880d681SAndroid Build Coastguard Worker 579*9880d681SAndroid Build Coastguard Workerif.then: 580*9880d681SAndroid Build Coastguard Worker %ptr = alloca i32, i32 4 581*9880d681SAndroid Build Coastguard Worker br label %for.body 582*9880d681SAndroid Build Coastguard Worker 583*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 584*9880d681SAndroid Build Coastguard Worker %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2] 585*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm "mov $0, #0", "=r,~{x19}"() 586*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.03 587*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %ptr 588*9880d681SAndroid Build Coastguard Worker br i1 undef, label %body1, label %body2 589*9880d681SAndroid Build Coastguard Worker 590*9880d681SAndroid Build Coastguard Workerbody1: 591*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "nop", "~{x19}"() 592*9880d681SAndroid Build Coastguard Worker br label %for.body 593*9880d681SAndroid Build Coastguard Worker 594*9880d681SAndroid Build Coastguard Workerbody2: 595*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "nop", "~{x19}"() 596*9880d681SAndroid Build Coastguard Worker br label %for.body 597*9880d681SAndroid Build Coastguard Worker 598*9880d681SAndroid Build Coastguard Workerif.end: 599*9880d681SAndroid Build Coastguard Worker ret void 600*9880d681SAndroid Build Coastguard Worker} 601*9880d681SAndroid Build Coastguard Worker 602*9880d681SAndroid Build Coastguard Worker; Another infinite loop test this time with two nested infinite loop. 603*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop3 604*9880d681SAndroid Build Coastguard Worker; CHECK: ret 605*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop3() { 606*9880d681SAndroid Build Coastguard Workerentry: 607*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop2a, label %body 608*9880d681SAndroid Build Coastguard Worker 609*9880d681SAndroid Build Coastguard Workerbody: ; preds = %entry 610*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop2a, label %end 611*9880d681SAndroid Build Coastguard Worker 612*9880d681SAndroid Build Coastguard Workerloop1: ; preds = %loop2a, %loop2b 613*9880d681SAndroid Build Coastguard Worker %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ] 614*9880d681SAndroid Build Coastguard Worker %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ] 615*9880d681SAndroid Build Coastguard Worker %0 = icmp eq i32* %var, null 616*9880d681SAndroid Build Coastguard Worker %next.load = load i32*, i32** undef 617*9880d681SAndroid Build Coastguard Worker br i1 %0, label %loop2a, label %loop2b 618*9880d681SAndroid Build Coastguard Worker 619*9880d681SAndroid Build Coastguard Workerloop2a: ; preds = %loop1, %body, %entry 620*9880d681SAndroid Build Coastguard Worker %var = phi i32* [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ] 621*9880d681SAndroid Build Coastguard Worker %next.var = phi i32* [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ] 622*9880d681SAndroid Build Coastguard Worker br label %loop1 623*9880d681SAndroid Build Coastguard Worker 624*9880d681SAndroid Build Coastguard Workerloop2b: ; preds = %loop1 625*9880d681SAndroid Build Coastguard Worker %gep1 = bitcast i32* %var.phi to i32* 626*9880d681SAndroid Build Coastguard Worker %next.ptr = bitcast i32* %gep1 to i32** 627*9880d681SAndroid Build Coastguard Worker store i32* %next.phi, i32** %next.ptr 628*9880d681SAndroid Build Coastguard Worker br label %loop1 629*9880d681SAndroid Build Coastguard Worker 630*9880d681SAndroid Build Coastguard Workerend: 631*9880d681SAndroid Build Coastguard Worker ret void 632*9880d681SAndroid Build Coastguard Worker} 633*9880d681SAndroid Build Coastguard Worker 634*9880d681SAndroid Build Coastguard Worker; Re-aligned stack pointer. See bug 26642. Avoid clobbering live 635*9880d681SAndroid Build Coastguard Worker; values in the prologue when re-aligning the stack pointer. 636*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: stack_realign: 637*9880d681SAndroid Build Coastguard Worker; ENABLE-DAG: lsl w[[LSL1:[0-9]+]], w0, w1 638*9880d681SAndroid Build Coastguard Worker; ENABLE-DAG: lsl w[[LSL2:[0-9]+]], w1, w0 639*9880d681SAndroid Build Coastguard Worker; DISABLE-NOT: lsl w[[LSL1:[0-9]+]], w0, w1 640*9880d681SAndroid Build Coastguard Worker; DISABLE-NOT: lsl w[[LSL2:[0-9]+]], w1, w0 641*9880d681SAndroid Build Coastguard Worker; CHECK: stp x29, x30, [sp, #-16]! 642*9880d681SAndroid Build Coastguard Worker; CHECK: mov x29, sp 643*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: sub x[[LSL1]], sp, #16 644*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: sub x[[LSL2]], sp, #16 645*9880d681SAndroid Build Coastguard Worker; DISABLE: sub x{{[0-9]+}}, sp, #16 646*9880d681SAndroid Build Coastguard Worker; DISABLE-DAG: lsl w[[LSL1:[0-9]+]], w0, w1 647*9880d681SAndroid Build Coastguard Worker; DISABLE-DAG: lsl w[[LSL2:[0-9]+]], w1, w0 648*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: str w[[LSL1]], 649*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: str w[[LSL2]], 650*9880d681SAndroid Build Coastguard Worker 651*9880d681SAndroid Build Coastguard Workerdefine i32 @stack_realign(i32 %a, i32 %b, i32* %ptr1, i32* %ptr2) { 652*9880d681SAndroid Build Coastguard Worker %tmp = alloca i32, align 32 653*9880d681SAndroid Build Coastguard Worker %shl1 = shl i32 %a, %b 654*9880d681SAndroid Build Coastguard Worker %shl2 = shl i32 %b, %a 655*9880d681SAndroid Build Coastguard Worker %tmp2 = icmp slt i32 %a, %b 656*9880d681SAndroid Build Coastguard Worker br i1 %tmp2, label %true, label %false 657*9880d681SAndroid Build Coastguard Worker 658*9880d681SAndroid Build Coastguard Workertrue: 659*9880d681SAndroid Build Coastguard Worker store i32 %a, i32* %tmp, align 4 660*9880d681SAndroid Build Coastguard Worker %tmp4 = load i32, i32* %tmp 661*9880d681SAndroid Build Coastguard Worker br label %false 662*9880d681SAndroid Build Coastguard Worker 663*9880d681SAndroid Build Coastguard Workerfalse: 664*9880d681SAndroid Build Coastguard Worker %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 665*9880d681SAndroid Build Coastguard Worker store i32 %shl1, i32* %ptr1 666*9880d681SAndroid Build Coastguard Worker store i32 %shl2, i32* %ptr2 667*9880d681SAndroid Build Coastguard Worker ret i32 %tmp.0 668*9880d681SAndroid Build Coastguard Worker} 669*9880d681SAndroid Build Coastguard Worker 670*9880d681SAndroid Build Coastguard Worker; Re-aligned stack pointer with all caller-save regs live. See bug 671*9880d681SAndroid Build Coastguard Worker; 26642. In this case we currently avoid shrink wrapping because 672*9880d681SAndroid Build Coastguard Worker; ensuring we have a scratch register to re-align the stack pointer is 673*9880d681SAndroid Build Coastguard Worker; too complicated. Output should be the same for both enabled and 674*9880d681SAndroid Build Coastguard Worker; disabled shrink wrapping. 675*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: stack_realign2: 676*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #-{{[0-9]+}}]! 677*9880d681SAndroid Build Coastguard Worker; CHECK: add x29, sp, #{{[0-9]+}} 678*9880d681SAndroid Build Coastguard Worker; CHECK: lsl {{w[0-9]+}}, w0, w1 679*9880d681SAndroid Build Coastguard Worker 680*9880d681SAndroid Build Coastguard Workerdefine void @stack_realign2(i32 %a, i32 %b, i32* %ptr1, i32* %ptr2, i32* %ptr3, i32* %ptr4, i32* %ptr5, i32* %ptr6) { 681*9880d681SAndroid Build Coastguard Worker %tmp = alloca i32, align 32 682*9880d681SAndroid Build Coastguard Worker %tmp1 = shl i32 %a, %b 683*9880d681SAndroid Build Coastguard Worker %tmp2 = shl i32 %b, %a 684*9880d681SAndroid Build Coastguard Worker %tmp3 = lshr i32 %a, %b 685*9880d681SAndroid Build Coastguard Worker %tmp4 = lshr i32 %b, %a 686*9880d681SAndroid Build Coastguard Worker %tmp5 = add i32 %b, %a 687*9880d681SAndroid Build Coastguard Worker %tmp6 = sub i32 %b, %a 688*9880d681SAndroid Build Coastguard Worker %tmp7 = add i32 %tmp1, %tmp2 689*9880d681SAndroid Build Coastguard Worker %tmp8 = sub i32 %tmp2, %tmp3 690*9880d681SAndroid Build Coastguard Worker %tmp9 = add i32 %tmp3, %tmp4 691*9880d681SAndroid Build Coastguard Worker %tmp10 = add i32 %tmp4, %tmp5 692*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %a, %b 693*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %true, label %false 694*9880d681SAndroid Build Coastguard Worker 695*9880d681SAndroid Build Coastguard Workertrue: 696*9880d681SAndroid Build Coastguard Worker store i32 %a, i32* %tmp, align 4 697*9880d681SAndroid Build Coastguard Worker call void asm sideeffect "nop", "~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28}"() nounwind 698*9880d681SAndroid Build Coastguard Worker br label %false 699*9880d681SAndroid Build Coastguard Worker 700*9880d681SAndroid Build Coastguard Workerfalse: 701*9880d681SAndroid Build Coastguard Worker store i32 %tmp1, i32* %ptr1, align 4 702*9880d681SAndroid Build Coastguard Worker store i32 %tmp2, i32* %ptr2, align 4 703*9880d681SAndroid Build Coastguard Worker store i32 %tmp3, i32* %ptr3, align 4 704*9880d681SAndroid Build Coastguard Worker store i32 %tmp4, i32* %ptr4, align 4 705*9880d681SAndroid Build Coastguard Worker store i32 %tmp5, i32* %ptr5, align 4 706*9880d681SAndroid Build Coastguard Worker store i32 %tmp6, i32* %ptr6, align 4 707*9880d681SAndroid Build Coastguard Worker %idx1 = getelementptr inbounds i32, i32* %ptr1, i64 1 708*9880d681SAndroid Build Coastguard Worker store i32 %a, i32* %idx1, align 4 709*9880d681SAndroid Build Coastguard Worker %idx2 = getelementptr inbounds i32, i32* %ptr1, i64 2 710*9880d681SAndroid Build Coastguard Worker store i32 %b, i32* %idx2, align 4 711*9880d681SAndroid Build Coastguard Worker %idx3 = getelementptr inbounds i32, i32* %ptr1, i64 3 712*9880d681SAndroid Build Coastguard Worker store i32 %tmp7, i32* %idx3, align 4 713*9880d681SAndroid Build Coastguard Worker %idx4 = getelementptr inbounds i32, i32* %ptr1, i64 4 714*9880d681SAndroid Build Coastguard Worker store i32 %tmp8, i32* %idx4, align 4 715*9880d681SAndroid Build Coastguard Worker %idx5 = getelementptr inbounds i32, i32* %ptr1, i64 5 716*9880d681SAndroid Build Coastguard Worker store i32 %tmp9, i32* %idx5, align 4 717*9880d681SAndroid Build Coastguard Worker %idx6 = getelementptr inbounds i32, i32* %ptr1, i64 6 718*9880d681SAndroid Build Coastguard Worker store i32 %tmp10, i32* %idx6, align 4 719*9880d681SAndroid Build Coastguard Worker 720*9880d681SAndroid Build Coastguard Worker ret void 721*9880d681SAndroid Build Coastguard Worker} 722