In #88217 a large set of matchers was changed to only accept poison values in splats, but not undef values. This is because we now use poison for non-demanded vector elements, and allowing undef can cause correctness issues. This patch covers the remaining matchers by changing the AllowUndef parameter of getSplatValue() to AllowPoison instead. We also carry out corresponding renames in matchers. As a followup, we may want to change the default for things like m_APInt to m_APIntAllowPoison (as this is much less risky when only allowing poison), but this change doesn't do that. There is one caveat here: We have a single place (X86FixupVectorConstants) which does require handling of vector splats with undefs. This is because this works on backend constant pool entries, which currently still use undef instead of poison for non-demanded elements (because SDAG as a whole does not have an explicit poison representation). As it's just the single use, I've open-coded a getSplatValueAllowUndef() helper there, to discourage use in any other places.
2572 lines
72 KiB
LLVM
2572 lines
72 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
|
|
|
|
; TODO: the instructions with poison operands should return poison
|
|
|
|
declare i81 @llvm.smax.i81(i81, i81)
|
|
declare i8 @llvm.smax.i8(i8, i8)
|
|
declare <2 x i8> @llvm.smax.v2i8(<2 x i8>, <2 x i8>)
|
|
declare i3 @llvm.smin.i3(i3, i3)
|
|
declare i8 @llvm.smin.i8(i8, i8)
|
|
declare <2 x i8> @llvm.smin.v2i8(<2 x i8>, <2 x i8>)
|
|
declare i8 @llvm.umax.i8(i8, i8)
|
|
declare <2 x i8> @llvm.umax.v2i8(<2 x i8>, <2 x i8>)
|
|
declare i8 @llvm.umin.i8(i8, i8)
|
|
declare <2 x i8> @llvm.umin.v2i8(<2 x i8>, <2 x i8>)
|
|
declare void @llvm.assume(i1)
|
|
|
|
@g = external dso_local global [9 x i32], align 4
|
|
|
|
define i8 @constexpr_maxvalue() {
|
|
; CHECK-LABEL: @constexpr_maxvalue(
|
|
; CHECK-NEXT: ret i8 ptrtoint (ptr @g to i8)
|
|
;
|
|
%umin = call i8 @llvm.umin.i8(i8 255, i8 ptrtoint (ptr @g to i8))
|
|
ret i8 %umin
|
|
}
|
|
|
|
define i8 @constexpr_maxvalue_commute() {
|
|
; CHECK-LABEL: @constexpr_maxvalue_commute(
|
|
; CHECK-NEXT: ret i8 ptrtoint (ptr @g to i8)
|
|
;
|
|
%umin = call i8 @llvm.umin.i8(i8 ptrtoint (ptr @g to i8), i8 255)
|
|
ret i8 %umin
|
|
}
|
|
|
|
define i81 @smax_sameval(i81 %x) {
|
|
; CHECK-LABEL: @smax_sameval(
|
|
; CHECK-NEXT: ret i81 [[X:%.*]]
|
|
;
|
|
%r = call i81 @llvm.smax.i81(i81 %x, i81 %x)
|
|
ret i81 %r
|
|
}
|
|
|
|
define i3 @smin_sameval(i3 %x) {
|
|
; CHECK-LABEL: @smin_sameval(
|
|
; CHECK-NEXT: ret i3 [[X:%.*]]
|
|
;
|
|
%r = call i3 @llvm.smin.i3(i3 %x, i3 %x)
|
|
ret i3 %r
|
|
}
|
|
|
|
define <2 x i8> @umax_sameval(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_sameval(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %x, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umin_sameval(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_sameval(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i81 @smax_undef(i81 %x) {
|
|
; CHECK-LABEL: @smax_undef(
|
|
; CHECK-NEXT: ret i81 1208925819614629174706175
|
|
;
|
|
%r = call i81 @llvm.smax.i81(i81 undef, i81 %x)
|
|
ret i81 %r
|
|
}
|
|
|
|
define i81 @smax_poison(i81 %x) {
|
|
; CHECK-LABEL: @smax_poison(
|
|
; CHECK-NEXT: ret i81 1208925819614629174706175
|
|
;
|
|
%r = call i81 @llvm.smax.i81(i81 poison, i81 %x)
|
|
ret i81 %r
|
|
}
|
|
|
|
define i3 @smin_undef(i3 %x) {
|
|
; CHECK-LABEL: @smin_undef(
|
|
; CHECK-NEXT: ret i3 -4
|
|
;
|
|
%r = call i3 @llvm.smin.i3(i3 %x, i3 undef)
|
|
ret i3 %r
|
|
}
|
|
|
|
define i3 @smin_poison(i3 %x) {
|
|
; CHECK-LABEL: @smin_poison(
|
|
; CHECK-NEXT: ret i3 -4
|
|
;
|
|
%r = call i3 @llvm.smin.i3(i3 %x, i3 poison)
|
|
ret i3 %r
|
|
}
|
|
|
|
define <2 x i8> @umax_undef(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_undef(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 -1, i8 -1>
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> undef, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umax_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_poison(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 -1, i8 -1>
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> poison, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umin_undef(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_undef(
|
|
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> undef)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umin_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_poison(
|
|
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> poison)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @smax_maxval(i8 %x) {
|
|
; CHECK-LABEL: @smax_maxval(
|
|
; CHECK-NEXT: ret i8 127
|
|
;
|
|
%r = call i8 @llvm.smax.i8(i8 %x, i8 127)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @smax_maxval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smax_maxval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 127, i8 127>
|
|
;
|
|
%r = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 127, i8 127>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @smin_minval(i8 %x) {
|
|
; CHECK-LABEL: @smin_minval(
|
|
; CHECK-NEXT: ret i8 -128
|
|
;
|
|
%r = call i8 @llvm.smin.i8(i8 -128, i8 %x)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @smin_minval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smin_minval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 -128, i8 -128>
|
|
;
|
|
%r = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 -128, i8 -128>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @umax_maxval(i8 %x) {
|
|
; CHECK-LABEL: @umax_maxval(
|
|
; CHECK-NEXT: ret i8 -1
|
|
;
|
|
%r = call i8 @llvm.umax.i8(i8 %x, i8 255)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @umax_maxval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_maxval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 -1, i8 -1>
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 255, i8 255>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @umin_minval(i8 %x) {
|
|
; CHECK-LABEL: @umin_minval(
|
|
; CHECK-NEXT: ret i8 0
|
|
;
|
|
%r = call i8 @llvm.umin.i8(i8 0, i8 %x)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @umin_minval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_minval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> zeroinitializer)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @smax_minval(i8 %x) {
|
|
; CHECK-LABEL: @smax_minval(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%r = call i8 @llvm.smax.i8(i8 %x, i8 -128)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @smax_minval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smax_minval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 -128, i8 -128>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @smin_maxval(i8 %x) {
|
|
; CHECK-LABEL: @smin_maxval(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%r = call i8 @llvm.smin.i8(i8 127, i8 %x)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @smin_maxval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smin_maxval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 127, i8 127>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @umax_minval(i8 %x) {
|
|
; CHECK-LABEL: @umax_minval(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%r = call i8 @llvm.umax.i8(i8 %x, i8 0)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @umax_minval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_minval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> zeroinitializer, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @umin_maxval(i8 %x) {
|
|
; CHECK-LABEL: @umin_maxval(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%r = call i8 @llvm.umin.i8(i8 255, i8 %x)
|
|
ret i8 %r
|
|
}
|
|
|
|
define <2 x i8> @umin_maxval_commute(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_maxval_commute(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 255, i8 255>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @smax_maxval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smax_maxval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 127, i8 127>
|
|
;
|
|
%r = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 poison, i8 127>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @smin_minval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smin_minval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 -128, i8 -128>
|
|
;
|
|
%r = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 -128, i8 poison>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umax_maxval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_maxval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> <i8 -1, i8 -1>
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 255, i8 poison>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umin_minval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_minval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 poison, i8 0>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @smax_minval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smax_minval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 poison, i8 -128>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @smin_maxval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smin_maxval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 poison, i8 127>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umax_minval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_minval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 0, i8 poison>, <2 x i8> %x)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define <2 x i8> @umin_maxval_partial_poison(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_maxval_partial_poison(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 255, i8 poison>)
|
|
ret <2 x i8> %r
|
|
}
|
|
|
|
define i8 @umax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umax_commute1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umax_commute2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @umax_umax_commute3(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @umax_umax_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> [[Y:%.*]], <2 x i8> [[X:%.*]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %y, <2 x i8> %x)
|
|
%m2 = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %m, <2 x i8> %x)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @umin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umin_umin_commute1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @umin_umin_commute2(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @umin_umin_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> %y)
|
|
%m2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %m, <2 x i8> %x)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @umin_umin_commute3(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @smax_smax_commute1(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @smax_smax_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[Y:%.*]], <2 x i8> [[X:%.*]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %y, <2 x i8> %x)
|
|
%m2 = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %x, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @smax_smax_commute2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_smax_commute3(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @smin_smin(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @smin_smin(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> %y)
|
|
%m2 = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @smin_smin_commute1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_smin_commute2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_smin_commute3(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umin_commute1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin_commute1(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umin_commute2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin_commute2(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @umax_umin_commute3(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @umax_umin_commute3(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %y, <2 x i8> %x)
|
|
%m2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %m, <2 x i8> %x)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @umin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umin_umax_commute1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax_commute1(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @umin_umax_commute2(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @umin_umax_commute2(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> %y)
|
|
%m2 = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %m, <2 x i8> %x)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @umin_umax_commute3(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax_commute3(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @smax_smin_commute1(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @smax_smin_commute1(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %y, <2 x i8> %x)
|
|
%m2 = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @smax_smin_commute2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin_commute2(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_smin_commute3(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin_commute3(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @smin_smax(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @smin_smax(
|
|
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> %y)
|
|
%m2 = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %x, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @smin_smax_commute1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_commute1(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %x, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_smax_commute2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_commute2(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_smax_commute3(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_commute3(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
; Negative test - mismatched intrinsics.
|
|
|
|
define i8 @smax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umin(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[M]], i8 [[X]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
; Negative test - mismatched intrinsics.
|
|
|
|
define i8 @smax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umax(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[M]], i8 [[X]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
; Negative test - mismatched intrinsics.
|
|
|
|
define i8 @umax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smin(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[M]], i8 [[X]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
; Negative test - mismatched intrinsics.
|
|
|
|
define i8 @umin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smin(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[M]], i8 [[X]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 %x)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umax_constants(i8 %x) {
|
|
; CHECK-LABEL: @umax_umax_constants(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 9)
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 9)
|
|
%m2 = call i8 @llvm.umax.i8(i8 7, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umax_constants_commute1(i8 %x) {
|
|
; CHECK-LABEL: @umax_umax_constants_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 -128, i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 128, i8 %x)
|
|
%m2 = call i8 @llvm.umax.i8(i8 7, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_umax_constants_commute2(i8 %x) {
|
|
; CHECK-LABEL: @umax_umax_constants_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 -56)
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 200)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %m, i8 127)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @umax_umax_constants_commute3(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umax_umax_constants_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 -2, i8 -2>, <2 x i8> [[X:%.*]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 254, i8 254>, <2 x i8> %x)
|
|
%m2 = call <2 x i8> @llvm.umax.v2i8(<2 x i8> %m, <2 x i8> <i8 128, i8 128>)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @umin_umin_constants(i8 %x) {
|
|
; CHECK-LABEL: @umin_umin_constants(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 7)
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 7)
|
|
%m2 = call i8 @llvm.umin.i8(i8 9, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umin_umin_constants_commute1(i8 %x) {
|
|
; CHECK-LABEL: @umin_umin_constants_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 7, i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 7, i8 %x)
|
|
%m2 = call i8 @llvm.umin.i8(i8 128, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @umin_umin_constants_commute2(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_umin_constants_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 127, i8 127>)
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 127, i8 127>)
|
|
%m2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %m, <2 x i8> <i8 200, i8 poison>)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @umin_umin_constants_commute3(i8 %x) {
|
|
; CHECK-LABEL: @umin_umin_constants_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 -128, i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 128, i8 %x)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %m, i8 254)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_smax_constants(i8 %x) {
|
|
; CHECK-LABEL: @smax_smax_constants(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 9)
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 9)
|
|
%m2 = call i8 @llvm.smax.i8(i8 7, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @smax_smax_constants_commute1(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smax_smax_constants_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 7, i8 7>, <2 x i8> [[X:%.*]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 7, i8 7>, <2 x i8> %x)
|
|
%m2 = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 -127, i8 -127>, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @smax_smax_constants_commute2(i8 %x) {
|
|
; CHECK-LABEL: @smax_smax_constants_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 0)
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 0)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %m, i8 -1)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_smax_constants_commute3(i8 %x) {
|
|
; CHECK-LABEL: @smax_smax_constants_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smax.i8(i8 -1, i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 -1, i8 %x)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %m, i8 -127)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define <2 x i8> @smin_smin_constants(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smin_smin_constants(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 7, i8 7>)
|
|
; CHECK-NEXT: ret <2 x i8> [[M]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 7, i8 7>)
|
|
%m2 = call <2 x i8> @llvm.smin.v2i8(<2 x i8> <i8 poison, i8 9>, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i8 @smin_smin_constants_commute1(i8 %x) {
|
|
; CHECK-LABEL: @smin_smin_constants_commute1(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 -127, i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 -127, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 7, i8 %m)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_smin_constants_commute2(i8 %x) {
|
|
; CHECK-LABEL: @smin_smin_constants_commute2(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 -1)
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 -1)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 0)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_smin_constants_commute3(i8 %x) {
|
|
; CHECK-LABEL: @smin_smin_constants_commute3(
|
|
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.smin.i8(i8 -127, i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M]]
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 -127, i8 %x)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %m, i8 -1)
|
|
ret i8 %m2
|
|
}
|
|
|
|
; Negative test - undef in inner constant must not propagate.
|
|
|
|
define <2 x i8> @umin_umin_constants_partial_undef(<2 x i8> %x) {
|
|
; CHECK-LABEL: @umin_umin_constants_partial_undef(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 7, i8 undef>)
|
|
; CHECK-NEXT: [[M2:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> <i8 9, i8 9>, <2 x i8> [[M]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M2]]
|
|
;
|
|
%m = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 7, i8 undef> )
|
|
%m2 = call <2 x i8> @llvm.umin.v2i8(<2 x i8> <i8 9, i8 9>, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
; Negative test - undef in inner constant must not propagate.
|
|
|
|
define <2 x i8> @smax_smax_constants_partial_undef(<2 x i8> %x) {
|
|
; CHECK-LABEL: @smax_smax_constants_partial_undef(
|
|
; CHECK-NEXT: [[M:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 undef, i8 10>)
|
|
; CHECK-NEXT: [[M2:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 9, i8 9>, <2 x i8> [[M]])
|
|
; CHECK-NEXT: ret <2 x i8> [[M2]]
|
|
;
|
|
%m = call <2 x i8> @llvm.smax.v2i8(<2 x i8> %x, <2 x i8> <i8 undef, i8 10> )
|
|
%m2 = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 9, i8 9>, <2 x i8> %m)
|
|
ret <2 x i8> %m2
|
|
}
|
|
|
|
define i1 @smax_slt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_slt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%r = icmp slt i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smax_sge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_sge(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%r = icmp sge i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umax_ult(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_ult(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%r = icmp ult i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umax_uge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_uge(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%r = icmp uge i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smax_sgt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_sgt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%r = icmp sgt i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smax_sle(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_sle(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%r = icmp sle i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umax_ugt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_ugt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%r = icmp ugt i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umax_ule(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_ule(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%r = icmp ule i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smin_sgt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_sgt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%r = icmp sgt i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smin_sle(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_sle(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%r = icmp sle i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umin_ugt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_ugt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%r = icmp ugt i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umin_ule(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_ule(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%r = icmp ule i8 %m, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smin_slt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_slt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%r = icmp slt i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smin_sge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_sge(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%r = icmp sge i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umin_ult(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_ult(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%r = icmp ult i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @umin_uge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_uge(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%r = icmp uge i8 %x, %m
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @smaxmin_sge(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @smaxmin_sge(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%max = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.smin.i8(i8 %z, i8 %x)
|
|
%c = icmp sge i8 %max, %min
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @smaxmin_sgt(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @smaxmin_sgt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%max = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.smin.i8(i8 %z, i8 %x)
|
|
%c = icmp sgt i8 %min, %max
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @smaxmin_sle(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @smaxmin_sle(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%max = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.smin.i8(i8 %z, i8 %x)
|
|
%c = icmp sle i8 %min, %max
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @smaxmin_slt(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @smaxmin_slt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%max = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.smin.i8(i8 %z, i8 %x)
|
|
%c = icmp slt i8 %max, %min
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @umaxmin_uge(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @umaxmin_uge(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.umin.i8(i8 %z, i8 %x)
|
|
%c = icmp uge i8 %max, %min
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @umaxmin_ugt(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @umaxmin_ugt(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.umin.i8(i8 %z, i8 %x)
|
|
%c = icmp ugt i8 %min, %max
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @umaxmin_ule(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @umaxmin_ule(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.umin.i8(i8 %z, i8 %x)
|
|
%c = icmp ule i8 %min, %max
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @umaxmin_ult(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @umaxmin_ult(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%min = call i8 @llvm.umin.i8(i8 %z, i8 %x)
|
|
%c = icmp ult i8 %max, %min
|
|
ret i1 %c
|
|
}
|
|
|
|
; Negative test - should reduce via instcombine, but not here.
|
|
|
|
define i1 @smax_eq(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_eq(
|
|
; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MAX]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%max = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%r = icmp eq i8 %max, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
; Negative test - should reduce via instcombine, but not here.
|
|
|
|
define i1 @smax_eq_commute(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_eq_commute(
|
|
; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[MAX]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%max = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%r = icmp eq i8 %x, %max
|
|
ret i1 %r
|
|
}
|
|
|
|
; Negative test - should reduce via instcombine, but not here.
|
|
|
|
define i1 @umax_eq(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_eq(
|
|
; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MAX]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%r = icmp eq i8 %max, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
; Negative test - should reduce via instcombine, but not here.
|
|
|
|
define i1 @umax_eq_commute(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_eq_commute(
|
|
; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[MAX]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%r = icmp eq i8 %x, %max
|
|
ret i1 %r
|
|
}
|
|
|
|
define i8 @smax_smax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smax_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin_smax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin_smin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin_umax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_smin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_smin_umin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_umax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umax_smax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_umax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umax_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @smax_umax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umax_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - smax(x,y) - but does not simplify.
|
|
|
|
define i8 @smax_umax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umax_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_umin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umin_smax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smax_umin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umin_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - smax(x,y) - but does not simplify.
|
|
|
|
define i8 @smax_umin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umin_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @smax_umin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_umin_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_smax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_smin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_umax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smax_umin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_smin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_smin_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_umax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umax_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_umax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umax_smin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @smin_umax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umax_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - smin(x,y) - but does not simplify.
|
|
|
|
define i8 @smin_umax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umax_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_umin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umin_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @smin_umin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umin_smin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - smin(x,y) - but does not simplify.
|
|
|
|
define i8 @smin_umin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umin_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @smin_umin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_umin_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.smin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @umax_smax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smax_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - umax(x,y) - but does not simplify.
|
|
|
|
define i8 @umax_smax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smax_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_smax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smax_umax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_smax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smax_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - umax(x,y) - but does not simplify.
|
|
|
|
define i8 @umax_smin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smin_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @umax_smin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smin_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_smin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smin_umax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_smin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_smin_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umax_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin_smax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin_smin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin_umax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umax_umin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_umin_umin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umax.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @umin_smax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smax_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - umin(x,y) - but does not simplify.
|
|
|
|
define i8 @umin_smax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smax_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_smax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smax_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_smax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smax_umin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could combine - umin(x,y) - but does not simplify.
|
|
|
|
define i8 @umin_smin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smin_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
; This could simplify (commuted min/max op).
|
|
|
|
define i8 @umin_smin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smin_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
|
|
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
|
|
; CHECK-NEXT: ret i8 [[R]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_smin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smin_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_smin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_smin_umin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umax_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax_smax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umax_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax_smin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umax_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax_umax(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umax_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umax_umin(
|
|
; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M2]]
|
|
;
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umin_smax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin_smax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umin_smin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin_smin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umin_umax(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin_umax(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i8 @umin_umin_umin(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_umin_umin(
|
|
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
|
|
; CHECK-NEXT: ret i8 [[M1]]
|
|
;
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
|
|
%r = call i8 @llvm.umin.i8(i8 %m1, i8 %m2)
|
|
ret i8 %r
|
|
}
|
|
|
|
define i1 @umin_ult_diff_const(i8 %x) {
|
|
; CHECK-LABEL: @umin_ult_diff_const(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 10)
|
|
%c = icmp ult i8 %m, 20
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @umax_ugt_diff_const(i8 %x) {
|
|
; CHECK-LABEL: @umax_ugt_diff_const(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 10)
|
|
%c = icmp ugt i8 %m, 5
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @smin_slt_diff_const(i8 %x) {
|
|
; CHECK-LABEL: @smin_slt_diff_const(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 10)
|
|
%c = icmp slt i8 %m, 20
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @smax_sgt_diff_const(i8 %x) {
|
|
; CHECK-LABEL: @smax_sgt_diff_const(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 10)
|
|
%c = icmp sgt i8 %m, 5
|
|
ret i1 %c
|
|
}
|
|
|
|
define i8 @umin_assume_uge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_assume_uge(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp uge i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umin_assume_ugt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_assume_ugt(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp ugt i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umin_assume_ule(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_assume_ule(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp ule i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umin_assume_ult(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_assume_ult(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp ult i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umax_assume_uge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_assume_uge(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp uge i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umax_assume_ugt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_assume_ugt(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp ugt i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umax_assume_ule(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_assume_ule(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp ule i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umax_assume_ult(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_assume_ult(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp ult i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smin_assume_sge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_assume_sge(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp sge i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smin_assume_sgt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_assume_sgt(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp sgt i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smin_assume_sle(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_assume_sle(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp sle i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smin_assume_slt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_assume_slt(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp slt i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smax_assume_sge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_assume_sge(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp sge i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smax_assume_sgt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_assume_sgt(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%c = icmp sgt i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smax_assume_sle(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_assume_sle(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp sle i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @smax_assume_slt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_assume_slt(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[C]])
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%c = icmp slt i8 %x, %y
|
|
call void @llvm.assume(i1 %c)
|
|
%m = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
ret i8 %m
|
|
}
|
|
|
|
define i8 @umax_add_nuw_1(i8 %x) {
|
|
; CHECK-LABEL: @umax_add_nuw_1(
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i8 [[ADD]]
|
|
;
|
|
%add = add nuw i8 %x, 1
|
|
%max = call i8 @llvm.umax.i8(i8 %add, i8 %x)
|
|
ret i8 %max
|
|
}
|
|
|
|
define i8 @umax_add_nuw_2(i8 %x) {
|
|
; CHECK-LABEL: @umax_add_nuw_2(
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: ret i8 [[ADD]]
|
|
;
|
|
%add = add nuw i8 %x, 42
|
|
%max = call i8 @llvm.umax.i8(i8 %add, i8 42)
|
|
ret i8 %max
|
|
}
|
|
|
|
define i8 @umax_range_metadata(ptr %p1, ptr %p2) {
|
|
; CHECK-LABEL: @umax_range_metadata(
|
|
; CHECK-NEXT: [[Y:%.*]] = load i8, ptr [[P2:%.*]], align 1, !range [[RNG0:![0-9]+]]
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%x = load i8, ptr %p1, !range !{i8 0, i8 10}
|
|
%y = load i8, ptr %p2, !range !{i8 20, i8 30}
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %max
|
|
}
|
|
|
|
define i8 @umax_zext_sext(i4 %x) {
|
|
; CHECK-LABEL: @umax_zext_sext(
|
|
; CHECK-NEXT: [[SEXT:%.*]] = sext i4 [[X:%.*]] to i8
|
|
; CHECK-NEXT: ret i8 [[SEXT]]
|
|
;
|
|
%zext = zext i4 %x to i8
|
|
%sext = sext i4 %x to i8
|
|
%max = call i8 @llvm.umax.i8(i8 %zext, i8 %sext)
|
|
ret i8 %max
|
|
}
|
|
|
|
define i8 @umax_lshr(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_lshr(
|
|
; CHECK-NEXT: ret i8 [[X:%.*]]
|
|
;
|
|
%shr = lshr i8 %x, %y
|
|
%max = call i8 @llvm.umax.i8(i8 %x, i8 %shr)
|
|
ret i8 %max
|
|
}
|
|
|
|
define i8 @umax_dom_cond_uge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_dom_cond_uge(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%cmp = icmp uge i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_dom_cond_ugt(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_dom_cond_ugt(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%cmp = icmp ugt i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_dom_cond_ule(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_dom_cond_ule(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%cmp = icmp ule i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umax_dom_cond_ult(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umax_dom_cond_ult(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%cmp = icmp ult i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @umin_dom_cond_uge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @umin_dom_cond_uge(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%cmp = icmp uge i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smax_dom_cond_sge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smax_dom_cond_sge(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
;
|
|
%cmp = icmp sge i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
define i8 @smin_dom_cond_sge(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @smin_dom_cond_sge(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
; CHECK: true:
|
|
; CHECK-NEXT: ret i8 [[Y]]
|
|
; CHECK: false:
|
|
; CHECK-NEXT: ret i8 [[X]]
|
|
;
|
|
%cmp = icmp sge i8 %x, %y
|
|
br i1 %cmp, label %true, label %false
|
|
|
|
true:
|
|
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
ret i8 %m1
|
|
|
|
false:
|
|
%m2 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
|
|
ret i8 %m2
|
|
}
|
|
|
|
; Tests from PR65833
|
|
define i8 @umin_and_mask(i8 %x) {
|
|
; CHECK-LABEL: @umin_and_mask(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i8 [[AND1]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, 3
|
|
%val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umax_and_mask(i8 %x) {
|
|
; CHECK-LABEL: @umax_and_mask(
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X:%.*]], 3
|
|
; CHECK-NEXT: ret i8 [[AND2]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, 3
|
|
%val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umin_or_mask(i8 %x) {
|
|
; CHECK-LABEL: @umin_or_mask(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i8 [[AND1]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, 3
|
|
%val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umax_or_mask(i8 %x) {
|
|
; CHECK-LABEL: @umax_or_mask(
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X:%.*]], 3
|
|
; CHECK-NEXT: ret i8 [[AND2]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, 3
|
|
%val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umin_and_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @umin_and_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X]], 2
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.umin.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, 2
|
|
%val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umax_and_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @umax_and_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X]], 2
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.umax.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, 2
|
|
%val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umin_or_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @umin_or_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X]], 2
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.umin.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, 2
|
|
%val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @umax_or_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @umax_or_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X]], 2
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.umax.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, 2
|
|
%val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smin_and_mask_subset1(i8 %x) {
|
|
; CHECK-LABEL: @smin_and_mask_subset1(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i8 [[AND1]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, 3
|
|
%val = call i8 @llvm.smin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smax_and_mask_subset1(i8 %x) {
|
|
; CHECK-LABEL: @smax_and_mask_subset1(
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X:%.*]], 3
|
|
; CHECK-NEXT: ret i8 [[AND2]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, 3
|
|
%val = call i8 @llvm.smax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smin_or_mask_subset1(i8 %x) {
|
|
; CHECK-LABEL: @smin_or_mask_subset1(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i8 [[AND1]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, 3
|
|
%val = call i8 @llvm.smin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smax_or_mask_subset1(i8 %x) {
|
|
; CHECK-LABEL: @smax_or_mask_subset1(
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X:%.*]], 3
|
|
; CHECK-NEXT: ret i8 [[AND2]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, 3
|
|
%val = call i8 @llvm.smax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smin_and_mask_subset2(i8 %x) {
|
|
; CHECK-LABEL: @smin_and_mask_subset2(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], -4
|
|
; CHECK-NEXT: ret i8 [[AND1]]
|
|
;
|
|
%and1 = and i8 %x, -4
|
|
%and2 = and i8 %x, -3
|
|
%val = call i8 @llvm.smin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smax_and_mask_subset2(i8 %x) {
|
|
; CHECK-LABEL: @smax_and_mask_subset2(
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X:%.*]], -3
|
|
; CHECK-NEXT: ret i8 [[AND2]]
|
|
;
|
|
%and1 = and i8 %x, -4
|
|
%and2 = and i8 %x, -3
|
|
%val = call i8 @llvm.smax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smin_or_mask_subset2(i8 %x) {
|
|
; CHECK-LABEL: @smin_or_mask_subset2(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], -4
|
|
; CHECK-NEXT: ret i8 [[AND1]]
|
|
;
|
|
%and1 = or i8 %x, -4
|
|
%and2 = or i8 %x, -3
|
|
%val = call i8 @llvm.smin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smax_or_mask_subset2(i8 %x) {
|
|
; CHECK-LABEL: @smax_or_mask_subset2(
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X:%.*]], -3
|
|
; CHECK-NEXT: ret i8 [[AND2]]
|
|
;
|
|
%and1 = or i8 %x, -4
|
|
%and2 = or i8 %x, -3
|
|
%val = call i8 @llvm.smax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smin_and_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @smin_and_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X]], -3
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.smin.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, -3
|
|
%val = call i8 @llvm.smin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smax_and_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @smax_and_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i8 [[X]], -3
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.smax.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = and i8 %x, 1
|
|
%and2 = and i8 %x, -3
|
|
%val = call i8 @llvm.smax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smin_or_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @smin_or_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X]], -3
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.smin.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, -3
|
|
%val = call i8 @llvm.smin.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|
|
|
|
define i8 @smax_or_mask_negative(i8 %x) {
|
|
; CHECK-LABEL: @smax_or_mask_negative(
|
|
; CHECK-NEXT: [[AND1:%.*]] = or i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[AND2:%.*]] = or i8 [[X]], -3
|
|
; CHECK-NEXT: [[VAL:%.*]] = call i8 @llvm.smax.i8(i8 [[AND1]], i8 [[AND2]])
|
|
; CHECK-NEXT: ret i8 [[VAL]]
|
|
;
|
|
%and1 = or i8 %x, 1
|
|
%and2 = or i8 %x, -3
|
|
%val = call i8 @llvm.smax.i8(i8 %and1, i8 %and2)
|
|
ret i8 %val
|
|
}
|