about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgnzlbg <gonzalobg88@gmail.com>2018-03-21 21:49:22 +0100
committergnzlbg <gonzalobg88@gmail.com>2018-03-26 10:20:41 +0200
commit7d5343a6700581e318189dcd74567b348bd7f68d (patch)
tree6a1de1c1a299aad05b03e849b3ce98ab53d3a69e
parent184156ed97a0a1256e80a17b8673749569407c94 (diff)
downloadrust-7d5343a6700581e318189dcd74567b348bd7f68d.tar.gz
rust-7d5343a6700581e318189dcd74567b348bd7f68d.zip
implement minmax intrinsics
-rw-r--r--src/librustc_llvm/ffi.rs3
-rw-r--r--src/librustc_trans/builder.rs13
-rw-r--r--src/librustc_trans/intrinsic.rs2
-rw-r--r--src/librustc_typeck/check/intrinsic.rs3
-rw-r--r--src/rustllvm/RustWrapper.cpp9
5 files changed, 29 insertions, 1 deletions
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 403fe4731f1..09ff3566713 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -1247,6 +1247,9 @@ extern "C" {
                                          IsNaN: bool)
                                          -> ValueRef;
 
+    pub fn LLVMRustBuildMinNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef;
+    pub fn LLVMRustBuildMaxNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef;
+
     pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef;
     pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef;
     pub fn LLVMBuildPtrDiff(B: BuilderRef,
diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs
index 5e2d32b3596..b5271b25b63 100644
--- a/src/librustc_trans/builder.rs
+++ b/src/librustc_trans/builder.rs
@@ -917,6 +917,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+        self.count_insn("minnum");
+        unsafe {
+            llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs)
+        }
+    }
+    pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
+        self.count_insn("maxnum");
+        unsafe {
+            llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs)
+        }
+    }
+
     pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef {
         self.count_insn("select");
         unsafe {
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index 2be29c08360..5c67f809114 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -1432,6 +1432,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         simd_and: TyUint, TyInt => and;
         simd_or: TyUint, TyInt => or;
         simd_xor: TyUint, TyInt => xor;
+        simd_fmax: TyFloat => maxnum;
+        simd_fmin: TyFloat => minnum;
     }
     span_bug!(span, "unknown SIMD intrinsic");
 }
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index da37cec31cf..377e3a89184 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -355,7 +355,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
         "simd_add" | "simd_sub" | "simd_mul" | "simd_rem" |
         "simd_div" | "simd_shl" | "simd_shr" |
-        "simd_and" | "simd_or" | "simd_xor" => {
+        "simd_and" | "simd_or" | "simd_xor" |
+        "simd_fmin" | "simd_fmax" => {
             (1, vec![param(0), param(0)], param(0))
         }
         "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index e815d151aeb..627827105cb 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -1500,3 +1500,12 @@ LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS,
   return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name));
 }
 #endif
+
+extern "C" LLVMValueRef
+LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
+    return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
+}
+extern "C" LLVMValueRef
+LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
+    return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
+}