Index: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp =================================================================== --- lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -2006,9 +2006,17 @@ LPM.markLoopAsDeleted(*L); }; + assert(!L->isInvalid() && "Unswitching invalid loop?"); bool Changed = unswitchLoop(*L, DT, LI, AC, TTI, NonTrivial, UnswitchCB); + // We might have done structural changes to a CFG that may break cached + // invariants in SCEV for this and any outer loop. + // FIXME: Is it OK that unswitching produces invalid loops?! + if (Changed && !L->isInvalid()) + if (auto *SEWP = getAnalysisIfAvailable()) + SEWP->getSE().forgetTopmostLoop(L); + // If anything was unswitched, also clear any cached information about this // loop. LPM.deleteSimpleAnalysisLoop(L); Index: test/Transforms/SimpleLoopUnswitch/invalidate_scev.ll =================================================================== --- test/Transforms/SimpleLoopUnswitch/invalidate_scev.ll +++ test/Transforms/SimpleLoopUnswitch/invalidate_scev.ll @@ -0,0 +1,34 @@ +; RUN: opt -iv-users -simple-loop-unswitch -indvars -S < %s | FileCheck %s +; PR37651 + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + + +; Make sure that SCEV gets invalidated properly after simple unswitching. +define void @f1() { + +; CHECK-LABEL: @f1 + +vector.ph: + br label %bb3 + +bb3: ; preds = %bb13, %vector.ph + %_tmp5329 = phi i8 [ %_tmp54, %bb13 ], [ undef, %vector.ph ] + %_tmp40 = icmp eq i8 undef, 0 + br label %bb11 + +bb11: ; preds = %bb12, %bb3 + br i1 %_tmp40, label %bb12, label %bb13 + +bb12: ; preds = %bb11 + br i1 false, label %bb11, label %bb13 + +bb13: ; preds = %bb12, %bb11 + %_tmp54 = add nsw i8 %_tmp5329, 1 + %_tmp57 = icmp eq i8 %_tmp54, 0 + br i1 %_tmp57, label %bb14.loopexit, label %bb3 + +bb14.loopexit: ; preds = %bb13 + ret void +}