| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s |
| |
| define i8 @test0(i8 %a) { |
| ; CHECK-LABEL: @test0( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 3 |
| ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp = icmp ult i8 %a, 3 |
| br i1 %cmp, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i8 @test1(i8 %a) { |
| ; CHECK-LABEL: @test1( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 4 |
| ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp = icmp ult i8 %a, 4 |
| br i1 %cmp, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i8 @test2(i8 %a) { |
| ; CHECK-LABEL: @test2( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 6 |
| ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp = icmp ult i8 %a, 6 |
| br i1 %cmp, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i8 @test3(i8 %a) { |
| ; CHECK-LABEL: @test3( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 7 |
| ; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp = icmp ult i8 %a, 7 |
| br i1 %cmp, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i8 @test4(i8 %a) { |
| ; CHECK-LABEL: @test4( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[A:%.*]], 3 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[A]], -3 |
| ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] |
| ; CHECK-NEXT: br i1 [[COND]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp1 = icmp slt i8 %a, 3 |
| %cmp2 = icmp sgt i8 %a, -3 |
| %cond = and i1 %cmp1, %cmp2 |
| br i1 %cond, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i8 @test5(i8 %a) { |
| ; CHECK-LABEL: @test5( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[A:%.*]], 3 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[A]], -4 |
| ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] |
| ; CHECK-NEXT: br i1 [[COND]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp1 = icmp slt i8 %a, 3 |
| %cmp2 = icmp sgt i8 %a, -4 |
| %cond = and i1 %cmp1, %cmp2 |
| br i1 %cond, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i8 @test6(i8 %a) { |
| ; CHECK-LABEL: @test6( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 [[A:%.*]], 4 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[A]], -3 |
| ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] |
| ; CHECK-NEXT: br i1 [[COND]], label [[BB:%.*]], label [[EXIT:%.*]] |
| ; CHECK: bb: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[A]], 50 |
| ; CHECK-NEXT: ret i8 [[MUL]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret i8 0 |
| ; |
| entry: |
| %cmp1 = icmp slt i8 %a, 4 |
| %cmp2 = icmp sgt i8 %a, -3 |
| %cond = and i1 %cmp1, %cmp2 |
| br i1 %cond, label %bb, label %exit |
| |
| bb: |
| %mul = mul i8 %a, 50 |
| ret i8 %mul |
| |
| exit: |
| ret i8 0 |
| } |
| |
| define i1 @nuw_range1(i8 %b) { |
| ; CHECK-LABEL: @nuw_range1( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], 1 |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[C]], 4 |
| ; CHECK-NEXT: ret i1 false |
| ; |
| entry: |
| %c = add nuw nsw i8 %b, 1 |
| %mul = mul nuw i8 %c, 4 |
| %cmp = icmp eq i8 %mul, 0 |
| ret i1 %cmp |
| } |
| |
| define i1 @nuw_range2(i8 %b) { |
| ; CHECK-LABEL: @nuw_range2( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], 3 |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[C]], 4 |
| ; CHECK-NEXT: ret i1 false |
| ; |
| entry: |
| %c = add nuw nsw i8 %b, 3 |
| %mul = mul nuw i8 %c, 4 |
| %cmp = icmp ult i8 %mul, 2 |
| ret i1 %cmp |
| } |
| |
| define i1 @nsw_range1(i8 %b) { |
| ; CHECK-LABEL: @nsw_range1( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], -3 |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[C]], 4 |
| ; CHECK-NEXT: ret i1 false |
| ; |
| entry: |
| %c = add nuw nsw i8 %b, -3 |
| %mul = mul nsw i8 %c, 4 |
| %cmp = icmp slt i8 %c, %mul |
| ret i1 %cmp |
| } |
| |
| define i1 @one_bit(i1 %a, i1 %b) { |
| ; CHECK-LABEL: @one_bit( |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i1 [[A:%.*]], [[B:%.*]] |
| ; CHECK-NEXT: ret i1 [[MUL]] |
| ; |
| %mul = mul i1 %a, %b |
| ret i1 %mul |
| } |
| |
| define i1 @test_mul_nuw_nsw_nneg(i32 %x, i32 range(i32 3, 2147483648) %y) { |
| ; CHECK-LABEL: @test_mul_nuw_nsw_nneg( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: ret i1 true |
| ; |
| entry: |
| %mul = mul nuw nsw i32 %x, %y |
| %cmp = icmp sgt i32 %mul, -1 |
| ret i1 %cmp |
| } |
| |
| define i1 @test_mul_nuw_nsw_nneg_complex(i32 %x, i32 noundef %y, i32 %z) { |
| ; CHECK-LABEL: @test_mul_nuw_nsw_nneg_complex( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[Y:%.*]], 2 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], 0 |
| ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i32 3, i32 4 |
| ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP1]], i32 [[Y]], i32 [[SEL1]] |
| ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[X]], [[SEL2]] |
| ; CHECK-NEXT: ret i1 true |
| ; |
| entry: |
| %cmp1 = icmp sgt i32 %y, 2 |
| %cmp2 = icmp eq i32 %x, 0 |
| %sel1 = select i1 %cmp2, i32 3, i32 4 |
| %sel2 = select i1 %cmp1, i32 %y, i32 %sel1 |
| %mul = mul nuw nsw i32 %x, %sel2 |
| %cmp3 = icmp sgt i32 %mul, -1 |
| ret i1 %cmp3 |
| } |