Fix $$min/$$max for vector.

This commit is contained in:
Christoffer Lerno
2022-08-29 10:23:16 +02:00
parent bb9c8fb93e
commit 54d6b1a4ec
8 changed files with 78 additions and 10 deletions

View File

@@ -2143,6 +2143,7 @@ bool type_is_user_defined(Type *type);
bool type_is_structurally_equivalent(Type *type1, Type *type);
bool type_flat_is_floatlike(Type *type);
bool type_flat_is_intlike(Type *type);
bool type_flat_is_numlike(Type *type);
bool type_may_have_sub_elements(Type *type);
const char *type_to_error_string(Type *type);
const char *type_quoted_error_string(Type *type);

View File

@@ -569,7 +569,8 @@ typedef enum
TYPE_BOOL,
TYPE_I8,
TYPE_INTEGER_FIRST = TYPE_I8,
TYPE_INT_FIRST = TYPE_I8,
TYPE_NUM_FIRST = TYPE_INTEGER_FIRST,
TYPE_INT_FIRST = TYPE_INTEGER_FIRST,
TYPE_I16,
TYPE_I32,
TYPE_I64,
@@ -589,6 +590,7 @@ typedef enum
TYPE_F64,
TYPE_F128,
TYPE_FLOAT_LAST = TYPE_F128,
TYPE_NUM_LAST = TYPE_FLOAT_LAST,
TYPE_ANY,
TYPE_ANYERR,
TYPE_TYPEID,

View File

@@ -4544,6 +4544,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
if (func == BUILTIN_MAX)
{
Type *type = type_flatten(expr->call_expr.arguments[0]->type);
RETRY:
switch (type->type_kind)
{
case ALL_SIGNED_INTS:
@@ -4556,6 +4557,9 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
case ALL_FLOATS:
intrinsic = intrinsic_id.maxnum;
break;
case TYPE_VECTOR:
type = type->array.base;
goto RETRY;
default:
UNREACHABLE
}
@@ -4563,6 +4567,7 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
else if (func == BUILTIN_MIN)
{
Type *type = type_flatten(expr->call_expr.arguments[0]->type);
RETRY2:
switch (type->type_kind)
{
case ALL_SIGNED_INTS:
@@ -4575,6 +4580,9 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
case ALL_FLOATS:
intrinsic = intrinsic_id.minnum;
break;
case TYPE_VECTOR:
type = type->array.base;
goto RETRY2;
default:
UNREACHABLE
}

View File

@@ -2504,6 +2504,7 @@ typedef enum
BA_CHAR,
BA_FLOATLIKE,
BA_INTLIKE,
BA_NUMLIKE,
} BuiltinArg;
static bool sema_check_builtin_args_match(Expr **args, size_t arg_len)
@@ -2567,6 +2568,13 @@ static bool sema_check_builtin_args(Expr **args, BuiltinArg *arg_type, size_t ar
return false;
}
break;
case BA_NUMLIKE:
if (!type_flat_is_numlike(type))
{
SEMA_ERROR(args[i], "Expected a number or vector.");
return false;
}
break;
case BA_FLOATLIKE:
if (!type_flat_is_floatlike(type))
{
@@ -2711,14 +2719,7 @@ static inline bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *ex
break;
case BUILTIN_MAX:
case BUILTIN_MIN:
if (type_is_integer(args[0]->type))
{
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_INTLIKE, BA_INTLIKE }, arg_count)) return false;
}
else
{
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_FLOATLIKE, BA_FLOATLIKE }, arg_count)) return false;
}
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_NUMLIKE, BA_NUMLIKE }, arg_count)) return false;
if (!sema_check_builtin_args_match(args, arg_count)) return false;
rtype = args[0]->type;
break;

View File

@@ -320,6 +320,14 @@ RETRY:
}
bool type_flat_is_numlike(Type *type)
{
type = type_flatten(type);
if (type->type_kind == TYPE_VECTOR) type = type->array.base;
TypeKind kind = type->type_kind;
return kind >= TYPE_NUM_FIRST && kind <= TYPE_NUM_LAST;
}
bool type_flat_is_floatlike(Type *type)
{
type = type_flatten(type);

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.33"
#define COMPILER_VERSION "0.3.34"

View File

@@ -0,0 +1,24 @@
// #target: macos-x64
module test;
fn void main()
{
{
float[<2>] vf1 = { 1, -1 };
float[<2>] vf2 = { 1, 1 };
float[<2>] max = $$max(vf1, vf2);
float[<2>] min = $$min(vf1, vf2);
}
{
int[<2>] v1 = { 1, -1 };
int[<2>] v2 = { 1, 1 };
int[<2>] max = $$max(v1, v2);
int[<2>] min = $$min(v1, v2);
}
}
/* #expect: test.ll
%2 = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %0, <2 x float> %1)
%5 = call <2 x float> @llvm.minnum.v2f32(<2 x float> %3, <2 x float> %4)
%8 = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %6, <2 x i32> %7)
%11 = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %9, <2 x i32> %10)

View File

@@ -0,0 +1,24 @@
// #target: macos-x64
module test;
fn void main()
{
{
float[<2>] vf1 = { 1, -1 };
float[<2>] vf2 = { 1, 1 };
float[<2>] max = $$max(vf1, vf2);
float[<2>] min = $$min(vf1, vf2);
}
{
int[<2>] v1 = { 1, -1 };
int[<2>] v2 = { 1, 1 };
int[<2>] max = $$max(v1, v2);
int[<2>] min = $$min(v1, v2);
}
}
/* #expect: test.ll
%2 = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %0, <2 x float> %1)
%5 = call <2 x float> @llvm.minnum.v2f32(<2 x float> %3, <2 x float> %4)
%8 = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %6, <2 x i32> %7)
%11 = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %9, <2 x i32> %10)