diff --git a/llvm/test/Transforms/InstCombine/binop-and-shifts.ll b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/binop-and-shifts.ll @@ -0,0 +1,571 @@ +; 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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 4 +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 4 +; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 80 +; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] +; 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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 2 +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 2 +; CHECK-NEXT: [[BW2:%.*]] = add i8 [[SHIFT2]], 48 +; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] +; 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: [[SHIFT1:%.*]] = lshr <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = lshr <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW2:%.*]] = and <2 x i8> [[SHIFT1]], +; CHECK-NEXT: [[BW1:%.*]] = or <2 x i8> [[SHIFT2]], [[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> %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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 1 +; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT1]], 20 +; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[SHIFT2]], [[BW2]] +; 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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 1 +; CHECK-NEXT: [[BW2:%.*]] = and i8 [[SHIFT2]], 118 +; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] +; 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: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 5 +; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 5 +; CHECK-NEXT: [[BW2:%.*]] = or i8 [[SHIFT1]], 6 +; CHECK-NEXT: [[BW1:%.*]] = and i8 [[BW2]], [[SHIFT2]] +; 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: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 5 +; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 5 +; CHECK-NEXT: [[BW2:%.*]] = or i8 [[SHIFT2]], -58 +; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW2]] +; 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: [[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> [[BW2]], [[SHIFT1]] +; 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 +} + +declare void @llvm.assume(i1) +define i8 @lshr_or_or_no_const(i8 %x, i8 %y, i8 %sh, i8 %mask) { +; CHECK-LABEL: @lshr_or_or_no_const( +; CHECK-NEXT: [[SHIFT1:%.*]] = lshr 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 = 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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]] +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], [[SH]] +; CHECK-NEXT: [[BW2:%.*]] = xor i8 [[SHIFT2]], [[MASK:%.*]] +; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[SHIFT1]], [[BW2]] +; 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: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], [[SH:%.*]] +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], [[SH]] +; CHECK-NEXT: [[BW2:%.*]] = and <2 x i8> [[SHIFT2]], [[MASK:%.*]] +; CHECK-NEXT: [[BW1:%.*]] = and <2 x i8> [[SHIFT1]], [[BW2]] +; 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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], [[SH:%.*]] +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], [[SH]] +; CHECK-NEXT: [[BW2:%.*]] = add i8 [[SHIFT2]], [[MASK:%.*]] +; CHECK-NEXT: [[BW1:%.*]] = add i8 [[SHIFT1]], [[BW2]] +; 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: [[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> @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: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT2]], +; CHECK-NEXT: [[BW1:%.*]] = or <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 = 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: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW2:%.*]] = or <2 x i8> [[SHIFT2]], +; CHECK-NEXT: [[BW1:%.*]] = or <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 = 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: [[SHIFT1:%.*]] = lshr i8 [[X:%.*]], 4 +; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 [[Y:%.*]], 4 +; CHECK-NEXT: [[BW21:%.*]] = or i8 [[SHIFT2]], 48 +; CHECK-NEXT: [[BW1:%.*]] = or i8 [[SHIFT1]], [[BW21]] +; 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: [[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 <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: [[SHIFT21:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[SHIFT21]], 1 +; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP1]], 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: [[SHIFT21:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[SHIFT21]], 1 +; CHECK-NEXT: [[BW1:%.*]] = xor i8 [[TMP1]], -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: [[SHIFT1:%.*]] = shl i8 [[X:%.*]], 1 +; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 [[Y:%.*]], 1 +; CHECK-NEXT: [[BW2:%.*]] = add i8 [[SHIFT2]], 123 +; CHECK-NEXT: [[BW1:%.*]] = and i8 [[SHIFT1]], [[BW2]] +; 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: [[SHIFT1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[BW2:%.*]] = and <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 = 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 +}