1# RUN: not --crash llc -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 \ 2# RUN: | FileCheck %s 3# REQUIRES: powerpc-registered-target 4 5# Test for a case we observed after the initial implementation of D129997 6# landed, in which case we observed a crash while building the ppc64le Linux 7# kernel. In that case, we had one block with two exits, both to the same 8# successor. Removing one of the exits corrupted the successor/predecessor 9# lists. 10 11# CHECK: *** Bad machine code: INLINEASM_BR indirect target missing from successor list *** 12# CHECK-NEXT: - function: ceph_con_v2_try_read 13# CHECK-NEXT: - basic block: %bb.3 if.else.i.i 14# CHECK-NEXT: - instruction: INLINEASM_BR &"" [sideeffect] [attdialect], $0:[imm], %bb.5 15# CHECK-NEXT: - operand 3: %bb.5 16 17# CHECK: *** Bad machine code: INLINEASM_BR indirect target predecessor list missing parent *** 18# CHECK-NEXT: - function: ceph_con_v2_try_read 19# CHECK-NEXT: - basic block: %bb.3 if.else.i.i 20# CHECK-NEXT: - instruction: INLINEASM_BR &"" [sideeffect] [attdialect], $0:[imm], %bb.5 21# CHECK-NEXT: - operand 3: %bb.5 22 23--- | 24 target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" 25 target triple = "powerpc64le-unknown-linux-gnu" 26 27 ; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn 28 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0 29 30 define void @ceph_con_v2_try_read(i32 %__trans_tmp_3.sroa.0.0.copyload, i1 %tobool.not.i.i) { 31 entry: 32 %skip.i.i = alloca i32, i32 0, align 4 33 %cond = icmp eq i32 %__trans_tmp_3.sroa.0.0.copyload, 0 34 br label %for.cond 35 36 for.cond: ; preds = %for.cond, %process_message_header.exit.i, %if.end.i, %entry 37 br i1 %cond, label %sw.bb, label %for.cond 38 39 sw.bb: ; preds = %for.cond 40 %call.i.i2 = call i32 null(ptr %skip.i.i) 41 br i1 %tobool.not.i.i, label %if.else.i.i, label %process_message_header.exit.i 42 43 if.else.i.i: ; preds = %sw.bb 44 callbr void asm sideeffect "", "!i"() 45 to label %if.end.i [label %if.end.i] 46 47 process_message_header.exit.i: ; preds = %sw.bb 48 call void @llvm.lifetime.end.p0(i64 0, ptr %skip.i.i) 49 br label %for.cond 50 51 if.end.i: ; preds = %if.else.i.i, %if.else.i.i 52 call void @llvm.lifetime.end.p0(i64 0, ptr %skip.i.i) 53 br label %for.cond 54 } 55 56 attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn } 57 58... 59--- 60name: ceph_con_v2_try_read 61alignment: 16 62exposesReturnsTwice: false 63legalized: false 64regBankSelected: false 65selected: false 66failedISel: false 67tracksRegLiveness: true 68hasWinCFI: false 69callsEHReturn: false 70callsUnwindInit: false 71hasEHCatchret: false 72hasEHScopes: false 73hasEHFunclets: false 74failsVerification: false 75tracksDebugUserValues: false 76registers: 77 - { id: 0, class: crbitrc, preferred-register: '' } 78 - { id: 1, class: g8rc, preferred-register: '' } 79 - { id: 2, class: g8rc, preferred-register: '' } 80 - { id: 3, class: crbitrc, preferred-register: '' } 81 - { id: 4, class: gprc, preferred-register: '' } 82 - { id: 5, class: crrc, preferred-register: '' } 83 - { id: 6, class: g8rc, preferred-register: '' } 84 - { id: 7, class: g8rc, preferred-register: '' } 85 - { id: 8, class: g8rc, preferred-register: '' } 86 - { id: 9, class: g8rc, preferred-register: '' } 87 - { id: 10, class: g8rc, preferred-register: '' } 88liveins: 89 - { reg: '$x3', virtual-reg: '%1' } 90 - { reg: '$x4', virtual-reg: '%2' } 91frameInfo: 92 isFrameAddressTaken: false 93 isReturnAddressTaken: false 94 hasStackMap: false 95 hasPatchPoint: false 96 stackSize: 0 97 offsetAdjustment: 0 98 maxAlignment: 4 99 adjustsStack: false 100 hasCalls: true 101 stackProtector: '' 102 functionContext: '' 103 maxCallFrameSize: 4294967295 104 cvBytesOfCalleeSavedRegisters: 0 105 hasOpaqueSPAdjustment: false 106 hasVAStart: false 107 hasMustTailInVarArgFunc: false 108 hasTailCall: false 109 localFrameSize: 0 110 savePoint: '' 111 restorePoint: '' 112fixedStack: [] 113stack: 114 - { id: 0, name: skip.i.i, type: default, offset: 0, size: 1, alignment: 4, 115 stack-id: default, callee-saved-register: '', callee-saved-restored: true, 116 debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } 117callSites: [] 118debugValueSubstitutions: [] 119constants: [] 120machineFunctionInfo: {} 121body: | 122 bb.0.entry: 123 successors: %bb.1(0x80000000) 124 liveins: $x3, $x4 125 126 %2:g8rc = COPY $x4 127 %1:g8rc = COPY $x3 128 %10:g8rc = ANDI8_rec %2, 1, implicit-def $cr0 129 %3:crbitrc = COPY $cr0gt 130 %4:gprc = COPY %1.sub_32 131 %5:crrc = CMPWI killed %4, 0 132 %0:crbitrc = COPY %5.sub_eq 133 134 bb.1.for.cond: 135 successors: %bb.2(0x30000000), %bb.1(0x50000000) 136 137 BCn %0, %bb.1 138 B %bb.2 139 140 bb.2.sw.bb: 141 successors: %bb.3(0x40000000), %bb.4(0x40000000) 142 143 ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 144 %6:g8rc = COPY $x2 145 STD %6, 24, $x1 :: (store (s64) into stack + 24) 146 %7:g8rc = ADDI8 %stack.0.skip.i.i, 0 147 %8:g8rc = LI8 0 148 $x3 = COPY %7 149 $x12 = COPY %8 150 MTCTR8 %8, implicit-def $ctr8 151 BCTRL8_LDinto_toc 24, $x1, csr_ppc64_altivec, implicit-def dead $lr8, implicit-def dead $x2, implicit $ctr8, implicit $rm, implicit $x3, implicit $x12, implicit $x2, implicit-def $r1, implicit-def $x3 152 ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 153 %9:g8rc = COPY $x3 154 BCn %3, %bb.4 155 B %bb.3 156 157 ; Oops, should have %bb.5 in the successor list! 158 bb.3.if.else.i.i: 159 successors: %bb.1(0x80000000) 160 161 INLINEASM_BR &"", 1 /* sideeffect attdialect */, 13 /* imm */, %bb.5 162 LIFETIME_END %stack.0.skip.i.i 163 B %bb.1 164 165 bb.4.process_message_header.exit.i: 166 successors: %bb.1(0x80000000) 167 168 LIFETIME_END %stack.0.skip.i.i 169 B %bb.1 170 171 ; Oops, should have %bb.3 in the predecessor list! 172 bb.5.if.end.i (machine-block-address-taken, inlineasm-br-indirect-target): 173 successors: %bb.1(0x80000000) 174 175 LIFETIME_END %stack.0.skip.i.i 176 B %bb.1 177 178... 179