From d0641826121d61cbf688dc8cd4bd368939292689 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Thu, 24 Jun 2021 21:25:06 +0300 Subject: [PATCH] [SimplifyCFG] Tail-merging all blocks with `resume` terminator Similar to what we already do for `ret` terminators. As noted by @rnk, clang seems to already generate a single `ret`/`resume`, so this isn't likely to cause widespread changes. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D104849 --- llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp | 9 +++++++-- .../Transforms/SimplifyCFG/tail-merge-resume.ll | 15 ++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp index dc21b3c72689..09d59b0e884a 100644 --- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -94,10 +94,15 @@ static bool tailMergeBlocksWithSimilarFunctionTerminators(Function &F, auto *Term = BB.getTerminator(); - // Fow now only support `ret` function terminators. + // Fow now only support `ret`/`resume` function terminators. // FIXME: lift this restriction. - if (Term->getOpcode() != Instruction::Ret) + switch (Term->getOpcode()) { + case Instruction::Ret: + case Instruction::Resume: + break; + default: continue; + } // We can't tail-merge block that contains a musttail call. if (BB.getTerminatingMustTailCall()) diff --git a/llvm/test/Transforms/SimplifyCFG/tail-merge-resume.ll b/llvm/test/Transforms/SimplifyCFG/tail-merge-resume.ll index 2268f4371ff0..57a057018263 100644 --- a/llvm/test/Transforms/SimplifyCFG/tail-merge-resume.ll +++ b/llvm/test/Transforms/SimplifyCFG/tail-merge-resume.ll @@ -39,19 +39,20 @@ define void @merge_simple(i1 %cond) personality i8* bitcast (i32 (...)* @__gxx_p ; CHECK-NEXT: cleanup ; CHECK-NEXT: call void @baz() ; CHECK-NEXT: br label [[RESUME2]] +; CHECK: common.resume: +; CHECK-NEXT: [[COMMON_RESUME_OP:%.*]] = phi { i8*, i32 } [ [[LP]], [[RESUME0]] ], [ [[LP]], [[RESUME1]] ], [ [[SEMICOMMON_LP:%.*]], [[RESUME2]] ] +; CHECK-NEXT: call void @common() +; CHECK-NEXT: resume { i8*, i32 } [[COMMON_RESUME_OP]] ; CHECK: resume0: ; CHECK-NEXT: call void @qux() -; CHECK-NEXT: call void @common() -; CHECK-NEXT: resume { i8*, i32 } [[LP]] +; CHECK-NEXT: br label [[COMMON_RESUME:%.*]] ; CHECK: resume1: ; CHECK-NEXT: call void @quux() -; CHECK-NEXT: call void @common() -; CHECK-NEXT: resume { i8*, i32 } [[LP]] +; CHECK-NEXT: br label [[COMMON_RESUME]] ; CHECK: resume2: -; CHECK-NEXT: [[SEMICOMMON_LP:%.*]] = phi { i8*, i32 } [ [[LP2]], [[LPAD2]] ], [ [[LP3]], [[LPAD3]] ] +; CHECK-NEXT: [[SEMICOMMON_LP]] = phi { i8*, i32 } [ [[LP2]], [[LPAD2]] ], [ [[LP3]], [[LPAD3]] ] ; CHECK-NEXT: call void @quuz() -; CHECK-NEXT: call void @common() -; CHECK-NEXT: resume { i8*, i32 } [[SEMICOMMON_LP]] +; CHECK-NEXT: br label [[COMMON_RESUME]] ; invoke void @maybe_throws() to label %invoke.cont unwind label %lpad