1 ; RUN: opt < %s -simplifycfg -S > %t 2 ; RUN: not grep {^BB.tomerge} %t 3 ; RUN: grep {^BB.nomerge} %t | count 2 4 5 ; ModuleID = '<stdin>' 6 declare i1 @foo() 7 8 declare i1 @bar(i32) 9 10 ; This function can't be merged 11 define void @a() { 12 entry: 13 br label %BB.nomerge 14 15 BB.nomerge: ; preds = %Common, %entry 16 ; This phi has a conflicting value (0) with below phi (2), so blocks 17 ; can't be merged. 18 %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1] 19 br label %Succ 20 21 Succ: ; preds = %Common, %BB.nomerge 22 %b = phi i32 [ %a, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0] 23 %conde = call i1 @foo( ) ; <i1> [#uses=1] 24 br i1 %conde, label %Common, label %Exit 25 26 Common: ; preds = %Succ 27 %cond = call i1 @foo( ) ; <i1> [#uses=1] 28 br i1 %cond, label %BB.nomerge, label %Succ 29 30 Exit: ; preds = %Succ 31 ret void 32 } 33 34 ; This function can't be merged 35 define void @b() { 36 entry: 37 br label %BB.nomerge 38 39 BB.nomerge: ; preds = %Common, %entry 40 br label %Succ 41 42 Succ: ; preds = %Common, %BB.nomerge 43 ; This phi has confliction values for Common and (through BB) Common, 44 ; blocks can't be merged 45 %b = phi i32 [ 1, %BB.nomerge ], [ 2, %Common ] ; <i32> [#uses=0] 46 %conde = call i1 @foo( ) ; <i1> [#uses=1] 47 br i1 %conde, label %Common, label %Exit 48 49 Common: ; preds = %Succ 50 %cond = call i1 @foo( ) ; <i1> [#uses=1] 51 br i1 %cond, label %BB.nomerge, label %Succ 52 53 Exit: ; preds = %Succ 54 ret void 55 } 56 57 ; This function can be merged 58 define void @c() { 59 entry: 60 br label %BB.tomerge 61 62 BB.tomerge: ; preds = %Common, %entry 63 br label %Succ 64 65 Succ: ; preds = %Common, %BB.tomerge, %Pre-Exit 66 ; This phi has identical values for Common and (through BB) Common, 67 ; blocks can't be merged 68 %b = phi i32 [ 1, %BB.tomerge ], [ 1, %Common ], [ 2, %Pre-Exit ] 69 %conde = call i1 @foo( ) ; <i1> [#uses=1] 70 br i1 %conde, label %Common, label %Pre-Exit 71 72 Common: ; preds = %Succ 73 %cond = call i1 @foo( ) ; <i1> [#uses=1] 74 br i1 %cond, label %BB.tomerge, label %Succ 75 76 Pre-Exit: ; preds = %Succ 77 ; This adds a backedge, so the %b phi node gets a third branch and is 78 ; not completely trivial 79 %cond2 = call i1 @foo( ) ; <i1> [#uses=1] 80 br i1 %cond2, label %Succ, label %Exit 81 82 Exit: ; preds = %Pre-Exit 83 ret void 84 } 85 86 ; This function can be merged 87 define void @d() { 88 entry: 89 br label %BB.tomerge 90 91 BB.tomerge: ; preds = %Common, %entry 92 ; This phi has a matching value (0) with below phi (0), so blocks 93 ; can be merged. 94 %a = phi i32 [ 1, %entry ], [ 0, %Common ] ; <i32> [#uses=1] 95 br label %Succ 96 97 Succ: ; preds = %Common, %BB.tomerge 98 %b = phi i32 [ %a, %BB.tomerge ], [ 0, %Common ] ; <i32> [#uses=0] 99 %conde = call i1 @foo( ) ; <i1> [#uses=1] 100 br i1 %conde, label %Common, label %Exit 101 102 Common: ; preds = %Succ 103 %cond = call i1 @foo( ) ; <i1> [#uses=1] 104 br i1 %cond, label %BB.tomerge, label %Succ 105 106 Exit: ; preds = %Succ 107 ret void 108 } 109 110 ; This function can be merged 111 define void @e() { 112 entry: 113 br label %BB.tomerge 114 115 BB.tomerge: ; preds = %Use, %entry 116 ; This phi is used somewhere else than Succ, but this should not prevent 117 ; merging this block 118 %a = phi i32 [ 1, %entry ], [ 0, %Use ] ; <i32> [#uses=1] 119 br label %Succ 120 121 Succ: ; preds = %BB.tomerge 122 %conde = call i1 @foo( ) ; <i1> [#uses=1] 123 br i1 %conde, label %Use, label %Exit 124 125 Use: ; preds = %Succ 126 %cond = call i1 @bar( i32 %a ) ; <i1> [#uses=1] 127 br i1 %cond, label %BB.tomerge, label %Exit 128 129 Exit: ; preds = %Use, %Succ 130 ret void 131 } 132