360 lines
10 KiB
LLVM
360 lines
10 KiB
LLVM
|
; 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 exact i8 -128, [[X]]
|
||
|
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
|
||
|
; CHECK-NEXT: [[SHIFT2:%.*]] = ashr exact 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 disjoint 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
|
||
|
}
|
||
|
|
||
|
define i8 @shl_or_with_or_disjoint_instead_of_add(i8 %x) {
|
||
|
; CHECK-LABEL: define i8 @shl_or_with_or_disjoint_instead_of_add
|
||
|
; CHECK-SAME: (i8 [[X:%.*]]) {
|
||
|
; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]]
|
||
|
; CHECK-NEXT: ret i8 [[BINOP]]
|
||
|
;
|
||
|
%shift = shl i8 16, %x
|
||
|
%add = or disjoint i8 %x, 1
|
||
|
%shift2 = shl i8 3, %add
|
||
|
%binop = or i8 %shift, %shift2
|
||
|
ret i8 %binop
|
||
|
}
|
||
|
|
||
|
define i8 @shl_or_with_or_instead_of_add(i8 %x) {
|
||
|
; CHECK-LABEL: define i8 @shl_or_with_or_instead_of_add
|
||
|
; CHECK-SAME: (i8 [[X:%.*]]) {
|
||
|
; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]]
|
||
|
; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], 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 = or i8 %x, 1
|
||
|
%shift2 = shl i8 3, %add
|
||
|
%binop = or i8 %shift, %shift2
|
||
|
ret i8 %binop
|
||
|
}
|