| ; 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 |
| } |