Blocks with UnreachableInst terminators are considered as root nodes in the PDT. This pessimize DSE, if there are no aliasing reads from the potentially dead store and the block with the unreachable terminator. If any of the root nodes of the PDF has UnreachableInst as terminator, fall back to the CFG scan, even the common dominator of all killing blocks does not post-dominate the block with potentially dead store. It looks like the compile-time impact for the extra scans is negligible. https://llvm-compile-time-tracker.com/compare.php?from=779bbbf27fe631154bdfaac7a443f198d4654688&to=ac59945f1bec1c6a7d7f5590c8c69fd9c5369c53&stat=instructions Fixes #53800. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D119760
196 lines
5.7 KiB
LLVM
196 lines
5.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -dse -S %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
; Make sure we do not crash when we encounter unreachable blocks while checking
|
|
; if all paths to DomAccess go through a killing block.
|
|
define void @test(float* %ptr, i1 %c.1, i1 %c.2, i1 %c.3) {
|
|
; CHECK-LABEL: @test(
|
|
; CHECK-NEXT: bb:
|
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB27:%.*]], label [[BB53:%.*]]
|
|
; CHECK: bb10:
|
|
; CHECK-NEXT: br label [[BB43:%.*]]
|
|
; CHECK: bb22:
|
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB22:%.*]], label [[BB53]]
|
|
; CHECK: bb27:
|
|
; CHECK-NEXT: br i1 [[C_3:%.*]], label [[BB38:%.*]], label [[BB39:%.*]]
|
|
; CHECK: bb38:
|
|
; CHECK-NEXT: store float 0.000000e+00, float* [[PTR:%.*]], align 4
|
|
; CHECK-NEXT: br label [[BB38]]
|
|
; CHECK: bb39:
|
|
; CHECK-NEXT: br i1 [[C_2]], label [[BB43]], label [[BB38]]
|
|
; CHECK: bb43:
|
|
; CHECK-NEXT: store float 0.000000e+00, float* [[PTR]], align 4
|
|
; CHECK-NEXT: br label [[BB50:%.*]]
|
|
; CHECK: bb50:
|
|
; CHECK-NEXT: br i1 [[C_3]], label [[BB27]], label [[BB53]]
|
|
; CHECK: bb53:
|
|
; CHECK-NEXT: br label [[BB53]]
|
|
;
|
|
bb:
|
|
br i1 %c.1, label %bb27, label %bb53
|
|
|
|
bb10: ; No predecessors!
|
|
br label %bb43
|
|
|
|
bb22: ; preds = %bb22
|
|
br i1 %c.2, label %bb22, label %bb53
|
|
|
|
bb27: ; preds = %bb50, %bb
|
|
br i1 %c.3, label %bb38, label %bb39
|
|
|
|
bb38: ; preds = %bb39, %bb38, %bb27
|
|
store float 0.000000e+00, float* %ptr, align 4
|
|
br label %bb38
|
|
|
|
bb39: ; preds = %bb27
|
|
br i1 %c.2, label %bb43, label %bb38
|
|
|
|
bb43: ; preds = %bb39, %bb10
|
|
store float 0.000000e+00, float* %ptr, align 4
|
|
br label %bb50
|
|
|
|
bb50: ; preds = %bb43
|
|
br i1 %c.3, label %bb27, label %bb53
|
|
|
|
bb53: ; preds = %bb53, %bb50, %bb22, %bb
|
|
br label %bb53
|
|
}
|
|
|
|
declare void @exit()
|
|
|
|
define void @unreachable_exit_with_no_call(i64* noalias %ptr, i1 %c.1) {
|
|
; CHECK-LABEL: @unreachable_exit_with_no_call(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: store i64 0, i64* [[PTR:%.*]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i64 1, i64* %ptr, align 8
|
|
br i1 %c.1, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
unreachable
|
|
|
|
if.end:
|
|
store i64 0, i64* %ptr, align 8
|
|
ret void
|
|
}
|
|
|
|
; Test for PR53800.
|
|
define void @unreachable_exit_with_nounwind_call_pr53800(i64* noalias %ptr, i1 %c.1) {
|
|
; CHECK-LABEL: @unreachable_exit_with_nounwind_call_pr53800(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: tail call void @exit() #[[ATTR0:[0-9]+]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: store i64 0, i64* [[PTR:%.*]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i64 1, i64* %ptr, align 8
|
|
br i1 %c.1, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
tail call void @exit() nounwind
|
|
unreachable
|
|
|
|
if.end:
|
|
store i64 0, i64* %ptr, align 8
|
|
ret void
|
|
}
|
|
|
|
; The call @exit may read %ptr as it is not marked as noalias
|
|
define void @unreachable_exit_and_call_may_read(i64* %ptr, i1 %c.1) {
|
|
; CHECK-LABEL: @unreachable_exit_and_call_may_read(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i64 1, i64* [[PTR:%.*]], align 8
|
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: tail call void @exit() #[[ATTR0]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i64 1, i64* %ptr, align 8
|
|
br i1 %c.1, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
tail call void @exit() nounwind
|
|
unreachable
|
|
|
|
if.end:
|
|
store i64 0, i64* %ptr, align 8
|
|
ret void
|
|
}
|
|
|
|
define void @unreachable_exit_with_may_unwind_call(i64* noalias %ptr, i1 %c.1) {
|
|
; CHECK-LABEL: @unreachable_exit_with_may_unwind_call(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i64 1, i64* [[PTR:%.*]], align 8
|
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: tail call void @exit()
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i64 1, i64* %ptr, align 8
|
|
br i1 %c.1, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
tail call void @exit()
|
|
unreachable
|
|
|
|
if.end:
|
|
store i64 0, i64* %ptr, align 8
|
|
ret void
|
|
}
|
|
|
|
; Cannot remove the store in entry, because it is not dead on the path to e.1
|
|
define void @unreachable_exit_but_another_exit(i64* noalias %ptr, i1 %c.1, i32 %s, i1 %c.2) {
|
|
; CHECK-LABEL: @unreachable_exit_but_another_exit(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i64 1, i64* [[PTR:%.*]], align 8
|
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[E_0:%.*]], label [[E_1:%.*]]
|
|
; CHECK: e.0:
|
|
; CHECK-NEXT: tail call void @exit() #[[ATTR0]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: e.1:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i64 1, i64* %ptr, align 8
|
|
br i1 %c.1, label %if.then, label %if.end
|
|
|
|
if.then:
|
|
br i1 %c.2, label %e.0, label %e.1
|
|
|
|
e.0:
|
|
tail call void @exit() nounwind
|
|
unreachable
|
|
|
|
e.1:
|
|
ret void
|
|
|
|
if.end:
|
|
store i64 0, i64* %ptr, align 8
|
|
ret void
|
|
}
|