1; RUN: opt -jump-threading -S -verify < %s | FileCheck %s 2 3declare i32 @f1() 4declare i32 @f2() 5declare void @f3() 6declare void @f4(i32) 7 8 9; Make sure we update the phi node properly. 10; 11; CHECK-LABEL: define void @test_br_folding_not_threading_update_phi( 12; CHECK: br label %L1 13; Make sure we update the phi node properly here, i.e. we only have 2 predecessors, entry and L0 14; CHECK: %res.0 = phi i32 [ 0, %L0 ], [ 1, %entry ] 15define void @test_br_folding_not_threading_update_phi(i32 %val) nounwind { 16entry: 17 %cmp = icmp eq i32 %val, 32 18 br i1 %cmp, label %L0, label %L1 19L0: 20 call i32 @f2() 21 call i32 @f2() 22 call i32 @f2() 23 call i32 @f2() 24 call i32 @f2() 25 call i32 @f2() 26 call i32 @f2() 27 call i32 @f2() 28 call i32 @f2() 29 call i32 @f2() 30 call i32 @f2() 31 call i32 @f2() 32 call i32 @f2() 33 switch i32 %val, label %L2 [ 34 i32 0, label %L1 35 i32 32, label %L1 36 ] 37 38L1: 39 %res.0 = phi i32 [ 0, %L0 ], [ 0, %L0 ], [1, %entry] 40 call void @f4(i32 %res.0) 41 ret void 42L2: 43 call void @f3() 44 ret void 45} 46 47; Make sure we can fold this branch ... We will not be able to thread it as 48; L0 is too big to duplicate. L2 is the unreachable block here. 49; 50; CHECK-LABEL: @test_br_folding_not_threading( 51; CHECK: L1: 52; CHECK: call i32 @f2() 53; CHECK: call void @f3() 54; CHECK-NEXT: ret void 55; CHECK-NOT: br 56; CHECK: L3: 57define void @test_br_folding_not_threading(i1 %cond) nounwind { 58entry: 59 br i1 %cond, label %L0, label %L3 60L0: 61 call i32 @f2() 62 call i32 @f2() 63 call i32 @f2() 64 call i32 @f2() 65 call i32 @f2() 66 call i32 @f2() 67 call i32 @f2() 68 call i32 @f2() 69 call i32 @f2() 70 call i32 @f2() 71 call i32 @f2() 72 call i32 @f2() 73 call i32 @f2() 74 br i1 %cond, label %L1, label %L2 75 76L1: 77 call void @f3() 78 ret void 79L2: 80 call void @f3() 81 ret void 82L3: 83 call void @f3() 84 ret void 85} 86 87 88; Make sure we can fold this branch ... We will not be able to thread it as 89; L0 is too big to duplicate. L2 is the unreachable block here. 90; With more than 1 predecessors. 91; 92; CHECK-LABEL: @test_br_folding_not_threading_multiple_preds( 93; CHECK: L1: 94; CHECK: call i32 @f2() 95; CHECK: call void @f3() 96; CHECK-NEXT: ret void 97; CHECK-NOT: br 98; CHECK: L3: 99define void @test_br_folding_not_threading_multiple_preds(i1 %condx, i1 %cond) nounwind { 100entry: 101 br i1 %condx, label %X0, label %X1 102 103X0: 104 br i1 %cond, label %L0, label %L3 105 106X1: 107 br i1 %cond, label %L0, label %L3 108 109L0: 110 call i32 @f2() 111 call i32 @f2() 112 call i32 @f2() 113 call i32 @f2() 114 call i32 @f2() 115 call i32 @f2() 116 call i32 @f2() 117 call i32 @f2() 118 call i32 @f2() 119 call i32 @f2() 120 call i32 @f2() 121 call i32 @f2() 122 call i32 @f2() 123 br i1 %cond, label %L1, label %L2 124 125L1: 126 call void @f3() 127 ret void 128L2: 129 call void @f3() 130 ret void 131L3: 132 call void @f3() 133 ret void 134} 135 136; Make sure we can do the RAUW for %add... 137; 138; CHECK-LABEL: @rauw_if_possible( 139; CHECK: call void @f4(i32 96) 140define void @rauw_if_possible(i32 %value) nounwind { 141entry: 142 %cmp = icmp eq i32 %value, 32 143 br i1 %cmp, label %L0, label %L3 144L0: 145 call i32 @f2() 146 call i32 @f2() 147 %add = add i32 %value, 64 148 switch i32 %add, label %L3 [ 149 i32 32, label %L1 150 i32 96, label %L2 151 ] 152 153L1: 154 call void @f3() 155 ret void 156L2: 157 call void @f4(i32 %add) 158 ret void 159L3: 160 call void @f3() 161 ret void 162} 163 164; Make sure we can NOT do the RAUW for %add... 165; 166; CHECK-LABEL: @rauw_if_possible2( 167; CHECK: call void @f4(i32 %add) 168define void @rauw_if_possible2(i32 %value) nounwind { 169entry: 170 %cmp = icmp eq i32 %value, 32 171 %add = add i32 %value, 64 172 br i1 %cmp, label %L0, label %L2 173L0: 174 call i32 @f2() 175 call i32 @f2() 176 switch i32 %add, label %L3 [ 177 i32 32, label %L1 178 i32 96, label %L2 179 ] 180 181L1: 182 call void @f3() 183 ret void 184L2: 185 call void @f4(i32 %add) 186 ret void 187L3: 188 call void @f3() 189 ret void 190} 191 192; Make sure we can fold this branch ... We will not be able to thread it as 193; L0 is too big to duplicate. 194; We do not attempt to rewrite the indirectbr target here, but we still take 195; its target after L0 into account and that enables us to fold. 196; 197; L2 is the unreachable block here. 198; 199; CHECK-LABEL: @test_br_folding_not_threading_indirect_branch( 200; CHECK: L1: 201; CHECK: call i32 @f2() 202; CHECK: call void @f3() 203; CHECK-NEXT: ret void 204; CHECK-NOT: br 205; CHECK: L3: 206define void @test_br_folding_not_threading_indirect_branch(i1 %condx, i1 %cond) nounwind { 207entry: 208 br i1 %condx, label %X0, label %X1 209 210X0: 211 br i1 %cond, label %L0, label %L3 212 213X1: 214 br i1 %cond, label %XX1, label %L3 215 216XX1: 217 indirectbr i8* blockaddress(@test_br_folding_not_threading_indirect_branch, %L0), [label %L0] 218 219L0: 220 call i32 @f2() 221 call i32 @f2() 222 call i32 @f2() 223 call i32 @f2() 224 call i32 @f2() 225 call i32 @f2() 226 call i32 @f2() 227 call i32 @f2() 228 call i32 @f2() 229 call i32 @f2() 230 call i32 @f2() 231 call i32 @f2() 232 call i32 @f2() 233 br i1 %cond, label %L1, label %L2 234 235L1: 236 call void @f3() 237 ret void 238 239L2: 240 call void @f3() 241 ret void 242 243L3: 244 call void @f3() 245 ret void 246} 247