; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -instcombine -S < %s | FileCheck %s ; RUN: opt -passes=instcombine -S < %s | FileCheck %s declare void @use(i32 %x) declare i1 @cond() define void @test_01(i32 %x, i32 %y) { ; CHECK-LABEL: @test_01( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[UNREACHED:%.*]] ; CHECK: unreached: ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X]], [[Y]] ; CHECK-NEXT: [[COMPARATOR:%.*]] = zext i1 [[C1]] to i32 ; CHECK-NEXT: call void @use(i32 [[COMPARATOR]]) ; CHECK-NEXT: unreachable ; CHECK: exit: ; CHECK-NEXT: ret void ; entry: %c1 = icmp eq i32 %x, %y %c2 = icmp slt i32 %x, %y %signed = select i1 %c2, i32 -1, i32 1 %comparator = select i1 %c1, i32 0, i32 %signed br i1 %c2, label %exit, label %unreached unreached: call void @use(i32 %comparator) unreachable exit: ret void } define void @test_02(i32 %x, i32 %y) { ; CHECK-LABEL: @test_02( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]] ; CHECK: medium: ; CHECK-NEXT: [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]] ; CHECK-NEXT: br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]] ; CHECK: unreached: ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[X]], [[Y]] ; CHECK-NEXT: [[SIGNED:%.*]] = select i1 [[C2]], i32 -1, i32 1 ; CHECK-NEXT: [[COMPARATOR:%.*]] = select i1 [[C1]], i32 0, i32 [[SIGNED]] ; CHECK-NEXT: call void @use(i32 [[COMPARATOR]]) ; CHECK-NEXT: unreachable ; CHECK: exit: ; CHECK-NEXT: ret void ; entry: %c1 = icmp eq i32 %x, %y %c2 = icmp slt i32 %x, %y %signed = select i1 %c2, i32 -1, i32 1 %comparator = select i1 %c1, i32 0, i32 %signed br i1 %c2, label %exit, label %medium medium: %c3 = icmp sgt i32 %x, %y br i1 %c3, label %exit, label %unreached unreached: call void @use(i32 %comparator) unreachable exit: ret void } define i32 @test_03(i32 %x, i32 %y) { ; CHECK-LABEL: @test_03( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]] ; CHECK: medium: ; CHECK-NEXT: [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]] ; CHECK-NEXT: br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]] ; CHECK: unreached: ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[X]], [[Y]] ; CHECK-NEXT: [[SIGNED:%.*]] = select i1 [[C2]], i32 -1, i32 1 ; CHECK-NEXT: [[COMPARATOR:%.*]] = select i1 [[C1]], i32 0, i32 [[SIGNED]] ; CHECK-NEXT: ret i32 [[COMPARATOR]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 ; entry: %c1 = icmp eq i32 %x, %y %c2 = icmp slt i32 %x, %y %signed = select i1 %c2, i32 -1, i32 1 %comparator = select i1 %c1, i32 0, i32 %signed br i1 %c2, label %exit, label %medium medium: %c3 = icmp sgt i32 %x, %y br i1 %c3, label %exit, label %unreached unreached: ret i32 %comparator exit: ret i32 0 } define i32 @test_04(i32 %x, i1 %c) { ; CHECK-LABEL: @test_04( ; CHECK-NEXT: bb0: ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: bb2: ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ 1, [[BB2]] ] ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 1 ; CHECK-NEXT: [[R:%.*]] = add i32 [[P]], [[A]] ; CHECK-NEXT: ret i32 [[R]] ; bb0: %a = add i32 %x, 1 br i1 %c, label %bb1, label %bb2 bb1: br label %bb3 bb2: br label %bb3 bb3: %p = phi i32 [0, %bb1], [1, %bb2] %r = add i32 %p, %a ret i32 %r } ; Do not sink into a potentially hotter block. define i32 @test_05_neg(i32 %x, i1 %cond) { ; CHECK-LABEL: @test_05_neg( ; CHECK-NEXT: bb0: ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 1 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: bb2: ; CHECK-NEXT: [[CALL:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[CALL]], label [[BB2]], label [[BB3]] ; CHECK: bb3: ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[A]], [[BB2]] ] ; CHECK-NEXT: ret i32 [[P]] ; bb0: %a = add i32 %x, 1 br i1 %cond, label %bb1, label %bb2 bb1: br label %bb3 bb2: %call = call i1 @cond() br i1 %call, label %bb2, label %bb3 bb3: %p = phi i32 [0, %bb1], [%a, %bb2] ret i32 %p }