1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE 2*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 5*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64--windows-gnu" 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; The output of this function with or without shrink-wrapping 8*9880d681SAndroid Build Coastguard Worker; shouldn't change. 9*9880d681SAndroid Build Coastguard Worker; Indeed, the epilogue block would have been if.else, meaning 10*9880d681SAndroid Build Coastguard Worker; after the pops, we will have additional instruction (jump, mov, 11*9880d681SAndroid Build Coastguard Worker; etc.) prior to the return and this is forbidden for Win64. 12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoSaveOutsideLoop: 13*9880d681SAndroid Build Coastguard Worker; CHECK: push 14*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: popq 15*9880d681SAndroid Build Coastguard Worker; CHECK: popq 16*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: popq 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 18*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 { 19*9880d681SAndroid Build Coastguard Workerentry: 20*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 21*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.preheader 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerfor.preheader: ; preds = %entry 24*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 25*9880d681SAndroid Build Coastguard Worker br label %for.body 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %for.preheader 28*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 29*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ] 30*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"() 31*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 32*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 33*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 34*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 37*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", "~{ebx}"() 38*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 39*9880d681SAndroid Build Coastguard Worker br label %if.end 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 42*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 43*9880d681SAndroid Build Coastguard Worker br label %if.end 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 46*9880d681SAndroid Build Coastguard Worker %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 47*9880d681SAndroid Build Coastguard Worker ret i32 %sum.1 48*9880d681SAndroid Build Coastguard Worker} 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; When we can sink the epilogue of the function into an existing exit block, 51*9880d681SAndroid Build Coastguard Worker; this is Ok for shrink-wrapping to kicks in. 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoSaveOutsideLoop2: 53*9880d681SAndroid Build Coastguard Worker; ENABLE: testl %ecx, %ecx 54*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: je [[ELSE_LABEL:.LBB[0-9_]+]] 55*9880d681SAndroid Build Coastguard Worker; 56*9880d681SAndroid Build Coastguard Worker; Prologue code. 57*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: rbx. 58*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbx 59*9880d681SAndroid Build Coastguard Worker; 60*9880d681SAndroid Build Coastguard Worker; DISABLE: testl %ecx, %ecx 61*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: je [[ELSE_LABEL:.LBB[0-9_]+]] 62*9880d681SAndroid Build Coastguard Worker; 63*9880d681SAndroid Build Coastguard Worker; CHECK: nop 64*9880d681SAndroid Build Coastguard Worker; CHECK: xorl [[SUM:%eax]], [[SUM]] 65*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $10, [[IV:%e[a-z]+]] 66*9880d681SAndroid Build Coastguard Worker; 67*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:.LBB[0-9_]+]]: # %for.body 68*9880d681SAndroid Build Coastguard Worker; CHECK: movl $1, [[TMP:%e[a-z]+]] 69*9880d681SAndroid Build Coastguard Worker; CHECK: addl [[TMP]], [[SUM]] 70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: decl [[IV]] 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jne [[LOOP_LABEL]] 72*9880d681SAndroid Build Coastguard Worker; Next BB. 73*9880d681SAndroid Build Coastguard Worker; CHECK: nop 74*9880d681SAndroid Build Coastguard Worker; CHECK: shll $3, [[SUM]] 75*9880d681SAndroid Build Coastguard Worker; 76*9880d681SAndroid Build Coastguard Worker; DISABLE: jmp [[EPILOG_BB:.LBB[0-9_]+]] 77*9880d681SAndroid Build Coastguard Worker; 78*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: popq %rbx 79*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: retq 80*9880d681SAndroid Build Coastguard Worker; 81*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: # %if.else 82*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register. 83*9880d681SAndroid Build Coastguard Worker; CHECK: addl %edx, %edx 84*9880d681SAndroid Build Coastguard Worker; CHECK: movl %edx, %eax 85*9880d681SAndroid Build Coastguard Worker; 86*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: # %if.end 87*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: popq %rbx 88*9880d681SAndroid Build Coastguard Worker; 89*9880d681SAndroid Build Coastguard Worker; CHECK: retq 90*9880d681SAndroid Build Coastguard Worker; 91*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoSaveOutsideLoop2(i32 %cond, i32 %N) #0 { 92*9880d681SAndroid Build Coastguard Workerentry: 93*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %cond, 0 94*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %for.preheader 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerfor.preheader: ; preds = %entry 97*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", ""() 98*9880d681SAndroid Build Coastguard Worker br label %for.body 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %for.preheader 101*9880d681SAndroid Build Coastguard Worker %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 102*9880d681SAndroid Build Coastguard Worker %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ] 103*9880d681SAndroid Build Coastguard Worker %call = tail call i32 asm "movl $$1, $0", "=r,~{ebx}"() 104*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %call, %sum.04 105*9880d681SAndroid Build Coastguard Worker %inc = add nuw nsw i32 %i.05, 1 106*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, 10 107*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 110*9880d681SAndroid Build Coastguard Worker tail call void asm "nop", "~{ebx}"() 111*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %add, 3 112*9880d681SAndroid Build Coastguard Worker ret i32 %shl 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Workerif.else: ; preds = %entry 115*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i32 %N, 1 116*9880d681SAndroid Build Coastguard Worker br label %if.end 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %if.else, %for.end 119*9880d681SAndroid Build Coastguard Worker ret i32 %mul 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerattributes #0 = { uwtable } 123