1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[WebAssembly] Replace SIMD int min/max builtins with patterns

Summary:
The instructions were originally implemented via builtins and
intrinsics so users would have to explicitly opt-in to using
them. This was useful while were validating whether these instructions
should have been merged into the spec proposal. Now that they have
been, we can use normal codegen patterns, so the intrinsics and
builtins are no longer useful.

Reviewers: aheejin

Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D71500
This commit is contained in:
Thomas Lively 2019-12-13 17:08:04 -08:00
parent 9191f8419a
commit e3ccbbd94d
5 changed files with 143 additions and 143 deletions

View File

@ -113,25 +113,6 @@ def int_wasm_sub_saturate_unsigned :
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
// TODO: Remove intrinsics and rely on codegen patterns once these are
// officially merged to the spec proposal
def int_wasm_min_signed :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
def int_wasm_min_unsigned :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
def int_wasm_max_signed :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
def int_wasm_max_unsigned :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
def int_wasm_bitselect :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],

View File

@ -181,6 +181,13 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
setOperationAction(Op, MVT::v2i64, Expand);
}
// But we do have integer min and max operations
if (Subtarget->hasUnimplementedSIMD128()) {
for (auto Op : {ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX})
for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
setOperationAction(Op, T, Legal);
}
// Expand float operations supported for scalars but not SIMD
for (auto Op : {ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FNEARBYINT,
ISD::FCOPYSIGN, ISD::FLOG, ISD::FLOG2, ISD::FLOG10,

View File

@ -732,10 +732,10 @@ defm MUL : SIMDBinaryIntNoI64x2<mul, "mul", 93>;
// Integer min_s / min_u / max_s / max_u
let isCommutable = 1 in {
defm MIN_S : SIMDBinaryIntNoI64x2<int_wasm_min_signed, "min_s", 94>;
defm MIN_U : SIMDBinaryIntNoI64x2<int_wasm_min_unsigned, "min_u", 95>;
defm MAX_S : SIMDBinaryIntNoI64x2<int_wasm_max_signed, "max_s", 96>;
defm MAX_U : SIMDBinaryIntNoI64x2<int_wasm_max_unsigned, "max_u", 97>;
defm MIN_S : SIMDBinaryIntNoI64x2<smin, "min_s", 94>;
defm MIN_U : SIMDBinaryIntNoI64x2<umin, "min_u", 95>;
defm MAX_S : SIMDBinaryIntNoI64x2<smax, "max_s", 96>;
defm MAX_U : SIMDBinaryIntNoI64x2<umax, "max_u", 97>;
} // isCommutable = 1
// Widening dot product: i32x4.dot_i16x8_s

View File

@ -47,6 +47,50 @@ define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) {
ret <16 x i8> %a
}
; CHECK-LABEL: min_s_v16i8:
; NO-SIMD128-NOT: i8x16
; SIMD128-NEXT: .functype min_s_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <16 x i8> @min_s_v16i8(<16 x i8> %x, <16 x i8> %y) {
%c = icmp slt <16 x i8> %x, %y
%a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
ret <16 x i8> %a
}
; CHECK-LABEL: min_u_v16i8:
; NO-SIMD128-NOT: i8x16
; SIMD128-NEXT: .functype min_u_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <16 x i8> @min_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
%c = icmp ult <16 x i8> %x, %y
%a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
ret <16 x i8> %a
}
; CHECK-LABEL: max_s_v16i8:
; NO-SIMD128-NOT: i8x16
; SIMD128-NEXT: .functype max_s_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <16 x i8> @max_s_v16i8(<16 x i8> %x, <16 x i8> %y) {
%c = icmp sgt <16 x i8> %x, %y
%a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
ret <16 x i8> %a
}
; CHECK-LABEL: max_u_v16i8:
; NO-SIMD128-NOT: i8x16
; SIMD128-NEXT: .functype max_u_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <16 x i8> @max_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
%c = icmp ugt <16 x i8> %x, %y
%a = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %y
ret <16 x i8> %a
}
; CHECK-LABEL: neg_v16i8:
; NO-SIMD128-NOT: i8x16
; SIMD128-NEXT: .functype neg_v16i8 (v128) -> (v128){{$}}
@ -293,6 +337,50 @@ define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) {
ret <8 x i16> %a
}
; CHECK-LABEL: min_s_v8i16:
; NO-SIMD128-NOT: i16x8
; SIMD128-NEXT: .functype min_s_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <8 x i16> @min_s_v8i16(<8 x i16> %x, <8 x i16> %y) {
%c = icmp slt <8 x i16> %x, %y
%a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
ret <8 x i16> %a
}
; CHECK-LABEL: min_u_v8i16:
; NO-SIMD128-NOT: i16x8
; SIMD128-NEXT: .functype min_u_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <8 x i16> @min_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
%c = icmp ult <8 x i16> %x, %y
%a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
ret <8 x i16> %a
}
; CHECK-LABEL: max_s_v8i16:
; NO-SIMD128-NOT: i16x8
; SIMD128-NEXT: .functype max_s_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <8 x i16> @max_s_v8i16(<8 x i16> %x, <8 x i16> %y) {
%c = icmp sgt <8 x i16> %x, %y
%a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
ret <8 x i16> %a
}
; CHECK-LABEL: max_u_v8i16:
; NO-SIMD128-NOT: i16x8
; SIMD128-NEXT: .functype max_u_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <8 x i16> @max_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
%c = icmp ugt <8 x i16> %x, %y
%a = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %y
ret <8 x i16> %a
}
; CHECK-LABEL: neg_v8i16:
; NO-SIMD128-NOT: i16x8
; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}}
@ -531,6 +619,50 @@ define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) {
ret <4 x i32> %a
}
; CHECK-LABEL: min_s_v4i32:
; NO-SIMD128-NOT: i32x4
; SIMD128-NEXT: .functype min_s_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <4 x i32> @min_s_v4i32(<4 x i32> %x, <4 x i32> %y) {
%c = icmp slt <4 x i32> %x, %y
%a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
ret <4 x i32> %a
}
; CHECK-LABEL: min_u_v4i32:
; NO-SIMD128-NOT: i32x4
; SIMD128-NEXT: .functype min_u_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <4 x i32> @min_u_v4i32(<4 x i32> %x, <4 x i32> %y) {
%c = icmp ult <4 x i32> %x, %y
%a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
ret <4 x i32> %a
}
; CHECK-LABEL: max_s_v4i32:
; NO-SIMD128-NOT: i32x4
; SIMD128-NEXT: .functype max_s_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <4 x i32> @max_s_v4i32(<4 x i32> %x, <4 x i32> %y) {
%c = icmp sgt <4 x i32> %x, %y
%a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
ret <4 x i32> %a
}
; CHECK-LABEL: max_u_v4i32:
; NO-SIMD128-NOT: i32x4
; SIMD128-NEXT: .functype max_u_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
define <4 x i32> @max_u_v4i32(<4 x i32> %x, <4 x i32> %y) {
%c = icmp ugt <4 x i32> %x, %y
%a = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %y
ret <4 x i32> %a
}
; CHECK-LABEL: neg_v4i32:
; NO-SIMD128-NOT: i32x4
; SIMD128-NEXT: .functype neg_v4i32 (v128) -> (v128){{$}}

View File

@ -65,46 +65,6 @@ define <16 x i8> @sub_sat_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
ret <16 x i8> %a
}
; CHECK-LABEL: min_s_v16i8:
; SIMD128-NEXT: .functype min_s_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <16 x i8> @llvm.wasm.min.signed.v16i8(<16 x i8>, <16 x i8>)
define <16 x i8> @min_s_v16i8(<16 x i8> %x, <16 x i8> %y) {
%a = call <16 x i8> @llvm.wasm.min.signed.v16i8(<16 x i8> %x, <16 x i8> %y)
ret <16 x i8> %a
}
; CHECK-LABEL: min_u_v16i8:
; SIMD128-NEXT: .functype min_u_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <16 x i8> @llvm.wasm.min.unsigned.v16i8(<16 x i8>, <16 x i8>)
define <16 x i8> @min_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
%a = call <16 x i8> @llvm.wasm.min.unsigned.v16i8(<16 x i8> %x, <16 x i8> %y)
ret <16 x i8> %a
}
; CHECK-LABEL: max_s_v16i8:
; SIMD128-NEXT: .functype max_s_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <16 x i8> @llvm.wasm.max.signed.v16i8(<16 x i8>, <16 x i8>)
define <16 x i8> @max_s_v16i8(<16 x i8> %x, <16 x i8> %y) {
%a = call <16 x i8> @llvm.wasm.max.signed.v16i8(<16 x i8> %x, <16 x i8> %y)
ret <16 x i8> %a
}
; CHECK-LABEL: max_u_v16i8:
; SIMD128-NEXT: .functype max_u_v16i8 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i8x16.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <16 x i8> @llvm.wasm.max.unsigned.v16i8(<16 x i8>, <16 x i8>)
define <16 x i8> @max_u_v16i8(<16 x i8> %x, <16 x i8> %y) {
%a = call <16 x i8> @llvm.wasm.max.unsigned.v16i8(<16 x i8> %x, <16 x i8> %y)
ret <16 x i8> %a
}
; CHECK-LABEL: any_v16i8:
; SIMD128-NEXT: .functype any_v16i8 (v128) -> (i32){{$}}
; SIMD128-NEXT: i8x16.any_true $push[[R:[0-9]+]]=, $0{{$}}
@ -208,46 +168,6 @@ define <8 x i16> @sub_sat_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
ret <8 x i16> %a
}
; CHECK-LABEL: min_s_v8i16:
; SIMD128-NEXT: .functype min_s_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <8 x i16> @llvm.wasm.min.signed.v8i16(<8 x i16>, <8 x i16>)
define <8 x i16> @min_s_v8i16(<8 x i16> %x, <8 x i16> %y) {
%a = call <8 x i16> @llvm.wasm.min.signed.v8i16(<8 x i16> %x, <8 x i16> %y)
ret <8 x i16> %a
}
; CHECK-LABEL: min_u_v8i16:
; SIMD128-NEXT: .functype min_u_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <8 x i16> @llvm.wasm.min.unsigned.v8i16(<8 x i16>, <8 x i16>)
define <8 x i16> @min_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
%a = call <8 x i16> @llvm.wasm.min.unsigned.v8i16(<8 x i16> %x, <8 x i16> %y)
ret <8 x i16> %a
}
; CHECK-LABEL: max_s_v8i16:
; SIMD128-NEXT: .functype max_s_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <8 x i16> @llvm.wasm.max.signed.v8i16(<8 x i16>, <8 x i16>)
define <8 x i16> @max_s_v8i16(<8 x i16> %x, <8 x i16> %y) {
%a = call <8 x i16> @llvm.wasm.max.signed.v8i16(<8 x i16> %x, <8 x i16> %y)
ret <8 x i16> %a
}
; CHECK-LABEL: max_u_v8i16:
; SIMD128-NEXT: .functype max_u_v8i16 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i16x8.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <8 x i16> @llvm.wasm.max.unsigned.v8i16(<8 x i16>, <8 x i16>)
define <8 x i16> @max_u_v8i16(<8 x i16> %x, <8 x i16> %y) {
%a = call <8 x i16> @llvm.wasm.max.unsigned.v8i16(<8 x i16> %x, <8 x i16> %y)
ret <8 x i16> %a
}
; CHECK-LABEL: any_v8i16:
; SIMD128-NEXT: .functype any_v8i16 (v128) -> (i32){{$}}
; SIMD128-NEXT: i16x8.any_true $push[[R:[0-9]+]]=, $0{{$}}
@ -347,46 +267,6 @@ define <8 x i16> @widen_high_unsigned_v8i16(<16 x i8> %v) {
; ==============================================================================
; 4 x i32
; ==============================================================================
; CHECK-LABEL: min_s_v4i32:
; SIMD128-NEXT: .functype min_s_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.min_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <4 x i32> @llvm.wasm.min.signed.v4i32(<4 x i32>, <4 x i32>)
define <4 x i32> @min_s_v4i32(<4 x i32> %x, <4 x i32> %y) {
%a = call <4 x i32> @llvm.wasm.min.signed.v4i32(<4 x i32> %x, <4 x i32> %y)
ret <4 x i32> %a
}
; CHECK-LABEL: min_u_v4i32:
; SIMD128-NEXT: .functype min_u_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.min_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <4 x i32> @llvm.wasm.min.unsigned.v4i32(<4 x i32>, <4 x i32>)
define <4 x i32> @min_u_v4i32(<4 x i32> %x, <4 x i32> %y) {
%a = call <4 x i32> @llvm.wasm.min.unsigned.v4i32(<4 x i32> %x, <4 x i32> %y)
ret <4 x i32> %a
}
; CHECK-LABEL: max_s_v4i32:
; SIMD128-NEXT: .functype max_s_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.max_s $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <4 x i32> @llvm.wasm.max.signed.v4i32(<4 x i32>, <4 x i32>)
define <4 x i32> @max_s_v4i32(<4 x i32> %x, <4 x i32> %y) {
%a = call <4 x i32> @llvm.wasm.max.signed.v4i32(<4 x i32> %x, <4 x i32> %y)
ret <4 x i32> %a
}
; CHECK-LABEL: max_u_v4i32:
; SIMD128-NEXT: .functype max_u_v4i32 (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.max_u $push[[R:[0-9]+]]=, $0, $1{{$}}
; SIMD128-NEXT: return $pop[[R]]{{$}}
declare <4 x i32> @llvm.wasm.max.unsigned.v4i32(<4 x i32>, <4 x i32>)
define <4 x i32> @max_u_v4i32(<4 x i32> %x, <4 x i32> %y) {
%a = call <4 x i32> @llvm.wasm.max.unsigned.v4i32(<4 x i32> %x, <4 x i32> %y)
ret <4 x i32> %a
}
; CHECK-LABEL: dot:
; SIMD128-NEXT: .functype dot (v128, v128) -> (v128){{$}}
; SIMD128-NEXT: i32x4.dot_i16x8_s $push[[R:[0-9]+]]=, $0, $1{{$}}