1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=armv7-apple-ios \ 2*9880d681SAndroid Build Coastguard Worker; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=ARM --check-prefix=ENABLE --check-prefix=ARM-ENABLE 3*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=armv7-apple-ios \ 4*9880d681SAndroid Build Coastguard Worker; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=ARM --check-prefix=DISABLE --check-prefix=ARM-DISABLE 5*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumbv7-apple-ios \ 6*9880d681SAndroid Build Coastguard Worker; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB --check-prefix=ENABLE --check-prefix=THUMB-ENABLE 7*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumbv7-apple-ios \ 8*9880d681SAndroid Build Coastguard Worker; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB --check-prefix=DISABLE --check-prefix=THUMB-DISABLE 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker; 11*9880d681SAndroid Build Coastguard Worker; Note: Lots of tests use inline asm instead of regular calls. 12*9880d681SAndroid Build Coastguard Worker; This allows to have a better control on what the allocation will do. 13*9880d681SAndroid Build Coastguard Worker; Otherwise, we may have spill right in the entry block, defeating 14*9880d681SAndroid Build Coastguard Worker; shrink-wrapping. Moreover, some of the inline asm statements (nop) 15*9880d681SAndroid Build Coastguard Worker; are here to ensure that the related paths do not end up as critical 16*9880d681SAndroid Build Coastguard Worker; edges. 17*9880d681SAndroid Build Coastguard Worker; Also disable the late if-converter as it makes harder to reason on 18*9880d681SAndroid Build Coastguard Worker; the diffs. 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; Initial motivating example: Simple diamond with a call just on one side. 21*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo: 22*9880d681SAndroid Build Coastguard Worker; 23*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit. 24*9880d681SAndroid Build Coastguard Worker; No prologue needed. 25*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, r1 26*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bge [[EXIT_LABEL:LBB[0-9_]+]] 27*9880d681SAndroid Build Coastguard Worker; 28*9880d681SAndroid Build Coastguard Worker; Prologue code. 29*9880d681SAndroid Build Coastguard Worker; CHECK: push {r7, lr} 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r7, sp 31*9880d681SAndroid Build Coastguard Worker;; 32*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit. 33*9880d681SAndroid Build Coastguard Worker; After the prologue is set. 34*9880d681SAndroid Build Coastguard Worker; DISABLE: sub sp 35*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp r0, r1 36*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: bge [[EXIT_LABEL:LBB[0-9_]+]] 37*9880d681SAndroid Build Coastguard Worker; 38*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca. 39*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE: push {r0} 40*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE: str r0, [sp, #-4] 41*9880d681SAndroid Build Coastguard Worker; DISABLE: str r0, [sp] 42*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument. 43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r1, sp 44*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero. 45*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov{{s?}} r0, #0 46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl{{x?}} _doSomething 47*9880d681SAndroid Build Coastguard Worker; 48*9880d681SAndroid Build Coastguard Worker; With shrink-wrapping, epilogue is just after the call. 49*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE-NEXT: mov sp, r7 50*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE-NEXT: add sp, #4 51*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop{{(\.w)?}} {r7, lr} 52*9880d681SAndroid Build Coastguard Worker; 53*9880d681SAndroid Build Coastguard Worker; CHECK: [[EXIT_LABEL]]: 54*9880d681SAndroid Build Coastguard Worker; 55*9880d681SAndroid Build Coastguard Worker; Without shrink-wrapping, epilogue is in the exit block. 56*9880d681SAndroid Build Coastguard Worker; Epilogue code. (What we pop does not matter.) 57*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE: mov sp, r7 58*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE: add sp, 59*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop {r7, pc} 60*9880d681SAndroid Build Coastguard Worker; 61*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 62*9880d681SAndroid Build Coastguard Workerdefine i32 @foo(i32 %a, i32 %b) { 63*9880d681SAndroid Build Coastguard Worker %tmp = alloca i32, align 4 64*9880d681SAndroid Build Coastguard Worker %tmp2 = icmp slt i32 %a, %b 65*9880d681SAndroid Build Coastguard Worker br i1 %tmp2, label %true, label %false 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Workertrue: 68*9880d681SAndroid Build Coastguard Worker store i32 %a, i32* %tmp, align 4 69*9880d681SAndroid Build Coastguard Worker %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 70*9880d681SAndroid Build Coastguard Worker br label %false 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Workerfalse: 73*9880d681SAndroid Build Coastguard Worker %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 74*9880d681SAndroid Build Coastguard Worker ret i32 %tmp.0 75*9880d681SAndroid Build Coastguard Worker} 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; Function Attrs: optsize 78*9880d681SAndroid Build Coastguard Workerdeclare i32 @doSomething(i32, i32*) 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the restore inside the loop whereas the save 82*9880d681SAndroid Build Coastguard Worker; is outside. 83*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop: 84*9880d681SAndroid Build Coastguard Worker; 85*9880d681SAndroid Build Coastguard Worker; Shrink-wrapping allows to skip the prologue in the else case. 86*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE: cmp r0, #0 87*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 88*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 89*9880d681SAndroid Build Coastguard Worker; 90*9880d681SAndroid Build Coastguard Worker; Prologue code. 91*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4. 92*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r7, lr} 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add r7, sp, #4 94*9880d681SAndroid Build Coastguard Worker; 95*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE: cmp r0, #0 96*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 97*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 98*9880d681SAndroid Build Coastguard Worker; 99*9880d681SAndroid Build Coastguard Worker; SUM is in r0 because it is coalesced with the second 100*9880d681SAndroid Build Coastguard Worker; argument on the else path. 101*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} [[SUM:r0]], #0 102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov{{s?}} [[IV:r[0-9]+]], #10 103*9880d681SAndroid Build Coastguard Worker; 104*9880d681SAndroid Build Coastguard Worker; Next BB. 105*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body 106*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{(\.w)?}} [[TMP:r[0-9]+]], #1 107*9880d681SAndroid Build Coastguard Worker; ARM: subs [[IV]], [[IV]], #1 108*9880d681SAndroid Build Coastguard Worker; THUMB: subs [[IV]], #1 109*9880d681SAndroid Build Coastguard Worker; ARM-NEXT: add [[SUM]], [[TMP]], [[SUM]] 110*9880d681SAndroid Build Coastguard Worker; THUMB-NEXT: add [[SUM]], [[TMP]] 111*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]] 112*9880d681SAndroid Build Coastguard Worker; 113*9880d681SAndroid Build Coastguard Worker; Next BB. 114*9880d681SAndroid Build Coastguard Worker; SUM << 3. 115*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} [[SUM]], [[SUM]], #3 116*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop {r4, r7, pc} 117*9880d681SAndroid Build Coastguard Worker; 118*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue. 119*9880d681SAndroid Build Coastguard Worker; DISABLE: pop {r4, r7, pc} 120*9880d681SAndroid Build Coastguard Worker; 121*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else 122*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 123*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} r0, r1, #1 124*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop {r4, r7, pc} 125*9880d681SAndroid Build Coastguard Worker; 126*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 127*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) { 128*9880d681SAndroid Build Coastguard Workerentry: 129*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 130*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.preheader 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Workerfor.preheader: 133*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 134*9880d681SAndroid Build Coastguard Worker br label %for.body 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 137*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 138*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ] 139*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"() 140*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 141*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 142*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 143*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 146*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 147*9880d681SAndroid Build Coastguard Worker br label %if.end 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 150*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 151*9880d681SAndroid Build Coastguard Worker br label %if.end 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 154*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 155*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Workerdeclare i32 @something(...) 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the shrink-wrapping inside the loop even 161*9880d681SAndroid Build Coastguard Worker; though that would be legal. The cost model must prevent that. 162*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop2: 163*9880d681SAndroid Build Coastguard Worker; Prologue code. 164*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4. 165*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4 166*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} [[SUM:r0]], #0 167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov{{s?}} [[IV:r[0-9]+]], #10 168*9880d681SAndroid Build Coastguard Worker; CHECK: nop 169*9880d681SAndroid Build Coastguard Worker; Next BB. 170*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: @ %for.body 171*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{(\.w)?}} [[TMP:r[0-9]+]], #1 172*9880d681SAndroid Build Coastguard Worker; ARM: subs [[IV]], [[IV]], #1 173*9880d681SAndroid Build Coastguard Worker; THUMB: subs [[IV]], #1 174*9880d681SAndroid Build Coastguard Worker; ARM: add [[SUM]], [[TMP]], [[SUM]] 175*9880d681SAndroid Build Coastguard Worker; THUMB: add [[SUM]], [[TMP]] 176*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP_LABEL]] 177*9880d681SAndroid Build Coastguard Worker; Next BB. 178*9880d681SAndroid Build Coastguard Worker; CHECK: @ %for.exit 179*9880d681SAndroid Build Coastguard Worker; CHECK: nop 180*9880d681SAndroid Build Coastguard Worker; CHECK: pop {r4 181*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) { 182*9880d681SAndroid Build Coastguard Workerentry: 183*9880d681SAndroid Build Coastguard Worker br label %for.preheader 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Workerfor.preheader: 186*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 187*9880d681SAndroid Build Coastguard Worker br label %for.body 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 190*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ] 191*9880d681SAndroid Build Coastguard Worker %sum.03 = phi i32 [ 0, %for.preheader ], [ %add, %for.body ] 192*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"() 193*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.03 194*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.04, 1 195*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 196*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.exit, label %for.body 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerfor.exit: 199*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 200*9880d681SAndroid Build Coastguard Worker br label %for.end 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 203*9880d681SAndroid Build Coastguard Worker ret i32 %add 204*9880d681SAndroid Build Coastguard Worker} 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have save within the loop and 207*9880d681SAndroid Build Coastguard Worker; restore outside. 208*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoSaveOutsideLoop: 209*9880d681SAndroid Build Coastguard Worker; 210*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE: cmp r0, #0 211*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 212*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 213*9880d681SAndroid Build Coastguard Worker; 214*9880d681SAndroid Build Coastguard Worker; Prologue code. 215*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4. 216*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r7, lr} 217*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add r7, sp, #4 218*9880d681SAndroid Build Coastguard Worker; 219*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE: cmp r0, #0 220*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 221*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 222*9880d681SAndroid Build Coastguard Worker; 223*9880d681SAndroid Build Coastguard Worker; SUM is in r0 because it is coalesced with the second 224*9880d681SAndroid Build Coastguard Worker; argument on the else path. 225*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} [[SUM:r0]], #0 226*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov{{s?}} [[IV:r[0-9]+]], #10 227*9880d681SAndroid Build Coastguard Worker; 228*9880d681SAndroid Build Coastguard Worker; Next BB. 229*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body 230*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{(\.w)?}} [[TMP:r[0-9]+]], #1 231*9880d681SAndroid Build Coastguard Worker; ARM: subs [[IV]], [[IV]], #1 232*9880d681SAndroid Build Coastguard Worker; THUMB: subs [[IV]], #1 233*9880d681SAndroid Build Coastguard Worker; ARM-NEXT: add [[SUM]], [[TMP]], [[SUM]] 234*9880d681SAndroid Build Coastguard Worker; THUMB-NEXT: add [[SUM]], [[TMP]] 235*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]] 236*9880d681SAndroid Build Coastguard Worker; 237*9880d681SAndroid Build Coastguard Worker; Next BB. 238*9880d681SAndroid Build Coastguard Worker; SUM << 3. 239*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} [[SUM]], [[SUM]], #3 240*9880d681SAndroid Build Coastguard Worker; ENABLE: pop {r4, r7, pc} 241*9880d681SAndroid Build Coastguard Worker; 242*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue. 243*9880d681SAndroid Build Coastguard Worker; DISABLE: pop {r4, r7, pc} 244*9880d681SAndroid Build Coastguard Worker; 245*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else 246*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 247*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} r0, r1, #1 248*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop {r4, r7, pc} 249*9880d681SAndroid Build Coastguard Worker; 250*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 251*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) { 252*9880d681SAndroid Build Coastguard Workerentry: 253*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 254*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.preheader 255*9880d681SAndroid Build Coastguard Worker 256*9880d681SAndroid Build Coastguard Workerfor.preheader: 257*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 258*9880d681SAndroid Build Coastguard Worker br label %for.body 259*9880d681SAndroid Build Coastguard Worker 260*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 261*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 262*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ] 263*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"() 264*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 265*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 266*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 267*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 270*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", "~{r4}"() 271*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 272*9880d681SAndroid Build Coastguard Worker br label %if.end 273*9880d681SAndroid Build Coastguard Worker 274*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 275*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 276*9880d681SAndroid Build Coastguard Worker br label %if.end 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 279*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 280*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 281*9880d681SAndroid Build Coastguard Worker} 282*9880d681SAndroid Build Coastguard Worker 283*9880d681SAndroid Build Coastguard Workerdeclare void @somethingElse(...) 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have restore within the loop and 286*9880d681SAndroid Build Coastguard Worker; save outside. 287*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoRestoreOutsideLoop: 288*9880d681SAndroid Build Coastguard Worker; 289*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE: cmp r0, #0 290*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 291*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 292*9880d681SAndroid Build Coastguard Worker; 293*9880d681SAndroid Build Coastguard Worker; Prologue code. 294*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4. 295*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r7, lr} 296*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add r7, sp, #4 297*9880d681SAndroid Build Coastguard Worker; 298*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE: cmp r0, #0 299*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 300*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 301*9880d681SAndroid Build Coastguard Worker; 302*9880d681SAndroid Build Coastguard Worker; SUM is in r0 because it is coalesced with the second 303*9880d681SAndroid Build Coastguard Worker; argument on the else path. 304*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} [[SUM:r0]], #0 305*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov{{s?}} [[IV:r[0-9]+]], #10 306*9880d681SAndroid Build Coastguard Worker; 307*9880d681SAndroid Build Coastguard Worker; Next BB. 308*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body 309*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{(\.w)?}} [[TMP:r[0-9]+]], #1 310*9880d681SAndroid Build Coastguard Worker; ARM: subs [[IV]], [[IV]], #1 311*9880d681SAndroid Build Coastguard Worker; THUMB: subs [[IV]], #1 312*9880d681SAndroid Build Coastguard Worker; ARM-NEXT: add [[SUM]], [[TMP]], [[SUM]] 313*9880d681SAndroid Build Coastguard Worker; THUMB-NEXT: add [[SUM]], [[TMP]] 314*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]] 315*9880d681SAndroid Build Coastguard Worker; 316*9880d681SAndroid Build Coastguard Worker; Next BB. 317*9880d681SAndroid Build Coastguard Worker; SUM << 3. 318*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} [[SUM]], [[SUM]], #3 319*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop {r4, r7, pc} 320*9880d681SAndroid Build Coastguard Worker; 321*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue. 322*9880d681SAndroid Build Coastguard Worker; DISABLE: pop {r4, r7, pc} 323*9880d681SAndroid Build Coastguard Worker; 324*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else 325*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 326*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} r0, r1, #1 327*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop {r4, r7, pc} 328*9880d681SAndroid Build Coastguard Worker; 329*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 330*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 { 331*9880d681SAndroid Build Coastguard Workerentry: 332*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 333*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %if.then 334*9880d681SAndroid Build Coastguard Worker 335*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 336*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", "~{r4}"() 337*9880d681SAndroid Build Coastguard Worker br label %for.body 338*9880d681SAndroid Build Coastguard Worker 339*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %if.then 340*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ] 341*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 342*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"() 343*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 344*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 345*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 346*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 347*9880d681SAndroid Build Coastguard Worker 348*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 349*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 350*9880d681SAndroid Build Coastguard Worker br label %if.end 351*9880d681SAndroid Build Coastguard Worker 352*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 353*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 354*9880d681SAndroid Build Coastguard Worker br label %if.end 355*9880d681SAndroid Build Coastguard Worker 356*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 357*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 358*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 359*9880d681SAndroid Build Coastguard Worker} 360*9880d681SAndroid Build Coastguard Worker 361*9880d681SAndroid Build Coastguard Worker; Check that we handle function with no frame information correctly. 362*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: emptyFrame: 363*9880d681SAndroid Build Coastguard Worker; CHECK: @ %entry 364*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov{{s?}} r0, #0 365*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bx lr 366*9880d681SAndroid Build Coastguard Workerdefine i32 @emptyFrame() { 367*9880d681SAndroid Build Coastguard Workerentry: 368*9880d681SAndroid Build Coastguard Worker ret i32 0 369*9880d681SAndroid Build Coastguard Worker} 370*9880d681SAndroid Build Coastguard Worker 371*9880d681SAndroid Build Coastguard Worker; Check that we handle inline asm correctly. 372*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: inlineAsm: 373*9880d681SAndroid Build Coastguard Worker; 374*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE: cmp r0, #0 375*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 376*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 377*9880d681SAndroid Build Coastguard Worker; 378*9880d681SAndroid Build Coastguard Worker; Prologue code. 379*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4. 380*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r7, lr} 381*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add r7, sp, #4 382*9880d681SAndroid Build Coastguard Worker; 383*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE: cmp r0, #0 384*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 385*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 386*9880d681SAndroid Build Coastguard Worker; 387*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} [[IV:r[0-9]+]], #10 388*9880d681SAndroid Build Coastguard Worker; 389*9880d681SAndroid Build Coastguard Worker; Next BB. 390*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body 391*9880d681SAndroid Build Coastguard Worker; ARM: subs [[IV]], [[IV]], #1 392*9880d681SAndroid Build Coastguard Worker; THUMB: subs [[IV]], #1 393*9880d681SAndroid Build Coastguard Worker; CHECK: add{{(\.w)?}} r4, r4, #1 394*9880d681SAndroid Build Coastguard Worker; CHECK: bne [[LOOP]] 395*9880d681SAndroid Build Coastguard Worker; 396*9880d681SAndroid Build Coastguard Worker; Next BB. 397*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} r0, #0 398*9880d681SAndroid Build Coastguard Worker; 399*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue. 400*9880d681SAndroid Build Coastguard Worker; DISABLE: pop {r4, r7, pc} 401*9880d681SAndroid Build Coastguard Worker; 402*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else 403*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 404*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} r0, r1, #1 405*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop {r4, r7, pc} 406*9880d681SAndroid Build Coastguard Worker; 407*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 408*9880d681SAndroid Build Coastguard Workerdefine i32 @inlineAsm(i32 %cond, i32 %N) { 409*9880d681SAndroid Build Coastguard Workerentry: 410*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 411*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.preheader 412*9880d681SAndroid Build Coastguard Worker 413*9880d681SAndroid Build Coastguard Workerfor.preheader: 414*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 415*9880d681SAndroid Build Coastguard Worker br label %for.body 416*9880d681SAndroid Build Coastguard Worker 417*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 418*9880d681SAndroid Build Coastguard Worker %i.03 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 419*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "add r4, #1", "~{r4}"() 420*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.03, 1 421*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 422*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.exit, label %for.body 423*9880d681SAndroid Build Coastguard Worker 424*9880d681SAndroid Build Coastguard Workerfor.exit: 425*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 426*9880d681SAndroid Build Coastguard Worker br label %if.end 427*9880d681SAndroid Build Coastguard Worker 428*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 429*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 430*9880d681SAndroid Build Coastguard Worker br label %if.end 431*9880d681SAndroid Build Coastguard Worker 432*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %for.body, %if.else 433*9880d681SAndroid Build Coastguard Worker %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ] 434*9880d681SAndroid Build Coastguard Worker ret i32 %sum.0 435*9880d681SAndroid Build Coastguard Worker} 436*9880d681SAndroid Build Coastguard Worker 437*9880d681SAndroid Build Coastguard Worker; Check that we handle calls to variadic functions correctly. 438*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: callVariadicFunc: 439*9880d681SAndroid Build Coastguard Worker; 440*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE: cmp r0, #0 441*9880d681SAndroid Build Coastguard Worker; ARM-ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 442*9880d681SAndroid Build Coastguard Worker; THUMB-ENABLE: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 443*9880d681SAndroid Build Coastguard Worker; 444*9880d681SAndroid Build Coastguard Worker; Prologue code. 445*9880d681SAndroid Build Coastguard Worker; CHECK: push {r7, lr} 446*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r7, sp 447*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub sp, {{(sp, )?}}#12 448*9880d681SAndroid Build Coastguard Worker; 449*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE: cmp r0, #0 450*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]] 451*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE-NEXT: cbz r0, [[ELSE_LABEL:LBB[0-9_]+]] 452*9880d681SAndroid Build Coastguard Worker; 453*9880d681SAndroid Build Coastguard Worker; Setup of the varags. 454*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r1 455*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r2, r1 456*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r3, r1 457*9880d681SAndroid Build Coastguard Worker; ARM-NEXT: str r1, [sp] 458*9880d681SAndroid Build Coastguard Worker; ARM-NEXT: str r1, [sp, #4] 459*9880d681SAndroid Build Coastguard Worker; THUMB-NEXT: strd r1, r1, [sp] 460*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str r1, [sp, #8] 461*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl{{x?}} _someVariadicFunc 462*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl{{s?}} r0, r0, #3 463*9880d681SAndroid Build Coastguard Worker; ARM-NEXT: mov sp, r7 464*9880d681SAndroid Build Coastguard Worker; THUMB-NEXT: add sp, #12 465*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: pop {r7, pc} 466*9880d681SAndroid Build Coastguard Worker; 467*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else 468*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 469*9880d681SAndroid Build Coastguard Worker; CHECK: lsl{{s?}} r0, r1, #1 470*9880d681SAndroid Build Coastguard Worker; 471*9880d681SAndroid Build Coastguard Worker; Epilogue code. 472*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 473*9880d681SAndroid Build Coastguard Worker; 474*9880d681SAndroid Build Coastguard Worker; ARM-DISABLE-NEXT: mov sp, r7 475*9880d681SAndroid Build Coastguard Worker; THUMB-DISABLE-NEXT: add sp, #12 476*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop {r7, pc} 477*9880d681SAndroid Build Coastguard Workerdefine i32 @callVariadicFunc(i32 %cond, i32 %N) { 478*9880d681SAndroid Build Coastguard Workerentry: 479*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 480*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %if.then 481*9880d681SAndroid Build Coastguard Worker 482*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 483*9880d681SAndroid Build Coastguard Worker %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N) 484*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %call, 3 485*9880d681SAndroid Build Coastguard Worker br label %if.end 486*9880d681SAndroid Build Coastguard Worker 487*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 488*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 489*9880d681SAndroid Build Coastguard Worker br label %if.end 490*9880d681SAndroid Build Coastguard Worker 491*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %if.then 492*9880d681SAndroid Build Coastguard Worker %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ] 493*9880d681SAndroid Build Coastguard Worker ret i32 %sum.0 494*9880d681SAndroid Build Coastguard Worker} 495*9880d681SAndroid Build Coastguard Worker 496*9880d681SAndroid Build Coastguard Workerdeclare i32 @someVariadicFunc(i32, ...) 497*9880d681SAndroid Build Coastguard Worker 498*9880d681SAndroid Build Coastguard Worker; Make sure we do not insert unreachable code after noreturn function. 499*9880d681SAndroid Build Coastguard Worker; Although this is not incorrect to insert such code, it is useless 500*9880d681SAndroid Build Coastguard Worker; and it hurts the binary size. 501*9880d681SAndroid Build Coastguard Worker; 502*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noreturn: 503*9880d681SAndroid Build Coastguard Worker; DISABLE: push 504*9880d681SAndroid Build Coastguard Worker; 505*9880d681SAndroid Build Coastguard Worker; CHECK: tst{{(\.w)?}} r0, #255 506*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[ABORT:LBB[0-9_]+]] 507*9880d681SAndroid Build Coastguard Worker; 508*9880d681SAndroid Build Coastguard Worker; CHECK: mov{{s?}} r0, #42 509*9880d681SAndroid Build Coastguard Worker; 510*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr 511*9880d681SAndroid Build Coastguard Worker; 512*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop 513*9880d681SAndroid Build Coastguard Worker;; 514*9880d681SAndroid Build Coastguard Worker; CHECK: [[ABORT]]: @ %if.abort 515*9880d681SAndroid Build Coastguard Worker; 516*9880d681SAndroid Build Coastguard Worker; ENABLE: push 517*9880d681SAndroid Build Coastguard Worker; 518*9880d681SAndroid Build Coastguard Worker; CHECK: bl{{x?}} _abort 519*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: pop 520*9880d681SAndroid Build Coastguard Workerdefine i32 @noreturn(i8 signext %bad_thing) { 521*9880d681SAndroid Build Coastguard Workerentry: 522*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i8 %bad_thing, 0 523*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.end, label %if.abort 524*9880d681SAndroid Build Coastguard Worker 525*9880d681SAndroid Build Coastguard Workerif.abort: 526*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"() 527*9880d681SAndroid Build Coastguard Worker tail call void @abort() #0 528*9880d681SAndroid Build Coastguard Worker unreachable 529*9880d681SAndroid Build Coastguard Worker 530*9880d681SAndroid Build Coastguard Workerif.end: 531*9880d681SAndroid Build Coastguard Worker ret i32 42 532*9880d681SAndroid Build Coastguard Worker} 533*9880d681SAndroid Build Coastguard Worker 534*9880d681SAndroid Build Coastguard Workerdeclare void @abort() #0 535*9880d681SAndroid Build Coastguard Worker 536*9880d681SAndroid Build Coastguard Workerattributes #0 = { noreturn nounwind } 537*9880d681SAndroid Build Coastguard Worker 538*9880d681SAndroid Build Coastguard Worker; Make sure that we handle infinite loops properly When checking that the Save 539*9880d681SAndroid Build Coastguard Worker; and Restore blocks are control flow equivalent, the loop searches for the 540*9880d681SAndroid Build Coastguard Worker; immediate (post) dominator for the (restore) save blocks. When either the Save 541*9880d681SAndroid Build Coastguard Worker; or Restore block is located in an infinite loop the only immediate (post) 542*9880d681SAndroid Build Coastguard Worker; dominator is itself. In this case, we cannot perform shrink wrapping, but we 543*9880d681SAndroid Build Coastguard Worker; should return gracefully and continue compilation. 544*9880d681SAndroid Build Coastguard Worker; The only condition for this test is the compilation finishes correctly. 545*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop 546*9880d681SAndroid Build Coastguard Worker; CHECK: pop 547*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop() { 548*9880d681SAndroid Build Coastguard Workerentry: 549*9880d681SAndroid Build Coastguard Worker br i1 undef, label %if.then, label %if.end 550*9880d681SAndroid Build Coastguard Worker 551*9880d681SAndroid Build Coastguard Workerif.then: 552*9880d681SAndroid Build Coastguard Worker %ptr = alloca i32, i32 4 553*9880d681SAndroid Build Coastguard Worker br label %for.body 554*9880d681SAndroid Build Coastguard Worker 555*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 556*9880d681SAndroid Build Coastguard Worker %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 557*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"() 558*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.03 559*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %ptr 560*9880d681SAndroid Build Coastguard Worker br label %for.body 561*9880d681SAndroid Build Coastguard Worker 562*9880d681SAndroid Build Coastguard Workerif.end: 563*9880d681SAndroid Build Coastguard Worker ret void 564*9880d681SAndroid Build Coastguard Worker} 565*9880d681SAndroid Build Coastguard Worker 566*9880d681SAndroid Build Coastguard Worker; Another infinite loop test this time with a body bigger than just one block. 567*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop2 568*9880d681SAndroid Build Coastguard Worker; CHECK: pop 569*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop2() { 570*9880d681SAndroid Build Coastguard Workerentry: 571*9880d681SAndroid Build Coastguard Worker br i1 undef, label %if.then, label %if.end 572*9880d681SAndroid Build Coastguard Worker 573*9880d681SAndroid Build Coastguard Workerif.then: 574*9880d681SAndroid Build Coastguard Worker %ptr = alloca i32, i32 4 575*9880d681SAndroid Build Coastguard Worker br label %for.body 576*9880d681SAndroid Build Coastguard Worker 577*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 578*9880d681SAndroid Build Coastguard Worker %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2] 579*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm "mov $0, #0", "=r,~{r4}"() 580*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.03 581*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %ptr 582*9880d681SAndroid Build Coastguard Worker br i1 undef, label %body1, label %body2 583*9880d681SAndroid Build Coastguard Worker 584*9880d681SAndroid Build Coastguard Workerbody1: 585*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "nop", "~{r4}"() 586*9880d681SAndroid Build Coastguard Worker br label %for.body 587*9880d681SAndroid Build Coastguard Worker 588*9880d681SAndroid Build Coastguard Workerbody2: 589*9880d681SAndroid Build Coastguard Worker tail call void asm sideeffect "nop", "~{r4}"() 590*9880d681SAndroid Build Coastguard Worker br label %for.body 591*9880d681SAndroid Build Coastguard Worker 592*9880d681SAndroid Build Coastguard Workerif.end: 593*9880d681SAndroid Build Coastguard Worker ret void 594*9880d681SAndroid Build Coastguard Worker} 595*9880d681SAndroid Build Coastguard Worker 596*9880d681SAndroid Build Coastguard Worker; Another infinite loop test this time with two nested infinite loop. 597*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop3 598*9880d681SAndroid Build Coastguard Worker; CHECK: bx lr 599*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop3() { 600*9880d681SAndroid Build Coastguard Workerentry: 601*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop2a, label %body 602*9880d681SAndroid Build Coastguard Worker 603*9880d681SAndroid Build Coastguard Workerbody: ; preds = %entry 604*9880d681SAndroid Build Coastguard Worker br i1 undef, label %loop2a, label %end 605*9880d681SAndroid Build Coastguard Worker 606*9880d681SAndroid Build Coastguard Workerloop1: ; preds = %loop2a, %loop2b 607*9880d681SAndroid Build Coastguard Worker %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ] 608*9880d681SAndroid Build Coastguard Worker %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ] 609*9880d681SAndroid Build Coastguard Worker %0 = icmp eq i32* %var, null 610*9880d681SAndroid Build Coastguard Worker %next.load = load i32*, i32** undef 611*9880d681SAndroid Build Coastguard Worker br i1 %0, label %loop2a, label %loop2b 612*9880d681SAndroid Build Coastguard Worker 613*9880d681SAndroid Build Coastguard Workerloop2a: ; preds = %loop1, %body, %entry 614*9880d681SAndroid Build Coastguard Worker %var = phi i32* [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ] 615*9880d681SAndroid Build Coastguard Worker %next.var = phi i32* [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ] 616*9880d681SAndroid Build Coastguard Worker br label %loop1 617*9880d681SAndroid Build Coastguard Worker 618*9880d681SAndroid Build Coastguard Workerloop2b: ; preds = %loop1 619*9880d681SAndroid Build Coastguard Worker %gep1 = bitcast i32* %var.phi to i32* 620*9880d681SAndroid Build Coastguard Worker %next.ptr = bitcast i32* %gep1 to i32** 621*9880d681SAndroid Build Coastguard Worker store i32* %next.phi, i32** %next.ptr 622*9880d681SAndroid Build Coastguard Worker br label %loop1 623*9880d681SAndroid Build Coastguard Worker 624*9880d681SAndroid Build Coastguard Workerend: 625*9880d681SAndroid Build Coastguard Worker ret void 626*9880d681SAndroid Build Coastguard Worker} 627*9880d681SAndroid Build Coastguard Worker 628*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readnone 629*9880d681SAndroid Build Coastguard Workerdeclare double @llvm.pow.f64(double, double) 630*9880d681SAndroid Build Coastguard Worker 631*9880d681SAndroid Build Coastguard Worker; This function needs to spill floating point registers to 632*9880d681SAndroid Build Coastguard Worker; exercise the path where we were dereferencing the end iterator 633*9880d681SAndroid Build Coastguard Worker; to access debug info location while inserting the spill code 634*9880d681SAndroid Build Coastguard Worker; during PEI with shrink-wrapping enable. 635*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: debug_info: 636*9880d681SAndroid Build Coastguard Worker; 637*9880d681SAndroid Build Coastguard Worker; ENABLE: tst{{(\.w)?}} r2, #1 638*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: beq [[BB13:LBB[0-9_]+]] 639*9880d681SAndroid Build Coastguard Worker; 640*9880d681SAndroid Build Coastguard Worker; CHECK: push 641*9880d681SAndroid Build Coastguard Worker; 642*9880d681SAndroid Build Coastguard Worker; DISABLE: tst{{(\.w)?}} r2, #1 643*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: beq [[BB13:LBB[0-9_]+]] 644*9880d681SAndroid Build Coastguard Worker; 645*9880d681SAndroid Build Coastguard Worker; CHECK: bl{{x?}} _pow 646*9880d681SAndroid Build Coastguard Worker; 647*9880d681SAndroid Build Coastguard Worker; 648*9880d681SAndroid Build Coastguard Worker; ENABLE: pop 649*9880d681SAndroid Build Coastguard Worker; 650*9880d681SAndroid Build Coastguard Worker; CHECK: [[BB13]]: 651*9880d681SAndroid Build Coastguard Worker; CHECK: vldr 652*9880d681SAndroid Build Coastguard Worker; 653*9880d681SAndroid Build Coastguard Worker; DISABLE: pop 654*9880d681SAndroid Build Coastguard Worker; 655*9880d681SAndroid Build Coastguard Worker; CHECK: bl 656*9880d681SAndroid Build Coastguard Workerdefine float @debug_info(float %gamma, float %slopeLimit, i1 %or.cond, double %tmp) { 657*9880d681SAndroid Build Coastguard Workerbb: 658*9880d681SAndroid Build Coastguard Worker br i1 %or.cond, label %bb3, label %bb13 659*9880d681SAndroid Build Coastguard Worker 660*9880d681SAndroid Build Coastguard Workerbb3: ; preds = %bb 661*9880d681SAndroid Build Coastguard Worker %tmp4 = fcmp ogt float %gamma, 1.000000e+00 662*9880d681SAndroid Build Coastguard Worker %tmp5 = fadd double 1.000000e+00, %tmp 663*9880d681SAndroid Build Coastguard Worker %tmp6 = select i1 %tmp4, double %tmp5, double %tmp 664*9880d681SAndroid Build Coastguard Worker %tmp10 = tail call double @llvm.pow.f64(double %tmp, double %tmp) 665*9880d681SAndroid Build Coastguard Worker %tmp11 = fcmp une double %tmp6, %tmp 666*9880d681SAndroid Build Coastguard Worker %tmp12 = fadd double %tmp10, %tmp10 667*9880d681SAndroid Build Coastguard Worker %cutoff.0 = select i1 %tmp11, double %tmp12, double %tmp 668*9880d681SAndroid Build Coastguard Worker %phitmp = fptrunc double %cutoff.0 to float 669*9880d681SAndroid Build Coastguard Worker br label %bb13 670*9880d681SAndroid Build Coastguard Worker 671*9880d681SAndroid Build Coastguard Workerbb13: ; preds = %bb3, %bb 672*9880d681SAndroid Build Coastguard Worker %cutoff.1 = phi float [ 0.000000e+00, %bb ], [ %phitmp, %bb3 ] 673*9880d681SAndroid Build Coastguard Worker ret float %cutoff.1 674*9880d681SAndroid Build Coastguard Worker} 675*9880d681SAndroid Build Coastguard Worker 676*9880d681SAndroid Build Coastguard Worker 677*9880d681SAndroid Build Coastguard Worker!llvm.dbg.cu = !{!0} 678*9880d681SAndroid Build Coastguard Worker!llvm.module.flags = !{!3} 679*9880d681SAndroid Build Coastguard Worker 680*9880d681SAndroid Build Coastguard Worker!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "LLVM", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2) 681*9880d681SAndroid Build Coastguard Worker!1 = !DIFile(filename: "a.cpp", directory: "b") 682*9880d681SAndroid Build Coastguard Worker!2 = !{} 683*9880d681SAndroid Build Coastguard Worker!3 = !{i32 2, !"Debug Info Version", i32 3} 684