| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -S -passes="simplifycfg<switch-range-to-icmp>" < %s | FileCheck %s |
| |
| ; Avoid getting stuck in the cycle pr165088_cycle_[1-4]. |
| |
| define void @pr165088_cycle_1(i8 %x) { |
| ; CHECK-LABEL: define void @pr165088_cycle_1( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[X]], 2 |
| ; CHECK-NEXT: br i1 [[TMP0]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] |
| ; CHECK: [[BLOCK1:.*]]: |
| ; CHECK-NEXT: [[COND2:%.*]] = icmp ugt i8 [[X]], 1 |
| ; CHECK-NEXT: br i1 [[COND2]], label %[[BLOCK3]], label %[[BLOCK2]] |
| ; CHECK: [[BLOCK2]]: |
| ; CHECK-NEXT: br label %[[BLOCK3]] |
| ; CHECK: [[BLOCK3]]: |
| ; CHECK-NEXT: [[COND3:%.*]] = icmp eq i8 [[X]], 0 |
| ; CHECK-NEXT: br i1 [[COND3]], label %[[EXIT:.*]], label %[[BLOCK1]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %switch = icmp uge i8 %x, 2 |
| %cond1 = icmp ugt i8 %x, 1 |
| %or.cond = and i1 %switch, %cond1 |
| br i1 %or.cond, label %block3, label %block2 |
| |
| block1: |
| %cond2 = icmp ugt i8 %x, 1 |
| br i1 %cond2, label %block3, label %block2 |
| |
| block2: |
| br label %block3 |
| |
| block3: |
| %cond3 = icmp eq i8 %x, 0 |
| br i1 %cond3, label %exit, label %block1 |
| |
| exit: |
| ret void |
| } |
| |
| define void @pr165088_cycle_2(i8 %x) { |
| ; CHECK-LABEL: define void @pr165088_cycle_2( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[X]], 2 |
| ; CHECK-NEXT: br i1 [[SWITCH]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] |
| ; CHECK: [[BLOCK1:.*]]: |
| ; CHECK-NEXT: [[COND2:%.*]] = icmp ugt i8 [[X]], 1 |
| ; CHECK-NEXT: br i1 [[COND2]], label %[[BLOCK3]], label %[[BLOCK2]] |
| ; CHECK: [[BLOCK2]]: |
| ; CHECK-NEXT: br label %[[BLOCK3]] |
| ; CHECK: [[BLOCK3]]: |
| ; CHECK-NEXT: [[COND3:%.*]] = icmp eq i8 [[X]], 0 |
| ; CHECK-NEXT: br i1 [[COND3]], label %[[EXIT:.*]], label %[[BLOCK1]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| switch i8 %x, label %block3 [ |
| i8 1, label %block2 |
| i8 0, label %block2 |
| ] |
| |
| block1: ; preds = %block3 |
| %cond2 = icmp ugt i8 %x, 1 |
| br i1 %cond2, label %block3, label %block2 |
| |
| block2: ; preds = %entry, %entry, %block1 |
| br label %block3 |
| |
| block3: ; preds = %entry, %block2, %block1 |
| %cond3 = icmp eq i8 %x, 0 |
| br i1 %cond3, label %exit, label %block1 |
| |
| exit: ; preds = %block3 |
| ret void |
| } |
| |
| define void @pr165088_cycle_3(i8 %x) { |
| ; CHECK-LABEL: define void @pr165088_cycle_3( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: br label %[[BLOCK3:.*]] |
| ; CHECK: [[BLOCK3]]: |
| ; CHECK-NEXT: [[COND3:%.*]] = icmp eq i8 [[X]], 0 |
| ; CHECK-NEXT: br i1 [[COND3]], label %[[EXIT:.*]], label %[[BLOCK3]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| switch i8 %x, label %block1 [ |
| i8 1, label %block2 |
| i8 0, label %block2 |
| ] |
| |
| block1: ; preds = %entry, %block3 |
| %cond2 = icmp ugt i8 %x, 1 |
| br i1 %cond2, label %block3, label %block2 |
| |
| block2: ; preds = %entry, %entry, %block1 |
| br label %block3 |
| |
| block3: ; preds = %block2, %block1 |
| %cond3 = icmp eq i8 %x, 0 |
| br i1 %cond3, label %exit, label %block1 |
| |
| exit: ; preds = %block3 |
| ret void |
| } |
| |
| define void @pr165088_cycle_4(i8 %x) { |
| ; CHECK-LABEL: define void @pr165088_cycle_4( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[X]], 2 |
| ; CHECK-NEXT: br i1 [[TMP0]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] |
| ; CHECK: [[BLOCK1:.*]]: |
| ; CHECK-NEXT: [[COND2_OLD:%.*]] = icmp ugt i8 [[X]], 1 |
| ; CHECK-NEXT: br i1 [[COND2_OLD]], label %[[BLOCK3]], label %[[BLOCK2]] |
| ; CHECK: [[BLOCK2]]: |
| ; CHECK-NEXT: br label %[[BLOCK3]] |
| ; CHECK: [[BLOCK3]]: |
| ; CHECK-NEXT: [[COND3:%.*]] = icmp eq i8 [[X]], 0 |
| ; CHECK-NEXT: br i1 [[COND3]], label %[[EXIT:.*]], label %[[BLOCK1]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %switch = icmp ult i8 %x, 2 |
| br i1 %switch, label %block2, label %block1 |
| |
| block1: ; preds = %entry, %block3 |
| %cond2 = icmp ugt i8 %x, 1 |
| br i1 %cond2, label %block3, label %block2 |
| |
| block2: ; preds = %entry, %block1 |
| br label %block3 |
| |
| block3: ; preds = %block2, %block1 |
| %cond3 = icmp eq i8 %x, 0 |
| br i1 %cond3, label %exit, label %block1 |
| |
| exit: ; preds = %block3 |
| ret void |
| } |
| |
| define void @pr165088_original(i8 %x) { |
| ; CHECK-LABEL: define void @pr165088_original( |
| ; CHECK-SAME: i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[X]], 2 |
| ; CHECK-NEXT: br i1 [[TMP0]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] |
| ; CHECK: [[BLOCK1:.*]]: |
| ; CHECK-NEXT: [[COND3_OLD_OLD:%.*]] = icmp ugt i8 [[X]], 1 |
| ; CHECK-NEXT: br i1 [[COND3_OLD_OLD]], label %[[BLOCK3]], label %[[BLOCK2]] |
| ; CHECK: [[BLOCK2]]: |
| ; CHECK-NEXT: br label %[[BLOCK3]] |
| ; CHECK: [[BLOCK3]]: |
| ; CHECK-NEXT: [[COND4:%.*]] = icmp eq i8 [[X]], 0 |
| ; CHECK-NEXT: br i1 [[COND4]], label %[[EXIT:.*]], label %[[BLOCK1]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %cond = icmp ne i8 %x, 0 |
| %cond3 = icmp ne i8 %x, 0 |
| %or.cond = and i1 %cond, %cond3 |
| br i1 %or.cond, label %block3, label %block2 |
| |
| block1: ; preds = %block3 |
| %cond3.old = icmp ugt i8 %x, 1 |
| br i1 %cond3.old, label %block3, label %block2 |
| |
| block2: ; preds = %block1, %entry |
| br label %block3 |
| |
| block3: ; preds = %block2, %block1, %entry |
| %cond4 = icmp eq i8 %x, 0 |
| br i1 %cond4, label %exit, label %block1 |
| |
| exit: ; preds = %block3 |
| ret void |
| } |