[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