diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -130,9 +130,12 @@ // Until then, keep track of the number of blocks to assert that we don't. const size_t NumBlocks = MF.size(); #endif + // Keep track of selected blocks, so we can delete unreachable ones later. + DenseSet SelectedBlocks; for (MachineBasicBlock *MBB : post_order(&MF)) { ISel->CurMBB = MBB; + SelectedBlocks.insert(MBB); if (MBB->empty()) continue; @@ -205,6 +208,15 @@ if (MBB.empty()) continue; + if (!SelectedBlocks.contains(&MBB)) { + // This is an unreachable block and therefore hasn't been selected, since + // the main selection loop above uses a postorder block traversal. + // We delete all the instructions in this block since it's unreachable. + MBB.clear(); + // Don't delete the block in case the block has it's address taken or is + // still being referenced by a phi somewhere. + continue; + } // Try to find redundant copies b/w vregs of the same register class. bool ReachedBegin = false; for (auto MII = std::prev(MBB.end()), Begin = MBB.begin(); !ReachedBegin;) { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir @@ -0,0 +1,61 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=aarch64-unknown-unknown -o - -verify-machineinstrs -run-pass=instruction-select %s | FileCheck %s +--- +name: test_unreachable_delete +alignment: 4 +exposesReturnsTwice: false +legalized: true +regBankSelected: true +selected: false +tracksRegLiveness: true +liveins: +body: | + ; CHECK-LABEL: name: test_unreachable_delete + ; CHECK: bb.0: + ; CHECK-NEXT: successors: %bb.2(0x80000000) + ; CHECK-NEXT: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32sp = COPY $w0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr + ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 + ; CHECK-NEXT: B %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1: + ; CHECK-NEXT: successors: %bb.2(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2: + ; CHECK-NEXT: successors: %bb.3(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[ADDWri:%[0-9]+]]:gpr32sp = ADDWri [[COPY]], 2, 0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3: + ; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32 = PHI [[ADDWri]], %bb.2 + ; CHECK-NEXT: $w0 = COPY [[PHI]] + ; CHECK-NEXT: RET_ReallyLR implicit $w0 + bb.1: + successors: %bb.3 + liveins: $w0 + + %0:gpr(s32) = COPY $w0 + %1:gpr(s32) = G_CONSTANT i32 0 + %3:gpr(s32) = G_CONSTANT i32 1 + %5:gpr(s32) = G_CONSTANT i32 2 + G_BR %bb.3 + + bb.5: + ; This block is unreachable. + %unreachable_inst:gpr(s32) = G_XOR %1, %3 + $w0 = COPY %unreachable_inst(s32) + + bb.3: + successors: %bb.4(0x80000000) + + %6:gpr(s32) = G_ADD %0, %5 + + bb.4: + %7:gpr(s32) = G_PHI %6(s32), %bb.3 + $w0 = COPY %7(s32) + RET_ReallyLR implicit $w0 + +...