Remove vestiges of top down widening.

This commit is contained in:
Christoffer Lerno
2023-09-19 09:27:09 +02:00
committed by Christoffer Lerno
parent e91cb85a66
commit 9eef34049d
16 changed files with 266 additions and 341 deletions

View File

@@ -193,7 +193,7 @@ fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
is_neg = true;
y = -y;
}
int pl = is_neg || self.flags.plus ? 1 : 0;
isz pl = is_neg || self.flags.plus ? 1 : 0;
// Print inf/nan
if (!math::is_finite(y))
{

View File

@@ -46,7 +46,7 @@ fn int main(int argc, char **argv)
byte_acc = 0;
bit_num = 0;
}
else if (x == w - 1)
else if (x == (double)w - 1)
{
byte_acc <<= (8 - w % 8);
putchar(byte_acc);

View File

@@ -6,7 +6,7 @@ double[] temparr;
fn double eval_A(int i, int j)
{
return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1);
return 1.0 / (double)((i + j) * (i + j + 1) / 2 + i + 1);
}
fn void eval_A_times_u(double[] u, double[] au, double[] x)

View File

@@ -755,14 +755,12 @@ typedef struct
ExprId left;
ExprId right;
BinaryOp operator : 8;
bool widen : 1;
} ExprBinary;
typedef struct
{
Expr* expr;
UnaryOp operator : 8;
bool widen : 1;
} ExprUnary;
@@ -2186,7 +2184,7 @@ Expr *expr_new(ExprKind kind, SourceSpan start);
Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v);
Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value);
Expr *expr_new_const_typeid(SourceSpan span, Type *type);
bool expr_is_simple(Expr *expr);
bool expr_is_simple(Expr *expr, bool to_float);
bool expr_is_pure(Expr *expr);
bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind);
bool expr_is_compile_time(Expr *ast);
@@ -2203,7 +2201,7 @@ bool expr_may_splat_as_vararg(Expr *expr, Type *variadic_base_type);
INLINE Expr *expr_new_expr(ExprKind kind, Expr *expr);
INLINE bool expr_ok(Expr *expr);
INLINE void expr_resolve_ident(Expr *expr, Decl *decl);
INLINE bool exprid_is_simple(ExprId expr_id);
INLINE bool exprid_is_simple(ExprId expr_id, bool to_float);
INLINE bool exprid_is_pure(ExprId expr_id);
INLINE Type *exprtype(ExprId expr_id);
INLINE void expr_replace(Expr *expr, Expr *replacement);
@@ -3152,7 +3150,7 @@ INLINE void expr_replace(Expr *expr, Expr *replacement)
INLINE bool expr_ok(Expr *expr) { return expr == NULL || expr->expr_kind != EXPR_POISONED; }
INLINE bool exprid_is_simple(ExprId expr_id) { return expr_is_simple(exprptr(expr_id)); }
INLINE bool exprid_is_simple(ExprId expr_id, bool to_float) { return expr_is_simple(exprptr(expr_id), to_float); }
INLINE void expr_resolve_ident(Expr *expr, Decl *decl)
{

View File

@@ -768,7 +768,7 @@ bool expr_is_pure(Expr *expr)
}
bool expr_is_simple(Expr *expr)
bool expr_is_simple(Expr *expr, bool to_float)
{
RETRY:
switch (expr->expr_kind)
@@ -777,7 +777,7 @@ bool expr_is_simple(Expr *expr)
expr = expr->inner_expr;
goto RETRY;
case EXPR_TERNARY:
return expr_is_simple(exprptr(expr->ternary_expr.else_expr)) && expr_is_simple(exprptr(expr->ternary_expr.then_expr));
return exprid_is_simple(expr->ternary_expr.else_expr, to_float) && exprid_is_simple(expr->ternary_expr.then_expr, to_float);
case EXPR_RETHROW:
expr = expr->rethrow_expr.inner;
goto RETRY;
@@ -786,6 +786,12 @@ bool expr_is_simple(Expr *expr)
case EXPR_BINARY:
switch (expr->binary_expr.operator)
{
case BINARYOP_DIV:
if (to_float) return false;
FALLTHROUGH;
case BINARYOP_MOD:
case BINARYOP_ELSE:
return exprid_is_simple(expr->binary_expr.left, to_float) && exprid_is_simple(expr->binary_expr.right, to_float);
case BINARYOP_AND:
case BINARYOP_OR:
case BINARYOP_GT:
@@ -806,6 +812,9 @@ bool expr_is_simple(Expr *expr)
case BINARYOP_SHL_ASSIGN:
case BINARYOP_SUB_ASSIGN:
return true;
case BINARYOP_SHL:
case BINARYOP_SHR:
return to_float;
default:
return false;
}
@@ -813,8 +822,9 @@ bool expr_is_simple(Expr *expr)
case EXPR_UNARY:
switch (expr->unary_expr.operator)
{
case UNARYOP_NEG:
case UNARYOP_BITNEG:
return to_float;
case UNARYOP_NEG:
return false;
default:
return true;

View File

@@ -622,27 +622,6 @@ bool cast_to_index(SemaContext *context, Expr *index)
}
}
bool cast_widen_top_down(SemaContext *context, Expr *expr, Type *type)
{
Type *to = type_no_optional(type);
Type *from = type_no_optional(expr->type);
RETRY:
if (type_is_integer(from) && type_is_integer(to)) goto CONVERT_IF_BIGGER;
if (type_is_float(from) && type_is_float(to)) goto CONVERT_IF_BIGGER;
if (type_is_integer(from) && type_is_float(to)) goto CONVERT;
if (type_flat_is_vector(from) && type_flat_is_vector(to))
{
to = type_vector_type(to);
from = type_vector_type(from);
goto RETRY;
}
return true;
CONVERT_IF_BIGGER:
if (type_size(to) <= type_size(from)) return true;
CONVERT:
return cast_implicit(context, expr, type);
}
Type *cast_numeric_arithmetic_promotion(Type *type)
{
if (!type) return NULL;
@@ -995,6 +974,21 @@ static bool rule_explicit_ok(CastContext *cc, bool is_explicit, bool silent)
}
static bool rule_int_to_float(CastContext *cc, bool is_explicit, bool is_silent)
{
if (is_explicit) return true;
Expr *expr = cc->expr;
if (!expr_is_simple(expr, true))
{
if (is_silent) return false;
RETURN_SEMA_ERROR(expr, "This conversion requires an explicit cast to %s, because the widening of the expression may be done in more than one way.",
type_quoted_error_string(cc->to_type));
}
return true;
}
static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
{
if (is_explicit) return true;
@@ -1006,11 +1000,11 @@ static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
// If widening, require simple.
if (to_size > from_size)
{
if (expr_is_simple(cc->expr)) return true;
if (expr_is_simple(cc->expr, type_is_float(cc->to))) return true;
if (is_silent) return false;
{
SEMA_ERROR(expr, "This conversion requires an explicit cast to %s, because the widening of the expression may be done in more than one way.",
type_quoted_error_string(cc->to_type));
type_quoted_error_string(cc->to_type));
}
return false;
}
@@ -1023,7 +1017,7 @@ static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
if (cc->to_group != CONV_INT)
{
RETURN_SEMA_ERROR(expr, "The value '%s' is out of range for %s, so you need an explicit cast to truncate the value.", expr_const_to_error_string(&expr->const_expr),
type_quoted_error_string(cc->to_type));
type_quoted_error_string(cc->to_type));
}
sema_error_const_int_out_of_range(expr, expr, cc->to_type);
}
@@ -1042,7 +1036,7 @@ static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
if (type_is_integer(type_flatten(problem->type))) expr = problem;
// Otherwise require a cast.
SEMA_ERROR(expr, "%s cannot implicitly be converted to %s, but you may use a cast.",
type_quoted_error_string(expr->type), type_quoted_error_string(cc->to_type));
type_quoted_error_string(expr->type), type_quoted_error_string(cc->to_type));
return false;
}
return true;
@@ -1868,6 +1862,7 @@ static void cast_typeid_to_bool(Expr *expr, Type *to_type)
#define REXPL &rule_explicit_ok /* Is explicit */
#define _NA__ &rule_not_applicable /* "Not applicable" - should not be seen. */
#define RIFIF &rule_widen_narrow /* Widen / narrow conversion of int/float */
#define RINFL &rule_int_to_float /* Simple expressions, check sizes */
#define ROKOK &rule_all_ok /* Always works */
#define RINPT &rule_int_to_ptr /* Int -> ptr (explicit + size match) */
#define RPTIN &rule_ptr_to_int /* Ptr -> int (explicit + size match) */
@@ -1897,7 +1892,7 @@ CastRule cast_rules[CONV_LAST + 1][CONV_LAST + 1] = {
{_NA__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // VOID (from)
{ROKOK, _NA__, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, _NO__}, // WILDCARD
{REXPL, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BOOL
{REXPL, _NO__, REXPL, RIFIF, ROKOK, RINPT, _NO__, ROKOK, RINBS, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, RINEN, _NO__, _NO__, RINPT, RINPT, _NO__}, // INT
{REXPL, _NO__, REXPL, RIFIF, RINFL, RINPT, _NO__, ROKOK, RINBS, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, RINEN, _NO__, _NO__, RINPT, RINPT, _NO__}, // INT
{REXPL, _NO__, REXPL, REXPL, RIFIF, _NO__, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // FLOAT
{REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE}, // PTR
{REXPL, _NO__, REXPL, _NO__, _NO__, RSAPT, RSASA, RSAVA, _NO__, RXXDI, RSAVA, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RSAPT, RSAFE}, // SARRAY

View File

@@ -113,7 +113,7 @@ static Type *sema_subscript_find_indexable_type_recursively(Type **type, Expr **
// -- binary helper functions
static void expr_binary_unify_failability(Expr *expr, Expr *left, Expr *right);
static inline bool sema_binary_promote_top_down(SemaContext *context, Expr *binary, Expr *left, Expr *right);
static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right);
static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context, Expr *expr, const char *error, bool bool_and_bitstruct_is_allowed);
static inline bool sema_binary_analyse_ct_identifier_lvalue(SemaContext *context, Expr *expr);
@@ -174,7 +174,7 @@ static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type
static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Type *type);
static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment,
AlignSize offset);
void expr_insert_widening_type(Expr *expr, Type *infer_type);
static inline int64_t expr_get_index_max(Expr *expr);
static inline bool expr_both_any_integer_or_integer_vector(Expr *left, Expr *right);
static inline bool expr_both_any_integer_or_integer_bool_vector(Expr *left, Expr *right);
@@ -1023,13 +1023,6 @@ static inline bool sema_expr_analyse_hash_identifier(SemaContext *context, Expr
}
static inline bool sema_binary_promote_top_down(SemaContext *context, Expr *binary, Expr *left, Expr *right)
{
if (!binary->binary_expr.widen) return true;
Type *to = binary->type;
return cast_widen_top_down(context, left, to) && cast_widen_top_down(context, right, to);
}
static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right)
{
// Special handling of f = FOO_BAR
@@ -1079,7 +1072,7 @@ static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context,
// 1. Analyse both sides.
if (!sema_binary_analyse_subexpr(context, expr, left, right)) return false;
if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
//if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
Type *left_type = type_no_optional(left->type)->canonical;
Type *right_type = type_no_optional(right->type)->canonical;
@@ -5090,8 +5083,6 @@ static bool sema_expr_analyse_sub(SemaContext *context, Expr *expr, Expr *left,
return sema_expr_analyse_enum_add_sub(context, expr, left, right);
}
if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
left_type = type_no_optional(left->type)->canonical;
right_type = type_no_optional(right->type)->canonical;
@@ -5270,8 +5261,6 @@ static bool sema_expr_analyse_add(SemaContext *context, Expr *expr, Expr *left,
return sema_expr_analyse_enum_add_sub(context, expr, left, right);
}
if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
left_type = type_no_optional(left->type)->canonical;
right_type = type_no_optional(right->type)->canonical;
@@ -5513,8 +5502,6 @@ static bool sema_expr_analyse_shift(SemaContext *context, Expr *expr, Expr *left
return sema_type_error_on_binop(expr);
}
if (expr->binary_expr.widen && !cast_widen_top_down(context, left, expr->type)) return false;
// 3. Promote lhs using the usual numeric promotion.
if (!cast_implicit(context, left, cast_numeric_arithmetic_promotion(type_no_optional(left->type)))) return false;
@@ -6011,7 +5998,6 @@ static inline bool sema_expr_analyse_neg_plus(SemaContext *context, Expr *expr)
Expr *inner = expr->unary_expr.expr;
bool is_plus = expr->unary_expr.operator == UNARYOP_PLUS;
if (!sema_analyse_expr(context, inner)) return false;
if (expr->unary_expr.widen && !cast_widen_top_down(context, inner, expr->type)) return false;
// 2. Check if it's possible to negate this (i.e. is it an int, float or vector)
Type *no_fail = type_no_optional(inner->type);
@@ -6069,8 +6055,6 @@ static inline bool sema_expr_analyse_bit_not(SemaContext *context, Expr *expr)
Expr *inner = expr->unary_expr.expr;
if (!sema_analyse_expr(context, inner)) return false;
if (expr->unary_expr.widen && !cast_widen_top_down(context, inner, expr->type)) return false;
// 2. Check that it's a vector, bool
Type *canonical = type_no_optional(inner->type)->canonical;
Type *flat = type_flatten(canonical);
@@ -6319,8 +6303,6 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr)
if (!sema_analyse_expr(context, lhs)) return false;
}
if (expr->binary_expr.widen && !cast_widen_top_down(context, lhs, expr->type)) return false;
Type *type = lhs->type;
if (!type_is_optional(type))
{
@@ -6335,7 +6317,6 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr)
// First we analyse the "else" and try to implictly cast.
if (!sema_analyse_expr(context, rhs)) return false;
if (expr->binary_expr.widen && !cast_widen_top_down(context, rhs, expr->type)) return false;
if (lhs->expr_kind == EXPR_OPTIONAL)
{
@@ -8350,58 +8331,6 @@ RETRY:
UNREACHABLE
}
void expr_insert_widening_type(Expr *expr, Type *infer_type)
{
if (!infer_type) return;
switch (expr->expr_kind)
{
case EXPR_BINARY:
switch (expr->binary_expr.operator)
{
case BINARYOP_MULT:
case BINARYOP_SUB:
case BINARYOP_ADD:
case BINARYOP_DIV:
case BINARYOP_MOD:
case BINARYOP_SHR:
case BINARYOP_SHL:
case BINARYOP_BIT_OR:
case BINARYOP_BIT_XOR:
case BINARYOP_BIT_AND:
case BINARYOP_ELSE:
if (!expr_is_simple(exprptr(expr->binary_expr.left)) || !expr_is_simple(exprptr(expr->binary_expr.right))) return;
expr->type = infer_type;
expr->binary_expr.widen = true;
return;
default:
return;
}
case EXPR_GROUP:
expr_insert_widening_type(expr->inner_expr, infer_type);
return;
case EXPR_TERNARY:
if (!exprid_is_simple(expr->ternary_expr.else_expr)) return;
if (expr->ternary_expr.then_expr && !exprid_is_simple(expr->ternary_expr.else_expr)) return;
expr->type = infer_type;
expr->ternary_expr.widen = true;
return;
case EXPR_UNARY:
switch (expr->unary_expr.operator)
{
case UNARYOP_NEG:
case UNARYOP_BITNEG:
if (!expr_is_simple(expr->unary_expr.expr)) return;
expr->type = infer_type;
expr->unary_expr.widen = true;
return;
default:
return;
}
default:
return;
}
UNREACHABLE
}
bool sema_analyse_inferred_expr(SemaContext *context, Type *infer_type, Expr *expr)
{
infer_type = type_no_optional(infer_type);
@@ -8436,7 +8365,6 @@ bool sema_analyse_inferred_expr(SemaContext *context, Type *infer_type, Expr *ex
if (!sema_expr_analyse_lambda(context, infer_type, expr)) return expr_poison(expr);
break;
default:
expr_insert_widening_type(expr, infer_type);
if (!sema_analyse_expr_dispatch(context, expr)) return expr_poison(expr);
break;
}

View File

@@ -80,7 +80,7 @@ bool sema_bit_assignment_check(Expr *right, Decl *member);
int sema_check_comp_time_bool(SemaContext *context, Expr *expr);
bool sema_expr_check_assign(SemaContext *c, Expr *expr);
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, CallABI abi, Signature *signature, bool is_real_function);
bool cast_widen_top_down(SemaContext *context, Expr *expr, Type *type);
MemberIndex sema_len_from_const(Expr *expr);
void cast_promote_vararg(Expr *arg);

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.651"
#define COMPILER_VERSION "0.4.652"

View File

@@ -7,7 +7,7 @@ fn void main()
int x = 222;
int y = 223;
long z = 0;
z = x + y;
z = (long)x + y;
z *= x;
int g = 0;
int* gp = &g;

View File

@@ -2,17 +2,17 @@ fn void test()
{
int x;
int y;
long z = x * y;
long z = x * (long)y;
z = x * y + z; // #error: 'long'
z = x * y + x; // #error: 'long'
z = x / y;
z = x + y;
z = x - y;
z = (long)x + y;
z = (long)x - y;
z = x % y;
z = x / y + z; // #error: 'long'
z = x / y + z;
z = x + y + z; // #error: 'long'
z = x - y + z; // #error: 'long'
z = x % y + z; // #error: 'long'
z = x % y + z;
z = x / y + x; // #error: 'long'
z = x + y + x; // #error: 'long'
z = x - y + x; // #error: 'long'

View File

@@ -2,15 +2,15 @@ fn void test()
{
int x;
int y;
long z = x * y;
long z = (long)x * y;
z = x / y;
z = x + y;
z = x - y;
z = (long)x + y;
z = (long)x - y;
z = x % y;
z = x << y;
z = x >> y;
z = ~x;
z = -x;
z = (long)x << y;
z = (long)x >> y;
z = (long)~x;
z = (long)-x;
int! w;
z = w ?? 1;
}
@@ -33,70 +33,64 @@ entry:
%mul = mul i64 %sext, %sext1
store i64 %mul, ptr %z, align 8
%2 = load i32, ptr %x, align 4
%sext2 = sext i32 %2 to i64
%3 = load i32, ptr %y, align 4
%sext3 = sext i32 %3 to i64
%sdiv = sdiv i64 %sext2, %sext3
store i64 %sdiv, ptr %z, align 8
%sdiv = sdiv i32 %2, %3
%sext2 = sext i32 %sdiv to i64
store i64 %sext2, ptr %z, align 8
%4 = load i32, ptr %x, align 4
%sext4 = sext i32 %4 to i64
%sext3 = sext i32 %4 to i64
%5 = load i32, ptr %y, align 4
%sext5 = sext i32 %5 to i64
%add = add i64 %sext4, %sext5
%sext4 = sext i32 %5 to i64
%add = add i64 %sext3, %sext4
store i64 %add, ptr %z, align 8
%6 = load i32, ptr %x, align 4
%sext6 = sext i32 %6 to i64
%sext5 = sext i32 %6 to i64
%7 = load i32, ptr %y, align 4
%sext7 = sext i32 %7 to i64
%sub = sub i64 %sext6, %sext7
%sext6 = sext i32 %7 to i64
%sub = sub i64 %sext5, %sext6
store i64 %sub, ptr %z, align 8
%8 = load i32, ptr %x, align 4
%sext8 = sext i32 %8 to i64
%9 = load i32, ptr %y, align 4
%sext9 = sext i32 %9 to i64
%smod = srem i64 %sext8, %sext9
store i64 %smod, ptr %z, align 8
%smod = srem i32 %8, %9
%sext7 = sext i32 %smod to i64
store i64 %sext7, ptr %z, align 8
%10 = load i32, ptr %x, align 4
%sext10 = sext i32 %10 to i64
%sext8 = sext i32 %10 to i64
%11 = load i32, ptr %y, align 4
%zext = zext i32 %11 to i64
%shl = shl i64 %sext10, %zext
%shl = shl i64 %sext8, %zext
%12 = freeze i64 %shl
store i64 %12, ptr %z, align 8
%13 = load i32, ptr %x, align 4
%sext11 = sext i32 %13 to i64
%sext9 = sext i32 %13 to i64
%14 = load i32, ptr %y, align 4
%zext12 = zext i32 %14 to i64
%ashr = ashr i64 %sext11, %zext12
%zext10 = zext i32 %14 to i64
%ashr = ashr i64 %sext9, %zext10
%15 = freeze i64 %ashr
store i64 %15, ptr %z, align 8
%16 = load i32, ptr %x, align 4
%sext13 = sext i32 %16 to i64
%bnot = xor i64 %sext13, -1
store i64 %bnot, ptr %z, align 8
%bnot = xor i32 %16, -1
%sext11 = sext i32 %bnot to i64
store i64 %sext11, ptr %z, align 8
%17 = load i32, ptr %x, align 4
%sext14 = sext i32 %17 to i64
%18 = load i32, ptr %x, align 4
%sext15 = sext i32 %18 to i64
%neg = sub i64 0, %sext15
store i64 %neg, ptr %z, align 8
%neg = sub i32 0, %18
%sext12 = sext i32 %neg to i64
store i64 %sext12, ptr %z, align 8
store i64 0, ptr %w.f, align 8
store i32 0, ptr %w, align 4
%optval = load i64, ptr %w.f, align 8
%not_err = icmp eq i64 %optval, 0
%19 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %19, label %after_check, label %else_block
after_check: ; preds = %entry
%20 = load i32, ptr %w, align 4
%sext16 = sext i32 %20 to i64
br label %phi_block
else_block: ; preds = %entry
br label %phi_block
phi_block: ; preds = %else_block, %after_check
%val = phi i64 [ %sext16, %after_check ], [ 1, %else_block ]
store i64 %val, ptr %z, align 8
%val = phi i32 [ %20, %after_check ], [ 1, %else_block ]
%sext13 = sext i32 %val to i64
store i64 %sext13, ptr %z, align 8
ret void
}

View File

@@ -5,10 +5,10 @@ extern fn int! testError();
fn void test()
{
double x = (testError() + testError()) ?? 100;
double x = ((double)testError() + testError()) ?? 100;
double y = (1 << testError()) ?? 100;
double z = testError() >> 1 ?? 100;
double w = testError() * testError() ?? 100;
double w = (double)testError() * testError() ?? 100;
}
/* #expect: else_checks.ll
@@ -23,12 +23,12 @@ entry:
%retparam = alloca i32, align 4
%retparam1 = alloca i32, align 4
%y = alloca double, align 8
%retparam4 = alloca i32, align 4
%retparam5 = alloca i32, align 4
%z = alloca double, align 8
%retparam11 = alloca i32, align 4
%retparam12 = alloca i32, align 4
%w = alloca double, align 8
%retparam18 = alloca i32, align 4
%retparam21 = alloca i32, align 4
%retparam19 = alloca i32, align 4
%retparam23 = alloca i32, align 4
%0 = call i64 @testError(ptr %retparam)
%not_err = icmp eq i64 %0, 0
%1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
@@ -36,6 +36,7 @@ entry:
after_check: ; preds = %entry
%2 = load i32, ptr %retparam, align 4
%sifp = sitofp i32 %2 to double
%3 = call i64 @testError(ptr %retparam1)
%not_err2 = icmp eq i64 %3, 0
%4 = call i1 @llvm.expect.i1(i1 %not_err2, i1 true)
@@ -43,75 +44,76 @@ after_check: ; preds = %entry
after_check3: ; preds = %after_check
%5 = load i32, ptr %retparam1, align 4
%add = add i32 %2, %5
%sifp4 = sitofp i32 %5 to double
%fadd = fadd double %sifp, %sifp4
br label %phi_block
else_block: ; preds = %after_check, %entry
br label %phi_block
phi_block: ; preds = %else_block, %after_check3
%val = phi i32 [ %add, %after_check3 ], [ 100, %else_block ]
%sifp = sitofp i32 %val to double
store double %sifp, ptr %x, align 8
%6 = call i64 @testError(ptr %retparam4)
%not_err5 = icmp eq i64 %6, 0
%7 = call i1 @llvm.expect.i1(i1 %not_err5, i1 true)
br i1 %7, label %after_check6, label %else_block7
%val = phi double [ %fadd, %after_check3 ], [ 1.000000e+02, %else_block ]
store double %val, ptr %x, align 8
%6 = call i64 @testError(ptr %retparam5)
%not_err6 = icmp eq i64 %6, 0
%7 = call i1 @llvm.expect.i1(i1 %not_err6, i1 true)
br i1 %7, label %after_check7, label %else_block8
after_check6: ; preds = %phi_block
%8 = load i32, ptr %retparam4, align 4
after_check7: ; preds = %phi_block
%8 = load i32, ptr %retparam5, align 4
%shl = shl i32 1, %8
%9 = freeze i32 %shl
br label %phi_block8
br label %phi_block9
else_block7: ; preds = %phi_block
br label %phi_block8
else_block8: ; preds = %phi_block
br label %phi_block9
phi_block8: ; preds = %else_block7, %after_check6
%val9 = phi i32 [ %9, %after_check6 ], [ 100, %else_block7 ]
%sifp10 = sitofp i32 %val9 to double
store double %sifp10, ptr %y, align 8
%10 = call i64 @testError(ptr %retparam11)
%not_err12 = icmp eq i64 %10, 0
%11 = call i1 @llvm.expect.i1(i1 %not_err12, i1 true)
br i1 %11, label %after_check13, label %else_block14
phi_block9: ; preds = %else_block8, %after_check7
%val10 = phi i32 [ %9, %after_check7 ], [ 100, %else_block8 ]
%sifp11 = sitofp i32 %val10 to double
store double %sifp11, ptr %y, align 8
%10 = call i64 @testError(ptr %retparam12)
%not_err13 = icmp eq i64 %10, 0
%11 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true)
br i1 %11, label %after_check14, label %else_block15
after_check13: ; preds = %phi_block8
%12 = load i32, ptr %retparam11, align 4
after_check14: ; preds = %phi_block9
%12 = load i32, ptr %retparam12, align 4
%ashr = ashr i32 %12, 1
%13 = freeze i32 %ashr
br label %phi_block15
br label %phi_block16
else_block14: ; preds = %phi_block8
br label %phi_block15
else_block15: ; preds = %phi_block9
br label %phi_block16
phi_block15: ; preds = %else_block14, %after_check13
%val16 = phi i32 [ %13, %after_check13 ], [ 100, %else_block14 ]
%sifp17 = sitofp i32 %val16 to double
store double %sifp17, ptr %z, align 8
%14 = call i64 @testError(ptr %retparam18)
%not_err19 = icmp eq i64 %14, 0
%15 = call i1 @llvm.expect.i1(i1 %not_err19, i1 true)
br i1 %15, label %after_check20, label %else_block24
phi_block16: ; preds = %else_block15, %after_check14
%val17 = phi i32 [ %13, %after_check14 ], [ 100, %else_block15 ]
%sifp18 = sitofp i32 %val17 to double
store double %sifp18, ptr %z, align 8
%14 = call i64 @testError(ptr %retparam19)
%not_err20 = icmp eq i64 %14, 0
%15 = call i1 @llvm.expect.i1(i1 %not_err20, i1 true)
br i1 %15, label %after_check21, label %else_block27
after_check20: ; preds = %phi_block15
%16 = load i32, ptr %retparam18, align 4
%17 = call i64 @testError(ptr %retparam21)
%not_err22 = icmp eq i64 %17, 0
%18 = call i1 @llvm.expect.i1(i1 %not_err22, i1 true)
br i1 %18, label %after_check23, label %else_block24
after_check21: ; preds = %phi_block16
%16 = load i32, ptr %retparam19, align 4
%sifp22 = sitofp i32 %16 to double
%17 = call i64 @testError(ptr %retparam23)
%not_err24 = icmp eq i64 %17, 0
%18 = call i1 @llvm.expect.i1(i1 %not_err24, i1 true)
br i1 %18, label %after_check25, label %else_block27
after_check23: ; preds = %after_check20
%19 = load i32, ptr %retparam21, align 4
%mul = mul i32 %16, %19
br label %phi_block25
after_check25: ; preds = %after_check21
%19 = load i32, ptr %retparam23, align 4
%sifp26 = sitofp i32 %19 to double
%fmul = fmul double %sifp22, %sifp26
br label %phi_block28
else_block24: ; preds = %after_check20, %phi_block15
br label %phi_block25
else_block27: ; preds = %after_check21, %phi_block16
br label %phi_block28
phi_block25: ; preds = %else_block24, %after_check23
%val26 = phi i32 [ %mul, %after_check23 ], [ 100, %else_block24 ]
%sifp27 = sitofp i32 %val26 to double
store double %sifp27, ptr %w, align 8
phi_block28: ; preds = %else_block27, %after_check25
%val29 = phi double [ %fmul, %after_check25 ], [ 1.000000e+02, %else_block27 ]
store double %val29, ptr %w, align 8
ret void
}

View File

@@ -58,7 +58,7 @@ fn Doc! readDoc(char[] url)
if (contains(url, "title-missing")) return { dupe(Head { .title = null })! };
if (contains(url, "title-empty")) return { dupe(Head { .title = dupe((char[])"")! })! };
// Not particularly elegant due to missing string functions.
int len = libc::snprintf(null, 0, "Title of %.*s", (int)url.len, url.ptr);
isz len = libc::snprintf(null, 0, "Title of %.*s", (int)url.len, url.ptr);
char* str = malloc(len + 1);
if (!str) return ReadError.OUT_OF_MEMORY?;
libc::snprintf(str, len + 1, "Title of %.*s", (int)url.len, url.ptr);
@@ -301,7 +301,7 @@ entry:
%retparam57 = alloca ptr, align 8
%varargslots62 = alloca [1 x %any], align 16
%indirectarg64 = alloca %"any[]", align 8
%len = alloca i32, align 4
%len = alloca i64, align 8
%str = alloca ptr, align 8
%using72 = alloca ptr, align 8
%error_var73 = alloca i64, align 8
@@ -310,29 +310,29 @@ entry:
%retparam77 = alloca ptr, align 8
%varargslots82 = alloca [1 x %any], align 16
%indirectarg84 = alloca %"any[]", align 8
%reterr92 = alloca i64, align 8
%literal93 = alloca %Doc, align 8
%error_var94 = alloca i64, align 8
%literal95 = alloca %Head, align 8
%error_var96 = alloca i64, align 8
%value99 = alloca %"char[]", align 8
%temp100 = alloca ptr, align 8
%reterr91 = alloca i64, align 8
%literal92 = alloca %Doc, align 8
%error_var93 = alloca i64, align 8
%literal94 = alloca %Head, align 8
%error_var95 = alloca i64, align 8
%value97 = alloca %"char[]", align 8
%temp98 = alloca ptr, align 8
%using99 = alloca ptr, align 8
%error_var100 = alloca i64, align 8
%using101 = alloca ptr, align 8
%error_var102 = alloca i64, align 8
%using103 = alloca ptr, align 8
%allocator105 = alloca ptr, align 8
%retparam107 = alloca ptr, align 8
%varargslots112 = alloca [1 x %any], align 16
%indirectarg114 = alloca %"any[]", align 8
%value121 = alloca %Head, align 8
%temp122 = alloca ptr, align 8
%allocator103 = alloca ptr, align 8
%retparam105 = alloca ptr, align 8
%varargslots110 = alloca [1 x %any], align 16
%indirectarg112 = alloca %"any[]", align 8
%value119 = alloca %Head, align 8
%temp120 = alloca ptr, align 8
%using121 = alloca ptr, align 8
%error_var122 = alloca i64, align 8
%using123 = alloca ptr, align 8
%error_var124 = alloca i64, align 8
%using125 = alloca ptr, align 8
%allocator127 = alloca ptr, align 8
%retparam129 = alloca ptr, align 8
%varargslots134 = alloca [1 x %any], align 16
%indirectarg136 = alloca %"any[]", align 8
%allocator125 = alloca ptr, align 8
%retparam127 = alloca ptr, align 8
%varargslots132 = alloca [1 x %any], align 16
%indirectarg134 = alloca %"any[]", align 8
store ptr %1, ptr %url, align 8
%ptroffset = getelementptr inbounds i64, ptr %url, i64 1
store i64 %2, ptr %ptroffset, align 8
@@ -570,17 +570,17 @@ if.exit71: ; preds = %if.exit18
%78 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%79 = load ptr, ptr %78, align 8
%80 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %trunc, ptr %79)
store i32 %80, ptr %len, align 4
%sext = sext i32 %80 to i64
store i64 %sext, ptr %len, align 8
%81 = load ptr, ptr @std.core.mem.thread_allocator, align 8
store ptr %81, ptr %using72, align 8
%82 = load ptr, ptr %using72, align 8
store ptr %82, ptr %using74, align 8
%83 = load i32, ptr %len, align 4
%add = add i32 %83, 1
%83 = load i64, ptr %len, align 8
%add = add i64 %83, 1
%84 = load ptr, ptr %using74, align 8
store ptr %84, ptr %allocator75, align 8
%sext = sext i32 %add to i64
%add76 = add i64 %sext, 0
%add76 = add i64 %add, 0
%85 = load ptr, ptr %allocator75, align 8
%86 = getelementptr inbounds %Allocator, ptr %85, i32 0, i32 0
%87 = load ptr, ptr %86, align 8
@@ -620,142 +620,140 @@ if.then87: ; preds = %noerr_block85
if.exit88: ; preds = %noerr_block85
%97 = load ptr, ptr %str, align 8
%98 = load i32, ptr %len, align 4
%sext89 = sext i32 %98 to i64
%add90 = add i64 %sext89, 1
%98 = load i64, ptr %len, align 8
%add89 = add i64 %98, 1
%99 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%100 = load i64, ptr %99, align 8
%trunc91 = trunc i64 %100 to i32
%trunc90 = trunc i64 %100 to i32
%101 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%102 = load ptr, ptr %101, align 8
%103 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %97, i64 %add90, ptr @.str.8, i32 %trunc91, ptr %102)
%104 = getelementptr inbounds %Doc, ptr %literal93, i32 0, i32 0
store ptr null, ptr %literal95, align 8
%105 = getelementptr inbounds %Head, ptr %literal95, i32 0, i32 0
%103 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %97, i64 %add89, ptr @.str.8, i32 %trunc90, ptr %102)
%104 = getelementptr inbounds %Doc, ptr %literal92, i32 0, i32 0
store ptr null, ptr %literal94, align 8
%105 = getelementptr inbounds %Head, ptr %literal94, i32 0, i32 0
%106 = load ptr, ptr %str, align 8
%107 = load i32, ptr %len, align 4
%sub = sub i32 %107, 1
%sext97 = sext i32 %sub to i64
%108 = add i64 %sext97, 1
%107 = load i64, ptr %len, align 8
%sub = sub i64 %107, 1
%108 = add i64 %sub, 1
%size = sub i64 %108, 0
%ptroffset98 = getelementptr inbounds i8, ptr %106, i64 0
%109 = insertvalue %"char[]" undef, ptr %ptroffset98, 0
%ptroffset96 = getelementptr inbounds i8, ptr %106, i64 0
%109 = insertvalue %"char[]" undef, ptr %ptroffset96, 0
%110 = insertvalue %"char[]" %109, i64 %size, 1
store %"char[]" %110, ptr %value99, align 8
store %"char[]" %110, ptr %value97, align 8
%111 = load ptr, ptr @std.core.mem.thread_allocator, align 8
store ptr %111, ptr %using101, align 8
%112 = load ptr, ptr %using101, align 8
store ptr %112, ptr %using103, align 8
%113 = load ptr, ptr %using103, align 8
store ptr %113, ptr %allocator105, align 8
%114 = load ptr, ptr %allocator105, align 8
store ptr %111, ptr %using99, align 8
%112 = load ptr, ptr %using99, align 8
store ptr %112, ptr %using101, align 8
%113 = load ptr, ptr %using101, align 8
store ptr %113, ptr %allocator103, align 8
%114 = load ptr, ptr %allocator103, align 8
%115 = getelementptr inbounds %Allocator, ptr %114, i32 0, i32 0
%116 = load ptr, ptr %115, align 8
%117 = load ptr, ptr %allocator105, align 8
%118 = call i64 %116(ptr %retparam107, ptr %117, i64 16, i64 0, i64 0, ptr null, i32 0)
%not_err108 = icmp eq i64 %118, 0
%119 = call i1 @llvm.expect.i1(i1 %not_err108, i1 true)
br i1 %119, label %after_check110, label %assign_optional109
%117 = load ptr, ptr %allocator103, align 8
%118 = call i64 %116(ptr %retparam105, ptr %117, i64 16, i64 0, i64 0, ptr null, i32 0)
%not_err106 = icmp eq i64 %118, 0
%119 = call i1 @llvm.expect.i1(i1 %not_err106, i1 true)
br i1 %119, label %after_check108, label %assign_optional107
assign_optional109: ; preds = %if.exit88
store i64 %118, ptr %error_var102, align 8
br label %panic_block111
assign_optional107: ; preds = %if.exit88
store i64 %118, ptr %error_var100, align 8
br label %panic_block109
after_check110: ; preds = %if.exit88
%120 = load ptr, ptr %retparam107, align 8
br label %noerr_block115
after_check108: ; preds = %if.exit88
%120 = load ptr, ptr %retparam105, align 8
br label %noerr_block113
panic_block111: ; preds = %assign_optional109
%121 = insertvalue %any undef, ptr %error_var102, 0
panic_block109: ; preds = %assign_optional107
%121 = insertvalue %any undef, ptr %error_var100, 0
%122 = insertvalue %any %121, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%123 = getelementptr inbounds [1 x %any], ptr %varargslots112, i64 0, i64 0
%123 = getelementptr inbounds [1 x %any], ptr %varargslots110, i64 0, i64 0
store %any %122, ptr %123, align 16
%124 = insertvalue %"any[]" undef, ptr %varargslots112, 0
%"#temp#113" = insertvalue %"any[]" %124, i64 1, 1
store %"any[]" %"#temp#113", ptr %indirectarg114, align 8
%124 = insertvalue %"any[]" undef, ptr %varargslots110, 0
%"#temp#111" = insertvalue %"any[]" %124, i64 1, 1
store %"any[]" %"#temp#111", ptr %indirectarg112, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func
unreachable
noerr_block115: ; preds = %after_check110
store ptr %120, ptr %temp100, align 8
%125 = load ptr, ptr %temp100, align 8
%not116 = icmp eq ptr %125, null
br i1 %not116, label %if.then117, label %if.exit118
noerr_block113: ; preds = %after_check108
store ptr %120, ptr %temp98, align 8
%125 = load ptr, ptr %temp98, align 8
%not114 = icmp eq ptr %125, null
br i1 %not114, label %if.then115, label %if.exit116
if.then117: ; preds = %noerr_block115
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var96, align 8
br label %guard_block119
if.then115: ; preds = %noerr_block113
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var95, align 8
br label %guard_block117
if.exit118: ; preds = %noerr_block115
%126 = load ptr, ptr %temp100, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %126, ptr align 8 %value99, i32 16, i1 false)
br label %noerr_block120
if.exit116: ; preds = %noerr_block113
%126 = load ptr, ptr %temp98, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %126, ptr align 8 %value97, i32 16, i1 false)
br label %noerr_block118
guard_block119: ; preds = %if.then117
%127 = load i64, ptr %error_var96, align 8
guard_block117: ; preds = %if.then115
%127 = load i64, ptr %error_var95, align 8
ret i64 %127
noerr_block120: ; preds = %if.exit118
%128 = load ptr, ptr %temp100, align 8
noerr_block118: ; preds = %if.exit116
%128 = load ptr, ptr %temp98, align 8
store ptr %128, ptr %105, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value121, ptr align 8 %literal95, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value119, ptr align 8 %literal94, i32 8, i1 false)
%129 = load ptr, ptr @std.core.mem.thread_allocator, align 8
store ptr %129, ptr %using123, align 8
%130 = load ptr, ptr %using123, align 8
store ptr %130, ptr %using125, align 8
%131 = load ptr, ptr %using125, align 8
store ptr %131, ptr %allocator127, align 8
%132 = load ptr, ptr %allocator127, align 8
store ptr %129, ptr %using121, align 8
%130 = load ptr, ptr %using121, align 8
store ptr %130, ptr %using123, align 8
%131 = load ptr, ptr %using123, align 8
store ptr %131, ptr %allocator125, align 8
%132 = load ptr, ptr %allocator125, align 8
%133 = getelementptr inbounds %Allocator, ptr %132, i32 0, i32 0
%134 = load ptr, ptr %133, align 8
%135 = load ptr, ptr %allocator127, align 8
%136 = call i64 %134(ptr %retparam129, ptr %135, i64 8, i64 0, i64 0, ptr null, i32 0)
%not_err130 = icmp eq i64 %136, 0
%137 = call i1 @llvm.expect.i1(i1 %not_err130, i1 true)
br i1 %137, label %after_check132, label %assign_optional131
%135 = load ptr, ptr %allocator125, align 8
%136 = call i64 %134(ptr %retparam127, ptr %135, i64 8, i64 0, i64 0, ptr null, i32 0)
%not_err128 = icmp eq i64 %136, 0
%137 = call i1 @llvm.expect.i1(i1 %not_err128, i1 true)
br i1 %137, label %after_check130, label %assign_optional129
assign_optional131: ; preds = %noerr_block120
store i64 %136, ptr %error_var124, align 8
br label %panic_block133
assign_optional129: ; preds = %noerr_block118
store i64 %136, ptr %error_var122, align 8
br label %panic_block131
after_check132: ; preds = %noerr_block120
%138 = load ptr, ptr %retparam129, align 8
br label %noerr_block137
after_check130: ; preds = %noerr_block118
%138 = load ptr, ptr %retparam127, align 8
br label %noerr_block135
panic_block133: ; preds = %assign_optional131
%139 = insertvalue %any undef, ptr %error_var124, 0
panic_block131: ; preds = %assign_optional129
%139 = insertvalue %any undef, ptr %error_var122, 0
%140 = insertvalue %any %139, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%141 = getelementptr inbounds [1 x %any], ptr %varargslots134, i64 0, i64 0
%141 = getelementptr inbounds [1 x %any], ptr %varargslots132, i64 0, i64 0
store %any %140, ptr %141, align 16
%142 = insertvalue %"any[]" undef, ptr %varargslots134, 0
%"#temp#135" = insertvalue %"any[]" %142, i64 1, 1
store %"any[]" %"#temp#135", ptr %indirectarg136, align 8
%142 = insertvalue %"any[]" undef, ptr %varargslots132, 0
%"#temp#133" = insertvalue %"any[]" %142, i64 1, 1
store %"any[]" %"#temp#133", ptr %indirectarg134, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func, i64 7
unreachable
noerr_block137: ; preds = %after_check132
store ptr %138, ptr %temp122, align 8
%143 = load ptr, ptr %temp122, align 8
%not138 = icmp eq ptr %143, null
br i1 %not138, label %if.then139, label %if.exit140
noerr_block135: ; preds = %after_check130
store ptr %138, ptr %temp120, align 8
%143 = load ptr, ptr %temp120, align 8
%not136 = icmp eq ptr %143, null
br i1 %not136, label %if.then137, label %if.exit138
if.then139: ; preds = %noerr_block137
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var94, align 8
br label %guard_block141
if.then137: ; preds = %noerr_block135
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var93, align 8
br label %guard_block139
if.exit140: ; preds = %noerr_block137
%144 = load ptr, ptr %temp122, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %144, ptr align 8 %value121, i32 8, i1 false)
br label %noerr_block142
if.exit138: ; preds = %noerr_block135
%144 = load ptr, ptr %temp120, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %144, ptr align 8 %value119, i32 8, i1 false)
br label %noerr_block140
guard_block141: ; preds = %if.then139
%145 = load i64, ptr %error_var94, align 8
guard_block139: ; preds = %if.then137
%145 = load i64, ptr %error_var93, align 8
ret i64 %145
noerr_block142: ; preds = %if.exit140
%146 = load ptr, ptr %temp122, align 8
noerr_block140: ; preds = %if.exit138
%146 = load ptr, ptr %temp120, align 8
store ptr %146, ptr %104, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal93, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal92, i32 8, i1 false)
ret i64 0
}

View File

@@ -73,8 +73,8 @@ fn int main(int c, char** v)
GameBoard board;
board.w = w;
board.h = h;
board.world = malloc(h * w);
board.temp = malloc(h * w);
board.world = malloc((isz)h * w);
board.temp = malloc((isz)h * w);
for (int i = h * w - 1; i >= 0; i--)
{

View File

@@ -3,7 +3,7 @@ module foo;
fn float[20] get()
{
float[20] y;
for (int i = 0; i < 20; i++) y[i] = i * i + 1;
for (int i = 0; i < 20; i++) y[i] = (float)i * i + 1;
return y;
}
fn void main()