1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=jump-threading -S < %s | FileCheck %s 3 4declare i32 @f1() 5declare i32 @f2() 6declare void @f3() 7 8define i32 @test1(i1 %cond) { 9; CHECK-LABEL: @test1( 10; CHECK-NEXT: br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]] 11; CHECK: T2: 12; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() 13; CHECK-NEXT: call void @f3() 14; CHECK-NEXT: ret i32 [[V1]] 15; CHECK: F2: 16; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() 17; CHECK-NEXT: ret i32 [[V2]] 18; 19 br i1 %cond, label %T1, label %F1 20 21T1: 22 %v1 = call i32 @f1() 23 br label %Merge 24 25F1: 26 %v2 = call i32 @f2() 27 br label %Merge 28 29Merge: 30 %A = phi i1 [true, %T1], [false, %F1] 31 %B = phi i32 [%v1, %T1], [%v2, %F1] 32 %A.fr = freeze i1 %A 33 br i1 %A.fr, label %T2, label %F2 34 35T2: 36 call void @f3() 37 ret i32 %B 38 39F2: 40 ret i32 %B 41} 42 43define i32 @test1_cast(i1 %cond) { 44; CHECK-LABEL: @test1_cast( 45; CHECK-NEXT: br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]] 46; CHECK: T2: 47; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() 48; CHECK-NEXT: call void @f3() 49; CHECK-NEXT: ret i32 [[V1]] 50; CHECK: F2: 51; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() 52; CHECK-NEXT: [[A:%.*]] = trunc i32 0 to i1 53; CHECK-NEXT: ret i32 [[V2]] 54; 55 br i1 %cond, label %T1, label %F1 56 57T1: 58 %v1 = call i32 @f1() 59 br label %Merge 60 61F1: 62 %v2 = call i32 @f2() 63 br label %Merge 64 65Merge: 66 %A0 = phi i32 [1, %T1], [0, %F1] 67 %B = phi i32 [%v1, %T1], [%v2, %F1] 68 %A = trunc i32 %A0 to i1 69 %A.fr = freeze i1 %A 70 br i1 %A.fr, label %T2, label %F2 71 72T2: 73 call void @f3() 74 ret i32 %B 75 76F2: 77 ret i32 %B 78} 79 80define i32 @test1_cast2(i1 %cond) { 81; CHECK-LABEL: @test1_cast2( 82; CHECK-NEXT: br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]] 83; CHECK: T2: 84; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() 85; CHECK-NEXT: call void @f3() 86; CHECK-NEXT: ret i32 [[V1]] 87; CHECK: F2: 88; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() 89; CHECK-NEXT: [[A0_FR:%.*]] = freeze i32 0 90; CHECK-NEXT: ret i32 [[V2]] 91; 92 br i1 %cond, label %T1, label %F1 93 94T1: 95 %v1 = call i32 @f1() 96 br label %Merge 97 98F1: 99 %v2 = call i32 @f2() 100 br label %Merge 101 102Merge: 103 %A0 = phi i32 [1, %T1], [0, %F1] 104 %B = phi i32 [%v1, %T1], [%v2, %F1] 105 %A0.fr = freeze i32 %A0 106 %A.fr = trunc i32 %A0.fr to i1 107 br i1 %A.fr, label %T2, label %F2 108 109T2: 110 call void @f3() 111 ret i32 %B 112 113F2: 114 ret i32 %B 115} 116 117define i32 @test1_undef(i1 %cond) { 118; CHECK-LABEL: @test1_undef( 119; CHECK-NEXT: br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]] 120; CHECK: T2: 121; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() 122; CHECK-NEXT: call void @f3() 123; CHECK-NEXT: ret i32 [[V1]] 124; CHECK: F2: 125; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() 126; CHECK-NEXT: ret i32 [[V2]] 127; 128 br i1 %cond, label %T1, label %F1 129 130T1: 131 %v1 = call i32 @f1() 132 br label %Merge 133 134F1: 135 %v2 = call i32 @f2() 136 br label %Merge 137 138Merge: 139 %A = phi i1 [true, %T1], [undef, %F1] 140 %B = phi i32 [%v1, %T1], [%v2, %F1] 141 %A.fr = freeze i1 %A 142 br i1 %A.fr, label %T2, label %F2 143 144T2: 145 call void @f3() 146 ret i32 %B 147 148F2: 149 ret i32 %B 150} 151 152define i32 @test2(i1 %cond, i1 %cond2) { 153; CHECK-LABEL: @test2( 154; CHECK-NEXT: br i1 [[COND:%.*]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]] 155; CHECK: Merge.thread: 156; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() 157; CHECK-NEXT: br label [[T2:%.*]] 158; CHECK: Merge: 159; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() 160; CHECK-NEXT: [[A_FR:%.*]] = freeze i1 [[COND2:%.*]] 161; CHECK-NEXT: br i1 [[A_FR]], label [[T2]], label [[F2:%.*]] 162; CHECK: T2: 163; CHECK-NEXT: [[B4:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ] 164; CHECK-NEXT: call void @f3() 165; CHECK-NEXT: ret i32 [[B4]] 166; CHECK: F2: 167; CHECK-NEXT: ret i32 [[V2]] 168; 169 br i1 %cond, label %T1, label %F1 170 171T1: 172 %v1 = call i32 @f1() 173 br label %Merge 174 175F1: 176 %v2 = call i32 @f2() 177 br label %Merge 178 179Merge: 180 %A = phi i1 [true, %T1], [%cond2, %F1] 181 %B = phi i32 [%v1, %T1], [%v2, %F1] 182 %A.fr = freeze i1 %A 183 br i1 %A.fr, label %T2, label %F2 184 185T2: 186 call void @f3() 187 ret i32 %B 188 189F2: 190 ret i32 %B 191} 192 193define i32 @freeze_known_predicate(i1 %cond) { 194; CHECK-LABEL: @freeze_known_predicate( 195; CHECK-NEXT: entry: 196; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE2:%.*]] 197; CHECK: if: 198; CHECK-NEXT: br label [[ELSE2]] 199; CHECK: else2: 200; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF]] ], [ 2, [[ENTRY:%.*]] ] 201; CHECK-NEXT: ret i32 1 202; 203entry: 204 br i1 %cond, label %if, label %join 205 206if: 207 br label %join 208 209join: 210 %phi = phi i32 [ 1, %if ], [ 2, %entry ] 211 %cmp = icmp eq i32 %phi, 0 212 %cmp.fr = freeze i1 %cmp 213 br i1 %cmp.fr, label %if2, label %else2 214 215if2: 216 ret i32 0 217 218else2: 219 ret i32 1 220} 221 222define i32 @freeze_known_predicate_barrier(i1 %cond) { 223; CHECK-LABEL: @freeze_known_predicate_barrier( 224; CHECK-NEXT: entry: 225; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE2:%.*]] 226; CHECK: if: 227; CHECK-NEXT: br label [[ELSE2]] 228; CHECK: else2: 229; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF]] ], [ 2, [[ENTRY:%.*]] ] 230; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[PHI]], 0 231; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f1() 232; CHECK-NEXT: ret i32 1 233; 234entry: 235 br i1 %cond, label %if, label %join 236 237if: 238 br label %join 239 240join: 241 %phi = phi i32 [ 1, %if ], [ 2, %entry ] 242 %cmp = icmp eq i32 %phi, 0 243 %cmp.fr = freeze i1 %cmp 244 call i32 @f1() 245 br i1 %cmp.fr, label %if2, label %else2 246 247if2: 248 ret i32 0 249 250else2: 251 ret i32 1 252} 253