1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=print-predicateinfo -disable-output < %s 2>&1 | FileCheck %s 3 4@a = external global i32 ; <ptr> [#uses=7] 5 6define i32 @test1() nounwind { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4 10; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 4 11; CHECK-NEXT: br i1 [[TMP1]], label [[BB:%.*]], label [[BB1:%.*]] 12; CHECK: bb: 13; CHECK-NEXT: br label [[BB8:%.*]] 14; CHECK: bb1: 15; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @a, align 4 16; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 5 17; CHECK-NEXT: br i1 [[TMP3]], label [[BB2:%.*]], label [[BB3:%.*]] 18; CHECK: bb2: 19; CHECK-NEXT: br label [[BB8]] 20; CHECK: bb3: 21; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr @a, align 4 22; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 4 23; CHECK-NEXT: br i1 [[TMP5]], label [[BB4:%.*]], label [[BB5:%.*]] 24; CHECK: bb4: 25; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr @a, align 4 26; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 5 27; CHECK-NEXT: br label [[BB8]] 28; CHECK: bb5: 29; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr @a, align 4 30; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 5 31; CHECK-NEXT: br i1 [[TMP9]], label [[BB6:%.*]], label [[BB7:%.*]] 32; CHECK: bb6: 33; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr @a, align 4 34; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP10]], 4 35; CHECK-NEXT: br label [[BB8]] 36; CHECK: bb7: 37; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr @a, align 4 38; CHECK-NEXT: br label [[BB8]] 39; CHECK: bb8: 40; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP12]], [[BB7]] ], [ [[TMP11]], [[BB6]] ], [ [[TMP7]], [[BB4]] ], [ 4, [[BB2]] ], [ 5, [[BB]] ] 41; CHECK-NEXT: br label [[RETURN:%.*]] 42; CHECK: return: 43; CHECK-NEXT: ret i32 [[DOT0]] 44; 45entry: 46 %0 = load i32, ptr @a, align 4 47 %1 = icmp eq i32 %0, 4 48 br i1 %1, label %bb, label %bb1 49 50bb: ; preds = %entry 51 br label %bb8 52 53bb1: ; preds = %entry 54 %2 = load i32, ptr @a, align 4 55 %3 = icmp eq i32 %2, 5 56 br i1 %3, label %bb2, label %bb3 57 58bb2: ; preds = %bb1 59 br label %bb8 60 61bb3: ; preds = %bb1 62 %4 = load i32, ptr @a, align 4 63 %5 = icmp eq i32 %4, 4 64 br i1 %5, label %bb4, label %bb5 65 66bb4: ; preds = %bb3 67 %6 = load i32, ptr @a, align 4 68 %7 = add i32 %6, 5 69 br label %bb8 70 71bb5: ; preds = %bb3 72 %8 = load i32, ptr @a, align 4 73 %9 = icmp eq i32 %8, 5 74 br i1 %9, label %bb6, label %bb7 75 76bb6: ; preds = %bb5 77 %10 = load i32, ptr @a, align 4 78 %11 = add i32 %10, 4 79 br label %bb8 80 81bb7: ; preds = %bb5 82 %12 = load i32, ptr @a, align 4 83 br label %bb8 84 85bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb 86 %.0 = phi i32 [ %12, %bb7 ], [ %11, %bb6 ], [ %7, %bb4 ], [ 4, %bb2 ], [ 5, %bb ] 87 br label %return 88 89return: ; preds = %bb8 90 ret i32 %.0 91} 92 93declare void @foo(i1) 94declare void @bar(i32) 95 96define void @test3(i32 %x, i32 %y) { 97; CHECK-LABEL: @test3( 98; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0 99; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 100; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]] 101; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) 102; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]]) 103; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) 104; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]]) 105; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]]) 106; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]] 107; CHECK: both_zero: 108; CHECK-NEXT: call void @foo(i1 [[XZ_0]]) 109; CHECK-NEXT: call void @foo(i1 [[YZ_0]]) 110; CHECK-NEXT: call void @bar(i32 [[X_0]]) 111; CHECK-NEXT: call void @bar(i32 [[Y_0]]) 112; CHECK-NEXT: ret void 113; CHECK: nope: 114; CHECK-NEXT: call void @foo(i1 [[Z_0]]) 115; CHECK-NEXT: ret void 116; 117 %xz = icmp eq i32 %x, 0 118 %yz = icmp eq i32 %y, 0 119 %z = and i1 %xz, %yz 120 br i1 %z, label %both_zero, label %nope 121both_zero: 122 call void @foo(i1 %xz) 123 call void @foo(i1 %yz) 124 call void @bar(i32 %x) 125 call void @bar(i32 %y) 126 ret void 127nope: 128 call void @foo(i1 %z) 129 ret void 130} 131 132define void @test4(i1 %b, i32 %x) { 133; CHECK-LABEL: @test4( 134; CHECK-NEXT: br i1 [[B:%.*]], label [[SW:%.*]], label [[CASE3:%.*]] 135; CHECK: sw: 136; CHECK: i32 0, label [[CASE0:%.*]] 137; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 138; CHECK-NEXT: i32 2, label [[CASE0]] 139; CHECK-NEXT: i32 3, label [[CASE3]] 140; CHECK-NEXT: i32 4, label [[DEFAULT:%.*]] 141; CHECK-NEXT: ] Edge: [label [[SW]],label %case1], RenamedOp: [[X:%.*]] } 142; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) 143; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT]] [ 144; CHECK-NEXT: i32 0, label [[CASE0]] 145; CHECK-NEXT: i32 1, label [[CASE1]] 146; CHECK-NEXT: i32 2, label [[CASE0]] 147; CHECK-NEXT: i32 3, label [[CASE3]] 148; CHECK-NEXT: i32 4, label [[DEFAULT]] 149; CHECK-NEXT: ] 150; CHECK: default: 151; CHECK-NEXT: call void @bar(i32 [[X]]) 152; CHECK-NEXT: ret void 153; CHECK: case0: 154; CHECK-NEXT: call void @bar(i32 [[X]]) 155; CHECK-NEXT: ret void 156; CHECK: case1: 157; CHECK-NEXT: call void @bar(i32 [[X_0]]) 158; CHECK-NEXT: ret void 159; CHECK: case3: 160; CHECK-NEXT: call void @bar(i32 [[X]]) 161; CHECK-NEXT: ret void 162; 163 br i1 %b, label %sw, label %case3 164sw: 165 switch i32 %x, label %default [ 166 i32 0, label %case0 167 i32 1, label %case1 168 i32 2, label %case0 169 i32 3, label %case3 170 i32 4, label %default 171 ] 172default: 173 call void @bar(i32 %x) 174 ret void 175case0: 176 call void @bar(i32 %x) 177 ret void 178case1: 179 call void @bar(i32 %x) 180 ret void 181case3: 182 call void @bar(i32 %x) 183 ret void 184} 185 186define i1 @test5(i32 %x, i32 %y) { 187; CHECK-LABEL: @test5( 188; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 189; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]]) 190; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]]) 191; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]]) 192; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]]) 193; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 194; CHECK: same: 195; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X_0]], [[Y_0]] 196; CHECK-NEXT: ret i1 [[CMP2]] 197; CHECK: different: 198; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X_1]], [[Y_1]] 199; CHECK-NEXT: ret i1 [[CMP3]] 200; 201 %cmp = icmp eq i32 %x, %y 202 br i1 %cmp, label %same, label %different 203 204same: 205 %cmp2 = icmp ne i32 %x, %y 206 ret i1 %cmp2 207 208different: 209 %cmp3 = icmp eq i32 %x, %y 210 ret i1 %cmp3 211} 212 213define i1 @test6(i32 %x, i32 %y) { 214; CHECK-LABEL: @test6( 215; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]] 216; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] 217; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X]], [[Y]] 218; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 219; CHECK: same: 220; CHECK-NEXT: ret i1 [[CMP2]] 221; CHECK: different: 222; CHECK-NEXT: ret i1 [[CMP3]] 223; 224 %cmp2 = icmp ne i32 %x, %y 225 %cmp = icmp eq i32 %x, %y 226 %cmp3 = icmp eq i32 %x, %y 227 br i1 %cmp, label %same, label %different 228 229same: 230 ret i1 %cmp2 231 232different: 233 ret i1 %cmp3 234} 235 236define i1 @test6_fp(float %x, float %y) { 237; CHECK-LABEL: @test6_fp( 238; CHECK-NEXT: [[CMP2:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]] 239; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X]], [[Y]] 240; CHECK-NEXT: [[CMP3:%.*]] = fcmp oeq float [[X]], [[Y]] 241; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 242; CHECK: same: 243; CHECK-NEXT: ret i1 [[CMP2]] 244; CHECK: different: 245; CHECK-NEXT: ret i1 [[CMP3]] 246; 247 %cmp2 = fcmp une float %x, %y 248 %cmp = fcmp oeq float %x, %y 249 %cmp3 = fcmp oeq float %x, %y 250 br i1 %cmp, label %same, label %different 251 252same: 253 ret i1 %cmp2 254 255different: 256 ret i1 %cmp3 257} 258 259define i1 @test7(i32 %x, i32 %y) { 260; CHECK-LABEL: @test7( 261; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 262; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]]) 263; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]]) 264; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]]) 265; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]]) 266; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 267; CHECK: same: 268; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X_0]], [[Y_0]] 269; CHECK-NEXT: ret i1 [[CMP2]] 270; CHECK: different: 271; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[X_1]], [[Y_1]] 272; CHECK-NEXT: ret i1 [[CMP3]] 273; 274 %cmp = icmp sgt i32 %x, %y 275 br i1 %cmp, label %same, label %different 276 277same: 278 %cmp2 = icmp sle i32 %x, %y 279 ret i1 %cmp2 280 281different: 282 %cmp3 = icmp sgt i32 %x, %y 283 ret i1 %cmp3 284} 285 286define i1 @test7_fp(float %x, float %y) { 287; CHECK-LABEL: @test7_fp( 288; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]] 289; CHECK: [[X_0:%.*]] = call float @llvm.ssa.copy.f32(float [[X]]) 290; CHECK: [[X_1:%.*]] = call float @llvm.ssa.copy.f32(float [[X]]) 291; CHECK: [[Y_0:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]]) 292; CHECK: [[Y_1:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]]) 293; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 294; CHECK: same: 295; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X_0]], [[Y_0]] 296; CHECK-NEXT: ret i1 [[CMP2]] 297; CHECK: different: 298; CHECK-NEXT: [[CMP3:%.*]] = fcmp ogt float [[X_1]], [[Y_1]] 299; CHECK-NEXT: ret i1 [[CMP3]] 300; 301 %cmp = fcmp ogt float %x, %y 302 br i1 %cmp, label %same, label %different 303 304same: 305 %cmp2 = fcmp ule float %x, %y 306 ret i1 %cmp2 307 308different: 309 %cmp3 = fcmp ogt float %x, %y 310 ret i1 %cmp3 311} 312 313define i1 @test8(i32 %x, i32 %y) { 314; CHECK-LABEL: @test8( 315; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]] 316; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]] 317; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[X]], [[Y]] 318; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 319; CHECK: same: 320; CHECK-NEXT: ret i1 [[CMP2]] 321; CHECK: different: 322; CHECK-NEXT: ret i1 [[CMP3]] 323; 324 %cmp2 = icmp sle i32 %x, %y 325 %cmp = icmp sgt i32 %x, %y 326 %cmp3 = icmp sgt i32 %x, %y 327 br i1 %cmp, label %same, label %different 328 329same: 330 ret i1 %cmp2 331 332different: 333 ret i1 %cmp3 334} 335 336define i1 @test8_fp(float %x, float %y) { 337; CHECK-LABEL: @test8_fp( 338; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]] 339; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X]], [[Y]] 340; CHECK-NEXT: [[CMP3:%.*]] = fcmp ogt float [[X]], [[Y]] 341; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 342; CHECK: same: 343; CHECK-NEXT: ret i1 [[CMP2]] 344; CHECK: different: 345; CHECK-NEXT: ret i1 [[CMP3]] 346; 347 %cmp2 = fcmp ule float %x, %y 348 %cmp = fcmp ogt float %x, %y 349 %cmp3 = fcmp ogt float %x, %y 350 br i1 %cmp, label %same, label %different 351 352same: 353 ret i1 %cmp2 354 355different: 356 ret i1 %cmp3 357} 358 359define i32 @test9(i32 %i, i32 %j) { 360; CHECK-LABEL: @test9( 361; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]] 362; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]]) 363; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]]) 364; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]] 365; CHECK: cond_true: 366; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]] 367; CHECK-NEXT: ret i32 [[DIFF]] 368; CHECK: ret: 369; CHECK-NEXT: ret i32 5 370; 371 %cmp = icmp eq i32 %i, %j 372 br i1 %cmp, label %cond_true, label %ret 373 374cond_true: 375 %diff = sub i32 %i, %j 376 ret i32 %diff 377 378ret: 379 ret i32 5 380} 381 382define i32 @test10(i32 %j, i32 %i) { 383; CHECK-LABEL: @test10( 384; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]] 385; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]]) 386; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]]) 387; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]] 388; CHECK: cond_true: 389; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]] 390; CHECK-NEXT: ret i32 [[DIFF]] 391; CHECK: ret: 392; CHECK-NEXT: ret i32 5 393; 394 %cmp = icmp eq i32 %i, %j 395 br i1 %cmp, label %cond_true, label %ret 396 397cond_true: 398 %diff = sub i32 %i, %j 399 ret i32 %diff 400 401ret: 402 ret i32 5 403} 404 405declare i32 @yogibar() 406 407define i32 @test11(i32 %x) { 408; CHECK-LABEL: @test11( 409; CHECK-NEXT: [[V0:%.*]] = call i32 @yogibar() 410; CHECK-NEXT: [[V1:%.*]] = call i32 @yogibar() 411; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V0]], [[V1]] 412; CHECK: [[V0_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0]]) 413; CHECK: [[V1_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V1]]) 414; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[NEXT:%.*]] 415; CHECK: cond_true: 416; CHECK-NEXT: ret i32 [[V1_0]] 417; CHECK: next: 418; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], [[V0_0]] 419; CHECK: [[V0_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0_0]]) 420; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE2:%.*]], label [[NEXT2:%.*]] 421; CHECK: cond_true2: 422; CHECK-NEXT: ret i32 [[V0_0_1]] 423; CHECK: next2: 424; CHECK-NEXT: ret i32 0 425; 426 %v0 = call i32 @yogibar() 427 %v1 = call i32 @yogibar() 428 %cmp = icmp eq i32 %v0, %v1 429 br i1 %cmp, label %cond_true, label %next 430 431cond_true: 432 ret i32 %v1 433 434next: 435 %cmp2 = icmp eq i32 %x, %v0 436 br i1 %cmp2, label %cond_true2, label %next2 437 438cond_true2: 439 ret i32 %v0 440 441next2: 442 ret i32 0 443} 444 445define i32 @test12(i32 %x) { 446; CHECK-LABEL: @test12( 447; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 448; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]]) 449; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]]) 450; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] 451; CHECK: cond_true: 452; CHECK-NEXT: br label [[RET:%.*]] 453; CHECK: cond_false: 454; CHECK-NEXT: br label [[RET]] 455; CHECK: ret: 456; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0]], [[COND_TRUE]] ], [ [[X_1]], [[COND_FALSE]] ] 457; CHECK-NEXT: ret i32 [[RES]] 458; 459 %cmp = icmp eq i32 %x, 0 460 br i1 %cmp, label %cond_true, label %cond_false 461 462cond_true: 463 br label %ret 464 465cond_false: 466 br label %ret 467 468ret: 469 %res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ] 470 ret i32 %res 471} 472