Optimize sret / byval. Fixes to types and failables.

This commit is contained in:
Christoffer Lerno
2022-10-15 02:36:07 +02:00
committed by Christoffer Lerno
parent dfe3128b16
commit 160659c4e3
44 changed files with 520 additions and 618 deletions

View File

@@ -183,7 +183,7 @@ jobs:
sudo apt-get update
sudo apt-get install -y clang-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}} llvm-${{matrix.llvm_version}}-dev lld-${{matrix.llvm_version}} liblld-${{matrix.llvm_version}}-dev
sudo apt-get install -y libmlir-${{matrix.llvm_version}} libmlir-${{matrix.llvm_version}}-dev mlir-${{matrix.llvm_version}}-tools
if [[ "${{matrix.llvm_version}}" = 15 ]]; then
if [[ "${{matrix.llvm_version}}" > 14 ]]; then
sudo apt-get install -y bolt-${{matrix.llvm_version}}
fi

View File

@@ -2196,12 +2196,9 @@ Decl *sema_find_label_symbol_anywhere(SemaContext *context, const char *symbol);
Decl *sema_resolve_symbol(SemaContext *context, const char *symbol, Path *path, SourceSpan span);
bool sema_symbol_is_defined_in_scope(SemaContext *c, const char *symbol);
bool sema_resolve_type(SemaContext *context, Type *type);
bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, ArraySize *len_ref);
bool sema_resolve_type_info(SemaContext *context, TypeInfo *type_info);
bool sema_resolve_type_info_maybe_inferred(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type);
bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type, bool in_shallow);
Type *sema_type_lower_by_size(Type *type, ArraySize element_size);
void sema_error_at(SourceSpan loc, const char *message, ...);
void sema_error_at_after(SourceSpan loc, const char *message, ...);

View File

@@ -21,7 +21,7 @@ static inline LLVMValueRef llvm_emit_expr_to_rvalue(GenContext *c, Expr *expr);
static inline LLVMValueRef llvm_emit_exprid_to_rvalue(GenContext *c, ExprId expr_id);
static void llvm_convert_vector_comparison(GenContext *c, BEValue *be_value, LLVMValueRef val, Type *vector_type);
static bool bitstruct_requires_bitswap(Decl *decl);
static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr, BEValue *target);
static inline LLVMValueRef llvm_emit_expr_to_rvalue(GenContext *c, Expr *expr)
{
@@ -113,8 +113,15 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
}
else
{
llvm_emit_expr(c, &value, expr);
llvm_store(c, ref, &value);
if (expr->expr_kind == EXPR_CALL)
{
llvm_emit_call_expr(c, &value, expr, ref);
}
else
{
llvm_emit_expr(c, &value, expr);
}
if (value.type != type_void) llvm_store(c, ref, &value);
}
if (failable)
@@ -4334,6 +4341,12 @@ void llvm_emit_parameter(GenContext *c, LLVMValueRef **args, ABIArgInfo *info, B
{
// If we want we could optimize for structs by doing it by reference here.
assert(info->indirect.alignment == type_abi_alignment(type) || info->attributes.realign);
if (info->attributes.by_val && llvm_value_is_addr(be_value) && info->indirect.alignment <= be_value->alignment)
{
llvm_value_fold_optional(c, be_value);
vec_add(*args, be_value->value);
return;
}
LLVMValueRef indirect = llvm_emit_alloca(c, llvm_get_type(c, type), info->indirect.alignment, "indirectarg");
llvm_store_to_ptr_aligned(c, indirect, be_value, info->indirect.alignment);
vec_add(*args, indirect);
@@ -4562,9 +4575,8 @@ static inline void llvm_emit_vararg_parameter(GenContext *c, BEValue *value, Typ
}
void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr, BEValue *target)
{
if (expr->call_expr.is_builtin)
{
llvm_emit_builtin_call(c, result_value, expr);
@@ -4669,6 +4681,7 @@ void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
*result_value = (BEValue){ .kind = BE_VALUE, .value = NULL };
// 6. Generate data for the return value.
bool sret_return = false;
switch (ret_info->kind)
{
case ABI_ARG_INDIRECT:
@@ -4682,6 +4695,14 @@ void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
// 6b. Return true is indirect, in this case we allocate a local, using the desired alignment on the caller side.
assert(ret_info->attributes.realign || ret_info->indirect.alignment == type_abi_alignment(call_return_type));
AlignSize alignment = ret_info->indirect.alignment;
// If we have a target, then use it.
if (target && alignment <= target->alignment)
{
assert(target->kind == BE_ADDRESS);
vec_add(values, target->value);
sret_return = true;
break;
}
llvm_value_set_address(result_value,
llvm_emit_alloca(c, llvm_get_type(c, call_return_type), alignment, "sretparam"),
call_return_type,
@@ -4817,7 +4838,7 @@ void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
// 13. Indirect, that is passing the result through an out parameter.
// 13a. In the case of an already present error_var, we don't need to do a load here.
if (error_var) break;
if (error_var || sret_return) break;
// 13b. Otherwise it will be contained in a be_value that is an address
// so we don't need to do anything more.
@@ -4927,6 +4948,11 @@ void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr)
}
// 17. Handle failables.
if (sret_return)
{
*result_value = (BEValue) { .type = type_void, .kind = BE_VALUE };
return;
}
if (prototype->is_failable)
{
BEValue no_err;
@@ -5847,7 +5873,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
gencontext_emit_access_addr(c, value, expr);
return;
case EXPR_CALL:
llvm_emit_call_expr(c, value, expr);
llvm_emit_call_expr(c, value, expr, NULL);
return;
case EXPR_EXPRESSION_LIST:
gencontext_emit_expression_list_expr(c, value, expr);

View File

@@ -121,13 +121,9 @@ static inline void llvm_process_parameter_value(GenContext *c, Decl *decl, ABIAr
case ABI_ARG_IGNORE:
return;
case ABI_ARG_INDIRECT:
{
// A simple memcopy, with alignment respected.
LLVMValueRef pointer = llvm_get_next_param(c, index);
llvm_emit_and_set_decl_alloca(c, decl);
llvm_emit_memcpy_to_decl(c, decl, pointer, info->indirect.alignment);
// Indirect is caller copied.
decl->backend_ref = llvm_get_next_param(c, index);
return;
}
case ABI_ARG_EXPAND_COERCE:
{
// Create the expand type:

View File

@@ -471,7 +471,7 @@ static Expr *parse_type_expr(ParseContext *c, Expr *left)
{
assert(!left && "Unexpected left hand side");
Expr *expr = EXPR_NEW_TOKEN(EXPR_TYPEINFO);
ASSIGN_TYPE_OR_RET(TypeInfo *type, parse_type(c), poisoned_expr);
ASSIGN_TYPE_OR_RET(TypeInfo *type, parse_optional_type(c), poisoned_expr);
expr->span = type->span;
expr->type_expr = type;
if (tok_is(c, TOKEN_SCOPE))
@@ -876,6 +876,7 @@ static Expr *parse_ct_sizeof(ParseContext *c, Expr *left)
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_expr);
Expr *typeof_expr = expr_new(EXPR_TYPEINFO, inner->span);
TypeInfo *type_info = type_info_new(TYPE_INFO_TYPEOF, inner->span);
type_info->failable = try_consume(c, TOKEN_BANG);
type_info->unresolved_type_expr = inner;
typeof_expr->type_expr = type_info;
access->access_expr.parent = typeof_expr;

View File

@@ -772,7 +772,6 @@ static inline Ast *parse_decl_or_expr_stmt(ParseContext *c)
if (expr->expr_kind == EXPR_FAILABLE && expr->inner_expr->expr_kind == EXPR_TYPEINFO)
{
UNREACHABLE
expr_replace(expr, expr->inner_expr);
}
if (expr->expr_kind == EXPR_TYPEINFO)
{

View File

@@ -441,6 +441,7 @@ static bool sema_analyse_struct_union(SemaContext *context, Decl *decl)
if (!sema_analyse_attributes(context, decl, decl->attributes, domain)) return decl_poison(decl);
DEBUG_LOG("Beginning analysis of %s.", decl->name ? decl->name : ".anon");
bool success;
Decl **members = decl->strukt.members;

View File

@@ -4,12 +4,22 @@
#include "sema_internal.h"
static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_info, bool allow_inferred);
static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, bool allow_inferred, bool shallow);
static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type, bool is_pointee);
INLINE bool sema_resolve_vatype(SemaContext *context, TypeInfo *type_info);
INLINE bool sema_resolve_evaltype(SemaContext *context, TypeInfo *type_info, bool is_pointee);
INLINE bool sema_resolve_typefrom(SemaContext *context, TypeInfo *type_info);
INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info);
static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_info, bool allow_inferred)
{
if (!sema_resolve_type_shallow(context, type_info->pointer, allow_inferred, true))
// Try to resolve this type shallowly.
if (!sema_resolve_type(context, type_info->pointer, allow_inferred, true))
{
return type_info_poison(type_info);
}
// Construct the type after resolving the underlying type.
type_info->type = type_get_ptr(type_info->pointer->type);
type_info->resolve_status = RESOLVE_DONE;
return true;
@@ -22,44 +32,68 @@ bool sema_resolve_type_info(SemaContext *context, TypeInfo *type_info)
bool sema_resolve_type_info_maybe_inferred(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type)
{
if (!sema_resolve_type_shallow(context, type_info, allow_inferred_type, false)) return false;
// Resolve the type non-shallow
if (!sema_resolve_type(context, type_info, allow_inferred_type, false)) return false;
// What is the underlying non-optional type.
Type *type = type_no_optional(type_info->type);
// usize and similar typedefs will not have a decl.
// usz and similar typedefs will not have a decl.
if (type->type_kind == TYPE_TYPEDEF && type->decl == NULL) return true;
// If it is a basic type, then we're done.
if (!type_is_user_defined(type)) return true;
// Otherwise analyse the underlying declaration.
return sema_analyse_decl(context, type->decl);
}
bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, ArraySize *len_ref)
{
// Get the expression describing the length.
Expr *len_expr = type_info->array.len;
// Analyse it.
if (!sema_analyse_expr(context, len_expr)) return type_info_poison(type_info);
// A constant expression is assumed.
if (len_expr->expr_kind != EXPR_CONST)
{
SEMA_ERROR(len_expr, "Expected a constant value as size.");
SEMA_ERROR(len_expr, "Expected a constant value as length.");
return type_info_poison(type_info);
}
// The constant must be an integer (and not just a distinct integer)
if (!type_is_integer(len_expr->type->canonical))
{
SEMA_ERROR(len_expr, "Expected an integer size.");
SEMA_ERROR(len_expr, "Expected an integer value.");
return type_info_poison(type_info);
}
bool is_vector = type_info->kind == TYPE_INFO_VECTOR;
// Check the length:
Int len = len_expr->const_expr.ixx;
// Is it negative?
if (int_is_neg(len))
{
SEMA_ERROR(len_expr,
is_vector ? "A vector may not have a negative width." :
"An array may not have a negative size.");
"An array may not have a negative length.");
return type_info_poison(type_info);
}
if (is_vector && int_is_zero(len))
// Is it zero?
if (int_is_zero(len))
{
SEMA_ERROR(len_expr, "A vector may not have a zero width.");
SEMA_ERROR(len_expr,
is_vector ? "A vector may not have a zero width."
: "An array may not have zero length.");
return type_info_poison(type_info);
}
// Check max values.
if (int_icomp(len, is_vector ? MAX_VECTOR_WIDTH : MAX_ARRAY_SIZE, BINARYOP_GT))
{
if (is_vector)
@@ -68,10 +102,11 @@ bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, Arra
}
else
{
SEMA_ERROR(len_expr, "The array size may not exceed %lld.", MAX_ARRAY_SIZE);
SEMA_ERROR(len_expr, "The array length may not exceed %lld.", MAX_ARRAY_SIZE);
}
return type_info_poison(type_info);
}
// We're done, return the size and mark it as a success.
*len_ref = (ArraySize)len.i.low;
return true;
}
@@ -79,9 +114,12 @@ bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, Arra
// TODO cleanup.
static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, bool allow_inferred, bool shallow)
{
if (type->kind == TYPE_INFO_SUBARRAY || shallow)
TypeInfoKind kind = type->kind;
// We can resolve the base type in a shallow way if we don't use it to determine
// length and alignment
if (kind == TYPE_INFO_SUBARRAY || shallow)
{
if (!sema_resolve_type_shallow(context, type->array.base, allow_inferred, true))
if (!sema_resolve_type(context, type->array.base, allow_inferred, true))
{
return type_info_poison(type);
}
@@ -210,57 +248,87 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in
}
bool sema_resolve_type(SemaContext *context, Type *type)
// $evaltype("Foo")
INLINE bool sema_resolve_evaltype(SemaContext *context, TypeInfo *type_info, bool is_pointee)
{
switch (type->type_kind)
Expr *expr = type_info->unresolved_type_expr;
TokenType type;
Expr *inner = sema_ct_eval_expr(context, "$evaltype", expr, true);
if (!inner) return type_info_poison(type_info);
if (inner->expr_kind != EXPR_TYPEINFO)
{
case TYPE_TYPEDEF:
return sema_resolve_type(context, type->canonical);
case TYPE_POISONED:
case ALL_INTS:
case ALL_FLOATS:
case TYPE_VOID:
case TYPE_BOOL:
case TYPE_TYPEID:
case TYPE_ANY:
case TYPE_ANYERR:
case TYPE_VECTOR:
case TYPE_TYPEINFO:
case TYPE_MEMBER:
case TYPE_UNTYPED_LIST:
case TYPE_FAILABLE_ANY:
return true;
case TYPE_POINTER:
return sema_resolve_type(context, type->pointer);
case TYPE_BITSTRUCT:
case TYPE_DISTINCT:
case TYPE_ENUM:
case TYPE_FAULTTYPE:
case TYPE_FUNC:
case TYPE_STRUCT:
case TYPE_UNION:
break;
case TYPE_ARRAY:
case TYPE_SUBARRAY:
case TYPE_INFERRED_ARRAY:
case TYPE_FLEXIBLE_ARRAY:
case TYPE_INFERRED_VECTOR:
case TYPE_SCALED_VECTOR:
return sema_resolve_type(context, type->array.base);
case TYPE_OPTIONAL:
return sema_resolve_type(context, type->failable);
SEMA_ERROR(expr, "Only type names may be resolved with $evaltype.");
return false;
}
return sema_analyse_decl(context, type->decl);
TypeInfo *inner_type = inner->type_expr;
if (!sema_resolve_type(context, inner_type, false, is_pointee)) return false;
if (type_is_invalid_storage_type(inner_type->type))
{
SEMA_ERROR(expr, "Compile-time types may not be used with $evaltype.");
return false;
}
type_info->type = inner_type->type;
return true;
}
bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type, bool in_shallow)
// $typeof(...)
INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info)
{
Expr *expr = type_info->unresolved_type_expr;
if (!sema_analyse_expr(context, expr))
{
return false;
}
if (type_is_invalid_storage_type(expr->type))
{
SEMA_ERROR(expr, "Expected a regular runtime expression here.");
return false;
}
type_info->type = expr->type;
return true;
}
INLINE bool sema_resolve_typefrom(SemaContext *context, TypeInfo *type_info)
{
Expr *expr = type_info->unresolved_type_expr;
if (!sema_analyse_expr(context, expr)) return false;
if (!expr_is_const(expr) || expr->const_expr.const_kind != CONST_TYPEID)
{
SEMA_ERROR(expr, "Expected a constant typeid value.");
return false;
}
type_info->type = expr->const_expr.typeid;
return true;
}
// $vatype(...)
INLINE bool sema_resolve_vatype(SemaContext *context, TypeInfo *type_info)
{
if (!context->current_macro)
{
SEMA_ERROR(type_info, "'%s' can only be used inside of a macro.", token_type_to_string(TOKEN_CT_VATYPE));
return false;
}
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, type_info->unresolved_type_expr),
false);
if (arg_expr->expr_kind != EXPR_TYPEINFO)
{
SEMA_ERROR(arg_expr, "The argument was not a type.");
return false;
}
assert(arg_expr->resolve_status == RESOLVE_DONE);
type_info->type = arg_expr->type_expr->type;
return true;
}
static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, bool allow_inferred_type, bool is_pointee)
{
// Ok, already resolved.
if (type_info->resolve_status == RESOLVE_DONE) return type_info_ok(type_info);
// We might have the resolve already running, if so then that's bad.
if (type_info->resolve_status == RESOLVE_RUNNING)
{
// TODO this is incorrect for unresolved expressions
SEMA_ERROR(type_info,
"Circular dependency resolving type '%s'.",
type_info->unresolved.name);
@@ -268,90 +336,35 @@ bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool a
}
type_info->resolve_status = RESOLVE_RUNNING;
// Type compression means we don't need that many nested type infos.
TypeInfoCompressedKind kind = type_info->subtype;
if (kind != TYPE_COMPRESSED_NONE)
{
in_shallow = true;
is_pointee = true;
}
switch (type_info->kind)
{
case TYPE_INFO_POISON:
UNREACHABLE
case TYPE_INFO_VATYPE:
if (context->current_macro)
{
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, type_info->unresolved_type_expr), false);
if (arg_expr->expr_kind != EXPR_TYPEINFO)
{
SEMA_ERROR(arg_expr, "The argument was not a type.");
return false;
}
*type_info = *arg_expr->type_expr;
assert(type_info->resolve_status == RESOLVE_DONE);
return true;
}
SEMA_ERROR(type_info, "'%s' can only be used inside of a macro.", token_type_to_string(TOKEN_CT_VATYPE));
return false;
if (!sema_resolve_vatype(context, type_info)) return type_info_poison(type_info);
goto APPEND_QUALIFIERS;
case TYPE_INFO_CT_IDENTIFIER:
case TYPE_INFO_IDENTIFIER:
if (!sema_resolve_type_identifier(context, type_info)) return false;
break;
// $Type or Foo
if (!sema_resolve_type_identifier(context, type_info)) return type_info_poison(type_info);
goto APPEND_QUALIFIERS;
case TYPE_INFO_EVALTYPE:
{
Expr *expr = type_info->unresolved_type_expr;
TokenType type;
Expr *inner = sema_ct_eval_expr(context, "$evaltype", expr, true);
if (!inner) return false;
if (inner->expr_kind != EXPR_TYPEINFO)
{
SEMA_ERROR(expr, "Only type names may be resolved with $evaltype.");
return type_info_poison(type_info);
}
if (type_is_invalid_storage_type(expr->type))
{
SEMA_ERROR(expr, "Compile-time types may not be used with $evaltype.");
return type_info_poison(type_info);
}
TypeInfo *inner_type = inner->type_expr;
if (!sema_resolve_type_info(context, inner_type)) return false;
type_info->type = inner_type->type;
type_info->resolve_status = RESOLVE_DONE;
if (!sema_resolve_evaltype(context, type_info, is_pointee)) return type_info_poison(type_info);
goto APPEND_QUALIFIERS;
}
case TYPE_INFO_TYPEOF:
{
Expr *expr = type_info->unresolved_type_expr;
if (!sema_analyse_expr(context, expr))
{
return type_info_poison(type_info);
}
if (type_is_invalid_storage_type(expr->type))
{
SEMA_ERROR(expr, "Expected a regular runtime expression here.");
return false;
}
type_info->type = expr->type;
type_info->resolve_status = RESOLVE_DONE;
assert(!type_info->failable);
if (!sema_resolve_typeof(context, type_info)) return type_info_poison(type_info);
goto APPEND_QUALIFIERS;
}
case TYPE_INFO_TYPEFROM:
{
Expr *expr = type_info->unresolved_type_expr;
if (!sema_analyse_expr(context, expr))
{
return type_info_poison(type_info);
}
if (!expr_is_const(expr) || expr->const_expr.const_kind != CONST_TYPEID)
{
SEMA_ERROR(expr, "Expected a constant typeid value.");
return type_info_poison(type_info);
}
type_info->type = expr->const_expr.typeid;
type_info->resolve_status = RESOLVE_DONE;
assert(!type_info->failable);
if (!sema_resolve_typefrom(context, type_info)) return type_info_poison(type_info);
goto APPEND_QUALIFIERS;
}
case TYPE_INFO_INFERRED_ARRAY:
case TYPE_INFO_INFERRED_VECTOR:
if (!allow_inferred_type)
@@ -365,10 +378,13 @@ bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool a
case TYPE_INFO_SUBARRAY:
case TYPE_INFO_ARRAY:
case TYPE_INFO_VECTOR:
if (!sema_resolve_array_type(context, type_info, allow_inferred_type, in_shallow)) return false;
if (!sema_resolve_array_type(context, type_info, allow_inferred_type, is_pointee))
{
return type_info_poison(type_info);
}
break;
case TYPE_INFO_POINTER:
if (!sema_resolve_ptr_type(context, type_info, allow_inferred_type)) return false;
if (!sema_resolve_ptr_type(context, type_info, allow_inferred_type)) return type_info_poison(type_info);
break;
}
APPEND_QUALIFIERS:
@@ -400,18 +416,7 @@ APPEND_QUALIFIERS:
Type *type = type_info->type;
if (!type_is_optional(type)) type_info->type = type_get_optional(type);
}
type_info->resolve_status = RESOLVE_DONE;
return true;
}
Type *sema_type_lower_by_size(Type *type, ArraySize element_size)
{
switch (type->type_kind)
{
case TYPE_INFERRED_ARRAY:
return type_get_array(type->array.base, element_size);
case TYPE_INFERRED_VECTOR:
return type_get_vector(type->array.base, element_size);
default:
return type;
}
}

View File

@@ -627,6 +627,7 @@ AlignSize type_abi_alignment(Type *type)
return t.iptr.canonical->builtin.abi_alignment;
case TYPE_STRUCT:
case TYPE_UNION:
assert(type->decl->resolve_status == RESOLVE_DONE);
return type->decl->alignment;
case TYPE_BOOL:
case ALL_INTS:

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.85"
#define COMPILER_VERSION "0.3.86"

View File

@@ -126,10 +126,10 @@ entry:
call void (double, ...) @test_test49_helper(double %0, double %1)
ret void
call void (i32, ...) @test52_helper(i32 0, <8 x float> %0, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (i32, ...) @test52_helper(i32 0, <8 x float> %0, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<8 x float>, ...) @test54_helper(<8 x float> %0, <8 x float> %1, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<8 x float>, ...) @test54_helper(<8 x float> %7, <8 x float> %8, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, %Complex* byval(%Complex) align 8 %indirectarg)
call void (<8 x float>, ...) @test54_helper(<8 x float> %0, <8 x float> %1, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<8 x float>, ...) @test54_helper(<8 x float> %7, <8 x float> %8, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, %Complex* byval(%Complex) align 8 %literal1)
declare void @f55(%St512* byval(%St512) align 64) #0
declare void @f56(<16 x float>* byval(<16 x float>) align 64) #0

View File

@@ -72,4 +72,4 @@ define void @test_f62() #0 {
call void (i32, ...) @test_f62_helper(i32 0, <16 x float> %0, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
define void @test_f64() #0 {
call void (<16 x float>, ...) @test_f64_helper(<16 x float> %0, <16 x float> %1, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<16 x float>, ...) @test_f64_helper(<16 x float> %7, <16 x float> %8, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, %Complex* byval(%Complex) align 8 %indirectarg)
call void (<16 x float>, ...) @test_f64_helper(<16 x float> %7, <16 x float> %8, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, %Complex* byval(%Complex) align 8 %literal1)

View File

@@ -14,12 +14,8 @@ fn SimdDouble4x4 ident(SimdDouble4x4 x) {
define void @foo_ident(%SimdDouble4x4* noalias sret(%SimdDouble4x4) align 32 %0, %SimdDouble4x4* byval(%SimdDouble4x4) align 32 %1) #0 {
entry:
%x = alloca %SimdDouble4x4, align 32
%2 = bitcast %SimdDouble4x4* %x to i8*
%2 = bitcast %SimdDouble4x4* %0 to i8*
%3 = bitcast %SimdDouble4x4* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 32 %2, i8* align 32 %3, i32 128, i1 false)
%4 = bitcast %SimdDouble4x4* %0 to i8*
%5 = bitcast %SimdDouble4x4* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 32 %4, i8* align 32 %5, i32 128, i1 false)
ret void
}
}

View File

@@ -21,10 +21,6 @@ fn Large f_scalar_stack_2(double a, int128 b, float128 c, V32i8 d,
define signext i32 @test_f_scalar_stack_1(i32 signext %0, i128 %1, float %2, fp128 %3, <32 x i8>* align 32 %4, i8 zeroext %5, i8 %6, i8 %7) #0 {
entry:
%e = alloca <32 x i8>, align 32
%8 = bitcast <32 x i8>* %e to i8*
%9 = bitcast <32 x i8>* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 32 %8, i8* align 32 %9, i32 32, i1 false)
%uisiext = zext i8 %6 to i32
%uisiext1 = zext i8 %7 to i32
%add = add i32 %uisiext, %uisiext1
@@ -32,25 +28,21 @@ entry:
}
define void @test_f_scalar_stack_2(%Large* noalias sret(%Large) align 8 %0, double %1, i128 %2, fp128 %3, <32 x i8>* align 32 %4, i8 zeroext %5, i8 %6, i8 %7) #0 {
entry:
%d = alloca <32 x i8>, align 32
%literal = alloca %Large, align 8
%8 = bitcast <32 x i8>* %d to i8*
%9 = bitcast <32 x i8>* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 32 %8, i8* align 32 %9, i32 32, i1 false)
%10 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 0
%8 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 0
%fpsi = fptosi double %1 to i64
store i64 %fpsi, i64* %10, align 8
%11 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 1
store i64 %fpsi, i64* %8, align 8
%9 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 1
%uisiext = zext i8 %5 to i64
store i64 %uisiext, i64* %11, align 8
%12 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 2
store i64 %uisiext, i64* %9, align 8
%10 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 2
%sisiext = sext i8 %6 to i64
store i64 %sisiext, i64* %12, align 8
%13 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 3
store i64 %sisiext, i64* %10, align 8
%11 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 3
%uisiext1 = zext i8 %7 to i64
store i64 %uisiext1, i64* %13, align 8
%14 = bitcast %Large* %0 to i8*
%15 = bitcast %Large* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %14, i8* align 8 %15, i32 32, i1 false)
store i64 %uisiext1, i64* %11, align 8
%12 = bitcast %Large* %0 to i8*
%13 = bitcast %Large* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %12, i8* align 8 %13, i32 32, i1 false)
ret void
}

View File

@@ -32,11 +32,11 @@ fn void use_vectors()
/* #expect: foo.ll
declare void @take_stringref(i8*, i64) #0
call void @take_stringref(i8* %lo, i64 %hi)
call void @take_stringref(i8* %lo, i64 %hi)
define void @foo_use_vectors() #0 {
entry:
%0 = call <8 x float> @get_m256()
call void @take_m256(<8 x float>* byval(<8 x float>) align 32 %indirectarg)
%2 = call <16 x float> @get_m512()
call void @take_m512(<16 x float>* byval(<16 x float>) align 64 %indirectarg1)
call void @take_m256(<8 x float>* byval(<8 x float>) align 32 %v1)
%1 = call <16 x float> @get_m512()
call void @take_m512(<16 x float>* byval(<16 x float>) align 64 %v2)

View File

@@ -25,15 +25,7 @@ declare void @foo1(%Abc* noalias sret(%Abc) align 8)
declare void @foo2(%Abc* noalias sret(%Abc) align 8)
%dummy1 = alloca %Abc, align 8
%sretparam = alloca %Abc, align 8
%dummy2 = alloca %Abc, align 8
%sretparam1 = alloca %Abc, align 8
call void @foo1(%Abc* sret(%Abc) align 8 %sretparam)
%0 = bitcast %Abc* %dummy1 to i8*
%1 = bitcast %Abc* %sretparam to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %0, i8* align 8 %1, i32 40, i1 false)
call void @foo2(%Abc* sret(%Abc) align 8 %sretparam1)
%2 = bitcast %Abc* %dummy2 to i8*
%3 = bitcast %Abc* %sretparam1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %2, i8* align 8 %3, i32 40, i1 false)
call void @foo1(%Abc* sret(%Abc) align 8 %dummy1)
call void @foo2(%Abc* sret(%Abc) align 8 %dummy2)
ret void

View File

@@ -45,76 +45,55 @@ entry:
define void @vector2_add(%Vector2* noalias sret(%Vector2) align 4 %0, %Vector2* byval(%Vector2) align 4 %1, %Vector2* byval(%Vector2) align 4 %2) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%3 = bitcast %Vector2* %v1 to i8*
%4 = bitcast %Vector2* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 8, i1 false)
%5 = bitcast %Vector2* %v2 to i8*
%6 = bitcast %Vector2* %2 to i8*
%3 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %4, align 4
%5 = bitcast %Vector2* %0 to i8*
%6 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %5, i8* align 4 %6, i32 8, i1 false)
%7 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %7, align 4
%8 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %8, align 4
%9 = bitcast %Vector2* %0 to i8*
%10 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %9, i8* align 4 %10, i32 8, i1 false)
ret void
}
; Function Attrs: nounwind
define void @vector2_add_value(%Vector2* noalias sret(%Vector2) align 4 %0, %Vector2* byval(%Vector2) align 4 %1, float %2) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%3 = bitcast %Vector2* %v to i8*
%4 = bitcast %Vector2* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 8, i1 false)
%5 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %5, align 4
%6 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %6, align 4
%7 = bitcast %Vector2* %0 to i8*
%8 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %7, i8* align 4 %8, i32 8, i1 false)
%3 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %4, align 4
%5 = bitcast %Vector2* %0 to i8*
%6 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %5, i8* align 4 %6, i32 8, i1 false)
ret void
}
; Function Attrs: nounwind
define void @vector2_subtract(%Vector2* noalias sret(%Vector2) align 4 %0, %Vector2* byval(%Vector2) align 4 %1, %Vector2* byval(%Vector2) align 4 %2) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%3 = bitcast %Vector2* %v1 to i8*
%4 = bitcast %Vector2* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 8, i1 false)
%5 = bitcast %Vector2* %v2 to i8*
%6 = bitcast %Vector2* %2 to i8*
%3 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %4, align 4
%5 = bitcast %Vector2* %0 to i8*
%6 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %5, i8* align 4 %6, i32 8, i1 false)
%7 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %7, align 4
%8 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %8, align 4
%9 = bitcast %Vector2* %0 to i8*
%10 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %9, i8* align 4 %10, i32 8, i1 false)
ret void
}
; Function Attrs: nounwind
define void @vector2_subtract_value(%Vector2* noalias sret(%Vector2) align 4 %0, %Vector2* byval(%Vector2) align 4 %1, float %2) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%3 = bitcast %Vector2* %v to i8*
%4 = bitcast %Vector2* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 8, i1 false)
%5 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %5, align 4
%6 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %6, align 4
%7 = bitcast %Vector2* %0 to i8*
%8 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %7, i8* align 4 %8, i32 8, i1 false)
%3 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %4, align 4
%5 = bitcast %Vector2* %0 to i8*
%6 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %5, i8* align 4 %6, i32 8, i1 false)
ret void
}

View File

@@ -3,7 +3,7 @@ const int CONSTANT = 1;
int[CONSTANT] a2;
int[3] a3 = { [CONSTANT] = 1 };
const bool B = true;
int[B] c2; // #error: Expected an integer size.
int[B] c2; // #error: Expected an integer
int non_constant = 10;
int[non_constant] b; // #error: Expected a constant value as

View File

@@ -17,8 +17,6 @@ fn void test(int[10] x, int[<10>] y)
define void @test_test([10 x i32]* byval([10 x i32]) align 8 %0, <10 x i32>* byval(<10 x i32>) align 64 %1) #0 {
entry:
%x = alloca [10 x i32], align 4
%y = alloca <10 x i32>, align 64
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
@@ -26,36 +24,30 @@ entry:
%j = alloca i32, align 4
%e = alloca i32, align 4
%f = alloca i32, align 4
%2 = bitcast [10 x i32]* %x to i8*
%3 = bitcast [10 x i32]* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %2, i8* align 8 %3, i32 40, i1 false)
%4 = bitcast <10 x i32>* %y to i8*
%5 = bitcast <10 x i32>* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 64 %4, i8* align 64 %5, i32 64, i1 false)
%6 = getelementptr inbounds [10 x i32], [10 x i32]* %x, i64 0, i64 4
%7 = load i32, i32* %6, align 4
store i32 %7, i32* %a, align 4
%8 = getelementptr inbounds [10 x i32], [10 x i32]* %x, i64 0, i64 8
%9 = load i32, i32* %8, align 4
store i32 %9, i32* %b, align 4
%10 = load <10 x i32>, <10 x i32>* %y, align 64
%11 = extractelement <10 x i32> %10, i64 4
store i32 %11, i32* %c, align 4
%12 = load <10 x i32>, <10 x i32>* %y, align 64
%13 = extractelement <10 x i32> %12, i64 8
store i32 %13, i32* %d, align 4
%2 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i64 0, i64 4
%3 = load i32, i32* %2, align 4
store i32 %3, i32* %a, align 4
%4 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i64 0, i64 8
%5 = load i32, i32* %4, align 4
store i32 %5, i32* %b, align 4
%6 = load <10 x i32>, <10 x i32>* %1, align 64
%7 = extractelement <10 x i32> %6, i64 4
store i32 %7, i32* %c, align 4
%8 = load <10 x i32>, <10 x i32>* %1, align 64
%9 = extractelement <10 x i32> %8, i64 8
store i32 %9, i32* %d, align 4
store i32 3, i32* %j, align 4
%14 = load <10 x i32>, <10 x i32>* %y, align 64
%15 = load i32, i32* %j, align 4
%sisiext = sext i32 %15 to i64
%16 = sub nuw i64 10, %sisiext
%17 = extractelement <10 x i32> %14, i64 %16
store i32 %17, i32* %e, align 4
%18 = load i32, i32* %j, align 4
%sisiext1 = sext i32 %18 to i64
%19 = sub nuw i64 10, %sisiext1
%20 = getelementptr inbounds [10 x i32], [10 x i32]* %x, i64 0, i64 %19
%21 = load i32, i32* %20, align 4
store i32 %21, i32* %f, align 4
%10 = load <10 x i32>, <10 x i32>* %1, align 64
%11 = load i32, i32* %j, align 4
%sisiext = sext i32 %11 to i64
%12 = sub nuw i64 10, %sisiext
%13 = extractelement <10 x i32> %10, i64 %12
store i32 %13, i32* %e, align 4
%14 = load i32, i32* %j, align 4
%sisiext1 = sext i32 %14 to i64
%15 = sub nuw i64 10, %sisiext1
%16 = getelementptr inbounds [10 x i32], [10 x i32]* %0, i64 0, i64 %15
%17 = load i32, i32* %16, align 4
store i32 %17, i32* %f, align 4
ret void
}

View File

@@ -1,5 +1,5 @@
int[-1] a; // #error: An array may not have a negative size
int[10-20] b; // #error: An array may not have a negative size
int[-1] a; // #error: An array may not have a negative
int[10-20] b; // #error: An array may not have a negative
int[<-1>] c; // #error: A vector may not have a negative width
int[<10-20>] d; // #error: A vector may not have a negative width

View File

@@ -356,13 +356,9 @@ entry:
; Function Attrs: nounwind
define void @test_test7(%STest2* noalias sret(%STest2) align 8 %0, %STest2* byval(%STest2) align 8 %1) #0 {
entry:
%x = alloca %STest2, align 8
%2 = bitcast %STest2* %x to i8*
%2 = bitcast %STest2* %0 to i8*
%3 = bitcast %STest2* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %2, i8* align 8 %3, i32 24, i1 false)
%4 = bitcast %STest2* %0 to i8*
%5 = bitcast %STest2* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %4, i8* align 8 %5, i32 24, i1 false)
ret void
}

View File

@@ -152,32 +152,28 @@ entry:
; Function Attrs: nounwind
define void @test_test2(%FooSt* byval(%FooSt) align 8 %0) #0 {
entry:
%y = alloca %FooSt, align 4
%indirectarg = alloca %FooSt, align 8
%indirectarg1 = alloca %FooSt, align 8
%1 = bitcast %FooSt* %y to i8*
%2 = bitcast %FooSt* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 8 %2, i32 20, i1 false)
%3 = getelementptr inbounds %FooSt, %FooSt* %y, i32 0, i32 0
%4 = load i8, i8* %3, align 4
%5 = getelementptr inbounds %FooSt, %FooSt* %y, i32 0, i32 1
%6 = load i16, i16* %5, align 2
%7 = getelementptr inbounds %FooSt, %FooSt* %y, i32 0, i32 2
%8 = load i8, i8* %7, align 4
%9 = getelementptr inbounds %FooSt, %FooSt* %y, i32 0, i32 3
%10 = load i32, i32* %9, align 4
%11 = getelementptr inbounds %FooSt, %FooSt* %y, i32 0, i32 4
%12 = load i16, i16* %11, align 4
%sisiext = sext i16 %12 to i32
%13 = call i32 @testE(i8 %4, i16 %6, i8 %8, i32 %10, i32 %sisiext, float 0x3FB99999A0000000)
%14 = bitcast %FooSt* %indirectarg to i8*
%15 = bitcast %FooSt* %y to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %14, i8* align 4 %15, i32 20, i1 false)
%16 = call i32 @testF(%FooSt* byval(%FooSt) align 8 %indirectarg, float 0x3FB99999A0000000)
%17 = bitcast %FooSt* %indirectarg1 to i8*
%18 = bitcast %FooSt* %y to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %17, i8* align 4 %18, i32 20, i1 false)
%1 = getelementptr inbounds %FooSt, %FooSt* %0, i32 0, i32 0
%2 = load i8, i8* %1, align 4
%3 = getelementptr inbounds %FooSt, %FooSt* %0, i32 0, i32 1
%4 = load i16, i16* %3, align 2
%5 = getelementptr inbounds %FooSt, %FooSt* %0, i32 0, i32 2
%6 = load i8, i8* %5, align 4
%7 = getelementptr inbounds %FooSt, %FooSt* %0, i32 0, i32 3
%8 = load i32, i32* %7, align 4
%9 = getelementptr inbounds %FooSt, %FooSt* %0, i32 0, i32 4
%10 = load i16, i16* %9, align 4
%sisiext = sext i16 %10 to i32
%11 = call i32 @testE(i8 %2, i16 %4, i8 %6, i32 %8, i32 %sisiext, float 0x3FB99999A0000000)
%12 = bitcast %FooSt* %indirectarg to i8*
%13 = bitcast %FooSt* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %12, i8* align 4 %13, i32 20, i1 false)
%14 = call i32 @testF(%FooSt* byval(%FooSt) align 8 %indirectarg, float 0x3FB99999A0000000)
%15 = bitcast %FooSt* %indirectarg1 to i8*
%16 = bitcast %FooSt* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %15, i8* align 4 %16, i32 20, i1 false)
call void @test_test2(%FooSt* byval(%FooSt) align 8 %indirectarg1)
call void @test_test3(%FooSt* %y)
call void @test_test3(%FooSt* %0)
ret void
}

View File

@@ -297,22 +297,18 @@ entry:
; Function Attrs: nounwind
define i32 @test_helo(double %0, %Bobo* byval(%Bobo) align 8 %1) #0 {
entry:
%b = alloca %Bobo, align 4
%de = alloca [3 x i32], align 4
%c = alloca %Bobo, align 4
%indirectarg = alloca %Bobo, align 8
%2 = bitcast %Bobo* %b to i8*
%3 = bitcast %Bobo* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %2, i8* align 8 %3, i32 20, i1 false)
%4 = bitcast [3 x i32]* %de to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %4, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
%5 = bitcast %Bobo* %c to i8*
%6 = bitcast %Bobo* %b to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %5, i8* align 4 %6, i32 20, i1 false)
%7 = bitcast %Bobo* %indirectarg to i8*
%8 = bitcast %Bobo* %c to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %7, i8* align 4 %8, i32 20, i1 false)
%9 = call i32 @test_helo(double 1.000000e+00, %Bobo* byval(%Bobo) align 8 %indirectarg)
%2 = bitcast [3 x i32]* %de to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %2, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
%3 = bitcast %Bobo* %c to i8*
%4 = bitcast %Bobo* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 20, i1 false)
%5 = bitcast %Bobo* %indirectarg to i8*
%6 = bitcast %Bobo* %c to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %5, i8* align 4 %6, i32 20, i1 false)
%7 = call i32 @test_helo(double 1.000000e+00, %Bobo* byval(%Bobo) align 8 %indirectarg)
ret i32 1
}

View File

@@ -338,22 +338,18 @@ entry:
; Function Attrs: nounwind
define i32 @test_helo(double %0, %Bobo* align 4 %1) #0 {
entry:
%b = alloca %Bobo, align 4
%de = alloca [3 x i32], align 4
%c = alloca %Bobo, align 4
%indirectarg = alloca %Bobo, align 4
%2 = bitcast %Bobo* %b to i8*
%3 = bitcast %Bobo* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %2, i8* align 4 %3, i32 20, i1 false)
%4 = bitcast [3 x i32]* %de to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %4, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
%5 = bitcast %Bobo* %c to i8*
%6 = bitcast %Bobo* %b to i8*
%2 = bitcast [3 x i32]* %de to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %2, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
%3 = bitcast %Bobo* %c to i8*
%4 = bitcast %Bobo* %1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 20, i1 false)
%5 = bitcast %Bobo* %indirectarg to i8*
%6 = bitcast %Bobo* %c to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %5, i8* align 4 %6, i32 20, i1 false)
%7 = bitcast %Bobo* %indirectarg to i8*
%8 = bitcast %Bobo* %c to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %7, i8* align 4 %8, i32 20, i1 false)
%9 = call i32 @test_helo(double 1.000000e+00, %Bobo* align 4 %indirectarg)
%7 = call i32 @test_helo(double 1.000000e+00, %Bobo* align 4 %indirectarg)
ret i32 1
}
@@ -380,89 +376,81 @@ if.exit: ; preds = %entry
; Function Attrs: nounwind
define i32 @test_sum_us(%"int[]"* align 8 %0) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%vararg = alloca %"int[]", align 8
%indirectarg = alloca %"int[]", align 8
%1 = bitcast %"int[]"* %x to i8*
%2 = bitcast %"int[]"* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 8 %2, i32 16, i1 false)
store i32 0, i32* %sum, align 4
%3 = getelementptr inbounds %"int[]", %"int[]"* %x, i32 0, i32 1
%4 = load i64, i64* %3, align 8
%eq = icmp eq i64 0, %4
%1 = getelementptr inbounds %"int[]", %"int[]"* %0, i32 0, i32 1
%2 = load i64, i64* %1, align 8
%eq = icmp eq i64 0, %2
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 0
if.exit: ; preds = %entry
%5 = load i32, i32* %sum, align 4
%6 = getelementptr inbounds %"int[]", %"int[]"* %x, i32 0, i32 0
%7 = load i32*, i32** %6, align 8
%ptroffset = getelementptr inbounds i32, i32* %7, i64 0
%8 = load i32, i32* %ptroffset, align 4
%9 = load %"int[]", %"int[]"* %x, align 8
%10 = extractvalue %"int[]" %9, 0
%11 = extractvalue %"int[]" %9, 1
%sub = sub i64 %11, 1
%12 = add i64 %sub, 1
%size = sub i64 %12, 1
%ptroffset1 = getelementptr inbounds i32, i32* %10, i64 1
%13 = insertvalue %"int[]" undef, i32* %ptroffset1, 0
%14 = insertvalue %"int[]" %13, i64 %size, 1
%15 = getelementptr inbounds %"int[]", %"int[]"* %vararg, i32 0, i32 1
%16 = getelementptr inbounds %"int[]", %"int[]"* %vararg, i32 0, i32 0
store %"int[]" %14, %"int[]"* %indirectarg, align 8
%17 = call i32 @test_sum_us(%"int[]"* align 8 %indirectarg)
%add = add i32 %8, %17
%add2 = add i32 %5, %add
%3 = load i32, i32* %sum, align 4
%4 = getelementptr inbounds %"int[]", %"int[]"* %0, i32 0, i32 0
%5 = load i32*, i32** %4, align 8
%ptroffset = getelementptr inbounds i32, i32* %5, i64 0
%6 = load i32, i32* %ptroffset, align 4
%7 = load %"int[]", %"int[]"* %0, align 8
%8 = extractvalue %"int[]" %7, 0
%9 = extractvalue %"int[]" %7, 1
%sub = sub i64 %9, 1
%10 = add i64 %sub, 1
%size = sub i64 %10, 1
%ptroffset1 = getelementptr inbounds i32, i32* %8, i64 1
%11 = insertvalue %"int[]" undef, i32* %ptroffset1, 0
%12 = insertvalue %"int[]" %11, i64 %size, 1
%13 = getelementptr inbounds %"int[]", %"int[]"* %vararg, i32 0, i32 1
%14 = getelementptr inbounds %"int[]", %"int[]"* %vararg, i32 0, i32 0
store %"int[]" %12, %"int[]"* %indirectarg, align 8
%15 = call i32 @test_sum_us(%"int[]"* align 8 %indirectarg)
%add = add i32 %6, %15
%add2 = add i32 %3, %add
store i32 %add2, i32* %sum, align 4
%18 = load i32, i32* %sum, align 4
ret i32 %18
%16 = load i32, i32* %sum, align 4
ret i32 %16
}
; Function Attrs: nounwind
define i32 @test_sumd(%"int[]"* align 8 %0) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%i = alloca i32, align 4
%1 = bitcast %"int[]"* %x to i8*
%2 = bitcast %"int[]"* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 8 %2, i32 16, i1 false)
store i32 0, i32* %sum, align 4
store i32 0, i32* %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, i32* %i, align 4
%sisiext = sext i32 %3 to i64
%4 = getelementptr inbounds %"int[]", %"int[]"* %x, i32 0, i32 1
%5 = load i64, i64* %4, align 8
%lt = icmp slt i64 %sisiext, %5
%check = icmp slt i64 %5, 0
%1 = load i32, i32* %i, align 4
%sisiext = sext i32 %1 to i64
%2 = getelementptr inbounds %"int[]", %"int[]"* %0, i32 0, i32 1
%3 = load i64, i64* %2, align 8
%lt = icmp slt i64 %sisiext, %3
%check = icmp slt i64 %3, 0
%siui-lt = or i1 %check, %lt
br i1 %siui-lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%6 = load i32, i32* %sum, align 4
%7 = getelementptr inbounds %"int[]", %"int[]"* %x, i32 0, i32 0
%8 = load i32*, i32** %7, align 8
%9 = load i32, i32* %i, align 4
%sisiext1 = sext i32 %9 to i64
%ptroffset = getelementptr inbounds i32, i32* %8, i64 %sisiext1
%10 = load i32, i32* %ptroffset, align 4
%add = add i32 %6, %10
%4 = load i32, i32* %sum, align 4
%5 = getelementptr inbounds %"int[]", %"int[]"* %0, i32 0, i32 0
%6 = load i32*, i32** %5, align 8
%7 = load i32, i32* %i, align 4
%sisiext1 = sext i32 %7 to i64
%ptroffset = getelementptr inbounds i32, i32* %6, i64 %sisiext1
%8 = load i32, i32* %ptroffset, align 4
%add = add i32 %4, %8
store i32 %add, i32* %sum, align 4
%11 = load i32, i32* %i, align 4
%add2 = add i32 %11, 1
%9 = load i32, i32* %i, align 4
%add2 = add i32 %9, 1
store i32 %add2, i32* %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%12 = load i32, i32* %sum, align 4
ret i32 %12
%10 = load i32, i32* %sum, align 4
ret i32 %10
}
; Function Attrs: nounwind

View File

@@ -165,21 +165,20 @@ entry:
%i59 = alloca i64, align 8
%y60 = alloca i32, align 4
%.anon64 = alloca [5 x i32], align 16
%sretparam = alloca [5 x i32], align 4
%.anon65 = alloca i64, align 8
%i69 = alloca i64, align 8
%y70 = alloca i32, align 4
%.anon73 = alloca [5 x i32]*, align 8
%sretparam74 = alloca [5 x i32], align 4
%.anon75 = alloca i64, align 8
%i79 = alloca i64, align 8
%y80 = alloca i32, align 4
%a83 = alloca i32, align 4
%a85 = alloca i32, align 4
%y87 = alloca i32*, align 8
%a88 = alloca i32, align 4
%a91 = alloca i32, align 4
%a93 = alloca i32, align 4
%sretparam = alloca [5 x i32], align 4
%.anon74 = alloca i64, align 8
%i78 = alloca i64, align 8
%y79 = alloca i32, align 4
%a82 = alloca i32, align 4
%a84 = alloca i32, align 4
%y86 = alloca i32*, align 8
%a87 = alloca i32, align 4
%a90 = alloca i32, align 4
%a92 = alloca i32, align 4
%0 = bitcast %Foo* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast (%Foo* @.__const to i8*), i32 12, i1 false)
store i32 0, i32* %a, align 4
@@ -390,96 +389,93 @@ loop.body58: ; preds = %loop.cond57
br label %loop.cond57
loop.exit63: ; preds = %loop.cond57
call void @foo_getFields([5 x i32]* sret([5 x i32]) align 4 %sretparam)
%83 = bitcast [5 x i32]* %.anon64 to i8*
%84 = bitcast [5 x i32]* %sretparam to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 16 %83, i8* align 4 %84, i32 20, i1 false)
call void @foo_getFields([5 x i32]* sret([5 x i32]) align 4 %.anon64)
store i64 0, i64* %.anon65, align 8
br label %loop.cond66
loop.cond66: ; preds = %loop.body68, %loop.exit63
%85 = load i64, i64* %.anon65, align 8
%gt67 = icmp ugt i64 5, %85
%83 = load i64, i64* %.anon65, align 8
%gt67 = icmp ugt i64 5, %83
br i1 %gt67, label %loop.body68, label %loop.exit72
loop.body68: ; preds = %loop.cond66
%86 = load i64, i64* %.anon65, align 8
store i64 %86, i64* %i69, align 8
%87 = load i64, i64* %.anon65, align 8
%88 = getelementptr inbounds [5 x i32], [5 x i32]* %.anon64, i64 0, i64 %87
%89 = load i32, i32* %88, align 4
store i32 %89, i32* %y70, align 4
%90 = load i64, i64* %i69, align 8
%91 = load i32, i32* %y70, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.10, i32 0, i32 0), i64 %90, i32 %91)
%92 = load i64, i64* %.anon65, align 8
%add71 = add i64 %92, 1
%84 = load i64, i64* %.anon65, align 8
store i64 %84, i64* %i69, align 8
%85 = load i64, i64* %.anon65, align 8
%86 = getelementptr inbounds [5 x i32], [5 x i32]* %.anon64, i64 0, i64 %85
%87 = load i32, i32* %86, align 4
store i32 %87, i32* %y70, align 4
%88 = load i64, i64* %i69, align 8
%89 = load i32, i32* %y70, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.10, i32 0, i32 0), i64 %88, i32 %89)
%90 = load i64, i64* %.anon65, align 8
%add71 = add i64 %90, 1
store i64 %add71, i64* %.anon65, align 8
br label %loop.cond66
loop.exit72: ; preds = %loop.cond66
call void @foo_getFields([5 x i32]* sret([5 x i32]) align 4 %sretparam74)
store [5 x i32]* %sretparam74, [5 x i32]** %.anon73, align 8
store i64 0, i64* %.anon75, align 8
br label %loop.cond76
call void @foo_getFields([5 x i32]* sret([5 x i32]) align 4 %sretparam)
store [5 x i32]* %sretparam, [5 x i32]** %.anon73, align 8
store i64 0, i64* %.anon74, align 8
br label %loop.cond75
loop.cond76: ; preds = %loop.body78, %loop.exit72
%93 = load i64, i64* %.anon75, align 8
%gt77 = icmp ugt i64 5, %93
br i1 %gt77, label %loop.body78, label %loop.exit82
loop.cond75: ; preds = %loop.body77, %loop.exit72
%91 = load i64, i64* %.anon74, align 8
%gt76 = icmp ugt i64 5, %91
br i1 %gt76, label %loop.body77, label %loop.exit81
loop.body78: ; preds = %loop.cond76
%94 = load i64, i64* %.anon75, align 8
store i64 %94, i64* %i79, align 8
%95 = load [5 x i32]*, [5 x i32]** %.anon73, align 8
%96 = load i64, i64* %.anon75, align 8
%97 = getelementptr inbounds [5 x i32], [5 x i32]* %95, i64 0, i64 %96
%98 = load i32, i32* %97, align 4
store i32 %98, i32* %y80, align 4
%99 = load i64, i64* %i79, align 8
%100 = load i32, i32* %y80, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.11, i32 0, i32 0), i64 %99, i32 %100)
%101 = load i64, i64* %.anon75, align 8
%add81 = add i64 %101, 1
store i64 %add81, i64* %.anon75, align 8
br label %loop.cond76
loop.body77: ; preds = %loop.cond75
%92 = load i64, i64* %.anon74, align 8
store i64 %92, i64* %i78, align 8
%93 = load [5 x i32]*, [5 x i32]** %.anon73, align 8
%94 = load i64, i64* %.anon74, align 8
%95 = getelementptr inbounds [5 x i32], [5 x i32]* %93, i64 0, i64 %94
%96 = load i32, i32* %95, align 4
store i32 %96, i32* %y79, align 4
%97 = load i64, i64* %i78, align 8
%98 = load i32, i32* %y79, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.11, i32 0, i32 0), i64 %97, i32 %98)
%99 = load i64, i64* %.anon74, align 8
%add80 = add i64 %99, 1
store i64 %add80, i64* %.anon74, align 8
br label %loop.cond75
loop.exit82: ; preds = %loop.cond76
store i32 0, i32* %a83, align 4
%102 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%103 = load i32, i32* %a83, align 4
%sisiext84 = sext i32 %103 to i64
%104 = getelementptr inbounds [3 x i32], [3 x i32]* %102, i64 0, i64 %sisiext84
%105 = load i32, i32* %104, align 4
store i32 1, i32* %a85, align 4
%106 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%107 = load i32, i32* %a85, align 4
%sisiext86 = sext i32 %107 to i64
%108 = getelementptr inbounds [3 x i32], [3 x i32]* %106, i64 0, i64 %sisiext86
%109 = load i32, i32* %108, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.12, i32 0, i32 0), i32 %105, i32 %109)
store i32 1, i32* %a88, align 4
%110 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%111 = load i32, i32* %a88, align 4
%sisiext89 = sext i32 %111 to i64
%112 = getelementptr inbounds [3 x i32], [3 x i32]* %110, i64 0, i64 %sisiext89
store i32* %112, i32** %y87, align 8
%113 = load i32*, i32** %y87, align 8
%114 = load i32, i32* %113, align 8
%add90 = add i32 %114, 1
store i32 %add90, i32* %113, align 8
store i32 0, i32* %a91, align 4
%115 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%116 = load i32, i32* %a91, align 4
%sisiext92 = sext i32 %116 to i64
%117 = getelementptr inbounds [3 x i32], [3 x i32]* %115, i64 0, i64 %sisiext92
%118 = load i32, i32* %117, align 4
store i32 1, i32* %a93, align 4
%119 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%120 = load i32, i32* %a93, align 4
%sisiext94 = sext i32 %120 to i64
%121 = getelementptr inbounds [3 x i32], [3 x i32]* %119, i64 0, i64 %sisiext94
%122 = load i32, i32* %121, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.13, i32 0, i32 0), i32 %118, i32 %122)
loop.exit81: ; preds = %loop.cond75
store i32 0, i32* %a82, align 4
%100 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%101 = load i32, i32* %a82, align 4
%sisiext83 = sext i32 %101 to i64
%102 = getelementptr inbounds [3 x i32], [3 x i32]* %100, i64 0, i64 %sisiext83
%103 = load i32, i32* %102, align 4
store i32 1, i32* %a84, align 4
%104 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%105 = load i32, i32* %a84, align 4
%sisiext85 = sext i32 %105 to i64
%106 = getelementptr inbounds [3 x i32], [3 x i32]* %104, i64 0, i64 %sisiext85
%107 = load i32, i32* %106, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.12, i32 0, i32 0), i32 %103, i32 %107)
store i32 1, i32* %a87, align 4
%108 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%109 = load i32, i32* %a87, align 4
%sisiext88 = sext i32 %109 to i64
%110 = getelementptr inbounds [3 x i32], [3 x i32]* %108, i64 0, i64 %sisiext88
store i32* %110, i32** %y86, align 8
%111 = load i32*, i32** %y86, align 8
%112 = load i32, i32* %111, align 8
%add89 = add i32 %112, 1
store i32 %add89, i32* %111, align 8
store i32 0, i32* %a90, align 4
%113 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%114 = load i32, i32* %a90, align 4
%sisiext91 = sext i32 %114 to i64
%115 = getelementptr inbounds [3 x i32], [3 x i32]* %113, i64 0, i64 %sisiext91
%116 = load i32, i32* %115, align 4
store i32 1, i32* %a92, align 4
%117 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%118 = load i32, i32* %a92, align 4
%sisiext93 = sext i32 %118 to i64
%119 = getelementptr inbounds [3 x i32], [3 x i32]* %117, i64 0, i64 %sisiext93
%120 = load i32, i32* %119, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.13, i32 0, i32 0), i32 %116, i32 %120)
ret void
}

View File

@@ -24,11 +24,7 @@ fn void test(Bar b)
define void @foo_test(%Bar* byval(%Bar) align 8 %0) #0 {
entry:
%b = alloca %Bar, align 4
%1 = bitcast %Bar* %b to i8*
%2 = bitcast %Bar* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 8 %2, i32 8, i1 false)
%3 = getelementptr inbounds %Bar, %Bar* %b, i32 0, i32 2
%4 = getelementptr inbounds [0 x i32], [0 x i32]* %3, i64 0, i64 1
%1 = getelementptr inbounds %Bar, %Bar* %0, i32 0, i32 2
%2 = getelementptr inbounds [0 x i32], [0 x i32]* %1, i64 0, i64 1
ret void
}

View File

@@ -1,7 +1,7 @@
define Foo = int[0];
define Foo = int[0]; // #error: An array may not have zero
struct Bar
{
Foo x; // #error: Zero length arrays are not valid members.
Foo x;
int b;
}

View File

@@ -128,7 +128,7 @@ entry:
call void (i32, ...) @test52_helper(i32 0, <8 x float> %0, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<8 x float>, ...) @test54_helper(<8 x float> %0, <8 x float> %1, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<8 x float>, ...) @test54_helper(<8 x float> %6, <8 x float> %7, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, ptr byval(%Complex) align 8 %indirectarg)
call void (<8 x float>, ...) @test54_helper(<8 x float> %6, <8 x float> %7, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, ptr byval(%Complex) align 8 %literal1)
declare void @f55(ptr byval(%St512) align 64)
declare void @f56(ptr byval(<16 x float>) align 64)

View File

@@ -71,4 +71,4 @@ define void @test_f62() #0 {
call void (i32, ...) @test_f62_helper(i32 0, <16 x float> %0, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
define void @test_f64() #0 {
call void (<16 x float>, ...) @test_f64_helper(<16 x float> %0, <16 x float> %1, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double %lo, double %hi)
call void (<16 x float>, ...) @test_f64_helper(<16 x float> %6, <16 x float> %7, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, ptr byval(%Complex) align 8 %indirectarg)
call void (<16 x float>, ...) @test_f64_helper(<16 x float> %6, <16 x float> %7, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, ptr byval(%Complex) align 8 %literal1)

View File

@@ -14,8 +14,6 @@ fn SimdDouble4x4 ident(SimdDouble4x4 x) {
define void @foo_ident(ptr noalias sret(%SimdDouble4x4) align 32 %0, ptr byval(%SimdDouble4x4) align 32 %1) #0 {
entry:
%x = alloca %SimdDouble4x4, align 32
call void @llvm.memcpy.p0.p0.i32(ptr align 32 %x, ptr align 32 %1, i32 128, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 32 %0, ptr align 32 %x, i32 128, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 32 %0, ptr align 32 %1, i32 128, i1 false)
ret void
}
}

View File

@@ -21,8 +21,6 @@ fn Large f_scalar_stack_2(double a, int128 b, float128 c, V32i8 d,
define signext i32 @test_f_scalar_stack_1(i32 signext %0, i128 %1, float %2, fp128 %3, ptr align 32 %4, i8 zeroext %5, i8 %6, i8 %7) #0 {
entry:
%e = alloca <32 x i8>, align 32
call void @llvm.memcpy.p0.p0.i32(ptr align 32 %e, ptr align 32 %4, i32 32, i1 false)
%uisiext = zext i8 %6 to i32
%uisiext1 = zext i8 %7 to i32
%add = add i32 %uisiext, %uisiext1
@@ -31,9 +29,7 @@ entry:
define void @test_f_scalar_stack_2(ptr noalias sret(%Large) align 8 %0, double %1, i128 %2, fp128 %3, ptr align 32 %4, i8 zeroext %5, i8 %6, i8 %7) #0 {
entry:
%d = alloca <32 x i8>, align 32
%literal = alloca %Large, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 32 %d, ptr align 32 %4, i32 32, i1 false)
%8 = getelementptr inbounds %Large, ptr %literal, i32 0, i32 0
%fpsi = fptosi double %1 to i64
store i64 %fpsi, ptr %8, align 8

View File

@@ -36,6 +36,6 @@ declare void @take_stringref(ptr, i64) #0
define void @foo_use_vectors() #0 {
%0 = call <8 x float> @get_m256()
call void @take_m256(ptr byval(<8 x float>) align 32 %indirectarg)
%2 = call <16 x float> @get_m512()
call void @take_m512(ptr byval(<16 x float>) align 64 %indirectarg1)
call void @take_m256(ptr byval(<8 x float>) align 32 %v1)
%1 = call <16 x float> @get_m512()
call void @take_m512(ptr byval(<16 x float>) align 64 %v2)

View File

@@ -16,8 +16,6 @@ fn void bar() {
Abc dummy2 = foo2();
}
// Cleanup for this result, since it's creating an unnecessary sret.
/* #expect: test_sret.ll
declare void @foo1(ptr noalias sret(%Abc) align 8) #0
@@ -27,12 +25,8 @@ declare void @foo2(ptr noalias sret(%Abc) align 8) #0
define void @test_sret_bar() #0 {
entry:
%dummy1 = alloca %Abc, align 8
%sretparam = alloca %Abc, align 8
%dummy2 = alloca %Abc, align 8
%sretparam1 = alloca %Abc, align 8
call void @foo1(ptr sret(%Abc) align 8 %sretparam)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %dummy1, ptr align 8 %sretparam, i32 40, i1 false)
call void @foo2(ptr sret(%Abc) align 8 %sretparam1)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %dummy2, ptr align 8 %sretparam1, i32 40, i1 false)
call void @foo1(ptr sret(%Abc) align 8 %dummy1)
call void @foo2(ptr sret(%Abc) align 8 %dummy2)
ret void
}

View File

@@ -42,11 +42,7 @@ entry:
define void @vector2_add(ptr noalias sret(%Vector2) align 4 %0, ptr byval(%Vector2) align 4 %1, ptr byval(%Vector2) align 4 %2) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %v1, ptr align 4 %1, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %v2, ptr align 4 %2, i32 8, i1 false)
%3 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 0
store float 0.000000e+00, ptr %3, align 4
%4 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 1
@@ -57,9 +53,7 @@ entry:
define void @vector2_add_value(ptr noalias sret(%Vector2) align 4 %0, ptr byval(%Vector2) align 4 %1, float %2) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %v, ptr align 4 %1, i32 8, i1 false)
%3 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 0
store float 0.000000e+00, ptr %3, align 4
%4 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 1
@@ -70,11 +64,7 @@ entry:
define void @vector2_subtract(ptr noalias sret(%Vector2) align 4 %0, ptr byval(%Vector2) align 4 %1, ptr byval(%Vector2) align 4 %2) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %v1, ptr align 4 %1, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %v2, ptr align 4 %2, i32 8, i1 false)
%3 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 0
store float 0.000000e+00, ptr %3, align 4
%4 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 1
@@ -83,11 +73,10 @@ entry:
ret void
}
; Function Attrs: nounwind
define void @vector2_subtract_value(ptr noalias sret(%Vector2) align 4 %0, ptr byval(%Vector2) align 4 %1, float %2) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %v, ptr align 4 %1, i32 8, i1 false)
%3 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 0
store float 0.000000e+00, ptr %3, align 4
%4 = getelementptr inbounds %Vector2, ptr %literal, i32 0, i32 1

View File

@@ -3,7 +3,7 @@ const int CONSTANT = 1;
int[CONSTANT] a2;
int[3] a3 = { [CONSTANT] = 1 };
const bool B = true;
int[B] c2; // #error: Expected an integer size.
int[B] c2; // #error: Expected an integer
int non_constant = 10;
int[non_constant] b; // #error: Expected a constant value as

View File

@@ -17,8 +17,6 @@ fn void test(int[10] x, int[<10>] y)
define void @test_test(ptr byval([10 x i32]) align 8 %0, ptr byval(<10 x i32>) align 64 %1) #0 {
entry:
%x = alloca [10 x i32], align 4
%y = alloca <10 x i32>, align 64
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
@@ -26,22 +24,20 @@ entry:
%j = alloca i32, align 4
%e = alloca i32, align 4
%f = alloca i32, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 8 %0, i32 40, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 64 %y, ptr align 64 %1, i32 64, i1 false)
%2 = getelementptr inbounds [10 x i32], ptr %x, i64 0, i64 4
%2 = getelementptr inbounds [10 x i32], ptr %0, i64 0, i64 4
%3 = load i32, ptr %2, align 4
store i32 %3, ptr %a, align 4
%4 = getelementptr inbounds [10 x i32], ptr %x, i64 0, i64 8
%4 = getelementptr inbounds [10 x i32], ptr %0, i64 0, i64 8
%5 = load i32, ptr %4, align 4
store i32 %5, ptr %b, align 4
%6 = load <10 x i32>, ptr %y, align 64
%6 = load <10 x i32>, ptr %1, align 64
%7 = extractelement <10 x i32> %6, i64 4
store i32 %7, ptr %c, align 4
%8 = load <10 x i32>, ptr %y, align 64
%8 = load <10 x i32>, ptr %1, align 64
%9 = extractelement <10 x i32> %8, i64 8
store i32 %9, ptr %d, align 4
store i32 3, ptr %j, align 4
%10 = load <10 x i32>, ptr %y, align 64
%10 = load <10 x i32>, ptr %1, align 64
%11 = load i32, ptr %j, align 4
%sisiext = sext i32 %11 to i64
%12 = sub nuw i64 10, %sisiext
@@ -50,7 +46,7 @@ entry:
%14 = load i32, ptr %j, align 4
%sisiext1 = sext i32 %14 to i64
%15 = sub nuw i64 10, %sisiext1
%16 = getelementptr inbounds [10 x i32], ptr %x, i64 0, i64 %15
%16 = getelementptr inbounds [10 x i32], ptr %0, i64 0, i64 %15
%17 = load i32, ptr %16, align 4
store i32 %17, ptr %f, align 4
ret void

View File

@@ -1,5 +1,5 @@
int[-1] a; // #error: An array may not have a negative size
int[10-20] b; // #error: An array may not have a negative size
int[-1] a; // #error: An array may not have a negative
int[10-20] b; // #error: An array may not have a negative
int[<-1>] c; // #error: A vector may not have a negative width
int[<10-20>] d; // #error: A vector may not have a negative width

View File

@@ -328,9 +328,7 @@ entry:
define void @test_test7(ptr noalias sret(%STest2) align 8 %0, ptr byval(%STest2) align 8 %1) #0 {
entry:
%x = alloca %STest2, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 8 %1, i32 24, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %x, i32 24, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %1, i32 24, i1 false)
ret void
}

View File

@@ -141,26 +141,24 @@ entry:
define void @test_test2(ptr byval(%FooSt) align 8 %0) #0 {
entry:
%y = alloca %FooSt, align 4
%indirectarg = alloca %FooSt, align 8
%indirectarg1 = alloca %FooSt, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %y, ptr align 8 %0, i32 20, i1 false)
%1 = getelementptr inbounds %FooSt, ptr %y, i32 0, i32 0
%1 = getelementptr inbounds %FooSt, ptr %0, i32 0, i32 0
%2 = load i8, ptr %1, align 4
%3 = getelementptr inbounds %FooSt, ptr %y, i32 0, i32 1
%3 = getelementptr inbounds %FooSt, ptr %0, i32 0, i32 1
%4 = load i16, ptr %3, align 2
%5 = getelementptr inbounds %FooSt, ptr %y, i32 0, i32 2
%5 = getelementptr inbounds %FooSt, ptr %0, i32 0, i32 2
%6 = load i8, ptr %5, align 4
%7 = getelementptr inbounds %FooSt, ptr %y, i32 0, i32 3
%7 = getelementptr inbounds %FooSt, ptr %0, i32 0, i32 3
%8 = load i32, ptr %7, align 4
%9 = getelementptr inbounds %FooSt, ptr %y, i32 0, i32 4
%9 = getelementptr inbounds %FooSt, ptr %0, i32 0, i32 4
%10 = load i16, ptr %9, align 4
%sisiext = sext i16 %10 to i32
%11 = call i32 @testE(i8 %2, i16 %4, i8 %6, i32 %8, i32 %sisiext, float 0x3FB99999A0000000)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg, ptr align 4 %y, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg, ptr align 4 %0, i32 20, i1 false)
%12 = call i32 @testF(ptr byval(%FooSt) align 8 %indirectarg, float 0x3FB99999A0000000)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg1, ptr align 4 %y, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg1, ptr align 4 %0, i32 20, i1 false)
call void @test_test2(ptr byval(%FooSt) align 8 %indirectarg1)
call void @test_test3(ptr %y)
call void @test_test3(ptr %0)
ret void
}

View File

@@ -296,13 +296,11 @@ entry:
; Function Attrs: nounwind
define i32 @test_helo(double %0, ptr byval(%Bobo) align 8 %1) #0 {
entry:
%b = alloca %Bobo, align 4
%de = alloca [3 x i32], align 4
%c = alloca %Bobo, align 4
%indirectarg = alloca %Bobo, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %b, ptr align 8 %1, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const, i32 12, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %c, ptr align 4 %b, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %c, ptr align 4 %1, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg, ptr align 4 %c, i32 20, i1 false)
%2 = call i32 @test_helo(double 1.000000e+00, ptr byval(%Bobo) align 8 %indirectarg)
ret i32 1

View File

@@ -337,13 +337,11 @@ entry:
; Function Attrs: nounwind
define i32 @test_helo(double %0, ptr align 4 %1) #0 {
entry:
%b = alloca %Bobo, align 4
%de = alloca [3 x i32], align 4
%c = alloca %Bobo, align 4
%indirectarg = alloca %Bobo, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %b, ptr align 4 %1, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const, i32 12, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %c, ptr align 4 %b, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %c, ptr align 4 %1, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %indirectarg, ptr align 4 %c, i32 20, i1 false)
%2 = call i32 @test_helo(double 1.000000e+00, ptr align 4 %indirectarg)
ret i32 1
@@ -372,13 +370,11 @@ if.exit: ; preds = %entry
; Function Attrs: nounwind
define i32 @test_sum_us(ptr align 8 %0) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%vararg = alloca %"int[]", align 8
%indirectarg = alloca %"int[]", align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 8 %0, i32 16, i1 false)
store i32 0, ptr %sum, align 4
%1 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%1 = getelementptr inbounds %"int[]", ptr %0, i32 0, i32 1
%2 = load i64, ptr %1, align 8
%eq = icmp eq i64 0, %2
br i1 %eq, label %if.then, label %if.exit
@@ -388,11 +384,11 @@ if.then: ; preds = %entry
if.exit: ; preds = %entry
%3 = load i32, ptr %sum, align 4
%4 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%4 = getelementptr inbounds %"int[]", ptr %0, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%ptroffset = getelementptr inbounds i32, ptr %5, i64 0
%6 = load i32, ptr %ptroffset, align 4
%7 = load %"int[]", ptr %x, align 8
%7 = load %"int[]", ptr %0, align 8
%8 = extractvalue %"int[]" %7, 0
%9 = extractvalue %"int[]" %7, 1
%sub = sub i64 %9, 1
@@ -415,10 +411,8 @@ if.exit: ; preds = %entry
; Function Attrs: nounwind
define i32 @test_sumd(ptr align 8 %0) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%i = alloca i32, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 8 %0, i32 16, i1 false)
store i32 0, ptr %sum, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
@@ -426,7 +420,7 @@ entry:
loop.cond: ; preds = %loop.body, %entry
%1 = load i32, ptr %i, align 4
%sisiext = sext i32 %1 to i64
%2 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%2 = getelementptr inbounds %"int[]", ptr %0, i32 0, i32 1
%3 = load i64, ptr %2, align 8
%lt = icmp slt i64 %sisiext, %3
%check = icmp slt i64 %3, 0
@@ -435,7 +429,7 @@ loop.cond: ; preds = %loop.body, %entry
loop.body: ; preds = %loop.cond
%4 = load i32, ptr %sum, align 4
%5 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%5 = getelementptr inbounds %"int[]", ptr %0, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
%7 = load i32, ptr %i, align 4
%sisiext1 = sext i32 %7 to i64

View File

@@ -163,21 +163,20 @@ entry:
%i59 = alloca i64, align 8
%y60 = alloca i32, align 4
%.anon64 = alloca [5 x i32], align 16
%sretparam = alloca [5 x i32], align 4
%.anon65 = alloca i64, align 8
%i69 = alloca i64, align 8
%y70 = alloca i32, align 4
%.anon73 = alloca ptr, align 8
%sretparam74 = alloca [5 x i32], align 4
%.anon75 = alloca i64, align 8
%i79 = alloca i64, align 8
%y80 = alloca i32, align 4
%a83 = alloca i32, align 4
%a85 = alloca i32, align 4
%y87 = alloca ptr, align 8
%a88 = alloca i32, align 4
%a91 = alloca i32, align 4
%a93 = alloca i32, align 4
%sretparam = alloca [5 x i32], align 4
%.anon74 = alloca i64, align 8
%i78 = alloca i64, align 8
%y79 = alloca i32, align 4
%a82 = alloca i32, align 4
%a84 = alloca i32, align 4
%y86 = alloca ptr, align 8
%a87 = alloca i32, align 4
%a90 = alloca i32, align 4
%a92 = alloca i32, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const, i32 12, i1 false)
store i32 0, ptr %a, align 4
%0 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
@@ -386,8 +385,7 @@ loop.body58: ; preds = %loop.cond57
br label %loop.cond57
loop.exit63: ; preds = %loop.cond57
call void @foo_getFields(ptr sret([5 x i32]) align 4 %sretparam)
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %.anon64, ptr align 4 %sretparam, i32 20, i1 false)
call void @foo_getFields(ptr sret([5 x i32]) align 4 %.anon64)
store i64 0, ptr %.anon65, align 8
br label %loop.cond66
@@ -412,67 +410,67 @@ loop.body68: ; preds = %loop.cond66
br label %loop.cond66
loop.exit72: ; preds = %loop.cond66
call void @foo_getFields(ptr sret([5 x i32]) align 4 %sretparam74)
store ptr %sretparam74, ptr %.anon73, align 8
store i64 0, ptr %.anon75, align 8
br label %loop.cond76
call void @foo_getFields(ptr sret([5 x i32]) align 4 %sretparam)
store ptr %sretparam, ptr %.anon73, align 8
store i64 0, ptr %.anon74, align 8
br label %loop.cond75
loop.cond76: ; preds = %loop.body78, %loop.exit72
%89 = load i64, ptr %.anon75, align 8
%gt77 = icmp ugt i64 5, %89
br i1 %gt77, label %loop.body78, label %loop.exit82
loop.cond75: ; preds = %loop.body77, %loop.exit72
%89 = load i64, ptr %.anon74, align 8
%gt76 = icmp ugt i64 5, %89
br i1 %gt76, label %loop.body77, label %loop.exit81
loop.body78: ; preds = %loop.cond76
%90 = load i64, ptr %.anon75, align 8
store i64 %90, ptr %i79, align 8
loop.body77: ; preds = %loop.cond75
%90 = load i64, ptr %.anon74, align 8
store i64 %90, ptr %i78, align 8
%91 = load ptr, ptr %.anon73, align 8
%92 = load i64, ptr %.anon75, align 8
%92 = load i64, ptr %.anon74, align 8
%93 = getelementptr inbounds [5 x i32], ptr %91, i64 0, i64 %92
%94 = load i32, ptr %93, align 4
store i32 %94, ptr %y80, align 4
%95 = load i64, ptr %i79, align 8
%96 = load i32, ptr %y80, align 4
store i32 %94, ptr %y79, align 4
%95 = load i64, ptr %i78, align 8
%96 = load i32, ptr %y79, align 4
call void (ptr, ...) @printf(ptr @.str.11, i64 %95, i32 %96)
%97 = load i64, ptr %.anon75, align 8
%add81 = add i64 %97, 1
store i64 %add81, ptr %.anon75, align 8
br label %loop.cond76
%97 = load i64, ptr %.anon74, align 8
%add80 = add i64 %97, 1
store i64 %add80, ptr %.anon74, align 8
br label %loop.cond75
loop.exit82: ; preds = %loop.cond76
store i32 0, ptr %a83, align 4
loop.exit81: ; preds = %loop.cond75
store i32 0, ptr %a82, align 4
%98 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
%99 = load i32, ptr %a83, align 4
%sisiext84 = sext i32 %99 to i64
%100 = getelementptr inbounds [3 x i32], ptr %98, i64 0, i64 %sisiext84
%99 = load i32, ptr %a82, align 4
%sisiext83 = sext i32 %99 to i64
%100 = getelementptr inbounds [3 x i32], ptr %98, i64 0, i64 %sisiext83
%101 = load i32, ptr %100, align 4
store i32 1, ptr %a85, align 4
store i32 1, ptr %a84, align 4
%102 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
%103 = load i32, ptr %a85, align 4
%sisiext86 = sext i32 %103 to i64
%104 = getelementptr inbounds [3 x i32], ptr %102, i64 0, i64 %sisiext86
%103 = load i32, ptr %a84, align 4
%sisiext85 = sext i32 %103 to i64
%104 = getelementptr inbounds [3 x i32], ptr %102, i64 0, i64 %sisiext85
%105 = load i32, ptr %104, align 4
call void (ptr, ...) @printf(ptr @.str.12, i32 %101, i32 %105)
store i32 1, ptr %a88, align 4
store i32 1, ptr %a87, align 4
%106 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
%107 = load i32, ptr %a88, align 4
%sisiext89 = sext i32 %107 to i64
%108 = getelementptr inbounds [3 x i32], ptr %106, i64 0, i64 %sisiext89
store ptr %108, ptr %y87, align 8
%109 = load ptr, ptr %y87, align 8
%107 = load i32, ptr %a87, align 4
%sisiext88 = sext i32 %107 to i64
%108 = getelementptr inbounds [3 x i32], ptr %106, i64 0, i64 %sisiext88
store ptr %108, ptr %y86, align 8
%109 = load ptr, ptr %y86, align 8
%110 = load i32, ptr %109, align 8
%add90 = add i32 %110, 1
store i32 %add90, ptr %109, align 8
store i32 0, ptr %a91, align 4
%add89 = add i32 %110, 1
store i32 %add89, ptr %109, align 8
store i32 0, ptr %a90, align 4
%111 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
%112 = load i32, ptr %a91, align 4
%sisiext92 = sext i32 %112 to i64
%113 = getelementptr inbounds [3 x i32], ptr %111, i64 0, i64 %sisiext92
%112 = load i32, ptr %a90, align 4
%sisiext91 = sext i32 %112 to i64
%113 = getelementptr inbounds [3 x i32], ptr %111, i64 0, i64 %sisiext91
%114 = load i32, ptr %113, align 4
store i32 1, ptr %a93, align 4
store i32 1, ptr %a92, align 4
%115 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
%116 = load i32, ptr %a93, align 4
%sisiext94 = sext i32 %116 to i64
%117 = getelementptr inbounds [3 x i32], ptr %115, i64 0, i64 %sisiext94
%116 = load i32, ptr %a92, align 4
%sisiext93 = sext i32 %116 to i64
%117 = getelementptr inbounds [3 x i32], ptr %115, i64 0, i64 %sisiext93
%118 = load i32, ptr %117, align 4
call void (ptr, ...) @printf(ptr @.str.13, i32 %114, i32 %118)
ret void

View File

@@ -24,9 +24,7 @@ fn void test(Bar b)
define void @foo_test(ptr byval(%Bar) align 8 %0) #0 {
entry:
%b = alloca %Bar, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %b, ptr align 8 %0, i32 8, i1 false)
%1 = getelementptr inbounds %Bar, ptr %b, i32 0, i32 2
%1 = getelementptr inbounds %Bar, ptr %0, i32 0, i32 2
%2 = getelementptr inbounds [0 x i32], ptr %1, i64 0, i64 1
ret void
}

View File

@@ -1,7 +1,7 @@
define Foo = int[0];
define Foo = int[0]; // #error: An array may not have zero
struct Bar
{
Foo x; // #error: Zero length arrays are not valid members.
Foo x;
int b;
}