1# RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -no-stack-coloring=false -run-pass stack-coloring -o - %s 2 3# Test to insure that the liveness analysis in the StackColoring 4# pass gracefully handles statically unreachable blocks. See PR 37310. 5 6# This MIR testcase was created by compiling the following test, first 7# with "clang -emit-llvm -S" and then "llc -stop-before stack-coloring", 8# and finally editing the resulting MIR by hand to introduce a statically 9# unreachable BB (to wit: rename all bb.3 to bb.4, rename bb.2 to bb.3, 10# then add bb.2 with unconditional jump to bb.4). 11 12# Original C code: 13# extern int inita(int *); 14# void foo(int x) { 15# if (x != 3) { 16# int q[128]; 17# inita(&q[0]); 18# return; 19# } 20# int r[128]; 21# inita(&r[x]); 22# } 23 24--- | 25 26 define void @foo(i32 %x) { 27 entry: 28 %q = alloca [128 x i32], align 16 29 %r = alloca [128 x i32], align 16 30 %cmp = icmp eq i32 %x, 3 31 br i1 %cmp, label %if.end, label %if.then 32 33 if.then: ; preds = %entry 34 %0 = bitcast [128 x i32]* %q to i8* 35 call void @llvm.lifetime.start.p0i8(i64 512, i8* nonnull %0) 36 %arrayidx2 = bitcast [128 x i32]* %q to i32* 37 %call = call i32 @inita(i32* nonnull %arrayidx2) 38 call void @llvm.lifetime.end.p0i8(i64 512, i8* nonnull %0) 39 br label %return 40 41 unreachable: 42 br label %return 43 44 if.end: ; preds = %entry 45 %1 = bitcast [128 x i32]* %r to i8* 46 call void @llvm.lifetime.start.p0i8(i64 512, i8* nonnull %1) 47 %arrayidx1 = getelementptr inbounds [128 x i32], [128 x i32]* %r, i64 0, i64 3 48 %call2 = call i32 @inita(i32* nonnull %arrayidx1) 49 call void @llvm.lifetime.end.p0i8(i64 512, i8* nonnull %1) 50 br label %return 51 52 return: ; preds = %if.end, %if.then 53 ret void 54 } 55 56 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) 57 58 declare i32 @inita(i32*) 59 60 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) 61 62 declare void @llvm.stackprotector(i8*, i8**) 63 64... 65--- 66name: foo 67alignment: 16 68exposesReturnsTwice: false 69legalized: false 70regBankSelected: false 71selected: false 72failedISel: false 73tracksRegLiveness: true 74registers: 75 - { id: 0, class: gr32, preferred-register: '' } 76 - { id: 1, class: gr32, preferred-register: '' } 77 - { id: 2, class: gr64, preferred-register: '' } 78 - { id: 3, class: gr32, preferred-register: '' } 79 - { id: 4, class: gr64, preferred-register: '' } 80 - { id: 5, class: gr32, preferred-register: '' } 81liveins: 82 - { reg: '$edi' } 83frameInfo: 84 isFrameAddressTaken: false 85 isReturnAddressTaken: false 86 hasStackMap: false 87 hasPatchPoint: false 88 stackSize: 0 89 offsetAdjustment: 0 90 maxAlignment: 16 91 adjustsStack: false 92 hasCalls: true 93 stackProtector: '' 94 maxCallFrameSize: 4294967295 95 hasOpaqueSPAdjustment: false 96 hasVAStart: false 97 hasMustTailInVarArgFunc: false 98 localFrameSize: 0 99 savePoint: '' 100 restorePoint: '' 101fixedStack: 102stack: 103 - { id: 0, name: q, type: default, offset: 0, size: 512, alignment: 16, 104 stack-id: default, callee-saved-register: '', callee-saved-restored: true, 105 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } 106 - { id: 1, name: r, type: default, offset: 0, size: 512, alignment: 16, 107 stack-id: default, callee-saved-register: '', callee-saved-restored: true, 108 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } 109constants: 110body: | 111 bb.0.entry: 112 successors: %bb.3(0x40000000), %bb.1(0x40000000) 113 liveins: $edi 114 115 %0:gr32 = COPY $edi 116 %1:gr32 = SUB32ri8 %0, 3, implicit-def $eflags 117 JCC_1 %bb.3, 4, implicit $eflags 118 JMP_1 %bb.1 119 120 bb.1.if.then: 121 successors: %bb.4(0x80000000) 122 123 LIFETIME_START %stack.0.q 124 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp 125 %2:gr64 = LEA64r %stack.0.q, 1, $noreg, 0, $noreg 126 $rdi = COPY %2 127 CALL64pcrel32 @inita, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax 128 ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp 129 %3:gr32 = COPY $eax 130 LIFETIME_END %stack.0.q 131 JMP_1 %bb.4 132 133 bb.2.unreachable: 134 successors: %bb.4(0x80000000) 135 136 JMP_1 %bb.4 137 138 bb.3.if.end: 139 successors: %bb.4(0x80000000) 140 141 LIFETIME_START %stack.1.r 142 %4:gr64 = LEA64r %stack.1.r, 1, $noreg, 12, $noreg 143 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp 144 $rdi = COPY %4 145 CALL64pcrel32 @inita, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax 146 ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp 147 %5:gr32 = COPY $eax 148 LIFETIME_END %stack.1.r 149 150 bb.4.return: 151 RET 0 152 153... 154