; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s define i8 @shl_and_and(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_and_and( ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 4 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[TMP2]], 80 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 4 %shift2 = shl i8 %y, 4 %bw2 = and i8 %shift2, 88 %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_and_and_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_and_and_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 4 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 5 ; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 64 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 4 %shift2 = shl i8 %y, 5 %bw2 = and i8 %shift2, 88 %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_add_add(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_add_add( ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 2 ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[TMP2]], 48 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 2 %shift2 = shl i8 %y, 2 %bw2 = add i8 %shift2, 48 %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_add_add_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_add_add_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 2 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 2 ; CHECK-NEXT: [[BW2:%.*]] = add nuw nsw i8 [[SHIFT2]], 48 ; CHECK-NEXT: [[BW1:%.*]] = add nuw i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 2 %shift2 = lshr i8 %y, 2 %bw2 = add i8 %shift2, 48 %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_and_and_fail2(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_and_and_fail2( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 4, [[X:%.*]] ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 4, [[Y:%.*]] ; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 88 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 4, %x %shift2 = shl i8 4, %y %bw2 = and i8 %shift2, 88 %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } define <2 x i8> @lshr_and_or(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_and_or( ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i8> [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = lshr <2 x i8> %x, %shift2 = lshr <2 x i8> %y, %bw2 = and <2 x i8> %shift1, %bw1 = or <2 x i8> %shift2, %bw2 ret <2 x i8> %bw1 } define <2 x i8> @lshr_and_or_fail(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_and_or_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[BW2:%.*]] = and <2 x i8> [[SHIFT2]], ; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = lshr <2 x i8> %x, %shift2 = lshr <2 x i8> %y, %bw2 = and <2 x i8> %shift2, %bw1 = or <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define i8 @shl_and_xor(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_and_xor( ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 10 ; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = shl i8 %y, 1 %bw2 = and i8 %shift1, 20 %bw1 = xor i8 %shift2, %bw2 ret i8 %bw1 } define i8 @shl_and_add(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_and_add( ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y:%.*]], 59 ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = shl i8 %y, 1 %bw2 = and i8 %shift2, 119 %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_xor_add_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_xor_add_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 1 ; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], 119 ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = shl i8 %y, 1 %bw2 = xor i8 %shift2, 119 %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_or_and(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_or_and( ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], -64 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = lshr i8 [[TMP2]], 5 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 5 %shift2 = lshr i8 %y, 5 %bw2 = or i8 %shift1, 198 %bw1 = and i8 %bw2, %shift2 ret i8 %bw1 } define i8 @lshr_or_or_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_or_or_fail( ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 5 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[TMP2]], -58 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 5 %shift2 = lshr i8 %y, 5 %bw2 = or i8 %shift2, 198 %bw1 = or i8 %shift1, %bw2 ret i8 %bw1 } define <2 x i8> @shl_xor_and(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @shl_xor_and( ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = shl <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %shift2 = shl <2 x i8> %y, %bw2 = xor <2 x i8> %shift2, %bw1 = and <2 x i8> %bw2, %shift1 ret <2 x i8> %bw1 } define <2 x i8> @shl_xor_and_fail(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @shl_xor_and_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[BW2:%.*]] = xor <2 x i8> [[SHIFT2]], ; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %shift2 = shl <2 x i8> %y, %bw2 = xor <2 x i8> %shift2, %bw1 = and <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define i8 @lshr_or_or_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { ; CHECK-LABEL: @lshr_or_or_no_const( ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SH:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[TMP2]], [[MASK:%.*]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, %sh %shift2 = lshr i8 %y, %sh %bw2 = or i8 %shift2, %mask %bw1 = or i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_or_or_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) { ; CHECK-LABEL: @lshr_or_or_no_const_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]] ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], [[SH]] ; CHECK-NEXT: [[BW2:%.*]] = or i8 [[SHIFT2]], [[MASK:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, %sh %shift2 = lshr i8 %y, %sh %bw2 = or i8 %shift2, %mask %bw1 = or i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_xor_xor_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { ; CHECK-LABEL: @shl_xor_xor_no_const( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SH:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], [[MASK:%.*]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, %sh %shift2 = shl i8 %y, %sh %bw2 = xor i8 %shift2, %mask %bw1 = xor i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_xor_and_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) { ; CHECK-LABEL: @shl_xor_and_no_const_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]] ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], [[SH]] ; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], [[MASK:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, %sh %shift2 = shl i8 %y, %sh %bw2 = xor i8 %shift2, %mask %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } define <2 x i8> @shl_and_and_no_const(<2 x i8> %x, <2 x i8> %y, <2 x i8> %sh, <2 x i8> %mask) { ; CHECK-LABEL: @shl_and_and_no_const( ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], [[SH:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[TMP2]], [[MASK:%.*]] ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %sh %shift2 = shl <2 x i8> %y, %sh %bw2 = and <2 x i8> %shift2, %mask %bw1 = and <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define i8 @shl_add_add_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { ; CHECK-LABEL: @shl_add_add_no_const( ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SH:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[TMP2]], [[MASK:%.*]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, %sh %shift2 = shl i8 %y, %sh %bw2 = add i8 %shift2, %mask %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_add_add_no_const_fail(i8 %x, i8 %y, i8 %sh, i8 %mask) { ; CHECK-LABEL: @lshr_add_add_no_const_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], [[SH:%.*]] ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], [[SH]] ; CHECK-NEXT: [[BW2:%.*]] = add i8 [[SHIFT2]], [[MASK:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, %sh %shift2 = lshr i8 %y, %sh %bw2 = add i8 %shift2, %mask %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define <2 x i8> @lshr_add_and(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_add_and( ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = lshr <2 x i8> %x, %shift2 = lshr <2 x i8> %y, %bw2 = add <2 x i8> %shift2, %bw1 = and <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define <2 x i8> @lshr_add_or_fail_dif_masks(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_add_or_fail_dif_masks( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[BW2:%.*]] = add <2 x i8> [[SHIFT2]], ; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = lshr <2 x i8> %x, %shift2 = lshr <2 x i8> %y, %bw2 = add <2 x i8> %shift2, %bw1 = and <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define <2 x i8> @shl_or_or_good_mask(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @shl_or_or_good_mask( ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], ; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %shift2 = shl <2 x i8> %y, %bw2 = or <2 x i8> %shift2, %bw1 = or <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define <2 x i8> @shl_or_or_fail_bad_mask(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @shl_or_or_fail_bad_mask( ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[TMP1]], ; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %shift2 = shl <2 x i8> %y, %bw2 = or <2 x i8> %shift2, %bw1 = or <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define i8 @lshr_xor_or_good_mask(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_xor_or_good_mask( ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], 4 ; CHECK-NEXT: [[BW1:%.*]] = or disjoint i8 [[TMP2]], 48 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 4 %shift2 = lshr i8 %y, 4 %bw2 = xor i8 %shift2, 48 %bw1 = or i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_xor_or_fail_bad_mask(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_xor_or_fail_bad_mask( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 6 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 6 ; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], -127 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 6 %shift2 = lshr i8 %y, 6 %bw2 = xor i8 %shift2, 129 %bw1 = or i8 %shift1, %bw2 ret i8 %bw1 } define <2 x i8> @lshr_or_xor_good_mask(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_or_xor_good_mask( ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = lshr <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = lshr <2 x i8> %x, %shift2 = lshr <2 x i8> %y, %bw2 = or <2 x i8> %shift2, %bw1 = xor <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define <2 x i8> @lshr_or_xor_fail_bad_mask(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_or_xor_fail_bad_mask( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT2]], ; CHECK-NEXT: [[BW1:%.*]] = xor <2 x i8> [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = lshr <2 x i8> %x, %shift2 = lshr <2 x i8> %y, %bw2 = or <2 x i8> %shift2, %bw1 = xor <2 x i8> %shift1, %bw2 ret <2 x i8> %bw1 } define i8 @shl_xor_xor_good_mask(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_xor_xor_good_mask( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 1 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], 88 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = shl i8 %y, 1 %bw2 = xor i8 %shift2, 88 %bw1 = xor i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_xor_xor_bad_mask_distribute(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_xor_xor_bad_mask_distribute( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], 1 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP2]], -68 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = shl i8 %y, 1 %bw2 = xor i8 %shift2, 188 %bw1 = xor i8 %shift1, %bw2 ret i8 %bw1 } define i8 @shl_add_and(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_add_and( ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 61 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = shl i8 [[TMP2]], 1 ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = shl i8 %y, 1 %bw2 = add i8 %shift2, 123 %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_and_add_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_and_add_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 ; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 123 ; CHECK-NEXT: [[BW1:%.*]] = add nuw i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 1 %shift2 = lshr i8 %y, 1 %bw2 = and i8 %shift2, 123 %bw1 = add i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_add_or_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_add_or_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 ; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123 ; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 1 %shift2 = lshr i8 %y, 1 %bw2 = add i8 %shift2, 123 %bw1 = or i8 %shift1, %bw2 ret i8 %bw1 } define i8 @lshr_add_xor_fail(i8 %x, i8 %y) { ; CHECK-LABEL: @lshr_add_xor_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 1 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 ; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123 ; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = lshr i8 %x, 1 %shift2 = lshr i8 %y, 1 %bw2 = add i8 %shift2, 123 %bw1 = xor i8 %shift1, %bw2 ret i8 %bw1 } define <2 x i8> @lshr_and_add(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_and_add( ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: [[BW1:%.*]] = shl <2 x i8> [[TMP2]], ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %shift2 = shl <2 x i8> %y, %bw2 = and <2 x i8> %shift1, %bw1 = add <2 x i8> %shift2, %bw2 ret <2 x i8> %bw1 } define <2 x i8> @lshr_or_add_fail(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @lshr_or_add_fail( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], ; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], ; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT1]], ; CHECK-NEXT: [[BW1:%.*]] = add <2 x i8> [[SHIFT2]], [[BW2]] ; CHECK-NEXT: ret <2 x i8> [[BW1]] ; %shift1 = shl <2 x i8> %x, %shift2 = shl <2 x i8> %y, %bw2 = or <2 x i8> %shift1, %bw1 = add <2 x i8> %shift2, %bw2 ret <2 x i8> %bw1 } define i8 @shl_add_and_fail_mismatch_shift(i8 %x, i8 %y) { ; CHECK-LABEL: @shl_add_and_fail_mismatch_shift( ; CHECK-NEXT: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 1 ; CHECK-NEXT: [[BW2:%.*]] = add nuw i8 [[SHIFT2]], 123 ; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] ; CHECK-NEXT: ret i8 [[BW1]] ; %shift1 = shl i8 %x, 1 %shift2 = lshr i8 %y, 1 %bw2 = add i8 %shift2, 123 %bw1 = and i8 %shift1, %bw2 ret i8 %bw1 } ; Fold (-x >> y) & ((x >> y) ^ -1) -> (-x & ~x) >> y define i8 @and_ashr_not(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @and_ashr_not( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[AND:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret i8 [[AND]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %and = and i8 %x.shift, %y.shift.not ret i8 %and } define i8 @and_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @and_ashr_not_commuted( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[AND:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret i8 [[AND]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %and = and i8 %y.shift.not, %x.shift ret i8 %and } ; Negative test: lshr instead of ashr define i8 @and_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @and_ashr_not_fail_lshr_ashr( ; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[AND]] ; %x.shift = lshr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %and = and i8 %x.shift, %y.shift.not ret i8 %and } ; Negative test: lshr instead of ashr define i8 @and_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @and_ashr_not_fail_ashr_lshr( ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[AND]] ; %x.shift = ashr i8 %x, %shamt %y.shift = lshr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %and = and i8 %x.shift, %y.shift.not ret i8 %and } ; Negative test: invalid xor constant define i8 @and_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @and_ashr_not_fail_invalid_xor_constant( ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -2 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[AND]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -2 %and = and i8 %x.shift, %y.shift.not ret i8 %and } define <4 x i8> @and_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @and_ashr_not_vec( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret <4 x i8> [[AND]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %and = and <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %and } define <4 x i8> @and_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @and_ashr_not_vec_commuted( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret <4 x i8> [[AND]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %and = and <4 x i8> %y.shift.not, %x.shift ret <4 x i8> %and } define <4 x i8> @and_ashr_not_vec_undef_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @and_ashr_not_vec_undef_1( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[AND:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret <4 x i8> [[AND]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %and = and <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %and } define <4 x i8> @and_ashr_not_vec_undef_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @and_ashr_not_vec_undef_2( ; CHECK-NEXT: ret <4 x i8> zeroinitializer ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %and = and <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %and } ; Fold (-x >> y) | ((x >> y) ^ -1) -> (-x | ~x) >> y define i8 @or_ashr_not(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @or_ashr_not( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 ; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[OR:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret i8 [[OR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %or = or i8 %x.shift, %y.shift.not ret i8 %or } define i8 @or_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @or_ashr_not_commuted( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -1 ; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[OR:%.*]] = ashr i8 [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret i8 [[OR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %or = or i8 %y.shift.not, %x.shift ret i8 %or } ; Negative test: lshr instead of ashr define i8 @or_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @or_ashr_not_fail_lshr_ashr( ; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[OR]] ; %x.shift = lshr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %or = or i8 %x.shift, %y.shift.not ret i8 %or } ; Negative test: lshr instead of ashr define i8 @or_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @or_ashr_not_fail_ashr_lshr( ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[OR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = lshr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %or = or i8 %x.shift, %y.shift.not ret i8 %or } ; Negative test: invalid xor constant define i8 @or_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @or_ashr_not_fail_invalid_xor_constant( ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -2 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[OR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -2 %or = or i8 %x.shift, %y.shift.not ret i8 %or } define <4 x i8> @or_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @or_ashr_not_vec( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret <4 x i8> [[OR]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %or = or <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %or } define <4 x i8> @or_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @or_ashr_not_vec_commuted( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret <4 x i8> [[OR]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %or = or <4 x i8> %y.shift.not, %x.shift ret <4 x i8> %or } define <4 x i8> @or_ashr_not_vec_undef_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @or_ashr_not_vec_undef_1( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], ; CHECK-NEXT: [[TMP2:%.*]] = or <4 x i8> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: [[OR:%.*]] = ashr <4 x i8> [[TMP2]], [[SHAMT:%.*]] ; CHECK-NEXT: ret <4 x i8> [[OR]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %or = or <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %or } define <4 x i8> @or_ashr_not_vec_undef_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @or_ashr_not_vec_undef_2( ; CHECK-NEXT: ret <4 x i8> ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %or = or <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %or } ; Fold (-x >> y) ^ ((x >> y) ^ -1) -> (-x ^ ~x) >> y define i8 @xor_ashr_not(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @xor_ashr_not( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr i8 [[TMP1]], [[SHAMT:%.*]] ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[DOTNOT]], -1 ; CHECK-NEXT: ret i8 [[XOR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %xor = xor i8 %x.shift, %y.shift.not ret i8 %xor } define i8 @xor_ashr_not_commuted(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @xor_ashr_not_commuted( ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr i8 [[TMP1]], [[SHAMT:%.*]] ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[DOTNOT]], -1 ; CHECK-NEXT: ret i8 [[XOR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %xor = xor i8 %y.shift.not, %x.shift ret i8 %xor } ; Negative test: lshr instead of ashr define i8 @xor_ashr_not_fail_lshr_ashr(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @xor_ashr_not_fail_lshr_ashr( ; CHECK-NEXT: [[X_SHIFT:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y_SHIFT]], [[X_SHIFT]] ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -1 ; CHECK-NEXT: ret i8 [[XOR]] ; %x.shift = lshr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %xor = xor i8 %x.shift, %y.shift.not ret i8 %xor } ; Negative test: lshr instead of ashr define i8 @xor_ashr_not_fail_ashr_lshr(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @xor_ashr_not_fail_ashr_lshr( ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y_SHIFT]], [[X_SHIFT]] ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -1 ; CHECK-NEXT: ret i8 [[XOR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = lshr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %xor = xor i8 %x.shift, %y.shift.not ret i8 %xor } ; Negative test: invalid xor constant define i8 @xor_ashr_not_fail_invalid_xor_constant(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @xor_ashr_not_fail_invalid_xor_constant( ; CHECK-NEXT: [[Y_SHIFT1:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 [[Y_SHIFT1]], [[SHAMT:%.*]] ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -2 ; CHECK-NEXT: ret i8 [[XOR]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -2 %xor = xor i8 %x.shift, %y.shift.not ret i8 %xor } define <4 x i8> @xor_ashr_not_vec(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @xor_ashr_not_vec( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]] ; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], ; CHECK-NEXT: ret <4 x i8> [[XOR]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %xor = xor <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %xor } define <4 x i8> @xor_ashr_not_vec_commuted(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @xor_ashr_not_vec_commuted( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]] ; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], ; CHECK-NEXT: ret <4 x i8> [[XOR]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %xor = xor <4 x i8> %y.shift.not, %x.shift ret <4 x i8> %xor } define <4 x i8> @xor_ashr_not_vec_undef_1(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @xor_ashr_not_vec_undef_1( ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i8> [[Y:%.*]], [[X:%.*]] ; CHECK-NEXT: [[DOTNOT:%.*]] = ashr <4 x i8> [[TMP1]], [[SHAMT:%.*]] ; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i8> [[DOTNOT]], ; CHECK-NEXT: ret <4 x i8> [[XOR]] ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %xor = xor <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %xor } define <4 x i8> @xor_ashr_not_vec_undef_2(<4 x i8> %x, <4 x i8> %y, <4 x i8> %shamt) { ; CHECK-LABEL: @xor_ashr_not_vec_undef_2( ; CHECK-NEXT: ret <4 x i8> undef ; %x.shift = ashr <4 x i8> %x, %shamt %y.shift = ashr <4 x i8> %y, %shamt %y.shift.not = xor <4 x i8> %y.shift, %xor = xor <4 x i8> %x.shift, %y.shift.not ret <4 x i8> %xor } ; Negative test: invalid binop define i8 @binop_ashr_not_fail_invalid_binop(i8 %x, i8 %y, i8 %shamt) { ; CHECK-LABEL: @binop_ashr_not_fail_invalid_binop( ; CHECK-NEXT: [[X_SHIFT:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] ; CHECK-NEXT: [[Y_SHIFT:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] ; CHECK-NEXT: [[Y_SHIFT_NOT:%.*]] = xor i8 [[Y_SHIFT]], -1 ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_SHIFT]], [[Y_SHIFT_NOT]] ; CHECK-NEXT: ret i8 [[ADD]] ; %x.shift = ashr i8 %x, %shamt %y.shift = ashr i8 %y, %shamt %y.shift.not = xor i8 %y.shift, -1 %add = add i8 %x.shift, %y.shift.not ret i8 %add }