[llvm] 22225cc - [Coroutines] Handle lifetime markers, bitcast and unused instruciton for symmetric transfer

Chuanqi Xu via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 11 23:59:57 PST 2022


Author: Chuanqi Xu
Date: 2022-01-12T15:58:38+08:00
New Revision: 22225cc5e6654eea3f9f1599e6dfc07fc979db62

URL: https://github.com/llvm/llvm-project/commit/22225cc5e6654eea3f9f1599e6dfc07fc979db62
DIFF: https://github.com/llvm/llvm-project/commit/22225cc5e6654eea3f9f1599e6dfc07fc979db62.diff

LOG: [Coroutines] Handle lifetime markers, bitcast and unused instruciton for symmetric transfer

This fixes bug49888. The root cause for this is that
simplifyTerminatorLeadingToRet didn't handle lifetime markers well.
Another issue also noted in D116327 is that we deleted some inlined
optimization pass in CoroSplit so that simplifyTerminatorLeadingToRet
need to remove dead instructions by hand.

This patch fixes bug49888 by skipping lifetime markers and bitcast
instruction and removing dead instructions by hand in
simplifyTerminatorLeadingToRet.

Reviewed By: junparser

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Coroutines/CoroSplit.cpp
    llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
    llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
    llvm/test/Transforms/Coroutines/coro-split-musttail7.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8ac0b4f9636aa..aadd7fe3dd565 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -1201,6 +1201,22 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
   assert(InitialInst->getModule());
   const DataLayout &DL = InitialInst->getModule()->getDataLayout();
 
+  auto GetFirstValidInstruction = [](Instruction *I) {
+    while (I) {
+      // BitCastInst wouldn't generate actual code so that we could skip it.
+      if (isa<BitCastInst>(I) || I->isDebugOrPseudoInst() ||
+          I->isLifetimeStartOrEnd())
+        I = I->getNextNode();
+      else if (isInstructionTriviallyDead(I))
+        // Duing we are in the middle of the transformation, we need to erase
+        // the dead instruction manually.
+        I = &*I->eraseFromParent();
+      else
+        break;
+    }
+    return I;
+  };
+
   auto TryResolveConstant = [&ResolvedValues](Value *V) {
     auto It = ResolvedValues.find(V);
     if (It != ResolvedValues.end())
@@ -1209,8 +1225,7 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
   };
 
   Instruction *I = InitialInst;
-  while (I->isTerminator() ||
-         (isa<CmpInst>(I) && I->getNextNode()->isTerminator())) {
+  while (I->isTerminator() || isa<CmpInst>(I)) {
     if (isa<ReturnInst>(I)) {
       if (I != InitialInst) {
         // If InitialInst is an unconditional branch,
@@ -1227,7 +1242,7 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
         if (I == InitialInst)
           UnconditionalSucc = Succ;
         scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues);
-        I = Succ->getFirstNonPHIOrDbgOrLifetime();
+        I = GetFirstValidInstruction(Succ->getFirstNonPHIOrDbgOrLifetime());
         continue;
       }
 
@@ -1247,7 +1262,8 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
     } else if (auto *CondCmp = dyn_cast<CmpInst>(I)) {
       // If the case number of suspended switch instruction is reduced to
       // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator.
-      auto *BR = dyn_cast<BranchInst>(I->getNextNode());
+      auto *BR = dyn_cast<BranchInst>(
+          GetFirstValidInstruction(CondCmp->getNextNode()));
       if (!BR || !BR->isConditional() || CondCmp != BR->getCondition())
         return false;
 
@@ -1280,9 +1296,10 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
 
       BasicBlock *BB = SI->findCaseValue(Cond)->getCaseSuccessor();
       scanPHIsAndUpdateValueMap(I, BB, ResolvedValues);
-      I = BB->getFirstNonPHIOrDbgOrLifetime();
+      I = GetFirstValidInstruction(BB->getFirstNonPHIOrDbgOrLifetime());
       continue;
     }
+
     return false;
   }
   return false;

diff  --git a/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
index 84a52e47f939d..9f29f1d8b8938 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll
@@ -36,10 +36,10 @@ exit:
   ret void
 }
 
-; FIXME: The fakeresume1 here should be marked as musttail.
 ; Verify that in the resume part resume call is marked with musttail.
 ; CHECK-LABEL: @g.resume(
-; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK:          musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK-NEXT:     ret void
 
 declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1
 declare i1 @llvm.coro.alloc(token) #2

diff  --git a/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
index f139b8fb58843..a86de71278a59 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll
@@ -40,10 +40,10 @@ exit:
   ret void
 }
 
-; FIXME: The fakeresume1 here should be marked as musttail.
 ; Verify that in the resume part resume call is marked with musttail.
 ; CHECK-LABEL: @g.resume(
-; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK:      musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK-NEXT: ret void
 
 ; It has a cleanup bb.
 define void @f() #0 {
@@ -92,7 +92,8 @@ exit:
 ; FIXME: The fakeresume1 here should be marked as musttail.
 ; Verify that in the resume part resume call is marked with musttail.
 ; CHECK-LABEL: @f.resume(
-; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK:      musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK-NEXT: ret void
 
 declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1
 declare i1 @llvm.coro.alloc(token) #2

diff  --git a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
index ce1f7203a0c7e..4d176cbb2c66a 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll
@@ -41,10 +41,10 @@ exit:
   ret void
 }
 
-; FIXME: The fakeresume1 here should be marked as musttail.
 ; Verify that in the resume part resume call is marked with musttail.
 ; CHECK-LABEL: @g.resume(
-; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK:         musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK-NEXT:    ret void
 
 ; It has a cleanup bb.
 define void @f() #0 {
@@ -94,7 +94,8 @@ exit:
 ; FIXME: The fakeresume1 here should be marked as musttail.
 ; Verify that in the resume part resume call is marked with musttail.
 ; CHECK-LABEL: @f.resume(
-; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK:         musttail call fastcc void @fakeresume1(i64* align 8 null)
+; CHECK-NEXT:    ret void
 
 declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1
 declare i1 @llvm.coro.alloc(token) #2


        


More information about the llvm-commits mailing list