1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -instcombine -S < %s | FileCheck %s 3; RUN: opt -passes=instcombine -S < %s | FileCheck %s 4 5declare void @use(i32 %x) 6declare i1 @cond() 7 8define void @test_01(i32 %x, i32 %y) { 9; CHECK-LABEL: @test_01( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 12; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[UNREACHED:%.*]] 13; CHECK: unreached: 14; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X]], [[Y]] 15; CHECK-NEXT: [[COMPARATOR:%.*]] = zext i1 [[C1]] to i32 16; CHECK-NEXT: call void @use(i32 [[COMPARATOR]]) 17; CHECK-NEXT: unreachable 18; CHECK: exit: 19; CHECK-NEXT: ret void 20; 21entry: 22 %c1 = icmp eq i32 %x, %y 23 %c2 = icmp slt i32 %x, %y 24 %signed = select i1 %c2, i32 -1, i32 1 25 %comparator = select i1 %c1, i32 0, i32 %signed 26 br i1 %c2, label %exit, label %unreached 27 28unreached: 29 call void @use(i32 %comparator) 30 unreachable 31 32exit: 33 ret void 34} 35 36 37define void @test_02(i32 %x, i32 %y) { 38; CHECK-LABEL: @test_02( 39; CHECK-NEXT: entry: 40; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 41; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]] 42; CHECK: medium: 43; CHECK-NEXT: [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]] 44; CHECK-NEXT: br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]] 45; CHECK: unreached: 46; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[X]], [[Y]] 47; CHECK-NEXT: [[SIGNED:%.*]] = select i1 [[C2]], i32 -1, i32 1 48; CHECK-NEXT: [[COMPARATOR:%.*]] = select i1 [[C1]], i32 0, i32 [[SIGNED]] 49; CHECK-NEXT: call void @use(i32 [[COMPARATOR]]) 50; CHECK-NEXT: unreachable 51; CHECK: exit: 52; CHECK-NEXT: ret void 53; 54entry: 55 %c1 = icmp eq i32 %x, %y 56 %c2 = icmp slt i32 %x, %y 57 %signed = select i1 %c2, i32 -1, i32 1 58 %comparator = select i1 %c1, i32 0, i32 %signed 59 br i1 %c2, label %exit, label %medium 60 61medium: 62 %c3 = icmp sgt i32 %x, %y 63 br i1 %c3, label %exit, label %unreached 64 65unreached: 66 call void @use(i32 %comparator) 67 unreachable 68 69exit: 70 ret void 71} 72 73define i32 @test_03(i32 %x, i32 %y) { 74; CHECK-LABEL: @test_03( 75; CHECK-NEXT: entry: 76; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 77; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]] 78; CHECK: medium: 79; CHECK-NEXT: [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]] 80; CHECK-NEXT: br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]] 81; CHECK: unreached: 82; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[X]], [[Y]] 83; CHECK-NEXT: [[SIGNED:%.*]] = select i1 [[C2]], i32 -1, i32 1 84; CHECK-NEXT: [[COMPARATOR:%.*]] = select i1 [[C1]], i32 0, i32 [[SIGNED]] 85; CHECK-NEXT: ret i32 [[COMPARATOR]] 86; CHECK: exit: 87; CHECK-NEXT: ret i32 0 88; 89entry: 90 %c1 = icmp eq i32 %x, %y 91 %c2 = icmp slt i32 %x, %y 92 %signed = select i1 %c2, i32 -1, i32 1 93 %comparator = select i1 %c1, i32 0, i32 %signed 94 br i1 %c2, label %exit, label %medium 95 96medium: 97 %c3 = icmp sgt i32 %x, %y 98 br i1 %c3, label %exit, label %unreached 99 100unreached: 101 ret i32 %comparator 102 103exit: 104 ret i32 0 105} 106 107define i32 @test_04(i32 %x, i1 %c) { 108; CHECK-LABEL: @test_04( 109; CHECK-NEXT: bb0: 110; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 111; CHECK: bb1: 112; CHECK-NEXT: br label [[BB3:%.*]] 113; CHECK: bb2: 114; CHECK-NEXT: br label [[BB3]] 115; CHECK: bb3: 116; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ 1, [[BB2]] ] 117; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 1 118; CHECK-NEXT: [[R:%.*]] = add i32 [[P]], [[A]] 119; CHECK-NEXT: ret i32 [[R]] 120; 121bb0: 122 %a = add i32 %x, 1 123 br i1 %c, label %bb1, label %bb2 124bb1: 125 br label %bb3 126bb2: 127 br label %bb3 128bb3: 129 %p = phi i32 [0, %bb1], [1, %bb2] 130 %r = add i32 %p, %a 131 ret i32 %r 132} 133 134; Do not sink into a potentially hotter block. 135define i32 @test_05_neg(i32 %x, i1 %cond) { 136; CHECK-LABEL: @test_05_neg( 137; CHECK-NEXT: bb0: 138; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 1 139; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 140; CHECK: bb1: 141; CHECK-NEXT: br label [[BB3:%.*]] 142; CHECK: bb2: 143; CHECK-NEXT: [[CALL:%.*]] = call i1 @cond() 144; CHECK-NEXT: br i1 [[CALL]], label [[BB2]], label [[BB3]] 145; CHECK: bb3: 146; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[A]], [[BB2]] ] 147; CHECK-NEXT: ret i32 [[P]] 148; 149bb0: 150 %a = add i32 %x, 1 151 br i1 %cond, label %bb1, label %bb2 152bb1: 153 br label %bb3 154bb2: 155 %call = call i1 @cond() 156 br i1 %call, label %bb2, label %bb3 157bb3: 158 %p = phi i32 [0, %bb1], [%a, %bb2] 159 ret i32 %p 160} 161