; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -verify-memoryssa -S %s | FileCheck %s ; REQUIRES: asserts target triple = "x86_64-unknown-linux-gnu" declare void @foo() ; In Test1, there are no definitions. MemorySSA updates insert trivial phis and remove them. ; Verify all are removed, considering the SLU pass leaves unreachable blocks hanging when the MSSA updates are done. ; CHECK-LABEL: @Test1 define void @Test1(i32) { header: br label %outer outer.loopexit.split: ; preds = %continue br label %outer.loopexit outer.loopexit: ; preds = %outer.loopexit.split.us, %outer.loopexit.split br label %outer outer: ; preds = %outer.loopexit, %header br i1 false, label %outer.split.us, label %outer.split outer.split.us: ; preds = %outer br label %inner.us inner.us: ; preds = %continue.us, %outer.split.us br label %overflow.us overflow.us: ; preds = %inner.us br label %continue.us continue.us: ; preds = %overflow.us br i1 true, label %outer.loopexit.split.us, label %inner.us outer.loopexit.split.us: ; preds = %continue.us br label %outer.loopexit outer.split: ; preds = %outer br label %inner inner: ; preds = %continue, %outer.split br label %switchme switchme: ; preds = %inner switch i32 %0, label %continue [ i32 88, label %go_out i32 99, label %case2 ] case2: ; preds = %switchme br label %continue continue: ; preds = %case2, %switchme br i1 true, label %outer.loopexit.split, label %inner go_out: ; preds = %switchme unreachable } ; In Test2 there is a single def (call to foo). There are already Phis in place that are cloned when unswitching. ; Ensure MemorySSA remains correct. Due to SLU's pruned cloning, continue.us2 becomes unreachable, with an empty Phi that is later cleaned. ; CHECK-LABEL: @Test2 define void @Test2(i32) { header: br label %outer outer.loopexit.split: ; preds = %continue br label %outer.loopexit outer.loopexit: ; preds = %outer.loopexit.split.us, %outer.loopexit.split br label %outer outer: ; preds = %outer.loopexit, %header br i1 false, label %outer.split.us, label %outer.split outer.split.us: ; preds = %outer br label %inner.us inner.us: ; preds = %continue.us, %outer.split.us br label %overflow.us overflow.us: ; preds = %inner.us br label %continue.us continue.us: ; preds = %overflow.us br i1 true, label %outer.loopexit.split.us, label %inner.us outer.loopexit.split.us: ; preds = %continue.us br label %outer.loopexit outer.split: ; preds = %outer br label %inner inner: ; preds = %continue, %outer.split br label %switchme switchme: ; preds = %inner switch i32 %0, label %continue [ i32 88, label %go_out i32 99, label %case2 ] case2: ; preds = %switchme call void @foo() br label %continue continue: ; preds = %case2, %switchme br i1 true, label %outer.loopexit.split, label %inner go_out: ; preds = %switchme unreachable }