; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -passes=instcombine < %s | FileCheck %s define void @test_shl(i1 %x) { ; CHECK-LABEL: @test_shl( ; CHECK-NEXT: call void @sink(i8 0) ; CHECK-NEXT: ret void ; %y = zext i1 %x to i8 %z = shl i8 64, %y %a = and i8 %z, 1 call void @sink(i8 %a) ret void } define void @test_lshr(i1 %x) { ; CHECK-LABEL: @test_lshr( ; CHECK-NEXT: call void @sink(i8 0) ; CHECK-NEXT: ret void ; %y = zext i1 %x to i8 %z = lshr i8 64, %y %a = and i8 %z, 1 call void @sink(i8 %a) ret void } define void @test_ashr(i1 %x) { ; CHECK-LABEL: @test_ashr( ; CHECK-NEXT: call void @sink(i8 0) ; CHECK-NEXT: ret void ; %y = zext i1 %x to i8 %z = ashr i8 -16, %y %a = and i8 %z, 3 call void @sink(i8 %a) ret void } define void @test_udiv(i8 %x) { ; CHECK-LABEL: @test_udiv( ; CHECK-NEXT: call void @sink(i8 0) ; CHECK-NEXT: ret void ; %y = udiv i8 10, %x %z = and i8 %y, 64 call void @sink(i8 %z) ret void } define i8 @test_cond(i8 %x) { ; CHECK-LABEL: @test_cond( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: ret i8 -4 ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp eq i8 %and, 0 br i1 %cmp, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_inv(i8 %x) { ; CHECK-LABEL: @test_cond_inv( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 ; CHECK-NEXT: call void @use(i1 [[CMP]]) ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[IF:%.*]] ; CHECK: if: ; CHECK-NEXT: ret i8 -4 ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp ne i8 %and, 0 call void @use(i1 %cmp) br i1 %cmp, label %exit, label %if if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_and(i8 %x, i1 %c) { ; CHECK-LABEL: @test_cond_and( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]] ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp eq i8 %and, 0 %cond = and i1 %cmp, %c br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) { ; CHECK-LABEL: @test_cond_and_commuted( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[C3:%.*]] = and i1 [[C1:%.*]], [[C2:%.*]] ; CHECK-NEXT: [[COND:%.*]] = and i1 [[C3]], [[CMP]] ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp eq i8 %and, 0 %c3 = and i1 %c1, %c2 %cond = and i1 %c3, %cmp br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_logical_and(i8 %x, i1 %c) { ; CHECK-LABEL: @test_cond_logical_and( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i1 [[C:%.*]], i1 false ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp eq i8 %and, 0 %cond = select i1 %cmp, i1 %c, i1 false br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_or_invalid(i8 %x, i1 %c) { ; CHECK-LABEL: @test_cond_or_invalid( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]] ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp eq i8 %and, 0 %cond = or i1 %cmp, %c br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_inv_or(i8 %x, i1 %c) { ; CHECK-LABEL: @test_cond_inv_or( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]] ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp ne i8 %and, 0 %cond = or i1 %cmp, %c br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_inv_logical_or(i8 %x, i1 %c) { ; CHECK-LABEL: @test_cond_inv_logical_or( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_NOT]], i1 [[C:%.*]], i1 false ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp ne i8 %and, 0 %cond = select i1 %cmp, i1 false, i1 %c br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } define i8 @test_cond_inv_and_invalid(i8 %x, i1 %c) { ; CHECK-LABEL: @test_cond_inv_and_invalid( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]] ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]] ; CHECK: if: ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR1]] ; CHECK: exit: ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4 ; CHECK-NEXT: ret i8 [[OR2]] ; %and = and i8 %x, 3 %cmp = icmp ne i8 %and, 0 %cond = and i1 %cmp, %c br i1 %cond, label %if, label %exit if: %or1 = or i8 %x, -4 ret i8 %or1 exit: %or2 = or i8 %x, -4 ret i8 %or2 } declare void @use(i1) declare void @sink(i8)