Prechádzať zdrojové kódy

Unify min/max semantics for simd_(min|max)

gingerBill 1 rok pred
rodič
commit
a7bab89c93
2 zmenil súbory, kde vykonal 6 pridanie a 6 odobranie
  1. 2 4
      src/llvm_backend_proc.cpp
  2. 4 2
      src/llvm_backend_utility.cpp

+ 2 - 4
src/llvm_backend_proc.cpp

@@ -1399,8 +1399,7 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
 		return res;
 	case BuiltinProc_simd_min:
 		if (is_float) {
-			LLVMValueRef cond = LLVMBuildFCmp(p->builder, LLVMRealOLT, arg0.value, arg1.value, "");
-			res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
+			return lb_emit_min(p, res.type, arg0, arg1);
 		} else {
 			LLVMValueRef cond = LLVMBuildICmp(p->builder, is_signed ? LLVMIntSLT : LLVMIntULT, arg0.value, arg1.value, "");
 			res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
@@ -1408,8 +1407,7 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
 		return res;
 	case BuiltinProc_simd_max:
 		if (is_float) {
-			LLVMValueRef cond = LLVMBuildFCmp(p->builder, LLVMRealOGT, arg0.value, arg1.value, "");
-			res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");
+			return lb_emit_max(p, res.type, arg0, arg1);
 		} else {
 			LLVMValueRef cond = LLVMBuildICmp(p->builder, is_signed ? LLVMIntSGT : LLVMIntUGT, arg0.value, arg1.value, "");
 			res.value = LLVMBuildSelect(p->builder, cond, arg0.value, arg1.value, "");

+ 4 - 2
src/llvm_backend_utility.cpp

@@ -124,7 +124,8 @@ gb_internal lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbVa
 gb_internal lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) {
 	x = lb_emit_conv(p, x, t);
 	y = lb_emit_conv(p, y, t);
-	if (is_type_float(t)) {
+	bool use_llvm_intrinsic = is_type_float(t) || (is_type_simd_vector(t) && is_type_float(base_array_type(t)));
+	if (use_llvm_intrinsic) {
 		// NOTE(bill): f either operand is a NaN, returns NaN. Otherwise returns the lesser of the two arguments.
 		// -0.0 is considered to be less than +0.0 for this intrinsic.
 		// These semantics are specified by IEEE 754-2019.
@@ -138,7 +139,8 @@ gb_internal lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) {
 gb_internal lbValue lb_emit_max(lbProcedure *p, Type *t, lbValue x, lbValue y) {
 	x = lb_emit_conv(p, x, t);
 	y = lb_emit_conv(p, y, t);
-	if (is_type_float(t)) {
+	bool use_llvm_intrinsic = is_type_float(t) || (is_type_simd_vector(t) && is_type_float(base_array_type(t)));
+	if (use_llvm_intrinsic) {
 		// NOTE(bill): If either operand is a NaN, returns NaN. Otherwise returns the greater of the two arguments.
 		// -0.0 is considered to be less than +0.0 for this intrinsic.
 		// These semantics are specified by IEEE 754-2019.