Index: llvm/lib/CodeGen/BreakFalseDeps.cpp =================================================================== --- llvm/lib/CodeGen/BreakFalseDeps.cpp +++ llvm/lib/CodeGen/BreakFalseDeps.cpp @@ -17,6 +17,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/ReachingDefAnalysis.h" @@ -290,10 +291,16 @@ LLVM_DEBUG(dbgs() << "********** BREAK FALSE DEPENDENCIES **********\n"); + // Skip Dead blocks due to ReachingDefAnalysis has no idea about instructions + // in them. + df_iterator_default_set Reachable; + for (MachineBasicBlock *MBB : depth_first_ext(&mf, Reachable)) + (void)MBB /* Mark all reachable blocks */; + // Traverse the basic blocks. - for (MachineBasicBlock &MBB : mf) { - processBasicBlock(&MBB); - } + for (MachineBasicBlock &MBB : mf) + if (Reachable.count(&MBB)) + processBasicBlock(&MBB); return false; } Index: llvm/lib/CodeGen/CodeGen.cpp =================================================================== --- llvm/lib/CodeGen/CodeGen.cpp +++ llvm/lib/CodeGen/CodeGen.cpp @@ -23,6 +23,7 @@ initializeBasicBlockSectionsPass(Registry); initializeBranchFolderPassPass(Registry); initializeBranchRelaxationPass(Registry); + initializeBreakFalseDepsPass(Registry); initializeCallBrPreparePass(Registry); initializeCFGuardLongjmpPass(Registry); initializeCFIFixupPass(Registry); Index: llvm/test/CodeGen/X86/break-false-dep-crash.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/break-false-dep-crash.mir @@ -0,0 +1,165 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 +# RUN: llc -run-pass=break-false-deps -verify-machineinstrs %s -o - | FileCheck %s +# +# Check that BreakFalseDeps pass does not crash in presense of dead blocks. +--- | + ; ModuleID = 'repro.ll' + target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" + target triple = "i686-unknown-unknown" + + declare fastcc void @hoge() #0 + + ; Function Attrs: nounwind + define fastcc void @widget(i32 %arg) #1 { + bb: + br label %bb1 + + bb1: ; preds = %bb1, %bb + %phi = phi i1 [ true, %bb ], [ false, %bb1 ] + br i1 %phi, label %bb1, label %bb2 + + bb2: ; preds = %bb1 + br i1 %phi, label %bb4, label %bb3 + + bb3: ; preds = %bb2 + ret void + + bb4: ; preds = %bb2 + br label %bb5 + + bb5: ; preds = %bb5, %bb4 + %phi6 = phi double [ 0.000000e+00, %bb4 ], [ %fmul, %bb5 ] + %fptosi = fptosi double %phi6 to i32 + %icmp = icmp slt i32 %fptosi, %arg + %select = select i1 %icmp, i32 %fptosi, i32 0 + %sitofp = sitofp i32 %select to double + %fsub = fsub double 0.000000e+00, %sitofp + %fmul = fmul double 0.000000e+00, %fsub + br label %bb5 + } + + declare fastcc void @quux() #0 + + declare fastcc void @hoge.1() #0 + + declare fastcc void @barney() #0 + + declare fastcc void @ham() #0 + + declare fastcc void @wombat() #0 + + attributes #0 = { "target-features"="+sse2" } + attributes #1 = { nounwind "target-features"="+sse2" } + +... +--- +name: widget +alignment: 16 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +callsEHReturn: false +callsUnwindInit: false +hasEHCatchret: false +hasEHScopes: false +hasEHFunclets: false +isOutlined: false +debugInstrRef: false +failsVerification: false +tracksDebugUserValues: true +registers: [] +liveins: + - { reg: '$ecx', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + functionContext: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + hasTailCall: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +debugValueSubstitutions: [] +constants: [] +machineFunctionInfo: {} +body: | + ; CHECK-LABEL: name: widget + ; CHECK: bb.0.bb: + ; CHECK-NEXT: successors: %bb.1(0x80000000) + ; CHECK-NEXT: liveins: $ecx + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: renamable $al = MOV8ri 1, implicit-def $eax + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1.bb1 (align 16): + ; CHECK-NEXT: successors: %bb.1(0x7c000000), %bb.2(0x04000000) + ; CHECK-NEXT: liveins: $eax, $ecx + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: TEST8ri renamable $al, 1, implicit-def $eflags, implicit killed $eax + ; CHECK-NEXT: renamable $eax = MOV32ri 0 + ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit $eflags + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.bb3: + ; CHECK-NEXT: RET32 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3.bb5: + ; CHECK-NEXT: successors: %bb.3(0x80000000) + ; CHECK-NEXT: liveins: $eax, $ecx, $xmm0, $xmm1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: renamable $edx = nofpexcept CVTTSD2SIrr killed renamable $xmm1, implicit $mxcsr + ; CHECK-NEXT: CMP32rr renamable $edx, renamable $ecx, implicit-def $eflags + ; CHECK-NEXT: renamable $edx = CMOV32rr killed renamable $edx, renamable $eax, 13, implicit killed $eflags + ; CHECK-NEXT: renamable $xmm2 = CVTSI2SDrr killed renamable $edx + ; CHECK-NEXT: renamable $xmm1 = XORPSrr undef $xmm1, undef $xmm1 + ; CHECK-NEXT: renamable $xmm1 = nofpexcept SUBSDrr killed renamable $xmm1, killed renamable $xmm2, implicit $mxcsr + ; CHECK-NEXT: renamable $xmm1 = nofpexcept MULSDrr killed renamable $xmm1, renamable $xmm0, implicit $mxcsr + ; CHECK-NEXT: JMP_1 %bb.3 + bb.0.bb: + successors: %bb.1(0x80000000) + liveins: $ecx + + renamable $al = MOV8ri 1, implicit-def $eax + + bb.1.bb1 (align 16): + successors: %bb.1(0x7c000000), %bb.2(0x04000000) + liveins: $eax, $ecx + + TEST8ri renamable $al, 1, implicit-def $eflags, implicit killed $eax + renamable $eax = MOV32ri 0 + JCC_1 %bb.1, 5, implicit $eflags + + bb.2.bb3: + RET32 + + bb.3.bb5: + successors: %bb.3(0x80000000) + liveins: $eax, $ecx, $xmm0, $xmm1 + + renamable $edx = nofpexcept CVTTSD2SIrr killed renamable $xmm1, implicit $mxcsr + CMP32rr renamable $edx, renamable $ecx, implicit-def $eflags + renamable $edx = CMOV32rr killed renamable $edx, renamable $eax, 13, implicit killed $eflags + renamable $xmm2 = CVTSI2SDrr killed renamable $edx + renamable $xmm1 = XORPSrr undef $xmm1, undef $xmm1 + renamable $xmm1 = nofpexcept SUBSDrr killed renamable $xmm1, killed renamable $xmm2, implicit $mxcsr + renamable $xmm1 = nofpexcept MULSDrr killed renamable $xmm1, renamable $xmm0, implicit $mxcsr + JMP_1 %bb.3 + +...