| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 |
| ; RUN: opt -S -passes=instcombine < %s | FileCheck %s |
| |
| define i8 @shl_or(i8 %x) { |
| ; CHECK-LABEL: define i8 @shl_or |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = shl i8 3, %add |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @lshr_or(i8 %x) { |
| ; CHECK-LABEL: define i8 @lshr_or |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 17, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = lshr i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = lshr i8 3, %add |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @ashr_or(i8 %x) { |
| ; CHECK-LABEL: define i8 @ashr_or |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = ashr i8 -64, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = ashr i8 -64, %x |
| %add = add i8 %x, 1 |
| %shift2 = ashr i8 -128, %add |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @shl_xor(i8 %x) { |
| ; CHECK-LABEL: define i8 @shl_xor |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = shl i8 3, %add |
| %binop = xor i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @lshr_xor(i8 %x) { |
| ; CHECK-LABEL: define i8 @lshr_xor |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 17, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = lshr i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = lshr i8 3, %add |
| %binop = xor i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @ashr_xor(i8 %x) { |
| ; CHECK-LABEL: define i8 @ashr_xor |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 96, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = ashr i8 -128, %x |
| %add = add i8 %x, 1 |
| %shift2 = ashr i8 -64, %add |
| %binop = xor i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @shl_and(i8 %x) { |
| ; CHECK-LABEL: define i8 @shl_and |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl i8 16, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 48, %x |
| %add = add i8 %x, 1 |
| %shift2 = shl i8 8, %add |
| %binop = and i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @lshr_and(i8 %x) { |
| ; CHECK-LABEL: define i8 @lshr_and |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 32, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = lshr i8 48, %x |
| %add = add i8 %x, 1 |
| %shift2 = lshr i8 64, %add |
| %binop = and i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @ashr_and(i8 %x) { |
| ; CHECK-LABEL: define i8 @ashr_and |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = ashr i8 -64, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = ashr i8 -64, %x |
| %add = add i8 %x, 1 |
| %shift2 = ashr i8 -128, %add |
| %binop = and i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @shl_add(i8 %x) { |
| ; CHECK-LABEL: define i8 @shl_add |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl i8 30, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = shl i8 7, %add |
| %binop = add i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @lshr_add_fail(i8 %x) { |
| ; CHECK-LABEL: define i8 @lshr_add_fail |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = lshr i8 16, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 7, [[ADD]] |
| ; CHECK-NEXT: [[BINOP:%.*]] = add nuw nsw i8 [[SHIFT]], [[SHIFT2]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = lshr i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = lshr i8 7, %add |
| %binop = add i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @ashr_add_fail(i8 %x) { |
| ; CHECK-LABEL: define i8 @ashr_add_fail |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = ashr i8 -128, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = ashr i8 -128, [[ADD]] |
| ; CHECK-NEXT: [[BINOP:%.*]] = add i8 [[SHIFT]], [[SHIFT2]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = ashr i8 -128, %x |
| %add = add i8 %x, 1 |
| %shift2 = ashr i8 -128, %add |
| %binop = add i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @shl_or_commuted(i8 %x) { |
| ; CHECK-LABEL: define i8 @shl_or_commuted |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = shl i8 3, %add |
| %binop = or i8 %shift2, %shift |
| ret i8 %binop |
| } |
| |
| define <2 x i8> @shl_or_splat(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @shl_or_splat |
| ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 22>, [[X]] |
| ; CHECK-NEXT: ret <2 x i8> [[BINOP]] |
| ; |
| %shift = shl <2 x i8> <i8 16, i8 16>, %x |
| %add = add <2 x i8> %x, <i8 1, i8 1> |
| %shift2 = shl <2 x i8> <i8 3, i8 3>, %add |
| %binop = or <2 x i8> %shift, %shift2 |
| ret <2 x i8> %binop |
| } |
| |
| define <2 x i8> @shl_or_non_splat(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @shl_or_non_splat |
| ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 60>, [[X]] |
| ; CHECK-NEXT: ret <2 x i8> [[BINOP]] |
| ; |
| %shift = shl <2 x i8> <i8 16, i8 32>, %x |
| %add = add <2 x i8> %x, <i8 1, i8 2> |
| %shift2 = shl <2 x i8> <i8 3, i8 7>, %add |
| %binop = or <2 x i8> %shift, %shift2 |
| ret <2 x i8> %binop |
| } |
| |
| define <2 x i8> @shl_or_undef_in_add(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @shl_or_undef_in_add |
| ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 poison>, [[X]] |
| ; CHECK-NEXT: ret <2 x i8> [[BINOP]] |
| ; |
| %shift = shl <2 x i8> <i8 16, i8 16>, %x |
| %add = add <2 x i8> %x, <i8 1, i8 undef> |
| %shift2 = shl <2 x i8> <i8 3, i8 3>, %add |
| %binop = or <2 x i8> %shift, %shift2 |
| ret <2 x i8> %binop |
| } |
| |
| define <2 x i8> @shl_or_undef_in_shift1(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @shl_or_undef_in_shift1 |
| ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 -1>, [[X]] |
| ; CHECK-NEXT: ret <2 x i8> [[BINOP]] |
| ; |
| %shift = shl <2 x i8> <i8 16, i8 undef>, %x |
| %add = add <2 x i8> %x, <i8 1, i8 1> |
| %shift2 = shl <2 x i8> <i8 3, i8 3>, %add |
| %binop = or <2 x i8> %shift, %shift2 |
| ret <2 x i8> %binop |
| } |
| |
| define <2 x i8> @shl_or_undef_in_shift2(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @shl_or_undef_in_shift2 |
| ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 16>, [[X]] |
| ; CHECK-NEXT: ret <2 x i8> [[BINOP]] |
| ; |
| %shift = shl <2 x i8> <i8 16, i8 16>, %x |
| %add = add <2 x i8> %x, <i8 1, i8 1> |
| %shift2 = shl <2 x i8> <i8 3, i8 undef>, %add |
| %binop = or <2 x i8> %shift, %shift2 |
| ret <2 x i8> %binop |
| } |
| |
| declare void @use(i8) |
| |
| define i8 @shl_or_multiuse(i8 %x) { |
| ; CHECK-LABEL: define i8 @shl_or_multiuse |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] |
| ; CHECK-NEXT: call void @use(i8 [[SHIFT]]) |
| ; CHECK-NEXT: call void @use(i8 [[ADD]]) |
| ; CHECK-NEXT: call void @use(i8 [[SHIFT2]]) |
| ; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = shl i8 3, %add |
| call void @use(i8 %shift) |
| call void @use(i8 %add) |
| call void @use(i8 %shift2) |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @mismatched_shifts(i8 %x) { |
| ; CHECK-LABEL: define i8 @mismatched_shifts |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 3, [[ADD]] |
| ; CHECK-NEXT: [[BINOP:%.*]] = or i8 [[SHIFT]], [[SHIFT2]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 1 |
| %shift2 = lshr i8 3, %add |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @mismatched_ops(i8 %x, i8 %y) { |
| ; CHECK-LABEL: define i8 @mismatched_ops |
| ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[Y]], 1 |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] |
| ; CHECK-NEXT: [[BINOP:%.*]] = or i8 [[SHIFT]], [[SHIFT2]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %y, 1 |
| %shift2 = shl i8 3, %add |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define i8 @add_out_of_range(i8 %x) { |
| ; CHECK-LABEL: define i8 @add_out_of_range |
| ; CHECK-SAME: (i8 [[X:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 32 |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] |
| ; CHECK-NEXT: [[BINOP:%.*]] = or i8 [[SHIFT]], [[SHIFT2]] |
| ; CHECK-NEXT: ret i8 [[BINOP]] |
| ; |
| %shift = shl i8 16, %x |
| %add = add i8 %x, 32 |
| %shift2 = shl i8 3, %add |
| %binop = or i8 %shift, %shift2 |
| ret i8 %binop |
| } |
| |
| define <2 x i8> @shl_or_non_splat_out_of_range(<2 x i8> %x) { |
| ; CHECK-LABEL: define <2 x i8> @shl_or_non_splat_out_of_range |
| ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { |
| ; CHECK-NEXT: [[SHIFT:%.*]] = shl <2 x i8> <i8 16, i8 32>, [[X]] |
| ; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 32> |
| ; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> <i8 3, i8 7>, [[ADD]] |
| ; CHECK-NEXT: [[BINOP:%.*]] = or <2 x i8> [[SHIFT]], [[SHIFT2]] |
| ; CHECK-NEXT: ret <2 x i8> [[BINOP]] |
| ; |
| %shift = shl <2 x i8> <i8 16, i8 32>, %x |
| %add = add <2 x i8> %x, <i8 1, i8 32> |
| %shift2 = shl <2 x i8> <i8 3, i8 7>, %add |
| %binop = or <2 x i8> %shift, %shift2 |
| ret <2 x i8> %binop |
| } |