[llvm] 3a93756 - [WebAssembly] Replace SIMD int min/max builtins with patterns

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 16 12:00:20 PST 2019


Author: Thomas Lively
Date: 2019-12-16T11:48:49-08:00
New Revision: 3a93756dfbb0dcb7c62fcbe5b0ab8f8591fc9721

URL: https://github.com/llvm/llvm-project/commit/3a93756dfbb0dcb7c62fcbe5b0ab8f8591fc9721
DIFF: https://github.com/llvm/llvm-project/commit/3a93756dfbb0dcb7c62fcbe5b0ab8f8591fc9721.diff

LOG: [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

Added: 
    

Modified: 
    clang/include/clang/Basic/BuiltinsWebAssembly.def
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/test/CodeGen/builtins-wasm.c
    llvm/include/llvm/IR/IntrinsicsWebAssembly.td
    llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
    llvm/test/CodeGen/WebAssembly/simd-arith.ll
    llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def
index 2c57c5b70ef6..5b4fee421a20 100644
--- a/clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -98,21 +98,6 @@ TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd1
 TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
 TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
 
-// TODO: Remove builtins and rely on codegen patterns once these are officially
-// merged to the spec proposal
-TARGET_BUILTIN(__builtin_wasm_min_s_i8x16, "V16cV16cV16c", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_min_u_i8x16, "V16cV16cV16c", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_max_s_i8x16, "V16cV16cV16c", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_max_u_i8x16, "V16cV16cV16c", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_min_s_i16x8, "V8sV8sV8s", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_min_u_i16x8, "V8sV8sV8s", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_max_s_i16x8, "V8sV8sV8s", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_max_u_i16x8, "V8sV8sV8s", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_min_s_i32x4, "V4iV4iV4i", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_min_u_i32x4, "V4iV4iV4i", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_max_s_i32x4, "V4iV4iV4i", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_max_u_i32x4, "V4iV4iV4i", "nc", "simd128")
-
 TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
 
 TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128")

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 29226d6af50c..2e6c95c02c3f 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -375,7 +375,7 @@ static Value *emitUnaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
     return CGF.Builder.CreateCall(F, Src0);
   }
 }
-  
+
 // Emit an intrinsic that has 2 operands of the same type as its result.
 // Depending on mode, this may be a constrained floating-point intrinsic.
 static Value *emitBinaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
@@ -14504,48 +14504,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
                                      ConvertType(E->getType()));
     return Builder.CreateCall(Callee, {V1, V2, C});
   }
-  case WebAssembly::BI__builtin_wasm_min_s_i8x16:
-  case WebAssembly::BI__builtin_wasm_min_u_i8x16:
-  case WebAssembly::BI__builtin_wasm_max_s_i8x16:
-  case WebAssembly::BI__builtin_wasm_max_u_i8x16:
-  case WebAssembly::BI__builtin_wasm_min_s_i16x8:
-  case WebAssembly::BI__builtin_wasm_min_u_i16x8:
-  case WebAssembly::BI__builtin_wasm_max_s_i16x8:
-  case WebAssembly::BI__builtin_wasm_max_u_i16x8:
-  case WebAssembly::BI__builtin_wasm_min_s_i32x4:
-  case WebAssembly::BI__builtin_wasm_min_u_i32x4:
-  case WebAssembly::BI__builtin_wasm_max_s_i32x4:
-  case WebAssembly::BI__builtin_wasm_max_u_i32x4: {
-    unsigned IntNo;
-    switch (BuiltinID) {
-    case WebAssembly::BI__builtin_wasm_min_s_i8x16:
-    case WebAssembly::BI__builtin_wasm_min_s_i16x8:
-    case WebAssembly::BI__builtin_wasm_min_s_i32x4:
-      IntNo = Intrinsic::wasm_min_signed;
-      break;
-    case WebAssembly::BI__builtin_wasm_min_u_i8x16:
-    case WebAssembly::BI__builtin_wasm_min_u_i16x8:
-    case WebAssembly::BI__builtin_wasm_min_u_i32x4:
-      IntNo = Intrinsic::wasm_min_unsigned;
-      break;
-    case WebAssembly::BI__builtin_wasm_max_s_i8x16:
-    case WebAssembly::BI__builtin_wasm_max_s_i16x8:
-    case WebAssembly::BI__builtin_wasm_max_s_i32x4:
-      IntNo = Intrinsic::wasm_max_signed;
-      break;
-    case WebAssembly::BI__builtin_wasm_max_u_i8x16:
-    case WebAssembly::BI__builtin_wasm_max_u_i16x8:
-    case WebAssembly::BI__builtin_wasm_max_u_i32x4:
-      IntNo = Intrinsic::wasm_max_unsigned;
-      break;
-    default:
-      llvm_unreachable("unexpected builtin ID");
-    }
-    Value *LHS = EmitScalarExpr(E->getArg(0));
-    Value *RHS = EmitScalarExpr(E->getArg(1));
-    Function *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
-    return Builder.CreateCall(Callee, {LHS, RHS});
-  }
   case WebAssembly::BI__builtin_wasm_dot_s_i32x4_i16x8: {
     Value *LHS = EmitScalarExpr(E->getArg(0));
     Value *RHS = EmitScalarExpr(E->getArg(1));

diff  --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c
index eea51eb71b69..7ea32feb0512 100644
--- a/clang/test/CodeGen/builtins-wasm.c
+++ b/clang/test/CodeGen/builtins-wasm.c
@@ -352,90 +352,6 @@ i16x8 sub_saturate_u_i16x8(i16x8 x, i16x8 y) {
   // WEBASSEMBLY-NEXT: ret
 }
 
-i8x16 min_s_i8x16(i8x16 x, i8x16 y) {
-  return __builtin_wasm_min_s_i8x16(x, y);
-  // WEBASSEMBLY: call <16 x i8> @llvm.wasm.min.signed.v16i8(
-  // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i8x16 min_u_i8x16(i8x16 x, i8x16 y) {
-  return __builtin_wasm_min_u_i8x16(x, y);
-  // WEBASSEMBLY: call <16 x i8> @llvm.wasm.min.unsigned.v16i8(
-  // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i8x16 max_s_i8x16(i8x16 x, i8x16 y) {
-  return __builtin_wasm_max_s_i8x16(x, y);
-  // WEBASSEMBLY: call <16 x i8> @llvm.wasm.max.signed.v16i8(
-  // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i8x16 max_u_i8x16(i8x16 x, i8x16 y) {
-  return __builtin_wasm_max_u_i8x16(x, y);
-  // WEBASSEMBLY: call <16 x i8> @llvm.wasm.max.unsigned.v16i8(
-  // WEBASSEMBLY-SAME: <16 x i8> %x, <16 x i8> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i16x8 min_s_i16x8(i16x8 x, i16x8 y) {
-  return __builtin_wasm_min_s_i16x8(x, y);
-  // WEBASSEMBLY: call <8 x i16> @llvm.wasm.min.signed.v8i16(
-  // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i16x8 min_u_i16x8(i16x8 x, i16x8 y) {
-  return __builtin_wasm_min_u_i16x8(x, y);
-  // WEBASSEMBLY: call <8 x i16> @llvm.wasm.min.unsigned.v8i16(
-  // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i16x8 max_s_i16x8(i16x8 x, i16x8 y) {
-  return __builtin_wasm_max_s_i16x8(x, y);
-  // WEBASSEMBLY: call <8 x i16> @llvm.wasm.max.signed.v8i16(
-  // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i16x8 max_u_i16x8(i16x8 x, i16x8 y) {
-  return __builtin_wasm_max_u_i16x8(x, y);
-  // WEBASSEMBLY: call <8 x i16> @llvm.wasm.max.unsigned.v8i16(
-  // WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i32x4 min_s_i32x4(i32x4 x, i32x4 y) {
-  return __builtin_wasm_min_s_i32x4(x, y);
-  // WEBASSEMBLY: call <4 x i32> @llvm.wasm.min.signed.v4i32(
-  // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i32x4 min_u_i32x4(i32x4 x, i32x4 y) {
-  return __builtin_wasm_min_u_i32x4(x, y);
-  // WEBASSEMBLY: call <4 x i32> @llvm.wasm.min.unsigned.v4i32(
-  // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i32x4 max_s_i32x4(i32x4 x, i32x4 y) {
-  return __builtin_wasm_max_s_i32x4(x, y);
-  // WEBASSEMBLY: call <4 x i32> @llvm.wasm.max.signed.v4i32(
-  // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
-i32x4 max_u_i32x4(i32x4 x, i32x4 y) {
-  return __builtin_wasm_max_u_i32x4(x, y);
-  // WEBASSEMBLY: call <4 x i32> @llvm.wasm.max.unsigned.v4i32(
-  // WEBASSEMBLY-SAME: <4 x i32> %x, <4 x i32> %y)
-  // WEBASSEMBLY-NEXT: ret
-}
-
 i32x4 dot_i16x8_s(i16x8 x, i16x8 y) {
   return __builtin_wasm_dot_s_i32x4_i16x8(x, y);
   // WEBASSEMBLY: call <4 x i32> @llvm.wasm.dot(<8 x i16> %x, <8 x i16> %y)

diff  --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index 422334a78bb4..99c4eec1e0a3 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -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>],

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 7b972eda27eb..5b177c0c5d9d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -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,

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
index 137234f89b30..4c8dd53702b8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -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

diff  --git a/llvm/test/CodeGen/WebAssembly/simd-arith.ll b/llvm/test/CodeGen/WebAssembly/simd-arith.ll
index acbb1f9d5c48..f087249534dd 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-arith.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-arith.ll
@@ -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){{$}}

diff  --git a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
index 757152407a8f..8019fc5c6868 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
@@ -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{{$}}


        


More information about the llvm-commits mailing list