1; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -verify-memoryssa -S %s | FileCheck %s 2; REQUIRES: asserts 3 4target triple = "x86_64-unknown-linux-gnu" 5 6declare void @foo() 7 8; In Test1, there are no definitions. MemorySSA updates insert trivial phis and remove them. 9; Verify all are removed, considering the SLU pass leaves unreachable blocks hanging when the MSSA updates are done. 10; CHECK-LABEL: @Test1 11define void @Test1(i32) { 12header: 13 br label %outer 14 15outer.loopexit.split: ; preds = %continue 16 br label %outer.loopexit 17 18outer.loopexit: ; preds = %outer.loopexit.split.us, %outer.loopexit.split 19 br label %outer 20 21outer: ; preds = %outer.loopexit, %header 22 br i1 false, label %outer.split.us, label %outer.split 23 24outer.split.us: ; preds = %outer 25 br label %inner.us 26 27inner.us: ; preds = %continue.us, %outer.split.us 28 br label %overflow.us 29 30overflow.us: ; preds = %inner.us 31 br label %continue.us 32 33continue.us: ; preds = %overflow.us 34 br i1 true, label %outer.loopexit.split.us, label %inner.us 35 36outer.loopexit.split.us: ; preds = %continue.us 37 br label %outer.loopexit 38 39outer.split: ; preds = %outer 40 br label %inner 41 42inner: ; preds = %continue, %outer.split 43 br label %switchme 44 45switchme: ; preds = %inner 46 switch i32 %0, label %continue [ 47 i32 88, label %go_out 48 i32 99, label %case2 49 ] 50 51case2: ; preds = %switchme 52 br label %continue 53 54continue: ; preds = %case2, %switchme 55 br i1 true, label %outer.loopexit.split, label %inner 56 57go_out: ; preds = %switchme 58 unreachable 59} 60 61; In Test2 there is a single def (call to foo). There are already Phis in place that are cloned when unswitching. 62; Ensure MemorySSA remains correct. Due to SLU's pruned cloning, continue.us2 becomes unreachable, with an empty Phi that is later cleaned. 63; CHECK-LABEL: @Test2 64define void @Test2(i32) { 65header: 66 br label %outer 67 68outer.loopexit.split: ; preds = %continue 69 br label %outer.loopexit 70 71outer.loopexit: ; preds = %outer.loopexit.split.us, %outer.loopexit.split 72 br label %outer 73 74outer: ; preds = %outer.loopexit, %header 75 br i1 false, label %outer.split.us, label %outer.split 76 77outer.split.us: ; preds = %outer 78 br label %inner.us 79 80inner.us: ; preds = %continue.us, %outer.split.us 81 br label %overflow.us 82 83overflow.us: ; preds = %inner.us 84 br label %continue.us 85 86continue.us: ; preds = %overflow.us 87 br i1 true, label %outer.loopexit.split.us, label %inner.us 88 89outer.loopexit.split.us: ; preds = %continue.us 90 br label %outer.loopexit 91 92outer.split: ; preds = %outer 93 br label %inner 94 95inner: ; preds = %continue, %outer.split 96 br label %switchme 97 98switchme: ; preds = %inner 99 switch i32 %0, label %continue [ 100 i32 88, label %go_out 101 i32 99, label %case2 102 ] 103 104case2: ; preds = %switchme 105 call void @foo() 106 br label %continue 107 108continue: ; preds = %case2, %switchme 109 br i1 true, label %outer.loopexit.split, label %inner 110 111go_out: ; preds = %switchme 112 unreachable 113} 114