Fix +a = 1 erronously being accepted. Refactorings.

This commit is contained in:
Christoffer Lerno
2025-01-05 02:24:11 +01:00
parent 86a674b87e
commit 07c59e6a6c
18 changed files with 304 additions and 387 deletions

View File

@@ -54,6 +54,7 @@
- Prohibit raw vaargs in regular functions with a function body.
- Assert on certain slice to slice casts. #1768.
- Fix vector float -> bool conversion.
- Fix `+a = 1` erronously being accepted.
### Stdlib changes
- Increase BitWriter.write_bits limit up to 32 bits.

View File

@@ -396,6 +396,7 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr)
switch (expr->expr_kind)
{
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_DISCARD:
case EXPR_RVALUE:
case EXPR_RECAST:

View File

@@ -3371,6 +3371,7 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc)
return;
case EXPR_SPLAT:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_DISCARD:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_ADDR_CONVERSION:
@@ -3606,6 +3607,7 @@ INLINE void expr_rewrite_recast(Expr *expr, Type *type)
expr->type = type;
}
INLINE void expr_rewrite_rvalue(Expr *expr, Type *type)
{
switch (expr->expr_kind)
@@ -3716,12 +3718,23 @@ INLINE void expr_rewrite_const_typeid(Expr *expr, Type *type)
expr->resolve_status = RESOLVE_DONE;
}
INLINE void expr_rewrite_ptr_access(Expr *expr, Type *type)
INLINE void expr_rewrite_ptr_access(Expr *expr, Expr *inner, Type *type)
{
Expr *inner = expr_copy(expr);
assert(inner->resolve_status == RESOLVE_DONE);
expr->expr_kind = EXPR_PTR_ACCESS;
expr->inner_expr = inner;
expr->type = type;
expr->resolve_status = RESOLVE_DONE;
}
INLINE void expr_rewrite_slice_len(Expr *expr, Expr *inner, Type *type)
{
assert(inner->resolve_status == RESOLVE_DONE);
expr->expr_kind = EXPR_SLICE_LEN;
expr->inner_expr = inner;
expr->type = type_add_optional(type, IS_OPTIONAL(inner));
expr->resolve_status = RESOLVE_DONE;
}
INLINE void expr_rewrite_int_to_bool(Expr *expr, bool negate)

View File

@@ -476,6 +476,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
case EXPR_SPLAT:
case EXPR_STRINGIFY:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_DISCARD:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_RVALUE:

View File

@@ -379,8 +379,6 @@ typedef enum BoolErr__
typedef enum
{
ACCESS_LEN,
ACCESS_PTR,
ACCESS_TYPEOFANY,
ACCESS_TYPEOFANYFAULT,
ACCESS_ENUMNAME,
@@ -552,7 +550,6 @@ typedef enum
CAST_EUER,
CAST_FPFP,
CAST_FPINT,
CAST_INTBOOL,
CAST_INTENUM,
CAST_INTFP,
CAST_IDPTR,
@@ -800,6 +797,7 @@ typedef enum
EXPR_RVALUE,
EXPR_RECAST,
EXPR_SLICE,
EXPR_SLICE_LEN,
EXPR_SLICE_ASSIGN,
EXPR_SLICE_COPY,
EXPR_SPLAT,

View File

@@ -84,6 +84,7 @@ bool expr_may_addr(Expr *expr)
case EXPR_TEST_HOOK:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_RVALUE:
case EXPR_RECAST:
case EXPR_DISCARD:
@@ -194,6 +195,7 @@ bool expr_is_runtime_const(Expr *expr)
case EXPR_BITACCESS:
case EXPR_COND:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
return false;
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_RVALUE:
@@ -213,8 +215,6 @@ bool expr_is_runtime_const(Expr *expr)
{
case ACCESS_ENUMNAME:
case ACCESS_FAULTNAME:
case ACCESS_LEN:
case ACCESS_PTR:
case ACCESS_FAULTORDINAL:
break;
case ACCESS_TYPEOFANYFAULT:
@@ -359,7 +359,6 @@ static inline bool expr_cast_is_runtime_const(Expr *expr)
case CAST_EUER:
case CAST_PTRBOOL:
case CAST_BOOLFP:
case CAST_INTBOOL:
case CAST_FPFP:
case CAST_FPINT:
case CAST_INTFP:
@@ -609,6 +608,7 @@ bool expr_is_pure(Expr *expr)
case EXPR_MAKE_ANY:
return expr_is_pure(expr->make_any_expr.inner) && expr_is_pure(expr->make_any_expr.typeid);
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_DISCARD:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_RVALUE:

View File

@@ -268,6 +268,10 @@ void print_var_expr(FILE *file, Expr *expr)
break;
case EXPR_VECTOR_FROM_ARRAY:
TODO
case EXPR_SLICE_LEN:
print_var_expr(file, expr->access_expr.parent);
fputs(".len", file);
break;
case EXPR_PTR_ACCESS:
print_var_expr(file, expr->access_expr.parent);
fputs(".ptr", file);

View File

@@ -709,17 +709,21 @@ static inline void llvm_emit_subscript_addr(GenContext *c, BEValue *value, Expr
if (parent_type_kind == TYPE_SLICE)
{
needs_len = safe_mode_enabled() || start_from_end;
if (needs_len)
{
llvm_emit_slice_len(c, value, &len);
llvm_value_rvalue(c, &len);
}
}
else if (parent_type_kind == TYPE_ARRAY)
else if (parent_type_kind == TYPE_ARRAY || parent_type_kind == TYPE_VECTOR)
{
// From back should always be folded.
ASSERT0(!expr_is_const(expr) || !start_from_end);
needs_len = (safe_mode_enabled() && !expr_is_const(expr)) || start_from_end;
}
if (needs_len)
{
llvm_emit_len_for_expr(c, &len, value);
llvm_value_rvalue(c, &len);
if (needs_len)
{
llvm_value_set_int(c, &len, type_isz, value->type->array.len);
}
}
llvm_emit_ptr_from_array(c, value);
@@ -1476,11 +1480,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
value->value = LLVMBuildUIToFP(c->builder, value->value, llvm_get_type(c, to_type), "boolfp");
value->kind = BE_VALUE;
break;
case CAST_INTBOOL:
llvm_value_rvalue(c, value);
value->value = LLVMBuildICmp(c->builder, LLVMIntNE, value->value, llvm_get_zero(c, from_type), "intbool");
value->kind = type_kind_is_any_vector(value->type->type_kind) ? BE_BOOLVECTOR : BE_BOOLEAN;
break;
case CAST_FPFP:
llvm_value_rvalue(c, value);
value->value = type_convert_will_trunc(to_type, from_type)
@@ -1542,22 +1541,7 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
value->type = type_lowering(to_type);
return;
case CAST_SLBOOL:
llvm_value_fold_optional(c, value);
if (llvm_value_is_addr(value))
{
value->value = llvm_emit_struct_gep_raw(c,
value->value,
llvm_get_type(c, value->type),
1,
value->alignment,
&value->alignment);
}
else
{
value->value = llvm_emit_extract_value(c, value->value, 1);
}
value->type = type_lowering(type_usz);
llvm_value_rvalue(c, value);
llvm_emit_slice_len(c, value, value);
llvm_emit_int_comp_zero(c, value, value, BINARYOP_NE);
break;
}
@@ -2749,54 +2733,8 @@ static void llvm_emit_unary_expr(GenContext *c, BEValue *value, Expr *expr)
llvm_value_set(value, llvm_value, res_type);
return;
}
switch (type->type_kind)
{
case ALL_FLOATS:
llvm_value_rvalue(c, value);
llvm_value = LLVMBuildFCmp(c->builder, LLVMRealUEQ, value->value, llvm_get_zero(c, type), "not");
break;
case TYPE_BOOL:
llvm_value_rvalue(c, value);
llvm_value = LLVMBuildNot(c->builder, value->value, "not");
break;
case TYPE_SLICE:
if (value->kind != BE_VALUE)
{
llvm_emit_len_for_expr(c, value, value);
llvm_value_rvalue(c, value);
llvm_value = value->value;
}
else
{
llvm_value = llvm_emit_extract_value(c, value->value, 1);
}
llvm_value = LLVMBuildIsNull(c->builder, llvm_value, "not");
break;
case ALL_INTS:
case TYPE_FUNC_PTR:
case TYPE_POINTER:
llvm_value_rvalue(c, value);
llvm_value = LLVMBuildIsNull(c->builder, value->value, "not");
break;
case TYPE_ANY:
case TYPE_INTERFACE:
llvm_emit_any_pointer(c, value, value);
llvm_value_rvalue(c, value);
llvm_value = LLVMBuildIsNull(c->builder, value->value, "not");
break;
case TYPE_ARRAY:
// Handle the bitstruct to bool case.
if (type->array.base == type_char)
{
llvm_value = llvm_emit_char_array_zero(c, value, true);
break;
}
FALLTHROUGH;
default:
DEBUG_LOG("Unexpectedly tried to not %s", type_quoted_error_string(inner->type));
UNREACHABLE
}
llvm_value_set(value, llvm_value, type_bool);
llvm_value_rvalue(c, value);
value->value = LLVMBuildNot(c->builder, value->value, "not");
return;
case UNARYOP_BITNEG:
llvm_emit_expr(c, value, inner);
@@ -2865,37 +2803,6 @@ static void llvm_emit_unary_expr(GenContext *c, BEValue *value, Expr *expr)
UNREACHABLE
}
void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_len)
{
switch (expr_to_len->type->type_kind)
{
case TYPE_SLICE:
llvm_value_fold_optional(c, be_value);
if (expr_to_len->kind == BE_VALUE)
{
llvm_value_set(be_value, llvm_emit_extract_value(c, expr_to_len->value, 1), type_usz);
}
else
{
LLVMTypeRef slice_type = llvm_get_type(c, expr_to_len->type);
AlignSize alignment;
LLVMValueRef len_addr = llvm_emit_struct_gep_raw(c,
expr_to_len->value,
slice_type,
1,
expr_to_len->alignment,
&alignment);
llvm_value_set_address(be_value, len_addr, type_usz, alignment);
}
break;
case TYPE_ARRAY:
case TYPE_VECTOR:
llvm_value_set(be_value, llvm_const_int(c, type_usz, expr_to_len->type->array.len), type_usz);
break;
default:
UNREACHABLE
}
}
static void llvm_emit_trap_negative(GenContext *c, Expr *expr, LLVMValueRef value, const char *error,
BEValue *index_val)
@@ -5448,7 +5355,11 @@ LLVMValueRef llvm_emit_const_ptradd_inbounds_raw(GenContext *c, LLVMValueRef ptr
void llvm_emit_slice_len(GenContext *c, BEValue *slice, BEValue *len)
{
llvm_value_addr(c, slice);
if (!llvm_value_is_addr(slice))
{
llvm_value_set(len, llvm_emit_extract_value(c, slice->value, 1), type_usz);
return;
}
AlignSize alignment = 0;
LLVMValueRef len_addr = llvm_emit_struct_gep_raw(c,
slice->value,
@@ -7092,18 +7003,6 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
llvm_value_fold_optional(c, be_value);
switch (expr->builtin_access_expr.kind)
{
case ACCESS_LEN:
llvm_emit_len_for_expr(c, be_value, be_value);
return;
case ACCESS_PTR:
if (type_is_any(be_value->type))
{
llvm_emit_any_pointer(c, be_value, be_value);
return;
}
ASSERT0(be_value->type->type_kind == TYPE_SLICE);
llvm_emit_slice_pointer(c, be_value, be_value);
return;
case ACCESS_FAULTORDINAL:
{
LLVMBasicBlockRef current_block = llvm_get_current_block_if_in_use(c);
@@ -7418,6 +7317,10 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
case EXPR_VECTOR_FROM_ARRAY:
llvm_emit_vector_from_array(c, value, expr);
return;
case EXPR_SLICE_LEN:
llvm_emit_expr(c, value, expr->inner_expr);
llvm_emit_slice_len(c, value, value);
return;
case EXPR_PTR_ACCESS:
llvm_emit_ptr_access(c, value, expr);
return;

View File

@@ -541,7 +541,7 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
INLINE void llvm_emit_exprid(GenContext *c, BEValue *value, ExprId expr);
INLINE void llvm_emit_statement_chain(GenContext *c, AstId current);
void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, ConstInitializer *initializer);
void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_len);
LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl);
LLVMValueRef llvm_emit_call_intrinsic(GenContext *c, unsigned intrinsic, LLVMTypeRef *types, unsigned type_count, LLVMValueRef *values, unsigned arg_count);
void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *value, Type *to_type, Type *from_type);

View File

@@ -345,6 +345,9 @@ Expr *recursive_may_narrow(Expr *expr, Type *type)
RETRY:
switch (expr->expr_kind)
{
case EXPR_RECAST:
expr = expr->inner_expr;
goto RETRY;
case EXPR_BITASSIGN:
case EXPR_BINARY:
switch (expr->binary_expr.operator)
@@ -409,14 +412,12 @@ RETRY:
}
UNREACHABLE
case EXPR_SLICE_LEN:
if (type_size(type) < type_size(type_cint)) return expr;
return NULL;
case EXPR_BUILTIN_ACCESS:
switch (expr->builtin_access_expr.kind)
{
case ACCESS_LEN:
// Special: we may resize this, but not smaller than cint.
if (type_size(type) < type_size(type_cint)) return expr;
return NULL;
case ACCESS_PTR:
case ACCESS_TYPEOFANYFAULT:
case ACCESS_TYPEOFANY:
case ACCESS_ENUMNAME:
@@ -1439,10 +1440,10 @@ static void cast_typeid_to_int(SemaContext *context, Expr *expr, Type *type) { e
static void cast_fault_to_int(SemaContext *context, Expr *expr, Type *type) { cast_typeid_to_int(context, expr, type); }
static void cast_typeid_to_ptr(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_IDPTR, type); }
static void cast_any_to_bool(SemaContext *context, Expr *expr, Type *type) {
expr_rewrite_ptr_access(expr, type_voidptr);
expr_rewrite_ptr_access(expr, expr_copy(expr), type_voidptr);
expr_rewrite_int_to_bool(expr, false);
}
static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_ptr_access(expr, type); }
static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type) { expr_rewrite_ptr_access(expr, expr_copy(expr), type); }
static void cast_all_to_void(SemaContext *context, Expr *expr, Type *to_type) { expr_rewrite_discard(expr); }
static void cast_retype(SemaContext *context, Expr *expr, Type *to_type) { expr->type = to_type; }
@@ -1758,8 +1759,14 @@ static void cast_vec_to_vec(SemaContext *context, Expr *expr, Type *to_type)
insert_runtime_cast(expr, CAST_INTFP, to_type);
return;
case TYPE_BOOL:
insert_runtime_cast(expr, CAST_INTBOOL, to_type);
{
Expr *left = expr_copy(expr);
Expr *right = expr_new_expr(EXPR_CONST, expr);
expr_rewrite_to_const_zero(right, left->type);
expr_rewrite_to_binary(expr, left, right, BINARYOP_VEC_NE);
expr->type = to_type;
return;
}
case ALL_INTS:
expr_rewrite_ext_trunc(expr, to_type, type_is_signed(type_flatten_to_int(expr->type)));
return;
@@ -1834,7 +1841,7 @@ static void cast_slice_to_ptr(SemaContext *context, Expr *expr, Type *type)
return;
}
expr_rewrite_ptr_access(expr, type);
expr_rewrite_ptr_access(expr, expr_copy(expr), type);
}
/**
@@ -1987,8 +1994,6 @@ static void cast_slice_to_bool(SemaContext *context, Expr *expr, Type *type)
*/
static void cast_slice_to_slice(SemaContext *context, Expr *expr, Type *to_type)
{
Type *to_type_base = type_flatten(type_flatten(to_type)->array.base);
Type *from_type_base = type_flatten(type_flatten(expr->type)->array.base);
if (sema_cast_const(expr))
{
expr->type = to_type;

View File

@@ -559,6 +559,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
case EXPR_POINTER_OFFSET:
case EXPR_POST_UNARY:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_RECAST:
case EXPR_RETHROW:
case EXPR_RETVAL:
@@ -605,6 +606,7 @@ static bool expr_may_ref(Expr *expr)
case EXPR_MEMBER_GET:
case EXPR_EXT_TRUNC:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_INT_TO_BOOL:
case EXPR_RVALUE:
@@ -4997,7 +4999,7 @@ CHECK_DEEPER:
expr_rewrite_const_int(expr, type_isz, parent->const_expr.bytes.len);
return true;
}
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_LEN, type_usz);
expr_rewrite_slice_len(expr, parent, type_usz);
return true;
}
if (flat_type->type_kind == TYPE_ARRAY || flat_type->type_kind == TYPE_VECTOR)
@@ -5035,12 +5037,12 @@ CHECK_DEEPER:
{
if (flat_type->type_kind == TYPE_SLICE)
{
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_PTR, type_get_ptr(flat_type->array.base));
expr_rewrite_ptr_access(expr, current_parent, type_get_ptr(flat_type->array.base));
return true;
}
if (type_is_any_raw(flat_type))
{
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_PTR, type_voidptr);
expr_rewrite_ptr_access(expr, current_parent, type_voidptr);
return true;
}
}
@@ -7064,20 +7066,25 @@ static inline bool sema_expr_analyse_neg_plus(SemaContext *context, Expr *expr)
{
if (is_plus)
{
SEMA_ERROR(expr, "Cannot use '+' with an expression of type %s.", type_quoted_error_string(no_fail));
return false;
RETURN_SEMA_ERROR(expr, "Cannot use '+' with an expression of type %s.", type_quoted_error_string(no_fail));
}
SEMA_ERROR(expr, "Cannot negate an expression of type %s.", type_quoted_error_string(no_fail));
return false;
RETURN_SEMA_ERROR(expr, "Cannot negate an expression of type %s.", type_quoted_error_string(no_fail));
}
// 3. Promote the type
Type *result_type = cast_numeric_arithmetic_promotion(no_fail);
if (!cast_implicit(context, inner, result_type, false)) return false;
// If it's a plus, we simply replace the inner with the outer.
// If it's a plus, we simply replace the inner with the outer or with a recast.
if (is_plus)
{
expr_replace(expr, inner);
if (expr_is_const(expr))
{
expr_replace(expr, inner);
return true;
}
expr->expr_kind = EXPR_RECAST;
expr->inner_expr = inner;
expr->type = inner->type;
return true;
}
// 4. If it's non-const, we're done.
@@ -8981,6 +8988,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
case EXPR_EXT_TRUNC:
case EXPR_INT_TO_BOOL:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_RVALUE:
case EXPR_RECAST:
@@ -9378,6 +9386,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
case EXPR_DISCARD:
return sema_analyse_expr(context, expr->inner_expr);
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_VECTOR_FROM_ARRAY:
return sema_analyse_expr(context, expr->inner_expr);
case EXPR_INT_TO_BOOL:
@@ -9822,13 +9831,16 @@ bool sema_analyse_expr(SemaContext *context, Expr *expr)
bool sema_cast_const(Expr *expr)
{
if (expr->resolve_status != RESOLVE_DONE)
{
puts("Tesst");
}
ASSERT_SPAN(expr, expr->resolve_status == RESOLVE_DONE);
switch (expr->expr_kind)
{
case EXPR_RECAST:
if (sema_cast_const(expr->inner_expr))
{
expr_replace(expr, expr->inner_expr);
return true;
}
return false;
case EXPR_ACCESS:
case EXPR_BITACCESS:
{

View File

@@ -330,6 +330,7 @@ RETRY:
case EXPR_RETHROW:
case EXPR_OPTIONAL:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_RVALUE:
case EXPR_RECAST:

View File

@@ -765,6 +765,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
case EXPR_EXT_TRUNC:
case EXPR_INT_TO_BOOL:
case EXPR_PTR_ACCESS:
case EXPR_SLICE_LEN:
case EXPR_VECTOR_FROM_ARRAY:
case EXPR_RVALUE:
case EXPR_RECAST:
@@ -1622,19 +1623,20 @@ SKIP_OVERLOAD:;
}
else
{
if (enumerator_type->type_kind == TYPE_ARRAY)
switch (enumerator_type->type_kind)
{
array_len = enumerator_type->array.len;
len_call = NULL;
}
else
{
len_call = expr_new(EXPR_BUILTIN_ACCESS, enumerator->span);
if (!sema_analyse_expr(context, enum_val)) return false;
len_call->builtin_access_expr.inner = exprid(enum_val);
len_call->builtin_access_expr.kind = ACCESS_LEN;
len_call->resolve_status = RESOLVE_DONE;
len_call->type = type_isz;
case TYPE_ARRAY:
case TYPE_VECTOR:
array_len = enumerator_type->array.len;
len_call = NULL;
break;
case TYPE_SLICE:
if (!sema_analyse_expr(context, enum_val)) return false;
len_call = expr_new_expr(EXPR_SLICE_LEN, enumerator);
expr_rewrite_slice_len(len_call, enum_val, type_isz);
break;
default:
UNREACHABLE
}
}
bool is_single_pass = array_len == 1;

View File

@@ -18,3 +18,10 @@ fn void test3()
@ok(+a);
long b = +a; // #error: 'long!' to 'long'
}
fn void test4()
{
int a = 1;
+a = 3; // #error: An assignable expression
}

View File

@@ -24,25 +24,22 @@ define void @test.main() #0 {
entry:
%z = alloca [7 x i32], align 16
%y = alloca [6 x i32], align 16
%taddr = alloca %"int[]", align 8
%varargslots = alloca [2 x %any], align 16
%retparam = alloca i64, align 8
%taddr6 = alloca %"int[]", align 8
%varargslots8 = alloca [2 x %any], align 16
%retparam10 = alloca i64, align 8
%varargslots5 = alloca [2 x %any], align 16
%retparam7 = alloca i64, align 8
%a = alloca %"int[][]", align 8
%literal = alloca [1 x %"int[]"], align 16
%literal11 = alloca [1 x i32], align 4
%literal8 = alloca [1 x i32], align 4
%b = alloca %"int[][]", align 8
%literal12 = alloca [1 x %"int[]"], align 16
%literal13 = alloca [1 x i32], align 4
%varargslots14 = alloca [1 x %any], align 16
%retparam15 = alloca i64, align 8
%taddr16 = alloca %"int[][]", align 8
%varargslots18 = alloca [1 x %any], align 16
%retparam19 = alloca i64, align 8
%varargslots21 = alloca [1 x %any], align 16
%retparam22 = alloca i64, align 8
%literal9 = alloca [1 x %"int[]"], align 16
%literal10 = alloca [1 x i32], align 4
%varargslots11 = alloca [1 x %any], align 16
%retparam12 = alloca i64, align 8
%varargslots13 = alloca [1 x %any], align 16
%retparam14 = alloca i64, align 8
%varargslots16 = alloca [1 x %any], align 16
%retparam17 = alloca i64, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %z, ptr align 16 @.__const, i32 28, i1 false)
call void @llvm.memset.p0.i64(ptr align 16 %y, i8 0, i64 24, i1 false)
%ptradd = getelementptr inbounds i8, ptr %z, i64 12
@@ -53,9 +50,7 @@ entry:
%3 = insertvalue %"int[]" %2, i64 3, 1
%4 = extractvalue %"int[]" %3, 0
%5 = extractvalue %"int[]" %1, 0
store %"int[]" %1, ptr %taddr, align 8
%ptradd2 = getelementptr inbounds i8, ptr %taddr, i64 8
%6 = load i64, ptr %ptradd2, align 8
%6 = extractvalue %"int[]" %1, 1
%7 = mul i64 %6, 4
call void @llvm.memmove.p0.p0.i64(ptr align 4 %4, ptr align 4 %5, i64 %7, i1 false)
%8 = insertvalue %any undef, ptr %y, 0
@@ -63,48 +58,46 @@ entry:
store %any %9, ptr %varargslots, align 16
%10 = insertvalue %any undef, ptr %z, 0
%11 = insertvalue %any %10, i64 ptrtoint (ptr @"$ct.a7$int" to i64), 1
%ptradd3 = getelementptr inbounds i8, ptr %varargslots, i64 16
store %any %11, ptr %ptradd3, align 16
%ptradd2 = getelementptr inbounds i8, ptr %varargslots, i64 16
store %any %11, ptr %ptradd2, align 16
%12 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 5, ptr %varargslots, i64 2)
%ptradd4 = getelementptr inbounds i8, ptr %z, i64 20
%13 = insertvalue %"int[]" undef, ptr %ptradd4, 0
%ptradd3 = getelementptr inbounds i8, ptr %z, i64 20
%13 = insertvalue %"int[]" undef, ptr %ptradd3, 0
%14 = insertvalue %"int[]" %13, i64 2, 1
%ptradd5 = getelementptr inbounds i8, ptr %y, i64 16
%15 = insertvalue %"int[]" undef, ptr %ptradd5, 0
%ptradd4 = getelementptr inbounds i8, ptr %y, i64 16
%15 = insertvalue %"int[]" undef, ptr %ptradd4, 0
%16 = insertvalue %"int[]" %15, i64 2, 1
%17 = extractvalue %"int[]" %16, 0
%18 = extractvalue %"int[]" %14, 0
store %"int[]" %14, ptr %taddr6, align 8
%ptradd7 = getelementptr inbounds i8, ptr %taddr6, i64 8
%19 = load i64, ptr %ptradd7, align 8
%19 = extractvalue %"int[]" %14, 1
%20 = mul i64 %19, 4
call void @llvm.memmove.p0.p0.i64(ptr align 4 %17, ptr align 4 %18, i64 %20, i1 false)
%21 = insertvalue %any undef, ptr %y, 0
%22 = insertvalue %any %21, i64 ptrtoint (ptr @"$ct.a6$int" to i64), 1
store %any %22, ptr %varargslots8, align 16
store %any %22, ptr %varargslots5, align 16
%23 = insertvalue %any undef, ptr %z, 0
%24 = insertvalue %any %23, i64 ptrtoint (ptr @"$ct.a7$int" to i64), 1
%ptradd9 = getelementptr inbounds i8, ptr %varargslots8, i64 16
store %any %24, ptr %ptradd9, align 16
%25 = call i64 @std.io.printfn(ptr %retparam10, ptr @.str.1, i64 5, ptr %varargslots8, i64 2)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal11, ptr align 4 @.__const.2, i32 4, i1 false)
%26 = insertvalue %"int[]" undef, ptr %literal11, 0
%ptradd6 = getelementptr inbounds i8, ptr %varargslots5, i64 16
store %any %24, ptr %ptradd6, align 16
%25 = call i64 @std.io.printfn(ptr %retparam7, ptr @.str.1, i64 5, ptr %varargslots5, i64 2)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal8, ptr align 4 @.__const.2, i32 4, i1 false)
%26 = insertvalue %"int[]" undef, ptr %literal8, 0
%27 = insertvalue %"int[]" %26, i64 1, 1
store %"int[]" %27, ptr %literal, align 8
%28 = insertvalue %"int[][]" undef, ptr %literal, 0
%29 = insertvalue %"int[][]" %28, i64 1, 1
store %"int[][]" %29, ptr %a, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal13, ptr align 4 @.__const.3, i32 4, i1 false)
%30 = insertvalue %"int[]" undef, ptr %literal13, 0
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal10, ptr align 4 @.__const.3, i32 4, i1 false)
%30 = insertvalue %"int[]" undef, ptr %literal10, 0
%31 = insertvalue %"int[]" %30, i64 1, 1
store %"int[]" %31, ptr %literal12, align 8
%32 = insertvalue %"int[][]" undef, ptr %literal12, 0
store %"int[]" %31, ptr %literal9, align 8
%32 = insertvalue %"int[][]" undef, ptr %literal9, 0
%33 = insertvalue %"int[][]" %32, i64 1, 1
store %"int[][]" %33, ptr %b, align 8
%34 = insertvalue %any undef, ptr %a, 0
%35 = insertvalue %any %34, i64 ptrtoint (ptr @"$ct.sa$sa$int" to i64), 1
store %any %35, ptr %varargslots14, align 16
%36 = call i64 @std.io.printfn(ptr %retparam15, ptr @.str.4, i64 2, ptr %varargslots14, i64 1)
store %any %35, ptr %varargslots11, align 16
%36 = call i64 @std.io.printfn(ptr %retparam12, ptr @.str.4, i64 2, ptr %varargslots11, i64 1)
%37 = load %"int[][]", ptr %b, align 8
%38 = extractvalue %"int[][]" %37, 0
%39 = insertvalue %"int[][]" undef, ptr %38, 0
@@ -115,24 +108,22 @@ entry:
%44 = insertvalue %"int[][]" %43, i64 1, 1
%45 = extractvalue %"int[][]" %44, 0
%46 = extractvalue %"int[][]" %40, 0
store %"int[][]" %40, ptr %taddr16, align 8
%ptradd17 = getelementptr inbounds i8, ptr %taddr16, i64 8
%47 = load i64, ptr %ptradd17, align 8
%47 = extractvalue %"int[][]" %40, 1
%48 = mul i64 %47, 16
call void @llvm.memmove.p0.p0.i64(ptr align 8 %45, ptr align 8 %46, i64 %48, i1 false)
%49 = insertvalue %any undef, ptr %a, 0
%50 = insertvalue %any %49, i64 ptrtoint (ptr @"$ct.sa$sa$int" to i64), 1
store %any %50, ptr %varargslots18, align 16
%51 = call i64 @std.io.printfn(ptr %retparam19, ptr @.str.5, i64 2, ptr %varargslots18, i64 1)
%ptradd20 = getelementptr inbounds i8, ptr %y, i64 8
%52 = insertvalue %"int[]" undef, ptr %ptradd20, 0
store %any %50, ptr %varargslots13, align 16
%51 = call i64 @std.io.printfn(ptr %retparam14, ptr @.str.5, i64 2, ptr %varargslots13, i64 1)
%ptradd15 = getelementptr inbounds i8, ptr %y, i64 8
%52 = insertvalue %"int[]" undef, ptr %ptradd15, 0
%53 = insertvalue %"int[]" %52, i64 3, 1
%54 = load %"int[][]", ptr %a, align 8
%55 = extractvalue %"int[][]" %54, 0
store %"int[]" %53, ptr %55, align 8
%56 = insertvalue %any undef, ptr %a, 0
%57 = insertvalue %any %56, i64 ptrtoint (ptr @"$ct.sa$sa$int" to i64), 1
store %any %57, ptr %varargslots21, align 16
%58 = call i64 @std.io.printfn(ptr %retparam22, ptr @.str.6, i64 2, ptr %varargslots21, i64 1)
store %any %57, ptr %varargslots16, align 16
%58 = call i64 @std.io.printfn(ptr %retparam17, ptr @.str.6, i64 2, ptr %varargslots16, i64 1)
ret void
}

View File

@@ -25,25 +25,22 @@ define void @test.main() #0 {
entry:
%z = alloca <7 x i32>, align 32
%y = alloca <6 x i32>, align 32
%taddr = alloca %"int[]", align 8
%varargslots = alloca [2 x %any], align 16
%retparam = alloca i64, align 8
%taddr6 = alloca %"int[]", align 8
%varargslots8 = alloca [2 x %any], align 16
%retparam10 = alloca i64, align 8
%varargslots5 = alloca [2 x %any], align 16
%retparam7 = alloca i64, align 8
%a = alloca %"int[][]", align 8
%literal = alloca [1 x %"int[]"], align 16
%literal11 = alloca [1 x i32], align 4
%literal8 = alloca [1 x i32], align 4
%b = alloca %"int[][]", align 8
%literal12 = alloca [1 x %"int[]"], align 16
%literal13 = alloca [1 x i32], align 4
%varargslots14 = alloca [1 x %any], align 16
%retparam15 = alloca i64, align 8
%taddr16 = alloca %"int[][]", align 8
%varargslots18 = alloca [1 x %any], align 16
%retparam19 = alloca i64, align 8
%varargslots21 = alloca [1 x %any], align 16
%retparam22 = alloca i64, align 8
%literal9 = alloca [1 x %"int[]"], align 16
%literal10 = alloca [1 x i32], align 4
%varargslots11 = alloca [1 x %any], align 16
%retparam12 = alloca i64, align 8
%varargslots13 = alloca [1 x %any], align 16
%retparam14 = alloca i64, align 8
%varargslots16 = alloca [1 x %any], align 16
%retparam17 = alloca i64, align 8
store <7 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, ptr %z, align 32
store <6 x i32> zeroinitializer, ptr %y, align 32
%ptradd = getelementptr inbounds i8, ptr %z, i64 12
@@ -54,9 +51,7 @@ entry:
%3 = insertvalue %"int[]" %2, i64 3, 1
%4 = extractvalue %"int[]" %3, 0
%5 = extractvalue %"int[]" %1, 0
store %"int[]" %1, ptr %taddr, align 8
%ptradd2 = getelementptr inbounds i8, ptr %taddr, i64 8
%6 = load i64, ptr %ptradd2, align 8
%6 = extractvalue %"int[]" %1, 1
%7 = mul i64 %6, 4
call void @llvm.memmove.p0.p0.i64(ptr align 4 %4, ptr align 4 %5, i64 %7, i1 false)
%8 = insertvalue %any undef, ptr %y, 0
@@ -64,48 +59,46 @@ entry:
store %any %9, ptr %varargslots, align 16
%10 = insertvalue %any undef, ptr %z, 0
%11 = insertvalue %any %10, i64 ptrtoint (ptr @"$ct.v7$int" to i64), 1
%ptradd3 = getelementptr inbounds i8, ptr %varargslots, i64 16
store %any %11, ptr %ptradd3, align 16
%ptradd2 = getelementptr inbounds i8, ptr %varargslots, i64 16
store %any %11, ptr %ptradd2, align 16
%12 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 5, ptr %varargslots, i64 2)
%ptradd4 = getelementptr inbounds i8, ptr %z, i64 20
%13 = insertvalue %"int[]" undef, ptr %ptradd4, 0
%ptradd3 = getelementptr inbounds i8, ptr %z, i64 20
%13 = insertvalue %"int[]" undef, ptr %ptradd3, 0
%14 = insertvalue %"int[]" %13, i64 2, 1
%ptradd5 = getelementptr inbounds i8, ptr %y, i64 16
%15 = insertvalue %"int[]" undef, ptr %ptradd5, 0
%ptradd4 = getelementptr inbounds i8, ptr %y, i64 16
%15 = insertvalue %"int[]" undef, ptr %ptradd4, 0
%16 = insertvalue %"int[]" %15, i64 2, 1
%17 = extractvalue %"int[]" %16, 0
%18 = extractvalue %"int[]" %14, 0
store %"int[]" %14, ptr %taddr6, align 8
%ptradd7 = getelementptr inbounds i8, ptr %taddr6, i64 8
%19 = load i64, ptr %ptradd7, align 8
%19 = extractvalue %"int[]" %14, 1
%20 = mul i64 %19, 4
call void @llvm.memmove.p0.p0.i64(ptr align 4 %17, ptr align 4 %18, i64 %20, i1 false)
%21 = insertvalue %any undef, ptr %y, 0
%22 = insertvalue %any %21, i64 ptrtoint (ptr @"$ct.v6$int" to i64), 1
store %any %22, ptr %varargslots8, align 16
store %any %22, ptr %varargslots5, align 16
%23 = insertvalue %any undef, ptr %z, 0
%24 = insertvalue %any %23, i64 ptrtoint (ptr @"$ct.v7$int" to i64), 1
%ptradd9 = getelementptr inbounds i8, ptr %varargslots8, i64 16
store %any %24, ptr %ptradd9, align 16
%25 = call i64 @std.io.printfn(ptr %retparam10, ptr @.str.1, i64 5, ptr %varargslots8, i64 2)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal11, ptr align 4 @.__const, i32 4, i1 false)
%26 = insertvalue %"int[]" undef, ptr %literal11, 0
%ptradd6 = getelementptr inbounds i8, ptr %varargslots5, i64 16
store %any %24, ptr %ptradd6, align 16
%25 = call i64 @std.io.printfn(ptr %retparam7, ptr @.str.1, i64 5, ptr %varargslots5, i64 2)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal8, ptr align 4 @.__const, i32 4, i1 false)
%26 = insertvalue %"int[]" undef, ptr %literal8, 0
%27 = insertvalue %"int[]" %26, i64 1, 1
store %"int[]" %27, ptr %literal, align 8
%28 = insertvalue %"int[][]" undef, ptr %literal, 0
%29 = insertvalue %"int[][]" %28, i64 1, 1
store %"int[][]" %29, ptr %a, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal13, ptr align 4 @.__const.2, i32 4, i1 false)
%30 = insertvalue %"int[]" undef, ptr %literal13, 0
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal10, ptr align 4 @.__const.2, i32 4, i1 false)
%30 = insertvalue %"int[]" undef, ptr %literal10, 0
%31 = insertvalue %"int[]" %30, i64 1, 1
store %"int[]" %31, ptr %literal12, align 8
%32 = insertvalue %"int[][]" undef, ptr %literal12, 0
store %"int[]" %31, ptr %literal9, align 8
%32 = insertvalue %"int[][]" undef, ptr %literal9, 0
%33 = insertvalue %"int[][]" %32, i64 1, 1
store %"int[][]" %33, ptr %b, align 8
%34 = insertvalue %any undef, ptr %a, 0
%35 = insertvalue %any %34, i64 ptrtoint (ptr @"$ct.sa$sa$int" to i64), 1
store %any %35, ptr %varargslots14, align 16
%36 = call i64 @std.io.printfn(ptr %retparam15, ptr @.str.3, i64 2, ptr %varargslots14, i64 1)
store %any %35, ptr %varargslots11, align 16
%36 = call i64 @std.io.printfn(ptr %retparam12, ptr @.str.3, i64 2, ptr %varargslots11, i64 1)
%37 = load %"int[][]", ptr %b, align 8
%38 = extractvalue %"int[][]" %37, 0
%39 = insertvalue %"int[][]" undef, ptr %38, 0
@@ -116,24 +109,22 @@ entry:
%44 = insertvalue %"int[][]" %43, i64 1, 1
%45 = extractvalue %"int[][]" %44, 0
%46 = extractvalue %"int[][]" %40, 0
store %"int[][]" %40, ptr %taddr16, align 8
%ptradd17 = getelementptr inbounds i8, ptr %taddr16, i64 8
%47 = load i64, ptr %ptradd17, align 8
%47 = extractvalue %"int[][]" %40, 1
%48 = mul i64 %47, 16
call void @llvm.memmove.p0.p0.i64(ptr align 8 %45, ptr align 8 %46, i64 %48, i1 false)
%49 = insertvalue %any undef, ptr %a, 0
%50 = insertvalue %any %49, i64 ptrtoint (ptr @"$ct.sa$sa$int" to i64), 1
store %any %50, ptr %varargslots18, align 16
%51 = call i64 @std.io.printfn(ptr %retparam19, ptr @.str.4, i64 2, ptr %varargslots18, i64 1)
%ptradd20 = getelementptr inbounds i8, ptr %y, i64 8
%52 = insertvalue %"int[]" undef, ptr %ptradd20, 0
store %any %50, ptr %varargslots13, align 16
%51 = call i64 @std.io.printfn(ptr %retparam14, ptr @.str.4, i64 2, ptr %varargslots13, i64 1)
%ptradd15 = getelementptr inbounds i8, ptr %y, i64 8
%52 = insertvalue %"int[]" undef, ptr %ptradd15, 0
%53 = insertvalue %"int[]" %52, i64 3, 1
%54 = load %"int[][]", ptr %a, align 8
%55 = extractvalue %"int[][]" %54, 0
store %"int[]" %53, ptr %55, align 8
%56 = insertvalue %any undef, ptr %a, 0
%57 = insertvalue %any %56, i64 ptrtoint (ptr @"$ct.sa$sa$int" to i64), 1
store %any %57, ptr %varargslots21, align 16
%58 = call i64 @std.io.printfn(ptr %retparam22, ptr @.str.5, i64 2, ptr %varargslots21, i64 1)
store %any %57, ptr %varargslots16, align 16
%58 = call i64 @std.io.printfn(ptr %retparam17, ptr @.str.5, i64 2, ptr %varargslots16, i64 1)
ret void
}

View File

@@ -76,22 +76,17 @@ entry:
%.anon38 = alloca i64, align 8
%a42 = alloca double, align 8
%.anon47 = alloca i64, align 8
%.anon48 = alloca i64, align 8
%a51 = alloca float, align 4
%.anon55 = alloca i64, align 8
%.anon56 = alloca i64, align 8
%a60 = alloca ptr, align 8
%.anon66 = alloca i64, align 8
%.anon67 = alloca i64, align 8
%i71 = alloca i64, align 8
%a72 = alloca float, align 4
%.anon76 = alloca i64, align 8
%.anon77 = alloca i64, align 8
%i81 = alloca i8, align 1
%a83 = alloca double, align 8
%.anon88 = alloca i64, align 8
%.anon89 = alloca i64, align 8
%a93 = alloca double, align 8
%a59 = alloca ptr, align 8
%.anon65 = alloca i64, align 8
%i69 = alloca i64, align 8
%a70 = alloca float, align 4
%.anon74 = alloca i64, align 8
%i78 = alloca i8, align 1
%a80 = alloca double, align 8
%.anon85 = alloca i64, align 8
%a89 = alloca double, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %foo, ptr align 4 @.__const, i32 12, i1 false)
store <3 x float> <float 2.000000e+00, float 4.500000e+00, float 8.000000e+00>, ptr %foo2, align 16
store i64 0, ptr %.anon, align 8
@@ -238,137 +233,127 @@ loop.body41: ; preds = %loop.cond39
br label %loop.cond39
loop.exit46: ; preds = %loop.cond39
store i64 3, ptr %.anon47, align 8
store i64 0, ptr %.anon48, align 8
br label %loop.cond49
store i64 0, ptr %.anon47, align 8
br label %loop.cond48
loop.cond49: ; preds = %loop.body50, %loop.exit46
%36 = load i64, ptr %.anon48, align 8
%37 = load i64, ptr %.anon47, align 8
%lt = icmp ult i64 %36, %37
br i1 %lt, label %loop.body50, label %loop.exit54
loop.cond48: ; preds = %loop.body50, %loop.exit46
%36 = load i64, ptr %.anon47, align 8
%gt49 = icmp ugt i64 3, %36
br i1 %gt49, label %loop.body50, label %loop.exit54
loop.body50: ; preds = %loop.cond49
%38 = load <3 x float>, ptr %foo2, align 16
%39 = load i64, ptr %.anon48, align 8
%40 = extractelement <3 x float> %38, i64 %39
store float %40, ptr %a51, align 4
%41 = load float, ptr %a51, align 4
%fpfpext52 = fpext float %41 to double
loop.body50: ; preds = %loop.cond48
%37 = load <3 x float>, ptr %foo2, align 16
%38 = load i64, ptr %.anon47, align 8
%39 = extractelement <3 x float> %37, i64 %38
store float %39, ptr %a51, align 4
%40 = load float, ptr %a51, align 4
%fpfpext52 = fpext float %40 to double
call void (ptr, ...) @printf(ptr @.str.6, double %fpfpext52)
%42 = load i64, ptr %.anon48, align 8
%addnuw53 = add nuw i64 %42, 1
store i64 %addnuw53, ptr %.anon48, align 8
br label %loop.cond49
%41 = load i64, ptr %.anon47, align 8
%addnuw53 = add nuw i64 %41, 1
store i64 %addnuw53, ptr %.anon47, align 8
br label %loop.cond48
loop.exit54: ; preds = %loop.cond49
store i64 3, ptr %.anon55, align 8
store i64 0, ptr %.anon56, align 8
br label %loop.cond57
loop.exit54: ; preds = %loop.cond48
store i64 0, ptr %.anon55, align 8
br label %loop.cond56
loop.cond57: ; preds = %loop.body59, %loop.exit54
%43 = load i64, ptr %.anon56, align 8
%44 = load i64, ptr %.anon55, align 8
%lt58 = icmp ult i64 %43, %44
br i1 %lt58, label %loop.body59, label %loop.exit65
loop.cond56: ; preds = %loop.body58, %loop.exit54
%42 = load i64, ptr %.anon55, align 8
%gt57 = icmp ugt i64 3, %42
br i1 %gt57, label %loop.body58, label %loop.exit64
loop.body59: ; preds = %loop.cond57
%45 = load i64, ptr %.anon56, align 8
%ptroffset61 = getelementptr inbounds [4 x i8], ptr %foo2, i64 %45
store ptr %ptroffset61, ptr %a60, align 8
%46 = load ptr, ptr %a60, align 8
loop.body58: ; preds = %loop.cond56
%43 = load i64, ptr %.anon55, align 8
%ptroffset60 = getelementptr inbounds [4 x i8], ptr %foo2, i64 %43
store ptr %ptroffset60, ptr %a59, align 8
%44 = load ptr, ptr %a59, align 8
%45 = load float, ptr %44, align 4
%fmul61 = fmul float %45, 2.000000e+00
store float %fmul61, ptr %44, align 4
%46 = load ptr, ptr %a59, align 8
%47 = load float, ptr %46, align 4
%fmul62 = fmul float %47, 2.000000e+00
store float %fmul62, ptr %46, align 4
%48 = load ptr, ptr %a60, align 8
%49 = load float, ptr %48, align 4
%fpfpext63 = fpext float %49 to double
call void (ptr, ...) @printf(ptr @.str.7, double %fpfpext63)
%50 = load i64, ptr %.anon56, align 8
%addnuw64 = add nuw i64 %50, 1
store i64 %addnuw64, ptr %.anon56, align 8
br label %loop.cond57
%fpfpext62 = fpext float %47 to double
call void (ptr, ...) @printf(ptr @.str.7, double %fpfpext62)
%48 = load i64, ptr %.anon55, align 8
%addnuw63 = add nuw i64 %48, 1
store i64 %addnuw63, ptr %.anon55, align 8
br label %loop.cond56
loop.exit65: ; preds = %loop.cond57
store i64 3, ptr %.anon66, align 8
store i64 0, ptr %.anon67, align 8
br label %loop.cond68
loop.exit64: ; preds = %loop.cond56
store i64 0, ptr %.anon65, align 8
br label %loop.cond66
loop.cond68: ; preds = %loop.body70, %loop.exit65
%51 = load i64, ptr %.anon67, align 8
%52 = load i64, ptr %.anon66, align 8
%lt69 = icmp ult i64 %51, %52
br i1 %lt69, label %loop.body70, label %loop.exit75
loop.cond66: ; preds = %loop.body68, %loop.exit64
%49 = load i64, ptr %.anon65, align 8
%gt67 = icmp ugt i64 3, %49
br i1 %gt67, label %loop.body68, label %loop.exit73
loop.body70: ; preds = %loop.cond68
%53 = load i64, ptr %.anon67, align 8
store i64 %53, ptr %i71, align 8
%54 = load <3 x float>, ptr %foo2, align 16
%55 = load i64, ptr %.anon67, align 8
%56 = extractelement <3 x float> %54, i64 %55
store float %56, ptr %a72, align 4
%57 = load float, ptr %a72, align 4
%fpfpext73 = fpext float %57 to double
%58 = load i64, ptr %i71, align 8
call void (ptr, ...) @printf(ptr @.str.8, i64 %58, double %fpfpext73)
%59 = load i64, ptr %.anon67, align 8
%addnuw74 = add nuw i64 %59, 1
store i64 %addnuw74, ptr %.anon67, align 8
br label %loop.cond68
loop.body68: ; preds = %loop.cond66
%50 = load i64, ptr %.anon65, align 8
store i64 %50, ptr %i69, align 8
%51 = load <3 x float>, ptr %foo2, align 16
%52 = load i64, ptr %.anon65, align 8
%53 = extractelement <3 x float> %51, i64 %52
store float %53, ptr %a70, align 4
%54 = load float, ptr %a70, align 4
%fpfpext71 = fpext float %54 to double
%55 = load i64, ptr %i69, align 8
call void (ptr, ...) @printf(ptr @.str.8, i64 %55, double %fpfpext71)
%56 = load i64, ptr %.anon65, align 8
%addnuw72 = add nuw i64 %56, 1
store i64 %addnuw72, ptr %.anon65, align 8
br label %loop.cond66
loop.exit75: ; preds = %loop.cond68
store i64 3, ptr %.anon76, align 8
store i64 0, ptr %.anon77, align 8
br label %loop.cond78
loop.exit73: ; preds = %loop.cond66
store i64 0, ptr %.anon74, align 8
br label %loop.cond75
loop.cond78: ; preds = %loop.body80, %loop.exit75
%60 = load i64, ptr %.anon77, align 8
%61 = load i64, ptr %.anon76, align 8
%lt79 = icmp ult i64 %60, %61
br i1 %lt79, label %loop.body80, label %loop.exit87
loop.cond75: ; preds = %loop.body77, %loop.exit73
%57 = load i64, ptr %.anon74, align 8
%gt76 = icmp ugt i64 3, %57
br i1 %gt76, label %loop.body77, label %loop.exit84
loop.body80: ; preds = %loop.cond78
%62 = load i64, ptr %.anon77, align 8
%trunc82 = trunc i64 %62 to i8
store i8 %trunc82, ptr %i81, align 1
%63 = load <3 x float>, ptr %foo2, align 16
%64 = load i64, ptr %.anon77, align 8
%65 = extractelement <3 x float> %63, i64 %64
%fpfpext84 = fpext float %65 to double
store double %fpfpext84, ptr %a83, align 8
%66 = load i8, ptr %i81, align 1
%zext85 = zext i8 %66 to i32
%67 = load double, ptr %a83, align 8
call void (ptr, ...) @printf(ptr @.str.9, i32 %zext85, double %67)
%68 = load i64, ptr %.anon77, align 8
%addnuw86 = add nuw i64 %68, 1
store i64 %addnuw86, ptr %.anon77, align 8
br label %loop.cond78
loop.body77: ; preds = %loop.cond75
%58 = load i64, ptr %.anon74, align 8
%trunc79 = trunc i64 %58 to i8
store i8 %trunc79, ptr %i78, align 1
%59 = load <3 x float>, ptr %foo2, align 16
%60 = load i64, ptr %.anon74, align 8
%61 = extractelement <3 x float> %59, i64 %60
%fpfpext81 = fpext float %61 to double
store double %fpfpext81, ptr %a80, align 8
%62 = load i8, ptr %i78, align 1
%zext82 = zext i8 %62 to i32
%63 = load double, ptr %a80, align 8
call void (ptr, ...) @printf(ptr @.str.9, i32 %zext82, double %63)
%64 = load i64, ptr %.anon74, align 8
%addnuw83 = add nuw i64 %64, 1
store i64 %addnuw83, ptr %.anon74, align 8
br label %loop.cond75
loop.exit87: ; preds = %loop.cond78
store i64 3, ptr %.anon88, align 8
store i64 0, ptr %.anon89, align 8
br label %loop.cond90
loop.exit84: ; preds = %loop.cond75
store i64 0, ptr %.anon85, align 8
br label %loop.cond86
loop.cond90: ; preds = %loop.body92, %loop.exit87
%69 = load i64, ptr %.anon89, align 8
%70 = load i64, ptr %.anon88, align 8
%lt91 = icmp ult i64 %69, %70
br i1 %lt91, label %loop.body92, label %loop.exit96
loop.cond86: ; preds = %loop.body88, %loop.exit84
%65 = load i64, ptr %.anon85, align 8
%gt87 = icmp ugt i64 3, %65
br i1 %gt87, label %loop.body88, label %loop.exit92
loop.body92: ; preds = %loop.cond90
%71 = load <3 x float>, ptr %foo2, align 16
%72 = load i64, ptr %.anon89, align 8
%73 = extractelement <3 x float> %71, i64 %72
%fpfpext94 = fpext float %73 to double
store double %fpfpext94, ptr %a93, align 8
%74 = load double, ptr %a93, align 8
call void (ptr, ...) @printf(ptr @.str.10, double %74)
%75 = load i64, ptr %.anon89, align 8
%addnuw95 = add nuw i64 %75, 1
store i64 %addnuw95, ptr %.anon89, align 8
br label %loop.cond90
loop.body88: ; preds = %loop.cond86
%66 = load <3 x float>, ptr %foo2, align 16
%67 = load i64, ptr %.anon85, align 8
%68 = extractelement <3 x float> %66, i64 %67
%fpfpext90 = fpext float %68 to double
store double %fpfpext90, ptr %a89, align 8
%69 = load double, ptr %a89, align 8
call void (ptr, ...) @printf(ptr @.str.10, double %69)
%70 = load i64, ptr %.anon85, align 8
%addnuw91 = add nuw i64 %70, 1
store i64 %addnuw91, ptr %.anon85, align 8
br label %loop.cond86
loop.exit96: ; preds = %loop.cond90
loop.exit92: ; preds = %loop.cond86
ret void
}

View File

@@ -83,6 +83,8 @@ fn void! testb() @test
fn void! testi() @test
{
int[<4>] x = { 4, 0, -1, 33 };
assert({ true, false, true, true} == (bool[<4>])x);
int[<4>] y = { 1, 2, 3, 4 };
int[<4>] z = { 2, 2, 2, -100 };
int[<4>] w = y + z;