diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1434,11 +1434,14 @@ // Check if only hoisting terminators is allowed. This does not add new // instructions to the hoist location. if (EqTermsOnly) { - if (!I1->isIdenticalToWhenDefined(I2)) + // Skip any debug intrinsics, as they are free to hoist. + auto *I1NonDbg = &*skipDebugIntrinsics(I1->getIterator()); + auto *I2NonDbg = &*skipDebugIntrinsics(I2->getIterator()); + if (!I1NonDbg->isIdenticalToWhenDefined(I2NonDbg)) return false; - if (!I1->isTerminator()) + if (!I2NonDbg->isTerminator()) return false; - goto HoistTerminator; + // Now we know that we only need to hoist debug instrinsics and the terminator. Let the loop below handle those 2 cases. } do { diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll b/llvm/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll --- a/llvm/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll +++ b/llvm/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll @@ -45,8 +45,10 @@ ; CHECK-LABEL: @hoist_with_debug2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp ugt i32 [[X:%.*]], 2 -; CHECK-NEXT: [[P:%.*]] = select i1 [[TOBOOL_NOT]], i1 false, i1 true -; CHECK-NEXT: ret i1 [[P]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[X]], metadata [[META21:![0-9]+]], metadata !DIExpression()), !dbg [[DBG23:![0-9]+]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[X]], metadata [[META21]], metadata !DIExpression()), !dbg [[DBG23]] +; CHECK-NEXT: [[DOT:%.*]] = select i1 [[TOBOOL_NOT]], i1 false, i1 true +; CHECK-NEXT: ret i1 [[DOT]] ; entry: %tobool.not = icmp ugt i32 %x, 2 @@ -72,15 +74,11 @@ ; CHECK-NEXT: br label [[FOR_COND:%.*]] ; CHECK: for.cond: ; CHECK-NEXT: [[C_0:%.*]] = icmp sgt i32 [[X:%.*]], 0 -; CHECK-NEXT: br i1 [[C_0]], label [[CHECK:%.*]], label [[LATCH:%.*]] -; CHECK: check: -; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i32 [[X]], 2 -; CHECK-NEXT: br label [[EXIT_1:%.*]] -; CHECK: latch: -; CHECK-NEXT: br i1 [[C_2:%.*]], label [[EXIT_1]], label [[FOR_COND]] +; CHECK-NEXT: [[BRMERGE:%.*]] = or i1 [[C_0]], [[C_2:%.*]] +; CHECK-NEXT: [[DOTMUX:%.*]] = select i1 [[C_0]], i16 0, i16 20 +; CHECK-NEXT: br i1 [[BRMERGE]], label [[EXIT_1:%.*]], label [[FOR_COND]] ; CHECK: exit.1: -; CHECK-NEXT: [[MERGE:%.*]] = phi i16 [ 20, [[LATCH]] ], [ 0, [[CHECK]] ] -; CHECK-NEXT: ret i16 [[MERGE]] +; CHECK-NEXT: ret i16 [[DOTMUX]] ; entry: br label %for.cond