[llvm] a495b67 - [NFC][SimplifyCFG] Precommit SimplifyCFG tests from D29428
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 27 14:37:45 PDT 2021
Author: Reid Kleckner
Date: 2021-04-28T00:35:44+03:00
New Revision: a495b672b7ff90fef9aaa296a1c52e0921e71875
URL: https://github.com/llvm/llvm-project/commit/a495b672b7ff90fef9aaa296a1c52e0921e71875
DIFF: https://github.com/llvm/llvm-project/commit/a495b672b7ff90fef9aaa296a1c52e0921e71875.diff
LOG: [NFC][SimplifyCFG] Precommit SimplifyCFG tests from D29428
Added:
llvm/test/Transforms/SimplifyCFG/tail-merge-assert.ll
llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll
Modified:
Removed:
################################################################################
diff --git a/llvm/test/Transforms/SimplifyCFG/tail-merge-assert.ll b/llvm/test/Transforms/SimplifyCFG/tail-merge-assert.ll
new file mode 100644
index 000000000000..e0af1e2c4bf4
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/tail-merge-assert.ll
@@ -0,0 +1,75 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S < %s | FileCheck %s
+
+; Test that we tail merge this kind of code with glibc-style assertion
+; failure calls:
+; #include <assert.h>
+; void merge_glibc_asserts(unsigned x, unsigned y) {
+; assert(x < y);
+; assert(y - x > 7);
+; assert(y - x < 40);
+; }
+;
+; glibc's __assert_fail function takes four parameters, and it is profitable to
+; phi two of them.
+
+ at .str = private unnamed_addr constant [6 x i8] c"x < y\00", align 1
+ at .str.1 = private unnamed_addr constant [6 x i8] c"t.cpp\00", align 1
+ at __PRETTY_FUNCTION__._Z1fjj = private unnamed_addr constant [35 x i8] c"void f(unsigned int, unsigned int)\00", align 1
+ at .str.2 = private unnamed_addr constant [10 x i8] c"y - x > 7\00", align 1
+ at .str.3 = private unnamed_addr constant [11 x i8] c"y - x < 40\00", align 1
+
+declare void @glibc_assert_fail(i8*, i8*, i32, i8*)
+
+define void @merge_glibc_asserts(i32 %x, i32 %y) {
+; CHECK-LABEL: @merge_glibc_asserts(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
+; CHECK: cond.false:
+; CHECK-NEXT: tail call void @glibc_assert_fail(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), i32 3, i8* getelementptr inbounds ([35 x i8], [35 x i8]* @__PRETTY_FUNCTION__._Z1fjj, i64 0, i64 0))
+; CHECK-NEXT: unreachable
+; CHECK: cond.end:
+; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y]], [[X]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[SUB]], 7
+; CHECK-NEXT: br i1 [[CMP1]], label [[COND_END4:%.*]], label [[COND_FALSE3:%.*]]
+; CHECK: cond.false3:
+; CHECK-NEXT: tail call void @glibc_assert_fail(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), i32 4, i8* getelementptr inbounds ([35 x i8], [35 x i8]* @__PRETTY_FUNCTION__._Z1fjj, i64 0, i64 0))
+; CHECK-NEXT: unreachable
+; CHECK: cond.end4:
+; CHECK-NEXT: [[CMP6:%.*]] = icmp ult i32 [[SUB]], 40
+; CHECK-NEXT: br i1 [[CMP6]], label [[COND_END9:%.*]], label [[COND_FALSE8:%.*]]
+; CHECK: cond.false8:
+; CHECK-NEXT: tail call void @glibc_assert_fail(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), i32 5, i8* getelementptr inbounds ([35 x i8], [35 x i8]* @__PRETTY_FUNCTION__._Z1fjj, i64 0, i64 0))
+; CHECK-NEXT: unreachable
+; CHECK: cond.end9:
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp = icmp ugt i32 %y, %x
+ br i1 %cmp, label %cond.end, label %cond.false
+
+cond.false: ; preds = %entry
+ tail call void @glibc_assert_fail(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), i32 3, i8* getelementptr inbounds ([35 x i8], [35 x i8]* @__PRETTY_FUNCTION__._Z1fjj, i64 0, i64 0)) #2
+ unreachable
+
+cond.end: ; preds = %entry
+ %sub = sub i32 %y, %x
+ %cmp1 = icmp ugt i32 %sub, 7
+ br i1 %cmp1, label %cond.end4, label %cond.false3
+
+cond.false3: ; preds = %cond.end
+ tail call void @glibc_assert_fail(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), i32 4, i8* getelementptr inbounds ([35 x i8], [35 x i8]* @__PRETTY_FUNCTION__._Z1fjj, i64 0, i64 0)) #2
+ unreachable
+
+cond.end4: ; preds = %cond.end
+ %cmp6 = icmp ult i32 %sub, 40
+ br i1 %cmp6, label %cond.end9, label %cond.false8
+
+cond.false8: ; preds = %cond.end4
+ tail call void @glibc_assert_fail(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), i32 5, i8* getelementptr inbounds ([35 x i8], [35 x i8]* @__PRETTY_FUNCTION__._Z1fjj, i64 0, i64 0)) #2
+ unreachable
+
+cond.end9: ; preds = %cond.end4
+ ret void
+}
diff --git a/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll b/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll
new file mode 100644
index 000000000000..aa074e443269
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll
@@ -0,0 +1,548 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S < %s | FileCheck %s
+
+; Test that we tail merge noreturn call blocks and phi constants properly.
+
+declare void @abort()
+declare void @assert_fail_1(i32)
+declare void @assert_fail_1_alt(i32)
+
+define void @merge_simple() {
+; CHECK-LABEL: @merge_simple(
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]]
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont1:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]]
+; CHECK: a2:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont2:
+; CHECK-NEXT: [[C3:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]]
+; CHECK: a3:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont3:
+; CHECK-NEXT: ret void
+;
+ %c1 = call i1 @foo()
+ br i1 %c1, label %cont1, label %a1
+a1:
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont1:
+ %c2 = call i1 @foo()
+ br i1 %c2, label %cont2, label %a2
+a2:
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont2:
+ %c3 = call i1 @foo()
+ br i1 %c3, label %cont3, label %a3
+a3:
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont3:
+ ret void
+}
+
+define void @phi_three_constants() {
+; CHECK-LABEL: @phi_three_constants(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]]
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont1:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]]
+; CHECK: a2:
+; CHECK-NEXT: call void @assert_fail_1(i32 1)
+; CHECK-NEXT: unreachable
+; CHECK: cont2:
+; CHECK-NEXT: [[C3:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]]
+; CHECK: a3:
+; CHECK-NEXT: call void @assert_fail_1(i32 2)
+; CHECK-NEXT: unreachable
+; CHECK: cont3:
+; CHECK-NEXT: ret void
+;
+entry:
+ %c1 = call i1 @foo()
+ br i1 %c1, label %cont1, label %a1
+a1:
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont1:
+ %c2 = call i1 @foo()
+ br i1 %c2, label %cont2, label %a2
+a2:
+ call void @assert_fail_1(i32 1)
+ unreachable
+cont2:
+ %c3 = call i1 @foo()
+ br i1 %c3, label %cont3, label %a3
+a3:
+ call void @assert_fail_1(i32 2)
+ unreachable
+cont3:
+ ret void
+}
+
+define void @dont_phi_values(i32 %x, i32 %y) {
+; CHECK-LABEL: @dont_phi_values(
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]]
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 [[X:%.*]])
+; CHECK-NEXT: unreachable
+; CHECK: cont1:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]]
+; CHECK: a2:
+; CHECK-NEXT: call void @assert_fail_1(i32 [[Y:%.*]])
+; CHECK-NEXT: unreachable
+; CHECK: cont2:
+; CHECK-NEXT: ret void
+;
+ %c1 = call i1 @foo()
+ br i1 %c1, label %cont1, label %a1
+a1:
+ call void @assert_fail_1(i32 %x)
+ unreachable
+cont1:
+ %c2 = call i1 @foo()
+ br i1 %c2, label %cont2, label %a2
+a2:
+ call void @assert_fail_1(i32 %y)
+ unreachable
+cont2:
+ ret void
+}
+
+define void @dont_phi_callees() {
+; CHECK-LABEL: @dont_phi_callees(
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]]
+; CHECK: cont1:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]]
+; CHECK: cont2:
+; CHECK-NEXT: ret void
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: a2:
+; CHECK-NEXT: call void @assert_fail_1_alt(i32 0)
+; CHECK-NEXT: unreachable
+;
+ %c1 = call i1 @foo()
+ br i1 %c1, label %cont1, label %a1
+cont1:
+ %c2 = call i1 @foo()
+ br i1 %c2, label %cont2, label %a2
+cont2:
+ ret void
+a1:
+ call void @assert_fail_1(i32 0)
+ unreachable
+a2:
+ call void @assert_fail_1_alt(i32 0)
+ unreachable
+}
+
+declare i1 @foo()
+declare i1 @bar()
+
+define void @unmergeable_phis(i32 %v, i1 %c) {
+; CHECK-LABEL: @unmergeable_phis(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[S1:%.*]], label [[S2:%.*]]
+; CHECK: s1:
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[A1:%.*]], label [[A2:%.*]]
+; CHECK: s2:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @bar()
+; CHECK-NEXT: br i1 [[C2]], label [[A1]], label [[A2]]
+; CHECK: a1:
+; CHECK-NEXT: [[L1:%.*]] = phi i32 [ 0, [[S1]] ], [ 1, [[S2]] ]
+; CHECK-NEXT: call void @assert_fail_1(i32 [[L1]])
+; CHECK-NEXT: unreachable
+; CHECK: a2:
+; CHECK-NEXT: [[L2:%.*]] = phi i32 [ 2, [[S1]] ], [ 3, [[S2]] ]
+; CHECK-NEXT: call void @assert_fail_1(i32 [[L2]])
+; CHECK-NEXT: unreachable
+;
+entry:
+ br i1 %c, label %s1, label %s2
+s1:
+ %c1 = call i1 @foo()
+ br i1 %c1, label %a1, label %a2
+s2:
+ %c2 = call i1 @bar()
+ br i1 %c2, label %a1, label %a2
+a1:
+ %l1 = phi i32 [ 0, %s1 ], [ 1, %s2 ]
+ call void @assert_fail_1(i32 %l1)
+ unreachable
+a2:
+ %l2 = phi i32 [ 2, %s1 ], [ 3, %s2 ]
+ call void @assert_fail_1(i32 %l2)
+ unreachable
+}
+
+define void @tail_merge_switch(i32 %v) {
+; CHECK-LABEL: @tail_merge_switch(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: switch i32 [[V:%.*]], label [[RET:%.*]] [
+; CHECK-NEXT: i32 0, label [[A1:%.*]]
+; CHECK-NEXT: i32 13, label [[A2:%.*]]
+; CHECK-NEXT: i32 42, label [[A3:%.*]]
+; CHECK-NEXT: ]
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: a2:
+; CHECK-NEXT: call void @assert_fail_1(i32 1)
+; CHECK-NEXT: unreachable
+; CHECK: a3:
+; CHECK-NEXT: call void @assert_fail_1(i32 2)
+; CHECK-NEXT: unreachable
+; CHECK: ret:
+; CHECK-NEXT: ret void
+;
+entry:
+ switch i32 %v, label %ret [
+ i32 0, label %a1
+ i32 13, label %a2
+ i32 42, label %a3
+ ]
+a1:
+ call void @assert_fail_1(i32 0)
+ unreachable
+a2:
+ call void @assert_fail_1(i32 1)
+ unreachable
+a3:
+ call void @assert_fail_1(i32 2)
+ unreachable
+ret:
+ ret void
+}
+
+define void @need_to_add_bb2_preds(i1 %c1) {
+; CHECK-LABEL: @need_to_add_bb2_preds(
+; CHECK-NEXT: bb1:
+; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB2:%.*]], label [[A1:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @bar()
+; CHECK-NEXT: br i1 [[C2]], label [[A2:%.*]], label [[A3:%.*]]
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: a2:
+; CHECK-NEXT: call void @assert_fail_1(i32 1)
+; CHECK-NEXT: unreachable
+; CHECK: a3:
+; CHECK-NEXT: call void @assert_fail_1(i32 2)
+; CHECK-NEXT: unreachable
+;
+bb1:
+ br i1 %c1, label %bb2, label %a1
+bb2:
+ %c2 = call i1 @bar()
+ br i1 %c2, label %a2, label %a3
+
+a1:
+ call void @assert_fail_1(i32 0)
+ unreachable
+a2:
+ call void @assert_fail_1(i32 1)
+ unreachable
+a3:
+ call void @assert_fail_1(i32 2)
+ unreachable
+}
+
+define void @phi_in_bb2() {
+; CHECK-LABEL: @phi_in_bb2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]]
+; CHECK: a1:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont1:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]]
+; CHECK: a2:
+; CHECK-NEXT: [[P2:%.*]] = phi i32 [ 1, [[CONT1]] ], [ 2, [[CONT2]] ]
+; CHECK-NEXT: call void @assert_fail_1(i32 [[P2]])
+; CHECK-NEXT: unreachable
+; CHECK: cont2:
+; CHECK-NEXT: [[C3:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A2]]
+; CHECK: cont3:
+; CHECK-NEXT: ret void
+;
+entry:
+ %c1 = call i1 @foo()
+ br i1 %c1, label %cont1, label %a1
+a1:
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont1:
+ %c2 = call i1 @foo()
+ br i1 %c2, label %cont2, label %a2
+a2:
+ %p2 = phi i32 [ 1, %cont1 ], [ 2, %cont2 ]
+ call void @assert_fail_1(i32 %p2)
+ unreachable
+cont2:
+ %c3 = call i1 @foo()
+ br i1 %c3, label %cont3, label %a2
+cont3:
+ ret void
+}
+
+; Don't tail merge these noreturn blocks using lifetime end. It prevents us
+; from sharing stack slots for x and y.
+
+declare void @escape_i32_ptr(i32*)
+declare void @llvm.lifetime.start(i64, i8* nocapture)
+declare void @llvm.lifetime.end(i64, i8* nocapture)
+
+define void @dont_merge_lifetimes(i32 %c1, i32 %c2) {
+; CHECK-LABEL: @dont_merge_lifetimes(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
+; CHECK-NEXT: switch i32 [[C1:%.*]], label [[IF_END9:%.*]] [
+; CHECK-NEXT: i32 13, label [[IF_THEN:%.*]]
+; CHECK-NEXT: i32 42, label [[IF_THEN3:%.*]]
+; CHECK-NEXT: ]
+; CHECK: if.then:
+; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[X]] to i8*
+; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[TMP0]])
+; CHECK-NEXT: store i32 0, i32* [[X]], align 4
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C2:%.*]], 0
+; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN1:%.*]]
+; CHECK: if.then1:
+; CHECK-NEXT: call void @escape_i32_ptr(i32* nonnull [[X]])
+; CHECK-NEXT: br label [[IF_END]]
+; CHECK: if.end:
+; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[TMP0]])
+; CHECK-NEXT: call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: if.then3:
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[Y]] to i8*
+; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[TMP1]])
+; CHECK-NEXT: store i32 0, i32* [[Y]], align 4
+; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i32 [[C2]], 0
+; CHECK-NEXT: br i1 [[TOBOOL5]], label [[IF_END7:%.*]], label [[IF_THEN6:%.*]]
+; CHECK: if.then6:
+; CHECK-NEXT: call void @escape_i32_ptr(i32* nonnull [[Y]])
+; CHECK-NEXT: br label [[IF_END7]]
+; CHECK: if.end7:
+; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[TMP1]])
+; CHECK-NEXT: call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: if.end9:
+; CHECK-NEXT: ret void
+;
+entry:
+ %x = alloca i32, align 4
+ %y = alloca i32, align 4
+ switch i32 %c1, label %if.end9 [
+ i32 13, label %if.then
+ i32 42, label %if.then3
+ ]
+
+if.then: ; preds = %entry
+ %0 = bitcast i32* %x to i8*
+ call void @llvm.lifetime.start(i64 4, i8* nonnull %0)
+ store i32 0, i32* %x, align 4
+ %tobool = icmp eq i32 %c2, 0
+ br i1 %tobool, label %if.end, label %if.then1
+
+if.then1: ; preds = %if.then
+ call void @escape_i32_ptr(i32* nonnull %x)
+ br label %if.end
+
+if.end: ; preds = %if.then1, %if.then
+ call void @llvm.lifetime.end(i64 4, i8* nonnull %0)
+ call void @abort()
+ unreachable
+
+if.then3: ; preds = %entry
+ %1 = bitcast i32* %y to i8*
+ call void @llvm.lifetime.start(i64 4, i8* nonnull %1)
+ store i32 0, i32* %y, align 4
+ %tobool5 = icmp eq i32 %c2, 0
+ br i1 %tobool5, label %if.end7, label %if.then6
+
+if.then6: ; preds = %if.then3
+ call void @escape_i32_ptr(i32* nonnull %y)
+ br label %if.end7
+
+if.end7: ; preds = %if.then6, %if.then3
+ call void @llvm.lifetime.end(i64 4, i8* nonnull %1)
+ call void @abort()
+ unreachable
+
+if.end9: ; preds = %entry
+ ret void
+}
+
+; Dead phis in the block need to be handled.
+
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
+
+define void @dead_phi() {
+; CHECK-LABEL: @dead_phi(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[C1:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]]
+; CHECK: a1:
+; CHECK-NEXT: [[DEAD:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[CONT1]] ]
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont1:
+; CHECK-NEXT: [[C2:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A1]]
+; CHECK: cont2:
+; CHECK-NEXT: [[C3:%.*]] = call i1 @foo()
+; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]]
+; CHECK: a3:
+; CHECK-NEXT: call void @assert_fail_1(i32 0)
+; CHECK-NEXT: unreachable
+; CHECK: cont3:
+; CHECK-NEXT: ret void
+;
+entry:
+ %c1 = call i1 @foo()
+ br i1 %c1, label %cont1, label %a1
+a1:
+ %dead = phi i32 [ 0, %entry ], [ 1, %cont1 ]
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont1:
+ %c2 = call i1 @foo()
+ br i1 %c2, label %cont2, label %a1
+cont2:
+ %c3 = call i1 @foo()
+ br i1 %c3, label %cont3, label %a3
+a3:
+ call void @assert_fail_1(i32 0)
+ unreachable
+cont3:
+ ret void
+}
+
+define void @strip_dbg_value(i32 %c) {
+; CHECK-LABEL: @strip_dbg_value(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[C:%.*]], metadata [[META5:![0-9]+]], metadata !DIExpression()), !dbg [[DBG7:![0-9]+]]
+; CHECK-NEXT: switch i32 [[C]], label [[SW_EPILOG:%.*]] [
+; CHECK-NEXT: i32 13, label [[SW_BB:%.*]]
+; CHECK-NEXT: i32 42, label [[SW_BB1:%.*]]
+; CHECK-NEXT: ]
+; CHECK: sw.bb:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 55, metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]]
+; CHECK-NEXT: tail call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: sw.bb1:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 67, metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]]
+; CHECK-NEXT: tail call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: sw.epilog:
+; CHECK-NEXT: ret void
+;
+entry:
+ call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !12, metadata !13), !dbg !14
+ switch i32 %c, label %sw.epilog [
+ i32 13, label %sw.bb
+ i32 42, label %sw.bb1
+ ]
+
+sw.bb: ; preds = %entry
+ call void @llvm.dbg.value(metadata i32 55, i64 0, metadata !12, metadata !13), !dbg !14
+ tail call void @abort()
+ unreachable
+
+sw.bb1: ; preds = %entry
+ call void @llvm.dbg.value(metadata i32 67, i64 0, metadata !12, metadata !13), !dbg !14
+ tail call void @abort()
+ unreachable
+
+sw.epilog: ; preds = %entry
+ ret void
+}
+
+define void @dead_phi_and_dbg(i32 %c) {
+; CHECK-LABEL: @dead_phi_and_dbg(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[C:%.*]], metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]]
+; CHECK-NEXT: switch i32 [[C]], label [[SW_EPILOG:%.*]] [
+; CHECK-NEXT: i32 13, label [[SW_BB:%.*]]
+; CHECK-NEXT: i32 42, label [[SW_BB1:%.*]]
+; CHECK-NEXT: i32 53, label [[SW_BB2:%.*]]
+; CHECK-NEXT: ]
+; CHECK: sw.bb:
+; CHECK-NEXT: [[C_1:%.*]] = phi i32 [ 55, [[ENTRY:%.*]] ], [ 67, [[SW_BB1]] ]
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[C_1]], metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]]
+; CHECK-NEXT: tail call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: sw.bb1:
+; CHECK-NEXT: br label [[SW_BB]]
+; CHECK: sw.bb2:
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 84, metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]]
+; CHECK-NEXT: tail call void @abort()
+; CHECK-NEXT: unreachable
+; CHECK: sw.epilog:
+; CHECK-NEXT: ret void
+;
+entry:
+ call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !12, metadata !13), !dbg !14
+ switch i32 %c, label %sw.epilog [
+ i32 13, label %sw.bb
+ i32 42, label %sw.bb1
+ i32 53, label %sw.bb2
+ ]
+
+sw.bb: ; preds = %entry
+ %c.1 = phi i32 [ 55, %entry], [ 67, %sw.bb1 ]
+ call void @llvm.dbg.value(metadata i32 %c.1, i64 0, metadata !12, metadata !13), !dbg !14
+ tail call void @abort()
+ unreachable
+
+sw.bb1:
+ br label %sw.bb
+
+sw.bb2: ; preds = %entry
+ call void @llvm.dbg.value(metadata i32 84, i64 0, metadata !12, metadata !13), !dbg !14
+ tail call void @abort()
+ unreachable
+
+sw.epilog: ; preds = %entry
+ ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "t.c", directory: "asdf")
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"PIC Level", i32 2}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 2, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0)
+!12 = !DILocalVariable(name: "c", scope: !7)
+!13 = !DIExpression()
+!14 = !DILocation(line: 2, column: 12, scope: !7)
More information about the llvm-commits
mailing list