Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -48,6 +48,7 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" +#include "llvm/Analysis/LoopPass.h" #include using namespace llvm; using namespace PatternMatch; @@ -691,6 +692,7 @@ AU.addPreserved(); AU.addPreserved(); + AU.addRequired(); } @@ -736,6 +738,7 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_END(GVN, "gvn", "Global Value Numbering", false, false) #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) Index: lib/Transforms/Utils/BreakCriticalEdges.cpp =================================================================== --- lib/Transforms/Utils/BreakCriticalEdges.cpp +++ lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -150,6 +150,14 @@ BasicBlock *TIBB = TI->getParent(); BasicBlock *DestBB = TI->getSuccessor(SuccNum); + LoopInfo *LI = P ? P->getAnalysisIfAvailable() : nullptr; + + Loop *TIBBLoop = LI ? LI->getLoopFor(TIBB) : nullptr; + Loop *DestBBLoop = LI ? LI->getLoopFor(DestBB) : nullptr; + + MDNode *TILoopMD = TIBBLoop ? TIBBLoop->getLoopID() : nullptr; + MDNode *DestLoopMD = DestBBLoop ? DestBBLoop->getLoopID() : nullptr; + // Splitting the critical edge to a landing pad block is non-trivial. Don't do // it in this generic function. if (DestBB->isLandingPad()) return nullptr; @@ -205,15 +213,12 @@ } } - - // If we don't have a pass object, we can't update anything... if (!P) return NewBB; DominatorTreeWrapperPass *DTWP = P->getAnalysisIfAvailable(); DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; - LoopInfo *LI = P->getAnalysisIfAvailable(); // If we have nothing to update, just return. if (!DT && !LI) @@ -351,6 +356,12 @@ "SplitCriticalEdge doesn't know how to update LCCSA form " "without LoopSimplify!"); } + // Loop metadata are stored in the loop latch branch. + // If loops latches were changed let's update new latches metadata. + if (TILoopMD) + TIBBLoop->setLoopID(TILoopMD); + if (DestLoopMD && DestBBLoop != TIBBLoop) + DestBBLoop->setLoopID(DestLoopMD); } return NewBB; Index: test/Transforms/LoopVectorize/vect.omp.persistence.gvn.ll =================================================================== --- /dev/null +++ test/Transforms/LoopVectorize/vect.omp.persistence.gvn.ll @@ -0,0 +1,41 @@ +; RUN: opt < %s -basicaa -gvn -S 2>&1 | FileCheck %s + +; CHECK-LABEL: @test_gvn +; CHECK-LABEL: for.body: +; Find a branch to critical edge +; CHECK: br {{.*}} %[[CE:[^_ ]+]]_crit_edge +; BB where critical edge was found +; CHECK: [[CE]]_crit_edge: +; Check that OMP SIMD branch metadata survived after critical edge splitting +; CHECK: br label %for.body, !llvm.loop !0 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; +; Ensure that "llvm.loop.vectorize.enable" metadata were not lost after GVN splitted critical edges. +; In past splitting critical edges was leading to clearing that metadata. +; + +define i64 @test_gvn(i64* nocapture readonly %a, i64* nocapture readonly %b) { +entry: + %0 = load i64* %b, align 4, !llvm.mem.parallel_loop_access !0 + br label %for.body +for.body: + %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i64* %a, i64 %i.0 + %1 = load i64* %arrayidx, align 4, !llvm.mem.parallel_loop_access !1 + %arrayidx2 = getelementptr inbounds i64* %b, i64 %i.0 + %2 = load i64* %arrayidx2, align 4, !llvm.mem.parallel_loop_access !1 + %cmp3 = icmp sgt i64 %1, %2 + %add16 = select i1 %cmp3, i64 0, i64 %2 + %inc = add nsw i64 %i.0, 1 + %add = add nsw i64 %0, %inc + %cmp = icmp slt i64 %i.0, %add + br i1 %cmp, label %for.body, label %for.end, !llvm.loop !0 +for.end: + ret i64 %inc +} + +!0 = metadata !{metadata !0, metadata !1} +!1 = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}