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