1 ; RUN: opt -jump-threading -S -verify < %s | FileCheck %s 2 3 declare i32 @f1() 4 declare i32 @f2() 5 declare void @f3() 6 declare 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 ] 15 define void @test_br_folding_not_threading_update_phi(i32 %val) nounwind { 16 entry: 17 %cmp = icmp eq i32 %val, 32 18 br i1 %cmp, label %L0, label %L1 19 L0: 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 38 L1: 39 %res.0 = phi i32 [ 0, %L0 ], [ 0, %L0 ], [1, %entry] 40 call void @f4(i32 %res.0) 41 ret void 42 L2: 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: 57 define void @test_br_folding_not_threading(i1 %cond) nounwind { 58 entry: 59 br i1 %cond, label %L0, label %L3 60 L0: 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 76 L1: 77 call void @f3() 78 ret void 79 L2: 80 call void @f3() 81 ret void 82 L3: 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: 99 define void @test_br_folding_not_threading_multiple_preds(i1 %condx, i1 %cond) nounwind { 100 entry: 101 br i1 %condx, label %X0, label %X1 102 103 X0: 104 br i1 %cond, label %L0, label %L3 105 106 X1: 107 br i1 %cond, label %L0, label %L3 108 109 L0: 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 125 L1: 126 call void @f3() 127 ret void 128 L2: 129 call void @f3() 130 ret void 131 L3: 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) 140 define void @rauw_if_possible(i32 %value) nounwind { 141 entry: 142 %cmp = icmp eq i32 %value, 32 143 br i1 %cmp, label %L0, label %L3 144 L0: 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 153 L1: 154 call void @f3() 155 ret void 156 L2: 157 call void @f4(i32 %add) 158 ret void 159 L3: 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) 168 define void @rauw_if_possible2(i32 %value) nounwind { 169 entry: 170 %cmp = icmp eq i32 %value, 32 171 %add = add i32 %value, 64 172 br i1 %cmp, label %L0, label %L2 173 L0: 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 181 L1: 182 call void @f3() 183 ret void 184 L2: 185 call void @f4(i32 %add) 186 ret void 187 L3: 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: 206 define void @test_br_folding_not_threading_indirect_branch(i1 %condx, i1 %cond) nounwind { 207 entry: 208 br i1 %condx, label %X0, label %X1 209 210 X0: 211 br i1 %cond, label %L0, label %L3 212 213 X1: 214 br i1 %cond, label %XX1, label %L3 215 216 XX1: 217 indirectbr i8* blockaddress(@test_br_folding_not_threading_indirect_branch, %L0), [label %L0] 218 219 L0: 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 235 L1: 236 call void @f3() 237 ret void 238 239 L2: 240 call void @f3() 241 ret void 242 243 L3: 244 call void @f3() 245 ret void 246 } 247