mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Optimize sret / byval. Fixes to types and failables.
This commit is contained in:
committed by
Christoffer Lerno
parent
dfe3128b16
commit
160659c4e3
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.85"
|
||||
#define COMPILER_VERSION "0.3.86"
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user