[Attributor][Fix] Make sure we do not delete live code
authorJohannes Doerfert <jdoerfert@anl.gov>
Wed, 4 Sep 2019 20:34:52 +0000 (20:34 +0000)
committerJohannes Doerfert <jdoerfert@anl.gov>
Wed, 4 Sep 2019 20:34:52 +0000 (20:34 +0000)
Summary: Liveness needs to mark edges, not blocks as dead.

Reviewers: sstefan1, uenoku

Subscribers: hiraditya, bollu, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67191

llvm-svn: 370975

llvm/lib/Transforms/IPO/Attributor.cpp
llvm/test/Transforms/FunctionAttrs/liveness.ll
llvm/test/Transforms/FunctionAttrs/noreturn_async.ll
llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll

index 04b9c5f..672968f 100644 (file)
@@ -1883,8 +1883,20 @@ struct AAIsDeadImpl : public AAIsDead {
           }
         }
 
-        if (SplitPos == &NormalDestBB->front())
-          assumeLive(A, *NormalDestBB);
+        if (SplitPos == &NormalDestBB->front()) {
+          // If this is an invoke of a noreturn function the edge to the normal
+          // destination block is dead but not necessarily the block itself.
+          // TODO: We need to move to an edge based system during deduction and
+          //       also manifest.
+          assert(!NormalDestBB->isLandingPad() &&
+                 "Expected the normal destination not to be a landingpad!");
+          BasicBlock *SplitBB =
+              SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
+          // The split block is live even if it contains only an unreachable
+          // instruction at the end.
+          assumeLive(A, *SplitBB);
+          SplitPos = SplitBB->getTerminator();
+        }
       }
 
       BB = SplitPos->getParent();
index 557dddb..93aac99 100644 (file)
@@ -177,7 +177,7 @@ cond.true:                                        ; preds = %entry
   %call = invoke i32 @foo_noreturn() to label %continue
             unwind label %cleanup
   ; CHECK:      %call = invoke i32 @foo_noreturn()
-  ; CHECK-NEXT:         to label %continue unwind label %cleanup
+  ; CHECK-NEXT:         to label %continue.dead unwind label %cleanup
 
 cond.false:                                       ; preds = %entry
   call void @normal_call()
@@ -189,7 +189,7 @@ cond.end:                                         ; preds = %cond.false, %contin
   ret i32 %cond
 
 continue:
-  ; CHECK:      continue:
+  ; CHECK:      continue.dead:
   ; CHECK-NEXT: unreachable
   br label %cond.end
 
@@ -663,3 +663,59 @@ define internal void @dead_e2() { ret void }
 ; CHECK: Function Attrs: nofree nosync nounwind willreturn
 ; CHECK-NEXT: define internal void @non_dead_d15()
 ; CHECK-NOT: define internal void @dead_e
+
+
+declare void @blowup() noreturn
+define void @live_with_dead_entry() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK:      define void @live_with_dead_entry(
+; CHECK-NEXT: entry:
+; CHECK-NEXT:   invoke void @blowup()
+; CHECK-NEXT:           to label %live_with_dead_entry.dead unwind label %lpad
+; CHECK:      lpad:                                             ; preds = %entry
+; CHECK-NEXT:   %0 = landingpad { i8*, i32 }
+; CHECK-NEXT:           catch i8* null
+; CHECK-NEXT:   br label %live_with_dead_entry
+; CHECK:      live_with_dead_entry.dead:                        ; preds = %entry
+; CHECK-NEXT:   unreachable
+; CHECK:      live_with_dead_entry:                             ; preds = %lpad
+; CHECK-NEXT:   ret void
+entry:
+  invoke void @blowup() to label %live_with_dead_entry unwind label %lpad
+lpad:
+  %0 = landingpad { i8*, i32 } catch i8* null
+  br label %live_with_dead_entry
+live_with_dead_entry:
+  ret void
+}
+
+define void @live_with_dead_entry_lp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK:      define void @live_with_dead_entry_lp(
+; CHECK-NEXT: entry:
+; CHECK-NEXT:   invoke void @blowup()
+; CHECK-NEXT:           to label %live_with_dead_entry.dead unwind label %lp1
+; CHECK:      lp1:                                              ; preds = %entry
+; CHECK-NEXT:   %lp = landingpad { i8*, i32 }
+; CHECK-NEXT:           catch i8* null
+; CHECK-NEXT:   invoke void @blowup()
+; CHECK-NEXT:           to label %live_with_dead_entry.dead1 unwind label %lp2
+; CHECK:      lp2:                                              ; preds = %lp1
+; CHECK-NEXT:   %0 = landingpad { i8*, i32 }
+; CHECK-NEXT:           catch i8* null
+; CHECK-NEXT:   br label %live_with_dead_entry
+; CHECK:      live_with_dead_entry.dead:                        ; preds = %entry
+; CHECK-NEXT:   unreachable
+; CHECK:      live_with_dead_entry.dead1:                       ; preds = %lp1
+; CHECK-NEXT:   unreachable
+; CHECK:      live_with_dead_entry:                             ; preds = %lp2
+; CHECK-NEXT:   ret void
+entry:
+  invoke void @blowup() to label %live_with_dead_entry unwind label %lp1
+lp1:
+  %lp = landingpad { i8*, i32 } catch i8* null
+  invoke void @blowup() to label %live_with_dead_entry unwind label %lp2
+lp2:
+  %0 = landingpad { i8*, i32 } catch i8* null
+  br label %live_with_dead_entry
+live_with_dead_entry:
+  ret void
+}
index b7e9b0f..1e34ca4 100644 (file)
@@ -42,12 +42,12 @@ entry:
   %retval = alloca i32, align 4
   %__exception_code = alloca i32, align 4
 ; CHECK: invoke void @"?overflow@@YAXXZ"()
-; CHECK:          to label %invoke.cont unwind label %catch.dispatch
+; CHECK:          to label %invoke.cont.dead unwind label %catch.dispatch
   invoke void @"?overflow@@YAXXZ"()
           to label %invoke.cont unwind label %catch.dispatch
 
 invoke.cont:                                      ; preds = %entry
-; CHECK:      invoke.cont:
+; CHECK:      invoke.cont.dead:
 ; CHECK-NEXT: unreachable
   br label %invoke.cont1
 
@@ -101,12 +101,12 @@ entry:
   %retval = alloca i32, align 4
   %__exception_code = alloca i32, align 4
 ; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"() 
-; CHECK:          to label %invoke.cont unwind label %catch.dispatch
+; CHECK:          to label %invoke.cont.dead unwind label %catch.dispatch
   invoke void @"?overflow@@YAXXZ_may_throw"() 
           to label %invoke.cont unwind label %catch.dispatch
 
 invoke.cont:                                      ; preds = %entry
-; CHECK:      invoke.cont:
+; CHECK:      invoke.cont.dead:
 ; CHECK-NEXT: unreachable
   br label %invoke.cont1
 
index fb9e8e6..0f1af27 100644 (file)
@@ -97,12 +97,12 @@ entry:
   %retval = alloca i32, align 4
   %__exception_code = alloca i32, align 4
 ; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"() 
-; CHECK:          to label %invoke.cont unwind label %catch.dispatch
+; CHECK:          to label %invoke.cont.dead unwind label %catch.dispatch
   invoke void @"?overflow@@YAXXZ_may_throw"() 
           to label %invoke.cont unwind label %catch.dispatch
 
 invoke.cont:                                      ; preds = %entry
-; CHECK:      invoke.cont:
+; CHECK:      invoke.cont.dead:
 ; CHECK-NEXT: unreachable
   br label %invoke.cont1