mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Fix $$min/$$max for vector.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.33"
|
||||
#define COMPILER_VERSION "0.3.34"
|
||||
24
test/test_suite/builtins/builtin_vector_min_max.c3t
Normal file
24
test/test_suite/builtins/builtin_vector_min_max.c3t
Normal 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)
|
||||
24
test/test_suite2/builtins/builtin_vector_min_max.c3t
Normal file
24
test/test_suite2/builtins/builtin_vector_min_max.c3t
Normal 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)
|
||||
Reference in New Issue
Block a user