Files
clang-p2996/llvm/test/Transforms/DeadStoreElimination/multiblock-unreachable.ll
Florian Hahn d03d3d7966 [DSE] Fall back to CFG scan for unreachable terminators.
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
2022-02-16 14:06:40 +00:00

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
}