|  | # RUN: not --crash llc -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 \ | 
|  | # RUN:  | FileCheck %s | 
|  | # REQUIRES: powerpc-registered-target | 
|  |  | 
|  | # Test for a case we observed after the initial implementation of D129997 | 
|  | # landed, in which case we observed a crash while building the ppc64le Linux | 
|  | # kernel. In that case, we had one block with two exits, both to the same | 
|  | # successor. Removing one of the exits corrupted the successor/predecessor | 
|  | # lists. | 
|  |  | 
|  | # CHECK: *** Bad machine code: INLINEASM_BR indirect target missing from successor list *** | 
|  | # CHECK-NEXT: - function:    ceph_con_v2_try_read | 
|  | # CHECK-NEXT: - basic block: %bb.3 if.else.i.i | 
|  | # CHECK-NEXT: - instruction: INLINEASM_BR &"" [sideeffect] [attdialect], $0:[imm], %bb.5 | 
|  | # CHECK-NEXT: - operand 3:   %bb.5 | 
|  |  | 
|  | # CHECK: *** Bad machine code: INLINEASM_BR indirect target predecessor list missing parent *** | 
|  | # CHECK-NEXT: - function:    ceph_con_v2_try_read | 
|  | # CHECK-NEXT: - basic block: %bb.3 if.else.i.i | 
|  | # CHECK-NEXT: - instruction: INLINEASM_BR &"" [sideeffect] [attdialect], $0:[imm], %bb.5 | 
|  | # CHECK-NEXT: - operand 3:   %bb.5 | 
|  |  | 
|  | --- | | 
|  | target datalayout = "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512" | 
|  | target triple = "powerpc64le-unknown-linux-gnu" | 
|  |  | 
|  | ; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn | 
|  | declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0 | 
|  |  | 
|  | define void @ceph_con_v2_try_read(i32 %__trans_tmp_3.sroa.0.0.copyload, i1 %tobool.not.i.i) { | 
|  | entry: | 
|  | %skip.i.i = alloca i32, i32 0, align 4 | 
|  | %cond = icmp eq i32 %__trans_tmp_3.sroa.0.0.copyload, 0 | 
|  | br label %for.cond | 
|  |  | 
|  | for.cond:                                         ; preds = %for.cond, %process_message_header.exit.i, %if.end.i, %entry | 
|  | br i1 %cond, label %sw.bb, label %for.cond | 
|  |  | 
|  | sw.bb:                                            ; preds = %for.cond | 
|  | %call.i.i2 = call i32 null(ptr %skip.i.i) | 
|  | br i1 %tobool.not.i.i, label %if.else.i.i, label %process_message_header.exit.i | 
|  |  | 
|  | if.else.i.i:                                      ; preds = %sw.bb | 
|  | callbr void asm sideeffect "", "!i"() | 
|  | to label %if.end.i [label %if.end.i] | 
|  |  | 
|  | process_message_header.exit.i:                    ; preds = %sw.bb | 
|  | call void @llvm.lifetime.end.p0(i64 0, ptr %skip.i.i) | 
|  | br label %for.cond | 
|  |  | 
|  | if.end.i:                                         ; preds = %if.else.i.i, %if.else.i.i | 
|  | call void @llvm.lifetime.end.p0(i64 0, ptr %skip.i.i) | 
|  | br label %for.cond | 
|  | } | 
|  |  | 
|  | attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn } | 
|  |  | 
|  | ... | 
|  | --- | 
|  | name:            ceph_con_v2_try_read | 
|  | alignment:       16 | 
|  | exposesReturnsTwice: false | 
|  | legalized:       false | 
|  | regBankSelected: false | 
|  | selected:        false | 
|  | failedISel:      false | 
|  | tracksRegLiveness: true | 
|  | hasWinCFI:       false | 
|  | callsEHReturn:   false | 
|  | callsUnwindInit: false | 
|  | hasEHContTarget: false | 
|  | hasEHScopes:     false | 
|  | hasEHFunclets:   false | 
|  | failsVerification: false | 
|  | tracksDebugUserValues: false | 
|  | registers: | 
|  | - { id: 0, class: crbitrc, preferred-register: '' } | 
|  | - { id: 1, class: g8rc, preferred-register: '' } | 
|  | - { id: 2, class: g8rc, preferred-register: '' } | 
|  | - { id: 3, class: crbitrc, preferred-register: '' } | 
|  | - { id: 4, class: gprc, preferred-register: '' } | 
|  | - { id: 5, class: crrc, preferred-register: '' } | 
|  | - { id: 6, class: g8rc, preferred-register: '' } | 
|  | - { id: 7, class: g8rc, preferred-register: '' } | 
|  | - { id: 8, class: g8rc, preferred-register: '' } | 
|  | - { id: 9, class: g8rc, preferred-register: '' } | 
|  | - { id: 10, class: g8rc, preferred-register: '' } | 
|  | liveins: | 
|  | - { reg: '$x3', virtual-reg: '%1' } | 
|  | - { reg: '$x4', virtual-reg: '%2' } | 
|  | frameInfo: | 
|  | isFrameAddressTaken: false | 
|  | isReturnAddressTaken: false | 
|  | hasStackMap:     false | 
|  | hasPatchPoint:   false | 
|  | stackSize:       0 | 
|  | offsetAdjustment: 0 | 
|  | maxAlignment:    4 | 
|  | adjustsStack:    false | 
|  | hasCalls:        true | 
|  | stackProtector:  '' | 
|  | functionContext: '' | 
|  | maxCallFrameSize: 4294967295 | 
|  | cvBytesOfCalleeSavedRegisters: 0 | 
|  | hasOpaqueSPAdjustment: false | 
|  | hasVAStart:      false | 
|  | hasMustTailInVarArgFunc: false | 
|  | hasTailCall:     false | 
|  | localFrameSize:  0 | 
|  | savePoint:       [] | 
|  | restorePoint:    [] | 
|  | fixedStack:      [] | 
|  | stack: | 
|  | - { id: 0, name: skip.i.i, type: default, offset: 0, size: 1, alignment: 4, | 
|  | stack-id: default, callee-saved-register: '', callee-saved-restored: true, | 
|  | debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } | 
|  | callSites:       [] | 
|  | debugValueSubstitutions: [] | 
|  | constants:       [] | 
|  | machineFunctionInfo: {} | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | successors: %bb.1(0x80000000) | 
|  | liveins: $x3, $x4 | 
|  |  | 
|  | %2:g8rc = COPY $x4 | 
|  | %1:g8rc = COPY $x3 | 
|  | %10:g8rc = ANDI8_rec %2, 1, implicit-def $cr0 | 
|  | %3:crbitrc = COPY $cr0gt | 
|  | %4:gprc = COPY %1.sub_32 | 
|  | %5:crrc = CMPWI killed %4, 0 | 
|  | %0:crbitrc = COPY %5.sub_eq | 
|  |  | 
|  | bb.1.for.cond: | 
|  | successors: %bb.2(0x30000000), %bb.1(0x50000000) | 
|  |  | 
|  | BCn %0, %bb.1 | 
|  | B %bb.2 | 
|  |  | 
|  | bb.2.sw.bb: | 
|  | successors: %bb.3(0x40000000), %bb.4(0x40000000) | 
|  |  | 
|  | ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 | 
|  | %6:g8rc = COPY $x2 | 
|  | STD %6, 24, $x1 :: (store (s64) into stack + 24) | 
|  | %7:g8rc = ADDI8 %stack.0.skip.i.i, 0 | 
|  | %8:g8rc = LI8 0 | 
|  | $x3 = COPY %7 | 
|  | $x12 = COPY %8 | 
|  | MTCTR8 %8, implicit-def $ctr8 | 
|  | 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 | 
|  | ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 | 
|  | %9:g8rc = COPY $x3 | 
|  | BCn %3, %bb.4 | 
|  | B %bb.3 | 
|  |  | 
|  | ; Oops, should have %bb.5 in the successor list! | 
|  | bb.3.if.else.i.i: | 
|  | successors: %bb.1(0x80000000) | 
|  |  | 
|  | INLINEASM_BR &"", 1 /* sideeffect attdialect */, 13 /* imm */, %bb.5 | 
|  | LIFETIME_END %stack.0.skip.i.i | 
|  | B %bb.1 | 
|  |  | 
|  | bb.4.process_message_header.exit.i: | 
|  | successors: %bb.1(0x80000000) | 
|  |  | 
|  | LIFETIME_END %stack.0.skip.i.i | 
|  | B %bb.1 | 
|  |  | 
|  | ; Oops, should have %bb.3 in the predecessor list! | 
|  | bb.5.if.end.i (machine-block-address-taken, inlineasm-br-indirect-target): | 
|  | successors: %bb.1(0x80000000) | 
|  |  | 
|  | LIFETIME_END %stack.0.skip.i.i | 
|  | B %bb.1 | 
|  |  | 
|  | ... |