Remove LLVM 14 support. Simplify ABI lowering.

This commit is contained in:
Christoffer Lerno
2023-01-29 19:29:02 +01:00
committed by Christoffer Lerno
parent 124a18a486
commit 539d733ceb
615 changed files with 2140 additions and 37161 deletions

View File

@@ -168,7 +168,7 @@ jobs:
- name: run compiler tests
run: |
cd test
python3 src/tester.py ../build/c3c.exe test_suite14/
python3 src/tester.py ../build/c3c.exe test_suite/
build-linux:
runs-on: ubuntu-latest
@@ -177,7 +177,7 @@ jobs:
fail-fast: false
matrix:
build_type: [Release, Debug]
llvm_version: [13, 15, 16, 17]
llvm_version: [15, 16, 17]
steps:
- uses: actions/checkout@v3
@@ -196,9 +196,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}}" > 13 ]]; then
sudo apt-get install -y libpolly-${{matrix.llvm_version}}-dev
fi
sudo apt-get install -y libpolly-${{matrix.llvm_version}}-dev
- name: CMake
run: |
cmake -B build \
@@ -238,11 +236,7 @@ jobs:
- name: run compiler tests
run: |
cd test
if [[ "${{matrix.llvm_version}}" < 15 ]]; then
python3 src/tester.py ../build/c3c test_suite14/
else
python3 src/tester.py ../build/c3c test_suite/
fi
python3 src/tester.py ../build/c3c test_suite/
- name: bundle_output
if: matrix.llvm_version == env.LLVM_RELEASE_VERSION
@@ -268,7 +262,7 @@ jobs:
fail-fast: false
matrix:
build_type: [Release, Debug]
llvm_version: [13, 14, 15]
llvm_version: [15]
steps:
- uses: actions/checkout@v3
- name: Download LLVM
@@ -318,11 +312,7 @@ jobs:
- name: run compiler tests
run: |
cd test
if [[ "${{matrix.llvm_version}}" < 15 ]]; then
python3 src/tester.py ../build/c3c test_suite14/
else
python3 src/tester.py ../build/c3c test_suite/
fi
python3 src/tester.py ../build/c3c test_suite/
- name: bundle_output
if: matrix.llvm_version == env.LLVM_RELEASE_VERSION

View File

@@ -46,7 +46,7 @@ if (NOT WIN32)
find_package(CURL)
endif()
if (NOT C3_LLVM_VERSION STREQUAL "auto")
if (${C3_LLVM_VERSION} VERSION_LESS 13 OR ${C3_LLVM_VERSION} VERSION_GREATER 17)
if (${C3_LLVM_VERSION} VERSION_LESS 15 OR ${C3_LLVM_VERSION} VERSION_GREATER 17)
message(FATAL_ERROR "LLVM ${C3_LLVM_VERSION} is not supported!")
endif()
endif()
@@ -68,7 +68,7 @@ endif()
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
if (C3_LLVM_VERSION STREQUAL "auto")
set(C3_LLVM_VERSION "14")
set(C3_LLVM_VERSION "15")
endif()
FetchContent_Declare(
LLVM_Windows
@@ -131,12 +131,9 @@ set(LLVM_LINK_COMPONENTS
Target
TransformUtils
WindowsManifest
WindowsDriver
)
if (${LLVM_PACKAGE_VERSION} VERSION_GREATER 14.1)
set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} WindowsDriver)
endif()
llvm_map_components_to_libnames(llvm_libs ${LLVM_LINK_COMPONENTS})
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/lib)
file(COPY ${CMAKE_SOURCE_DIR}/lib DESTINATION ${CMAKE_BINARY_DIR})
@@ -147,21 +144,10 @@ message(STATUS "using find_library")
find_library(LLD_COFF NAMES lldCOFF.lib lldCOFF.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_COMMON NAMES lldCommon.lib lldCommon.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_ELF NAMES lldELF.lib lldELF.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
if (${LLVM_PACKAGE_VERSION} VERSION_LESS 14)
find_library(LLD_MACHO NAMES lldMachO2.lib lldMachO2.a liblldMachO2.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
else ()
find_library(LLD_MACHO NAMES lldMachO.lib lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
endif ()
find_library(LLD_MACHO NAMES lldMachO.lib lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MINGW NAMES lldMinGW.lib lldMinGW.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_WASM NAMES lldWasm.lib lldWasm.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
if (${LLVM_PACKAGE_VERSION} VERSION_LESS 14)
find_library(LLD_CORE NAMES lldCore.lib lldCore.a liblldCore.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_DRIVER NAMES lldDriver.lib lldDriver.a liblldDriver.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_READER_WRITER NAMES lldReaderWriter.lib lldReaderWriter.a liblldReaderWriter.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_YAML NAMES lldYAML.lib lldYAML.a liblldYAML.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
endif ()
if (${LLVM_PACKAGE_VERSION} VERSION_GREATER_EQUAL 16)
find_library(LLD_LOONG NAMES libLLVMLoongArchCodeGen.lib libLLVMLoongArchAsmParser.lib libLLVMLoongArchCodeGen.a libLLVMLoongArchAsmParser.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
set(lld_libs

View File

@@ -46,7 +46,7 @@ extern fn CULong stroul(char* str, char** endptr, int base);
extern fn void abort();
extern fn void atexit(TerminateFunction f);
extern fn void exit(int status);
extern fn char* getenv(char* name);
extern fn ZString getenv(char* name);
extern fn int system(char* str);
extern fn void bsearch(void* key, void *base, usz items, usz size, CompareFunction compare);
extern fn void qsort(void* base, usz items, usz size, CompareFunction compare);
@@ -348,9 +348,9 @@ const CLOCKS_PER_SEC = 1000000;
define Time = long;
define Clock = ulong;
extern fn char* asctime(Tm *timeptr);
extern fn ZString asctime(Tm *timeptr);
extern fn Clock clock();
extern fn char* ctime(Time *timer);
extern fn ZString ctime(Time *timer);
extern fn double difftime(Time time1, Time time2);
extern fn Tm* gmtime(Time *timer);
extern fn Tm* localtime(Time *timer);

View File

@@ -294,7 +294,6 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
switch (source_expr->expr_kind)
{
case EXPR_VARIANTSWITCH:
case EXPR_ARGV_TO_SUBARRAY:
UNREACHABLE
case EXPR_MACRO_BODY_EXPANSION:
MACRO_COPY_EXPR_LIST(expr->body_expansion_expr.values);

View File

@@ -207,7 +207,6 @@ typedef enum
{
EXPR_POISONED,
EXPR_ACCESS,
EXPR_ARGV_TO_SUBARRAY,
EXPR_ASM,
EXPR_BINARY,
EXPR_BITACCESS,

View File

@@ -82,7 +82,6 @@ bool expr_may_addr(Expr *expr)
return true;
case EXPR_TEST_HOOK:
return false;
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_ASM:
case EXPR_BINARY:
case EXPR_BITASSIGN:
@@ -327,7 +326,6 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
case EXPR_FLATPATH:
case EXPR_COMPOUND_LITERAL:
case EXPR_POISONED:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_CT_ARG:
case EXPR_ASM:
case EXPR_SUBSCRIPT_ASSIGN:
@@ -670,7 +668,6 @@ bool expr_is_pure(Expr *expr)
return true;
case EXPR_VASPLAT:
return true;
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_BITASSIGN:
return false;
case EXPR_VARIANTSWITCH:

View File

@@ -93,9 +93,6 @@ LLVMValueRef llvm_emit_is_no_opt(GenContext *c, LLVMValueRef error_value)
LLVMValueRef llvm_emit_memclear_size_align(GenContext *c, LLVMValueRef ptr, uint64_t size, AlignSize align)
{
#if LLVM_VERSION_MAJOR < 15
ptr = LLVMBuildBitCast(c->builder, ptr, llvm_get_type(c, type_get_ptr(type_char)), "");
#endif
return LLVMBuildMemSet(c->builder, ptr, llvm_get_zero(c, type_char), llvm_const_int(c, type_usize, size), align);
}
@@ -469,10 +466,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
break;
}
if (init_value && LLVMTypeOf(init_value) != llvm_get_type(c, var_type))
{
decl->backend_ref = global_ref = llvm_emit_bitcast_ptr(c, global_ref, var_type);
}
decl->backend_ref = global_ref;
LLVMReplaceAllUsesWith(old, global_ref);
LLVMDeleteGlobal(old);
@@ -1173,7 +1167,7 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC
if (test_count)
{
LLVMValueRef array_of_names = LLVMConstArray(c->chars_type, names, test_count);
LLVMValueRef array_of_decls = LLVMConstArray(LLVMPointerType(opt_test, 0), decls, test_count);
LLVMValueRef array_of_decls = LLVMConstArray(c->ptr_type, decls, test_count);
LLVMTypeRef arr_type = LLVMTypeOf(array_of_names);
name_ref = llvm_add_global_raw(c, ".test_names", arr_type, 0);
decl_ref = llvm_add_global_raw(c, ".test_decls", LLVMTypeOf(array_of_decls), 0);
@@ -1183,13 +1177,11 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC
LLVMSetGlobalConstant(decl_ref, 1);
LLVMSetInitializer(name_ref, array_of_names);
LLVMSetInitializer(decl_ref, array_of_decls);
name_ref = LLVMBuildBitCast(c->builder, name_ref, llvm_get_ptr_type(c, type_chars), "");
decl_ref = LLVMBuildBitCast(c->builder, decl_ref, llvm_get_ptr_type(c, type_voidptr), "");
}
else
{
name_ref = LLVMConstNull(llvm_get_ptr_type(c, type_chars));
decl_ref = LLVMConstNull(llvm_get_ptr_type(c, type_voidptr));
name_ref = LLVMConstNull(c->ptr_type);
decl_ref = LLVMConstNull(c->ptr_type);
}
LLVMValueRef count = llvm_const_int(c, type_usize, test_count);
Type *chars_array = type_get_subarray(type_chars);

View File

@@ -132,7 +132,7 @@ INLINE void llvm_emit_stacktrace(GenContext *c, BEValue *result_value, Expr *exp
llvm_value_set(result_value, llvm_get_zero(c, type_voidptr), type_voidptr);
return;
}
llvm_value_set(result_value, llvm_emit_bitcast(c, c->debug.stack_slot, type_voidptr), type_voidptr);
llvm_value_set(result_value, c->debug.stack_slot, type_voidptr);
}
INLINE void llvm_emit_volatile_store(GenContext *c, BEValue *result_value, Expr *expr)
@@ -282,8 +282,6 @@ INLINE void llvm_emit_memcpy_builtin(GenContext *c, unsigned intrinsic, BEValue
Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[4];
llvm_emit_intrinsic_args(c, args, arg_slots, 4);
arg_slots[0] = llvm_emit_bitcast(c, arg_slots[0], type_voidptr);
arg_slots[1] = llvm_emit_bitcast(c, arg_slots[1], type_voidptr);
LLVMTypeRef call_type[3];
call_type[0] = call_type[1] = llvm_get_type(c, type_voidptr);
call_type[2] = llvm_get_type(c, type_usize);
@@ -302,8 +300,6 @@ INLINE void llvm_emit_memmove_builtin(GenContext *c, BEValue *be_value, Expr *ex
Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[4];
llvm_emit_intrinsic_args(c, args, arg_slots, 4);
arg_slots[0] = llvm_emit_bitcast(c, arg_slots[0], type_voidptr);
arg_slots[1] = llvm_emit_bitcast(c, arg_slots[1], type_voidptr);
LLVMTypeRef call_type[3];
call_type[0] = call_type[1] = llvm_get_type(c, type_voidptr);
call_type[2] = llvm_get_type(c, type_usize);
@@ -322,7 +318,6 @@ INLINE void llvm_emit_memset_builtin(GenContext *c, unsigned intrinsic, BEValue
Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[4];
llvm_emit_intrinsic_args(c, args, arg_slots, 4);
arg_slots[0] = llvm_emit_bitcast(c, arg_slots[0], type_voidptr);
LLVMTypeRef call_type[2] = { llvm_get_type(c, type_voidptr), llvm_get_type(c, type_usize) };
LLVMValueRef result = llvm_emit_call_intrinsic(c, intrinsic, call_type, 2, arg_slots, 4);
assert(args[4]->const_expr.const_kind == CONST_INTEGER);

View File

@@ -14,7 +14,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 inline LLVMValueRef llvm_update_vector(GenContext *c, LLVMValueRef vector, LLVMValueRef value, MemberIndex index);
static inline void gencontext_emit_expression_list_expr(GenContext *context, BEValue *be_value, Expr *expr);
static inline void llvm_emit_argv_to_subarray(GenContext *c, BEValue *value, Expr *expr);
static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEValue parent, Decl *parent_decl, Decl *member);
static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Expr *expr);
static inline void llvm_emit_const_initialize_reference(GenContext *c, BEValue *ref, Expr *expr);
@@ -48,7 +48,7 @@ static void llvm_emit_initialize_designated(GenContext *c, BEValue *ref, AlignSi
static void llvm_emit_macro_body_expansion(GenContext *c, BEValue *value, Expr *body_expr);
static void llvm_emit_post_unary_expr(GenContext *context, BEValue *be_value, Expr *expr);
static void llvm_emit_unary_expr(GenContext *c, BEValue *value, Expr *expr);
static void llvm_enter_struct_for_coerce(GenContext *c, LLVMValueRef *struct_ptr, LLVMTypeRef *type, ByteSize dest_size);
static LLVMTypeRef llvm_find_inner_struct_type_for_coerce(GenContext *c, LLVMTypeRef struct_type, ByteSize dest_size);
static void llvm_expand_type_to_args(GenContext *context, Type *param_type, LLVMValueRef expand_ptr, LLVMValueRef *args, unsigned *arg_count_ref, AlignSize alignment);
INLINE LLVMValueRef llvm_emit_bitstruct_value_update(GenContext *c, LLVMValueRef current_val, TypeSize bits, LLVMTypeRef bitstruct_type, Decl *member, LLVMValueRef val);
@@ -197,14 +197,14 @@ static LLVMValueRef llvm_emit_coerce_alignment(GenContext *c, BEValue *be_value,
// If we are loading something with greater alignment than what we have, we cannot directly memcpy.
if (!llvm_value_is_addr(be_value) || be_value->alignment < target_alignment)
{
LLVMValueRef cast = llvm_emit_alloca(c, llvm_get_type(c, be_value->type), target_alignment, "coerce");
LLVMValueRef target = LLVMBuildBitCast(c->builder, cast, LLVMPointerType(coerce_type, 0), "");
// COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef target = llvm_emit_alloca(c, llvm_get_type(c, be_value->type), target_alignment, "coerce");
llvm_store_to_ptr_aligned(c, target, be_value, target_alignment);
*resulting_alignment = target_alignment;
return target;
}
*resulting_alignment = be_value->alignment;
return LLVMBuildBitCast(c->builder, be_value->value, LLVMPointerType(coerce_type, 0), "");
return be_value->value;
}
LLVMValueRef llvm_emit_aggregate_two(GenContext *c, Type *type, LLVMValueRef value1, LLVMValueRef value2)
@@ -286,30 +286,25 @@ static inline LLVMValueRef llvm_emit_add_int(GenContext *c, Type *type, LLVMValu
return LLVMBuildAdd(c->builder, left, right, "add");
}
static void llvm_enter_struct_for_coerce(GenContext *c, LLVMValueRef *struct_ptr, LLVMTypeRef *type, ByteSize dest_size)
static LLVMTypeRef llvm_find_inner_struct_type_for_coerce(GenContext *c, LLVMTypeRef type, ByteSize dest_size)
{
while (1)
{
if (LLVMGetTypeKind(*type) != LLVMStructTypeKind) return;
if (!LLVMCountStructElementTypes(*type)) return;
LLVMTypeRef first_element = LLVMStructGetTypeAtIndex(*type, 0);
if (LLVMGetTypeKind(type) != LLVMStructTypeKind) break;
if (!LLVMCountStructElementTypes(type)) break;
LLVMTypeRef first_element = LLVMStructGetTypeAtIndex(type, 0);
ByteSize first_element_size = llvm_store_size(c, first_element);
// If the size is smaller than the total size and smaller than the destination size
// then we're done.
if (first_element_size < dest_size && first_element_size < llvm_store_size(c, *type))
{
return;
}
if (first_element_size < dest_size && first_element_size < llvm_store_size(c, type)) break;
AlignSize dummy;
LLVMValueRef ref = llvm_emit_struct_gep_raw(c, *struct_ptr, *type, 0, llvm_abi_alignment(c, *type), &dummy);
*struct_ptr = ref;
*type = first_element;
type = first_element;
}
return type;
}
/**
* General functionality to convert int <-> int ptr <-> int
* General functionality to convert ptr <-> int
*/
LLVMValueRef llvm_coerce_int_ptr(GenContext *c, LLVMValueRef value, LLVMTypeRef from, LLVMTypeRef to)
{
@@ -320,12 +315,7 @@ LLVMValueRef llvm_coerce_int_ptr(GenContext *c, LLVMValueRef value, LLVMTypeRef
bool to_is_pointer = LLVMGetTypeKind(to) == LLVMPointerTypeKind;
if (LLVMGetTypeKind(from) == LLVMPointerTypeKind)
{
// 2a. Destination is a pointer, perform a bitcast.
if (to_is_pointer)
{
return LLVMBuildBitCast(c->builder, value, to, "coerce.val");
}
// 2b. Otherwise perform ptr -> int
assert(!to_is_pointer && "ptr<->ptr should never happen in LLVM 15+");
from = llvm_get_type(c, type_iptr);
value = LLVMBuildPtrToInt(c->builder, value, from, "");
}
@@ -392,7 +382,7 @@ LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value
// 3. If this is a struct, we index into it.
if (LLVMGetTypeKind(llvm_source_type) == LLVMStructTypeKind)
{
llvm_enter_struct_for_coerce(c, &addr, &llvm_source_type, target_size);
llvm_source_type = llvm_find_inner_struct_type_for_coerce(c, llvm_source_type, target_size);
}
// --> from now on we only use LLVM types.
@@ -410,8 +400,8 @@ LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value
if (source_size >= target_size && source_type_kind != LLVMScalableVectorTypeKind && coerced_type_kind != LLVMScalableVectorTypeKind)
{
LLVMValueRef val = LLVMBuildBitCast(c->builder, addr, LLVMPointerType(coerced, 0), "");
return llvm_load(c, coerced, val, value->alignment, "");
// COERCE UPDATE bitcast removed, check for ways to optimize
return llvm_load(c, coerced, addr, value->alignment, "");
}
if (coerced_type_kind == LLVMScalableVectorTypeKind)
@@ -442,7 +432,7 @@ void llvm_emit_coerce_store(GenContext *c, LLVMValueRef addr, AlignSize alignmen
// 3. Enter into a struct in case the result is a struct.
if (LLVMGetTypeKind(target_type) == LLVMStructTypeKind)
{
llvm_enter_struct_for_coerce(c, &addr, &target_type, src_size);
target_type = llvm_find_inner_struct_type_for_coerce(c, target_type, src_size);
}
// 4. If we are going from int/ptr <-> ptr/int
@@ -460,8 +450,8 @@ void llvm_emit_coerce_store(GenContext *c, LLVMValueRef addr, AlignSize alignmen
ByteSize target_size = llvm_alloc_size(c, target_type);
if (src_size <= target_size && coerced_type_kind != LLVMScalableVectorTypeKind && source_type_kind != LLVMScalableVectorTypeKind)
{
LLVMValueRef val = LLVMBuildBitCast(c->builder, addr, LLVMPointerType(coerced, 0), "");
llvm_store_to_ptr_raw_aligned(c, val, value, alignment);
// COERCE UPDATE bitcast removed, check for ways to optimize
llvm_store_to_ptr_raw_aligned(c, addr, value, alignment);
return;
}
@@ -648,7 +638,6 @@ static inline void llvm_emit_pointer_offset(GenContext *c, BEValue *value, Expr
{
Expr *pointer = exprptr(expr->pointer_offset_expr.ptr);
Expr *offset_expr = exprptr(expr->pointer_offset_expr.offset);
LLVMTypeRef pointee_type = llvm_get_pointee_type(c, pointer->type);
// Emit the pointer
llvm_emit_expr(c, value, pointer);
@@ -661,14 +650,11 @@ static inline void llvm_emit_pointer_offset(GenContext *c, BEValue *value, Expr
if (expr->pointer_offset_expr.raw_offset)
{
LLVMValueRef raw_pointer = llvm_emit_bitcast_ptr(c, value->value, type_char);
LLVMValueRef pointer_offset = llvm_emit_pointer_gep_raw(c, c->byte_type, raw_pointer, offset.value);
value->value = LLVMBuildBitCast(c->builder, pointer_offset, pointee_type, "");
}
else
{
value->value = llvm_emit_pointer_gep_raw(c, pointee_type, value->value, offset.value);
// COERCE UPDATE bitcast removed, check for ways to optimize
value->value = llvm_emit_pointer_gep_raw(c, c->byte_type, value->value, offset.value);
return;
}
value->value = llvm_emit_pointer_gep_raw(c, llvm_get_pointee_type(c, pointer->type), value->value, offset.value);
}
@@ -1130,7 +1116,7 @@ static void llvm_emit_arr_to_subarray_cast(GenContext *c, BEValue *value, Type *
if (size)
{
llvm_value_rvalue(c, value);
pointer = llvm_emit_bitcast_ptr(c, value->value, array_type);
pointer = value->value;
}
else
{
@@ -1207,10 +1193,9 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
case CAST_PTRANY:
{
llvm_value_rvalue(c, value);
LLVMValueRef pointer = llvm_emit_bitcast(c, value->value, type_voidptr);
BEValue typeid;
llvm_emit_typeid(c, &typeid, from_type->pointer);
llvm_value_aggregate_two(c, value, to_type, pointer, typeid.value);
llvm_value_aggregate_two(c, value, to_type, value->value, typeid.value);
return;
}
case CAST_BSARRY:
@@ -1242,14 +1227,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
break;
case CAST_ANYPTR:
llvm_emit_any_pointer(c, value, value);
if (llvm_value_is_addr(value))
{
value->value = LLVMBuildBitCast(c->builder, value->value, llvm_get_ptr_type(c, to_type), "");
}
else
{
value->value = LLVMBuildBitCast(c->builder, value->value, llvm_get_type(c, to_type), "");
}
break;
case CAST_XIERR:
to_type = type_lowering(to_type);
@@ -1277,17 +1254,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
break;
case CAST_SAPTR:
llvm_emit_subarray_pointer(c, value, value);
if (value->type != to_type)
{
if (llvm_value_is_addr(value))
{
value->value = LLVMBuildPointerCast(c->builder, value->value, llvm_get_ptr_type(c, to_type), "saptr");
}
else
{
value->value = LLVMBuildPointerCast(c->builder, value->value, llvm_get_ptr_type(c, to_type), "saptr");
}
}
break;
case CAST_EREU:
// This is a no op.
@@ -1388,7 +1354,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
break;
case CAST_STST:
llvm_value_addr(c, value);
value->value = LLVMBuildBitCast(c->builder, value->value, llvm_get_ptr_type(c, to_type), "");
value->type = to_type;
return;
case CAST_INTENUM:
@@ -1523,11 +1488,6 @@ void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref,
// Ensure we have a reference.
llvm_value_addr(c, ref);
if (expected_type != type)
{
global_copy = LLVMBuildBitCast(c->builder, global_copy, LLVMPointerType(expected_type, 0), "");
}
// Perform the memcpy.
llvm_emit_memcpy(c, ref->value, ref->alignment, global_copy, alignment, type_size(expr->type));
}
@@ -1720,8 +1680,6 @@ static inline void llvm_emit_initialize_reference_list(GenContext *c, BEValue *r
{
assert(vec_size(elements) == 1);
real_type = type_lowering(real_type->decl->strukt.members[0]->type);
value = LLVMBuildBitCast(c->builder, ref->value, llvm_get_ptr_type(c, real_type), "");
ref->value = value;
ref->type = real_type;
}
@@ -1829,7 +1787,7 @@ static void llvm_emit_initialize_designated(GenContext *c, BEValue *ref, AlignSi
if (ref->type->type_kind == TYPE_UNION)
{
llvm_value_set_address(&value,
llvm_emit_bitcast_ptr(c, ref->value, type),
ref->value,
type,
type_min_alignment(offset, decl_alignment));
}
@@ -2741,7 +2699,6 @@ static void gencontext_emit_slice(GenContext *c, BEValue *be_value, Expr *expr)
// Move pointer
AlignSize alignment;
start_pointer = llvm_emit_array_gep_raw_index(c, parent.value, llvm_get_type(c, parent.type), start.value, type_abi_alignment(parent.type), &alignment);
start_pointer = llvm_emit_bitcast_ptr(c, start_pointer, parent.type->array.base);
break;
}
case TYPE_SUBARRAY:
@@ -4288,7 +4245,6 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
LLVMSetGlobalConstant(global_name, 1);
LLVMSetInitializer(global_name, llvm_get_bytes(c, expr->const_expr.bytes.ptr, expr->const_expr.bytes.len));
global_name = llvm_emit_bitcast_ptr(c, global_name, type_char);
llvm_value_set_address_abi_aligned(be_value, global_name, type);
return;
}
@@ -4357,12 +4313,10 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
LLVMSetInitializer(global_name, string);
if (is_array)
{
global_name = llvm_emit_bitcast_ptr(c, global_name, type);
llvm_value_set_address(be_value, global_name, type, 1);
}
else
{
global_name = llvm_emit_bitcast(c, global_name, type);
llvm_value_set(be_value, global_name, type);
}
return;
@@ -4786,7 +4740,7 @@ static void llvm_emit_splatted_variadic_arg(GenContext *c, Expr *expr, Type *var
case TYPE_POINTER:
// Load the pointer
llvm_value_rvalue(c, &value);
llvm_value_aggregate_two(c, subarray, vararg_type, llvm_emit_bitcast_ptr(c, value.value, type->pointer->array.base), llvm_const_int(c, type_usize, type->pointer->array.len));
llvm_value_aggregate_two(c, subarray, vararg_type, value.value, llvm_const_int(c, type_usize, type->pointer->array.len));
return;
case TYPE_SUBARRAY:
*subarray = value;
@@ -4877,7 +4831,7 @@ static inline void llvm_emit_vararg_parameter(GenContext *c, BEValue *value, Typ
&store_alignment);
llvm_store_to_ptr_aligned(c, slot, &temp_value, store_alignment);
}
llvm_value_aggregate_two(c, value, vararg_type, llvm_emit_bitcast_ptr(c, array_ref, pointee_type), llvm_const_int(c, type_usize, elements));
llvm_value_aggregate_two(c, value, vararg_type, array_ref, llvm_const_int(c, type_usize, elements));
}
@@ -4963,12 +4917,13 @@ void llvm_emit_raw_call(GenContext *c, BEValue *result_value, FunctionPrototype
// { lo, hi } set into { pad, lo, pad, hi } -> original type.
// 15a. Create memory to hold the return type.
LLVMValueRef ret = llvm_emit_alloca_aligned(c, call_return_type, "");
llvm_value_set_address_abi_aligned(result_value, ret, call_return_type);
// COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef coerce = llvm_emit_alloca_aligned(c, call_return_type, "");
llvm_value_set_address_abi_aligned(result_value, coerce, call_return_type);
// 15b. "Convert" this return type pointer in memory to our coerce type which is { pad, lo, pad, hi }
// COERCE UPDATE bitcast removed, check for ways to optimize
// 15b. Construct our coerce type which is { pad, lo, pad, hi }
LLVMTypeRef coerce_type = llvm_get_coerce_type(c, ret_info);
LLVMValueRef coerce = LLVMBuildBitCast(c->builder, ret, coerce_type, "");
// 15d. Find the address to the low value
AlignSize alignment;
@@ -5721,7 +5676,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
llvm_value_rvalue(c, value);
LLVMValueRef kind;
LLVMValueRef ref = LLVMBuildIntToPtr(c->builder, value->value, LLVMPointerType(c->introspect_type, 0), "introspect*");
LLVMValueRef ref = LLVMBuildIntToPtr(c->builder, value->value, c->ptr_type, "introspect*");
AlignSize align = llvm_abi_alignment(c, c->introspect_type);
AlignSize alignment;
if (active_target.feature.safe_mode || expr->typeid_info_expr.kind == TYPEID_INFO_KIND)
@@ -5798,9 +5753,8 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
LLVMValueRef len = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_LEN, align, &alignment);
len = llvm_load(c, c->size_type, len, alignment, "namelen");
LLVMValueRef val = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_ADDITIONAL, align, &alignment);
LLVMValueRef ptr_to_first = llvm_emit_bitcast_ptr(c, val, type_chars);
Type *subarray = type_get_subarray(type_chars);
llvm_value_set(value, llvm_emit_aggregate_two(c, subarray, ptr_to_first, len), subarray);
llvm_value_set(value, llvm_emit_aggregate_two(c, subarray, val, len), subarray);
}
break;
case TYPEID_INFO_LEN:
@@ -5914,88 +5868,6 @@ static inline void llvm_emit_variant(GenContext *c, BEValue *value, Expr *expr)
llvm_value_set(value, var, type_any);
}
static inline void llvm_emit_argv_to_subarray(GenContext *c, BEValue *value, Expr *expr)
{
EMIT_LOC(c, expr);
BEValue argc_value;
BEValue argv_value;
llvm_value_set_decl(c, &argc_value, expr->argv_expr.argc);
llvm_value_set_decl(c, &argv_value, expr->argv_expr.argv);
llvm_value_rvalue(c, &argc_value);
llvm_value_rvalue(c, &argv_value);
LLVMValueRef argv_ptr = argv_value.value;
LLVMValueRef count = argc_value.value;
Type *arg_array_type = type_chars;
AlignSize alignment = type_alloca_alignment(type_get_array(arg_array_type, 1));
LLVMTypeRef arg_array_elem_type = llvm_get_type(c, arg_array_type);
LLVMValueRef arg_array = LLVMBuildArrayAlloca(c->builder, arg_array_elem_type, count, "argarray");
LLVMSetAlignment(arg_array, alignment);
// Store the addresses.
LLVMTypeRef loop_type = llvm_get_type(c, type_usize);
LLVMTypeRef char_ptr_type = llvm_get_ptr_type(c, type_char);
LLVMValueRef size = llvm_zext_trunc(c, count, loop_type);
llvm_value_aggregate_two(c, value, expr->type, arg_array, size);
// Check if zero:
BEValue cond;
llvm_value_set(&cond, LLVMBuildICmp(c->builder, LLVMIntEQ, count, llvm_get_zero(c, argc_value.type), ""), type_bool);
LLVMBasicBlockRef exit_block = llvm_basic_block_new(c, "exit_loop");
LLVMBasicBlockRef pre_loop_block = llvm_basic_block_new(c, "pre_loop");
// Jump to exit if zero
llvm_emit_cond_br(c, &cond, exit_block, pre_loop_block);
// Now we create the pre loop block
llvm_emit_block(c, pre_loop_block);
EMIT_LOC(c, expr);
LLVMBasicBlockRef body_block = llvm_basic_block_new(c, "body_loop");
LLVMValueRef zero = llvm_get_zero_raw(loop_type);
// Jump to the first entry
llvm_emit_br(c, body_block);
llvm_emit_block(c, body_block);
LLVMValueRef index_var = LLVMBuildPhi(c->builder, loop_type, "");
// Find the current substring
LLVMValueRef index = LLVMBuildInBoundsGEP2(c->builder, arg_array_elem_type, arg_array, &index_var, 1, "indexfe");
LLVMValueRef pointer_to_arg = LLVMBuildInBoundsGEP2(c->builder, char_ptr_type, argv_ptr, &index_var, 1, "");
// Get the char* to the argument
LLVMValueRef pointer_value = llvm_load(c, llvm_get_ptr_type(c, type_char), pointer_to_arg,
type_abi_alignment(type_get_ptr(type_char)), "");
AlignSize index_align;
// Get strlen to calculate length
LLVMValueRef strlen = LLVMGetNamedFunction(c->module, "strlen");
LLVMTypeRef strlen_type = LLVMFunctionType(loop_type, &char_ptr_type, 1, false);
if (!strlen)
{
strlen = LLVMAddFunction(c->module, "strlen", strlen_type);
}
EMIT_LOC(c, expr);
LLVMValueRef len = LLVMBuildCall2(c->builder, strlen_type, strlen, &pointer_value, 1, "");
// We first set the pointer
AlignSize align = type_abi_alignment(arg_array_type);
LLVMValueRef ptr_loc = llvm_emit_struct_gep_raw(c, index, arg_array_elem_type, 0, align, &index_align);
llvm_store_to_ptr_raw_aligned(c, ptr_loc, pointer_value, index_align);
// Then the length
LLVMValueRef len_loc = llvm_emit_struct_gep_raw(c, index, arg_array_elem_type, 1, align, &index_align);
llvm_store_to_ptr_raw_aligned(c, len_loc, len, index_align);
// Add index
LLVMValueRef index_plus = LLVMBuildNUWAdd(c->builder, index_var, llvm_const_int(c, type_usize, 1), "");
llvm_value_set(&cond, LLVMBuildICmp(c->builder, LLVMIntULT, index_plus, size, ""), type_bool);
llvm_emit_cond_br(c, &cond, body_block, exit_block);
LLVMValueRef values[2] = { index_plus, zero };
LLVMBasicBlockRef blocks[2] = { body_block, pre_loop_block };
LLVMAddIncoming(index_var, values, blocks, 2);
llvm_emit_block(c, exit_block);
EMIT_LOC(c, expr);
}
static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Expr *expr)
{
Expr *inner = exprptr(expr->builtin_access_expr.inner);
@@ -6034,11 +5906,11 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
llvm_emit_br(c, exit_block);
llvm_emit_block(c, ok_block);
LLVMValueRef fault_data = LLVMBuildIntToPtr(c->builder, be_value->value,
LLVMPointerType(c->fault_type, 0), "");
c->ptr_type, "");
LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->fault_type, fault_data, 1, "");
llvm_emit_br(c, exit_block);
llvm_emit_block(c, exit_block);
LLVMValueRef phi = LLVMBuildPhi(c->builder, llvm_get_ptr_type(c, type_chars), "faultname");
LLVMValueRef phi = LLVMBuildPhi(c->builder, c->ptr_type, "faultname");
LLVMValueRef values[] = { zero.value, ptr };
LLVMBasicBlockRef blocks[] = { zero_block, ok_block };
LLVMAddIncoming(phi, values, blocks, 2);
@@ -6053,11 +5925,10 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
LLVMTypeRef subarray = llvm_get_type(c, type_chars);
LLVMValueRef to_introspect = LLVMBuildIntToPtr(c->builder, inner_type->backend_typeid,
LLVMPointerType(c->introspect_type, 0), "");
c->ptr_type, "");
LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->introspect_type, to_introspect, INTROSPECT_INDEX_ADDITIONAL, "");
LLVMValueRef ptr_to_first = llvm_emit_bitcast_ptr(c, ptr, type_chars);
LLVMValueRef val = llvm_zext_trunc(c, be_value->value, llvm_get_type(c, type_usize));
llvm_value_set_address(be_value, llvm_emit_pointer_gep_raw(c, subarray, ptr_to_first, val),
llvm_value_set_address(be_value, llvm_emit_pointer_gep_raw(c, subarray, ptr, val),
type_chars, llvm_abi_alignment(c, subarray));
return;
}
@@ -6166,9 +6037,6 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
case EXPR_VARIANT:
llvm_emit_variant(c, value, expr);
return;
case EXPR_ARGV_TO_SUBARRAY:
llvm_emit_argv_to_subarray(c, value, expr);
return;
case EXPR_TRY_UNWRAP_CHAIN:
llvm_emit_try_unwrap_chain(c, value, expr);
return;

View File

@@ -98,8 +98,8 @@ static void llvm_expand_from_args(GenContext *c, Type *type, LLVMValueRef ref, u
case TYPE_UNION:
{
Type *largest_type = type_find_largest_union_element(type);
LLVMValueRef cast_addr = llvm_emit_bitcast_ptr(c, ref, largest_type);
llvm_expand_from_args(c, largest_type, cast_addr, index, alignment);
// COERCE UPDATE bitcast removed, check for ways to optimize
llvm_expand_from_args(c, largest_type, ref, index, alignment);
return;
}
default:
@@ -128,7 +128,8 @@ static inline void llvm_process_parameter_value(GenContext *c, Decl *decl, ABIAr
{
// Create the expand type:
LLVMTypeRef coerce_type = llvm_get_coerce_type(c, info);
LLVMValueRef temp = LLVMBuildBitCast(c->builder, decl->backend_ref, LLVMPointerType(coerce_type, 0), "coerce");
// COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef temp = decl->backend_ref;
llvm_emit_and_set_decl_alloca(c, decl);
AlignSize alignment = decl->alignment;
@@ -144,35 +145,33 @@ static inline void llvm_process_parameter_value(GenContext *c, Decl *decl, ABIAr
}
case ABI_ARG_DIRECT_PAIR:
{
// Create the two abi types.
LLVMTypeRef lo = llvm_abi_type(c, info->direct_pair.lo);
LLVMTypeRef hi = llvm_abi_type(c, info->direct_pair.hi);
LLVMTypeRef struct_type = llvm_get_twostruct(c, lo, hi);
AlignSize decl_alignment = decl->alignment;
LLVMValueRef coerce;
if (llvm_store_size(c, struct_type) > type_size(decl->type))
{
AlignSize struct_alignment = llvm_abi_alignment(c, struct_type);
if (decl_alignment < struct_alignment) decl->alignment = decl_alignment = struct_alignment;
coerce = llvm_emit_alloca(c, struct_type, decl_alignment, "");
decl->backend_ref = LLVMBuildBitCast(c->builder, coerce, llvm_get_ptr_type(c, decl->type), decl->name ? decl->name : ".anon");
}
else
{
llvm_emit_and_set_decl_alloca(c, decl);
// Here we do the following transform:
// lo, hi -> { lo, hi } -> struct
// Cast to { lo, hi }
coerce = LLVMBuildBitCast(c->builder, decl->backend_ref, LLVMPointerType(struct_type, 0), "pair");
}
// Point to the lo value.
AlignSize element_align;
LLVMValueRef lo_ptr = llvm_emit_struct_gep_raw(c, coerce, struct_type, 0, decl_alignment, &element_align);
// Store it in the struct.
llvm_store_to_ptr_raw_aligned(c, lo_ptr, llvm_get_next_param(c, index), element_align);
// Point to the hi value.
LLVMValueRef hi_ptr = llvm_emit_struct_gep_raw(c, coerce, struct_type, 1, decl_alignment, &element_align);
// Store it in the struct.
llvm_store_to_ptr_raw_aligned(c, hi_ptr, llvm_get_next_param(c, index), element_align);
AlignSize hi_alignment = llvm_abi_alignment(c, hi);
AlignSize lo_alignment = llvm_abi_alignment(c, lo);
ByteSize hi_aligned_size = aligned_offset(llvm_store_size(c, hi), hi_alignment);
AlignSize pref_align = MAX(hi_alignment, lo_alignment);
// Realign to best alignment.
if (pref_align > decl_alignment) decl_alignment = decl->alignment = pref_align;
AlignSize hi_offset = aligned_offset(llvm_store_size(c, lo), hi_alignment);
assert(hi_offset + llvm_store_size(c, hi) <= type_size(decl->type));
// Emit decl
llvm_emit_and_set_decl_alloca(c, decl);
LLVMValueRef addr = decl->backend_ref;
// Store it in the lo position.
llvm_store_to_ptr_raw_aligned(c, addr, llvm_get_next_param(c, index), decl_alignment);
// Calculate the address
addr = llvm_emit_pointer_inbounds_gep_raw(c, hi, addr, llvm_const_int(c, type_usz, hi_offset / hi_aligned_size));
// Store it in the hi location
llvm_store_to_ptr_raw_aligned(c, addr, llvm_get_next_param(c, index), type_min_alignment(decl_alignment, hi_offset));
return;
}
case ABI_ARG_DIRECT:
@@ -193,7 +192,8 @@ static inline void llvm_process_parameter_value(GenContext *c, Decl *decl, ABIAr
llvm_emit_and_set_decl_alloca(c, decl);
// Cast to the coerce type.
LLVMValueRef cast = LLVMBuildBitCast(c->builder, decl->backend_ref, LLVMPointerType(coerce_type, 0), "coerce");
// COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef cast = decl->backend_ref;
AlignSize decl_alignment = decl->alignment;
// Store each expanded parameter.
@@ -334,7 +334,8 @@ void llvm_emit_return_abi(GenContext *c, BEValue *return_value, BEValue *optiona
LLVMTypeRef coerce_type = llvm_get_coerce_type(c, info);
// Create the new pointer
assert(return_value);
LLVMValueRef coerce = LLVMBuildBitCast(c->builder, return_value->value, coerce_type, "");
// COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef coerce = return_value->value;
// We might have only one value, in that case, build a GEP to that one.
LLVMValueRef lo_val;
AlignSize alignment;
@@ -476,13 +477,12 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
if (c->debug.enable_stacktrace)
{
LLVMTypeRef slot_type = c->debug.stack_type;
LLVMTypeRef ptr_to_slot_type = LLVMPointerType(slot_type, 0);
if (!c->debug.last_ptr)
{
const char *name = ".$last_stack";
LLVMValueRef last_stack = c->debug.last_ptr = llvm_add_global_raw(c, name, ptr_to_slot_type, 0);
LLVMValueRef last_stack = c->debug.last_ptr = llvm_add_global_raw(c, name, c->ptr_type, 0);
LLVMSetThreadLocal(last_stack, true);
LLVMSetInitializer(last_stack, llvm_get_zero_raw(ptr_to_slot_type));
LLVMSetInitializer(last_stack, llvm_get_zero_raw(c->ptr_type));
llvm_set_weak(c, last_stack);
}
AlignSize alignment = llvm_abi_alignment(c, slot_type);
@@ -491,7 +491,7 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
LLVMValueRef prev_ptr = llvm_emit_struct_gep_raw(c, c->debug.stack_slot, slot_type, 0, alignment, &align_to_use);
llvm_store_to_ptr_raw_aligned(c,
prev_ptr,
LLVMBuildLoad2(c->builder, ptr_to_slot_type, c->debug.last_ptr, ""),
LLVMBuildLoad2(c->builder, c->ptr_type, c->debug.last_ptr, ""),
align_to_use);
LLVMValueRef func_name = llvm_emit_struct_gep_raw(c, c->debug.stack_slot, slot_type, 1, alignment, &align_to_use);
llvm_store_to_ptr_raw_aligned(c, func_name, c->debug.func_name, align_to_use);

View File

@@ -87,6 +87,7 @@ typedef struct GenContext_
LLVMTypeRef fault_type;
LLVMTypeRef size_type;
LLVMTypeRef char_ptr_type;
LLVMTypeRef ptr_type;
LLVMTypeRef chars_type;
Decl *panic_var;
struct
@@ -276,7 +277,7 @@ TypeSize llvm_abi_size(GenContext *c, LLVMTypeRef type);
BitSize llvm_bitsize(GenContext *c, LLVMTypeRef type);
AlignSize llvm_abi_alignment(GenContext *c, LLVMTypeRef type);
LLVMTypeRef llvm_func_type(GenContext *context, FunctionPrototype *prototype);
LLVMTypeRef llvm_update_prototype_abi(GenContext *context, FunctionPrototype *prototype, LLVMTypeRef **params);
LLVMTypeRef llvm_update_prototype_abi(GenContext *c, FunctionPrototype *prototype, LLVMTypeRef **params);
LLVMTypeRef llvm_get_twostruct(GenContext *context, LLVMTypeRef lo, LLVMTypeRef hi);
LLVMTypeRef llvm_const_padding_type(GenContext *c, TypeSize size);
LLVMMetadataRef llvm_get_debug_type(GenContext *c, Type *type);
@@ -285,7 +286,6 @@ LLVMTypeRef llvm_get_pointee_type(GenContext *c, Type *any_type);
void llvm_emit_function_decl(GenContext *c, Decl *decl);
void llvm_emit_xxlizer(GenContext *c, Decl *decl);
bool llvm_types_are_similar(LLVMTypeRef original, LLVMTypeRef coerce);
INLINE LLVMTypeRef llvm_get_ptr_type(GenContext *c, Type *type);
// -- Attributes ---
void llvm_attribute_add_range(GenContext *c, LLVMValueRef value_to_add_attribute_to, unsigned attribute, int index_start, int index_end);
@@ -318,9 +318,6 @@ void llvm_emit_and_set_decl_alloca(GenContext *c, Decl *decl);
INLINE void llvm_set_alignment(LLVMValueRef alloca, AlignSize alignment);
INLINE AlignSize llvm_type_or_alloca_align(LLVMValueRef dest, Type *type);
// -- Bitcast --
static inline LLVMValueRef llvm_emit_bitcast(GenContext *c, LLVMValueRef value, Type *type);
INLINE LLVMValueRef llvm_emit_bitcast_ptr(GenContext *c, LLVMValueRef value, Type *type);
INLINE LLVMValueRef llvm_zext_trunc(GenContext *c, LLVMValueRef data, LLVMTypeRef type);
// -- Constants --

View File

@@ -64,27 +64,13 @@ INLINE LLVMValueRef llvm_store_to_ptr_raw(GenContext *c, LLVMValueRef pointer, L
return llvm_store_to_ptr_raw_aligned(c, pointer, value, llvm_type_or_alloca_align(pointer, type));
}
static inline LLVMValueRef llvm_emit_bitcast(GenContext *c, LLVMValueRef value, Type *type)
{
assert(type->type_kind == TYPE_POINTER);
LLVMTypeRef result_type = llvm_get_type(c, type);
if (result_type == LLVMTypeOf(value)) return value;
return LLVMBuildBitCast(c->builder, value, result_type, "");
}
INLINE void llvm_value_bitcast(GenContext *c, BEValue *value, Type *type)
{
assert(llvm_value_is_addr(value));
type = type_lowering(type);
value->value = llvm_emit_bitcast(c, value->value, type_get_ptr(type));
value->type = type;
}
INLINE LLVMValueRef llvm_emit_bitcast_ptr(GenContext *c, LLVMValueRef value, Type *type)
{
return llvm_emit_bitcast(c, value, type_get_ptr(type));
}
INLINE LLVMValueRef llvm_emit_shl(GenContext *c, LLVMValueRef value, LLVMValueRef shift)
{
return LLVMBuildShl(c->builder, value, shift, "shl");
@@ -197,11 +183,6 @@ INLINE bool llvm_is_local_eval(GenContext *c)
}
INLINE LLVMTypeRef llvm_get_ptr_type(GenContext *c, Type *type)
{
return llvm_get_type(c, type_get_ptr(type));
}
INLINE LLVMValueRef llvm_emit_and_raw(GenContext *c, LLVMValueRef lhs, LLVMValueRef rhs)
{
if (llvm_is_const_null(lhs)) return lhs;

View File

@@ -115,11 +115,11 @@ void gencontext_begin_module(GenContext *c)
}
c->bool_type = LLVMInt1TypeInContext(c->context);
c->byte_type = LLVMInt8TypeInContext(c->context);
c->ptr_type = LLVMPointerType(c->byte_type, 0);
c->chars_type = llvm_get_type(c, type_chars);
c->introspect_type = create_introspection_type(c);
c->fault_type = create_fault_type(c);
c->size_type = llvm_get_type(c, type_usize);
c->char_ptr_type = LLVMPointerType(c->byte_type, 0);
if (c->panic_var) c->panic_var->backend_ref = NULL;
if (active_target.debug_info != DEBUG_INFO_NONE)
@@ -134,7 +134,7 @@ void gencontext_begin_module(GenContext *c)
if (active_target.debug_info == DEBUG_INFO_FULL && active_target.feature.safe_mode)
{
c->debug.stack_type = LLVMStructCreateNamed(c->context, ".$callstack");
LLVMTypeRef types[4] = { LLVMPointerType(c->debug.stack_type, 0),
LLVMTypeRef types[4] = { c->ptr_type,
c->chars_type,
c->chars_type,
llvm_get_type(c, type_uint) };

View File

@@ -1270,7 +1270,7 @@ LLVMValueRef llvm_emit_zstring_named(GenContext *c, const char *str, const char
LLVMSetInitializer(global_string, llvm_get_zstring(c, str, len));
AlignSize alignment;
LLVMValueRef string = llvm_emit_array_gep_raw(c, global_string, char_array_type, 0, 1, &alignment);
return llvm_emit_bitcast_ptr(c, string, type_char);
return string;
}

View File

@@ -47,12 +47,10 @@ LLVMValueRef llvm_store_to_ptr_aligned(GenContext *c, LLVMValueRef destination,
// Here we do an optimized(?) memcopy.
ByteSize size = type_size(value->type);
LLVMValueRef copy_size = llvm_const_int(c, size <= UINT32_MAX ? type_uint : type_usize, size);
destination = LLVMBuildBitCast(c->builder, destination, llvm_get_ptr_type(c, type_char), "");
LLVMValueRef source = LLVMBuildBitCast(c->builder, value->value, llvm_get_ptr_type(c, type_char), "");
LLVMValueRef copy = LLVMBuildMemCpy(c->builder,
destination,
alignment,
source,
value->value,
value->alignment ? value->alignment : type_abi_alignment(value->type),
copy_size);
return copy;

View File

@@ -5,10 +5,10 @@
#include "llvm_codegen_internal.h"
static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl);
static inline LLVMTypeRef llvm_type_from_ptr(GenContext *context, Type *type);
static inline LLVMTypeRef llvm_type_from_array(GenContext *context, Type *type);
static void param_expand(GenContext *context, LLVMTypeRef** params_ref, Type *type);
static inline void add_func_type_param(GenContext *context, Type *param_type, ABIArgInfo *arg_info, LLVMTypeRef **params);
static inline void add_func_type_param(GenContext *c, Type *param_type, ABIArgInfo *arg_info, LLVMTypeRef **params);
static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl)
{
@@ -87,19 +87,6 @@ static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl)
UNREACHABLE
}
static inline LLVMTypeRef llvm_type_from_ptr(GenContext *context, Type *type)
{
if (type->canonical != type)
{
return type->backend_type = llvm_get_type(context, type->canonical);
}
if (type == type_voidptr)
{
return type->backend_type = llvm_get_ptr_type(context, type_char);
}
return type->backend_type = LLVMPointerType(llvm_get_type(context, type->pointer), /** TODO **/0);
}
static inline LLVMTypeRef llvm_type_from_array(GenContext *context, Type *type)
{
@@ -165,7 +152,7 @@ static void param_expand(GenContext *context, LLVMTypeRef** params_ref, Type *ty
}
static inline void add_func_type_param(GenContext *context, Type *param_type, ABIArgInfo *arg_info, LLVMTypeRef **params)
static inline void add_func_type_param(GenContext *c, Type *param_type, ABIArgInfo *arg_info, LLVMTypeRef **params)
{
arg_info->param_index_start = (MemberIndex)vec_size(*params);
switch (arg_info->kind)
@@ -173,31 +160,31 @@ static inline void add_func_type_param(GenContext *context, Type *param_type, AB
case ABI_ARG_IGNORE:
break;
case ABI_ARG_INDIRECT:
vec_add(*params, llvm_get_ptr_type(context, param_type));
vec_add(*params, c->ptr_type);
break;
case ABI_ARG_EXPAND_COERCE:
vec_add(*params, llvm_abi_type(context, arg_info->coerce_expand.lo));
vec_add(*params, llvm_abi_type(c, arg_info->coerce_expand.lo));
if (abi_type_is_valid(arg_info->coerce_expand.hi))
{
vec_add(*params, llvm_abi_type(context, arg_info->coerce_expand.hi));
vec_add(*params, llvm_abi_type(c, arg_info->coerce_expand.hi));
}
break;
case ABI_ARG_EXPAND:
// Expanding a structs
param_expand(context, params, param_type->canonical);
param_expand(c, params, param_type->canonical);
// If we have padding, add it here.
if (arg_info->expand.padding_type)
{
vec_add(*params, llvm_get_type(context, arg_info->expand.padding_type));
vec_add(*params, llvm_get_type(c, arg_info->expand.padding_type));
}
break;
case ABI_ARG_DIRECT:
vec_add(*params, llvm_get_type(context, param_type));
vec_add(*params, llvm_get_type(c, param_type));
break;
case ABI_ARG_DIRECT_SPLIT_STRUCT:
{
// Normal direct.
LLVMTypeRef coerce_type = llvm_get_type(context, arg_info->direct_struct_expand.type);
LLVMTypeRef coerce_type = llvm_get_type(c, arg_info->direct_struct_expand.type);
for (unsigned idx = 0; idx < arg_info->direct_struct_expand.elements; idx++)
{
vec_add(*params, coerce_type);
@@ -207,27 +194,27 @@ static inline void add_func_type_param(GenContext *context, Type *param_type, AB
case ABI_ARG_DIRECT_COERCE_INT:
{
// Normal direct.
LLVMTypeRef coerce_type = LLVMIntTypeInContext(context->context, type_size(param_type) * 8);
LLVMTypeRef coerce_type = LLVMIntTypeInContext(c->context, type_size(param_type) * 8);
vec_add(*params, coerce_type);
break;
}
case ABI_ARG_DIRECT_COERCE:
{
// Normal direct.
LLVMTypeRef coerce_type = llvm_get_type(context, arg_info->direct_coerce_type);
LLVMTypeRef coerce_type = llvm_get_type(c, arg_info->direct_coerce_type);
vec_add(*params, coerce_type);
break;
}
case ABI_ARG_DIRECT_PAIR:
// Pairs are passed by param.
vec_add(*params, llvm_abi_type(context, arg_info->direct_pair.lo));
vec_add(*params, llvm_abi_type(context, arg_info->direct_pair.hi));
vec_add(*params, llvm_abi_type(c, arg_info->direct_pair.lo));
vec_add(*params, llvm_abi_type(c, arg_info->direct_pair.hi));
break;
}
arg_info->param_index_end = (MemberIndex)vec_size(*params);
}
LLVMTypeRef llvm_update_prototype_abi(GenContext *context, FunctionPrototype *prototype, LLVMTypeRef **params)
LLVMTypeRef llvm_update_prototype_abi(GenContext *c, FunctionPrototype *prototype, LLVMTypeRef **params)
{
LLVMTypeRef retval = NULL;
Type *call_return_type = prototype->abi_ret_type;
@@ -241,59 +228,59 @@ LLVMTypeRef llvm_update_prototype_abi(GenContext *context, FunctionPrototype *pr
case ABI_ARG_EXPAND:
UNREACHABLE;
case ABI_ARG_INDIRECT:
vec_add(*params, llvm_get_ptr_type(context, call_return_type));
retval = llvm_get_type(context, type_void);
vec_add(*params, c->ptr_type);
retval = llvm_get_type(c, type_void);
break;
case ABI_ARG_EXPAND_COERCE:
{
LLVMTypeRef lo = llvm_abi_type(context, ret_arg_info->direct_pair.lo);
LLVMTypeRef lo = llvm_abi_type(c, ret_arg_info->direct_pair.lo);
if (!abi_type_is_valid(ret_arg_info->direct_pair.hi))
{
retval = lo;
break;
}
LLVMTypeRef hi = llvm_abi_type(context, ret_arg_info->direct_pair.hi);
retval = llvm_get_twostruct(context, lo, hi);
LLVMTypeRef hi = llvm_abi_type(c, ret_arg_info->direct_pair.hi);
retval = llvm_get_twostruct(c, lo, hi);
break;
}
case ABI_ARG_IGNORE:
retval = llvm_get_type(context, type_void);
retval = llvm_get_type(c, type_void);
break;
case ABI_ARG_DIRECT_PAIR:
{
LLVMTypeRef lo = llvm_abi_type(context, ret_arg_info->direct_pair.lo);
LLVMTypeRef hi = llvm_abi_type(context, ret_arg_info->direct_pair.hi);
retval = llvm_get_twostruct(context, lo, hi);
LLVMTypeRef lo = llvm_abi_type(c, ret_arg_info->direct_pair.lo);
LLVMTypeRef hi = llvm_abi_type(c, ret_arg_info->direct_pair.hi);
retval = llvm_get_twostruct(c, lo, hi);
break;
}
case ABI_ARG_DIRECT:
retval = llvm_get_type(context, call_return_type);
retval = llvm_get_type(c, call_return_type);
break;
case ABI_ARG_DIRECT_SPLIT_STRUCT:
UNREACHABLE
case ABI_ARG_DIRECT_COERCE_INT:
retval = LLVMIntTypeInContext(context->context, type_size(call_return_type) * 8);
retval = LLVMIntTypeInContext(c->context, type_size(call_return_type) * 8);
break;
case ABI_ARG_DIRECT_COERCE:
retval = llvm_get_type(context, ret_arg_info->direct_coerce_type);
retval = llvm_get_type(c, ret_arg_info->direct_coerce_type);
break;
}
// If it's optional and it's not void (meaning ret_abi_info will be NULL)
if (prototype->ret_by_ref)
{
add_func_type_param(context, type_get_ptr(type_lowering(prototype->ret_by_ref_type)), prototype->ret_by_ref_abi_info, params);
add_func_type_param(c, type_get_ptr(type_lowering(prototype->ret_by_ref_type)), prototype->ret_by_ref_abi_info, params);
}
// Add in all of the required arguments.
VECEACH(prototype->param_types, i)
{
add_func_type_param(context, prototype->param_types[i], prototype->abi_args[i], params);
add_func_type_param(c, prototype->param_types[i], prototype->abi_args[i], params);
}
VECEACH(prototype->varargs, i)
{
add_func_type_param(context, prototype->varargs[i], prototype->abi_varargs[i], params);
add_func_type_param(c, prototype->varargs[i], prototype->abi_varargs[i], params);
}
return retval;
}
@@ -377,7 +364,8 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type)
case TYPE_BOOL:
return any_type->backend_type = LLVMIntTypeInContext(c->context, 8U);
case TYPE_POINTER:
return any_type->backend_type = llvm_type_from_ptr(c, any_type);
assert(c->ptr_type);
return any_type->backend_type = c->ptr_type;
case TYPE_ARRAY:
case TYPE_FLEXIBLE_ARRAY:
return any_type->backend_type = llvm_type_from_array(c, any_type);
@@ -612,14 +600,7 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
llvm_set_linkonce(c, global_ref);
LLVMSetInitializer(global_ref, associated_value_arr);
LLVMSetGlobalConstant(global_ref, true);
if (mixed)
{
associated_value->backend_ref = llvm_emit_bitcast_ptr(c, global_ref, type_get_array(associated_value->type, elements));
}
else
{
associated_value->backend_ref = global_ref;
}
associated_value->backend_ref = global_ref;
}
return val;
}
@@ -668,11 +649,10 @@ static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type)
llvm_set_linkonce(c, global_name);
val->backend_ref = LLVMBuildPointerCast(c->builder, global_name, llvm_get_type(c, type_typeid), "");
}
LLVMTypeRef element_type = llvm_get_type(c, type_typeid);
LLVMValueRef* values = elements ? MALLOC(sizeof(LLVMValueRef) * elements) : NULL;
for (unsigned i = 0; i < elements; i++)
{
values[i] = LLVMBuildBitCast(c->builder, fault_vals[i]->backend_ref, element_type, "");
values[i] = fault_vals[i]->backend_ref;
}
return llvm_generate_introspection_global(c, ref, type, INTROSPECT_TYPE_FAULT, NULL, elements, NULL, false);
}

View File

@@ -54,7 +54,7 @@ void llvm_value_addr(GenContext *c, BEValue *value)
LLVMValueRef ref = llvm_add_global_raw(c, ".taddr", LLVMTypeOf(val), 0);
llvm_set_private_linkage(ref);
LLVMSetInitializer(ref, val);
llvm_value_set_address_abi_aligned(value, llvm_emit_bitcast_ptr(c, ref, value->type), value->type);
llvm_value_set_address_abi_aligned(value, ref, value->type);
}
else
{

View File

@@ -757,7 +757,6 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type)
case EXPR_TRY_UNWRAP_CHAIN:
case EXPR_SUBSCRIPT_ADDR:
case EXPR_VARIANTSWITCH:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_COMPILER_CONST:
case EXPR_STRINGIFY:
case EXPR_CT_EVAL:
@@ -925,7 +924,6 @@ Expr *recursive_may_narrow_int(Expr *expr, Type *type)
case EXPR_TRY_UNWRAP:
case EXPR_TRY_UNWRAP_CHAIN:
case EXPR_SUBSCRIPT_ADDR:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_VARIANTSWITCH:
case EXPR_COMPILER_CONST:
case EXPR_STRINGIFY:

View File

@@ -443,7 +443,6 @@ static bool sema_binary_is_expr_lvalue(Expr *top_expr, Expr *expr)
if (!vec_size(expr->expression_list)) return false;
return sema_binary_is_expr_lvalue(top_expr, VECLAST(expr->expression_list));
case EXPR_POISONED:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_ASM:
case EXPR_BINARY:
case EXPR_BITASSIGN:
@@ -7020,9 +7019,6 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr)
case EXPR_STRINGIFY:
if (!sema_expr_analyse_ct_stringify(context, expr)) return false;
return true;
case EXPR_ARGV_TO_SUBARRAY:
expr->type = type_get_subarray(global_context_string_type());
return true;
case EXPR_DECL:
if (!sema_analyse_var_decl(context, expr->decl_expr, true)) return false;
expr->type = expr->decl_expr->type;

View File

@@ -320,13 +320,13 @@ void* CONCAT(foreach_vec_, __LINE__) = (vec__); unsigned CONCAT(foreach_len_, __
#if IS_GCC || IS_CLANG
#define MAX(_a, _b) ({ \
typeof(_a) __a__ = (_a); \
typeof(_b) __b__ = (_b); \
__auto_type __a__ = (_a); \
__auto_type __b__ = (_b); \
__a__ > __b__ ? __a__ : __b__; })
#define MIN(_a, _b) ({ \
typeof(_a) __a__ = (_a); \
typeof(_b) __b__ = (_b); \
__auto_type __a__ = (_a); \
__auto_type __b__ = (_b); \
__a__ < __b__ ? __a__ : __b__; })
#else

View File

@@ -22,11 +22,9 @@ entry:
%literal = alloca %Test, align 4
%literal1 = alloca %Test, align 4
store i32 0, ptr %literal, align 4
%0 = getelementptr inbounds %Test, ptr %literal, i32 0, i32 0
%1 = load i32, ptr %0, align 4
call void @blorg(i32 %1)
%0 = load i32, ptr %literal, align 4
call void @blorg(i32 %0)
store i32 0, ptr %literal1, align 4
%2 = getelementptr inbounds %Test, ptr %literal1, i32 0, i32 0
%3 = load i32, ptr %2, align 4
ret i32 %3
}
%1 = load i32, ptr %literal1, align 4
ret i32 %1
}

View File

@@ -25,12 +25,10 @@ entry:
%literal = alloca %Test, align 4
%literal1 = alloca %Test, align 4
store i32 0, ptr %literal, align 4
%0 = getelementptr inbounds %Test, ptr %literal, i32 0, i32 0
%1 = load i32, ptr %0, align 4
%2 = zext i32 %1 to i64
call void @blorg(i64 %2)
%0 = load i32, ptr %literal, align 4
%1 = zext i32 %0 to i64
call void @blorg(i64 %1)
store i32 0, ptr %literal1, align 4
%3 = getelementptr inbounds %Test, ptr %literal1, i32 0, i32 0
%4 = load i32, ptr %3, align 4
ret i32 %4
%2 = load i32, ptr %literal1, align 4
ret i32 %2
}

View File

@@ -23,11 +23,9 @@ entry:
%literal = alloca %Test, align 4
%literal1 = alloca %Test, align 4
store i32 0, ptr %literal, align 4
%0 = getelementptr inbounds %Test, ptr %literal, i32 0, i32 0
%1 = load i32, ptr %0, align 4
call void @blorg(i32 %1)
%0 = load i32, ptr %literal, align 4
call void @blorg(i32 %0)
store i32 0, ptr %literal1, align 4
%2 = getelementptr inbounds %Test, ptr %literal1, i32 0, i32 0
%3 = load i32, ptr %2, align 4
ret i32 %3
%1 = load i32, ptr %literal1, align 4
ret i32 %1
}

View File

@@ -18,26 +18,25 @@ fn void test(Rectangle r)
define void @foo_test(<2 x float> %0, <2 x float> %1) #0 {
entry:
%r = alloca %Rectangle, align 4
%r = alloca %Rectangle, align 8
%literal = alloca %Rectangle, align 4
%coerce = alloca %Rectangle, align 8
%2 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %r, i32 0, i32 0
store <2 x float> %0, ptr %2, align 4
%3 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %r, i32 0, i32 1
store <2 x float> %1, ptr %3, align 4
%4 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 0
store float 1.000000e+00, ptr %4, align 4
%5 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 1
store float 2.000000e+00, ptr %5, align 4
%6 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 2
store float 3.000000e+00, ptr %6, align 4
%7 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 3
store float 4.000000e+00, ptr %7, align 4
store <2 x float> %0, ptr %r, align 8
%ptroffset = getelementptr inbounds <2 x float>, ptr %r, i64 1
store <2 x float> %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 0
store float 1.000000e+00, ptr %2, align 4
%3 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 1
store float 2.000000e+00, ptr %3, align 4
%4 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 2
store float 3.000000e+00, ptr %4, align 4
%5 = getelementptr inbounds %Rectangle, ptr %literal, i32 0, i32 3
store float 4.000000e+00, ptr %5, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %coerce, ptr align 4 %literal, i32 16, i1 false)
%8 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %coerce, i32 0, i32 0
%lo = load <2 x float>, ptr %8, align 8
%9 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %coerce, i32 0, i32 1
%hi = load <2 x float>, ptr %9, align 8
%6 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %coerce, i32 0, i32 0
%lo = load <2 x float>, ptr %6, align 8
%7 = getelementptr inbounds { <2 x float>, <2 x float> }, ptr %coerce, i32 0, i32 1
%hi = load <2 x float>, ptr %7, align 8
call void @foo_test(<2 x float> %lo, <2 x float> %hi)
ret void
}

View File

@@ -23,15 +23,15 @@ declare void @hello2(i64, i64) #0
define void @unionx64_hello(i64 %0, i64 %1) #0 {
entry:
%f = alloca %Foo, align 8
store i64 %0, ptr %f, align 8
%ptroffset = getelementptr inbounds i64, ptr %f, i64 1
store i64 %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds { i64, i64 }, ptr %f, i32 0, i32 0
store i64 %0, ptr %2, align 8
%lo = load i64, ptr %2, align 8
%3 = getelementptr inbounds { i64, i64 }, ptr %f, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds { i64, i64 }, ptr %f, i32 0, i32 0
%lo = load i64, ptr %4, align 8
%5 = getelementptr inbounds { i64, i64 }, ptr %f, i32 0, i32 1
%hi = load i64, ptr %5, align 8
%hi = load i64, ptr %3, align 8
call void @hello2(i64 %lo, i64 %hi)
ret void
}
attributes #0 = { nounwind }

View File

@@ -184,10 +184,8 @@ entry:
%le1 = icmp sle i32 %3, %4
%or = or i1 %le, %le1
br i1 %or, label %if.then, label %if.exit
if.then: ; preds = %entry
ret ptr null
if.exit: ; preds = %entry
ret ptr %0
}
@@ -198,9 +196,8 @@ define void @test_teste2() #0 {
entry:
%xqic = alloca %Foostruct, align 2
store i16 0, ptr %xqic, align 2
%0 = getelementptr inbounds %Foostruct, ptr %xqic, i32 0, i32 0
%1 = load i16, ptr %0, align 2
%2 = call i32 @foo3(i16 %1)
%0 = load i16, ptr %xqic, align 2
%1 = call i32 @foo3(i16 %0)
ret void
}
@@ -213,22 +210,18 @@ entry:
store ptr null, ptr %basel, align 8
store ptr null, ptr %rcand, align 8
br label %loop.body
loop.body: ; preds = %if.exit, %entry
%2 = load i32, ptr %lvalid, align 4
%not = icmp eq i32 %2, 0
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %loop.body
%3 = load ptr, ptr %basel, align 8
%4 = getelementptr inbounds %Edge_rec, ptr %3, i32 0, i32 1
%5 = load ptr, ptr %4, align 8
%ptrxi = ptrtoint ptr %5 to i32
ret i32 %ptrxi
if.exit: ; preds = %loop.body
br label %loop.body
loop.exit: ; No predecessors!
ret i32 1
}
@@ -261,60 +254,56 @@ entry:
define i32 @test_test2(i32 %0, i64 %1, i32 %2, i32 %3) #0 {
entry:
%4 = alloca { i64, i32 }, align 8
%5 = getelementptr inbounds { i64, i32 }, ptr %4, i32 0, i32 0
store i64 %1, ptr %5, align 8
%6 = getelementptr inbounds { i64, i32 }, ptr %4, i32 0, i32 1
store i32 %2, ptr %6, align 8
%a = alloca %Test, align 8
store i64 %1, ptr %a, align 8
%ptroffset = getelementptr inbounds i32, ptr %a, i64 2
store i32 %2, ptr %ptroffset, align 8
%add = add i32 %0, %3
%7 = getelementptr inbounds %Test, ptr %4, i32 0, i32 1
%8 = load i16, ptr %7, align 2
%sisiext = sext i16 %8 to i32
%4 = getelementptr inbounds %Test, ptr %a, i32 0, i32 1
%5 = load i16, ptr %4, align 2
%sisiext = sext i16 %5 to i32
%add1 = add i32 %add, %sisiext
%9 = getelementptr inbounds %Test, ptr %4, i32 0, i32 2
%10 = load i32, ptr %9, align 4
%add2 = add i32 %add1, %10
%6 = getelementptr inbounds %Test, ptr %a, i32 0, i32 2
%7 = load i32, ptr %6, align 4
%add2 = add i32 %add1, %7
ret i32 %add2
}
define i32 @test_test3(i64 %0, i32 %1, i64 %2, i32 %3) #0 {
entry:
%4 = alloca { i64, i32 }, align 8
%5 = alloca { i64, i32 }, align 8
%6 = getelementptr inbounds { i64, i32 }, ptr %4, i32 0, i32 0
store i64 %0, ptr %6, align 8
%7 = getelementptr inbounds { i64, i32 }, ptr %4, i32 0, i32 1
store i32 %1, ptr %7, align 8
%8 = getelementptr inbounds { i64, i32 }, ptr %5, i32 0, i32 0
store i64 %2, ptr %8, align 8
%9 = getelementptr inbounds { i64, i32 }, ptr %5, i32 0, i32 1
store i32 %3, ptr %9, align 8
%10 = getelementptr inbounds %Test, ptr %4, i32 0, i32 1
%11 = load i16, ptr %10, align 2
%sisiext = sext i16 %11 to i32
%12 = getelementptr inbounds %Test, ptr %4, i32 0, i32 2
%13 = load i32, ptr %12, align 4
%add = add i32 %sisiext, %13
%14 = getelementptr inbounds %Test, ptr %5, i32 0, i32 2
%15 = load i32, ptr %14, align 4
%add1 = add i32 %add, %15
%16 = getelementptr inbounds %Test, ptr %5, i32 0, i32 3
%17 = load i32, ptr %16, align 8
%add2 = add i32 %add1, %17
ret i32 %add2
%a = alloca %Test, align 8
%b = alloca %Test, align 8
store i64 %0, ptr %a, align 8
%ptroffset = getelementptr inbounds i32, ptr %a, i64 2
store i32 %1, ptr %ptroffset, align 8
store i64 %2, ptr %b, align 8
%ptroffset1 = getelementptr inbounds i32, ptr %b, i64 2
store i32 %3, ptr %ptroffset1, align 8
%4 = getelementptr inbounds %Test, ptr %a, i32 0, i32 1
%5 = load i16, ptr %4, align 2
%sisiext = sext i16 %5 to i32
%6 = getelementptr inbounds %Test, ptr %a, i32 0, i32 2
%7 = load i32, ptr %6, align 4
%add = add i32 %sisiext, %7
%8 = getelementptr inbounds %Test, ptr %b, i32 0, i32 2
%9 = load i32, ptr %8, align 4
%add2 = add i32 %add, %9
%10 = getelementptr inbounds %Test, ptr %b, i32 0, i32 3
%11 = load i32, ptr %10, align 8
%add3 = add i32 %add2, %11
ret i32 %add3
}
define { i64, i32 } @test_test4(i64 %0, i32 %1) #0 {
entry:
%2 = alloca { i64, i32 }, align 8
%a = alloca %Test, align 8
%tempcoerce = alloca { i64, i32 }, align 8
%3 = getelementptr inbounds { i64, i32 }, ptr %2, i32 0, i32 0
store i64 %0, ptr %3, align 8
%4 = getelementptr inbounds { i64, i32 }, ptr %2, i32 0, i32 1
store i32 %1, ptr %4, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %tempcoerce, ptr align 8 %2, i32 12, i1 false)
%5 = load { i64, i32 }, ptr %tempcoerce, align 8
ret { i64, i32 } %5
store i64 %0, ptr %a, align 8
%ptroffset = getelementptr inbounds i32, ptr %a, i64 2
store i32 %1, ptr %ptroffset, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %tempcoerce, ptr align 8 %a, i32 12, i1 false)
%2 = load { i64, i32 }, ptr %tempcoerce, align 8
ret { i64, i32 } %2
}
define i32 @test_test6() #0 {

View File

@@ -0,0 +1,996 @@
// #target: macos-x64
module foo;
extern fn void* malloc(uint);
struct List
{
int data;
List* next;
}
fn List* passThroughList(List* l) {
return l;
}
// Recursive data structure tests...
List* data;
fn void foo()
{
static int foo = 0; // Test static local variable
foo += 1; // Increment static variable
data = (List*)malloc(12); // This is not a proper list allocation
}
List listNode3 = { 4, null };
List listNode2 = { 3, &listNode3 };
List listNode0 = { 1, &listNode1 };
List listNode1 = { 2, &listNode2 };
List[10] listArray;
// Iterative insert fn
fn void insertIntoListTail(List **l, int data) {
while (*l) l = &(*l).next;
*l = (List*)malloc(List.sizeof);
(*l).data = data;
(*l).next = null;
}
// Recursive list search fn
fn List *findData(List *l, int data) {
if (!l) return null;
if (l.data == data) return l;
return findData(l.next, data);
}
extern fn void foundIt();
// Driver fn...
fn void doListStuff() {
List* myList = null;
insertIntoListTail(&myList, 100);
insertIntoListTail(&myList, 12);
insertIntoListTail(&myList, 42);
insertIntoListTail(&myList, 1123);
insertIntoListTail(&myList, 1213);
if (findData(myList, 75)) foundIt();
if (findData(myList, 42)) foundIt();
if (findData(myList, 700)) foundIt();
}
fn int floatcomptest(double *x, double *y, float *x1, float *y1) {
return (int)(*x < *y || *x1 < *y1);
}
// Exposed a bug
fn void* memset_impl(void* dstpp, int c, uint len)
{
iptr dstp = (iptr)dstpp;
while (dstp % 4 != 0)
{
((char*)dstp)[0] = (char)c;
dstp += 1;
len -= 1;
}
return dstpp;
}
// TEST problem with signed/unsigned versions of the same constants being shared
// incorrectly!
private char* temp;
private int remaining;
private fn char* localmalloc(int size) {
char* blah;
if (size>remaining)
{
temp = (char*) malloc(32768);
remaining = 32768;
return temp;
}
return null;
}
struct PBVTest { double x; double y; int z; }
fn PBVTest testRetStruct(float x, double y, int z) {
PBVTest t = { x, y, z };
return t;
}
extern fn PBVTest testRetStruct2(); // external func no inlining
fn double callRetStruct(float x, double y, int z) {
PBVTest t = testRetStruct2();
return t.x+x+y+z;
}
extern fn int fp(int, char*);
char *ext;
fn void __bb_exit_func()
{
fp(12, ext ? ext : "<none>");
}
extern fn int puts(char* s);
struct FunStructTest {
int test1;
char *pointer;
int[12] array;
}
struct SubStruct {
short x, y;
}
struct Quad {
int w;
SubStruct ss;
SubStruct *ssp;
char c;
int y;
}
Quad globalQuad = { 4, {1, 2}, null, 3, 156 };
define FuncPtr = fn int(int);
fn uint ptrFunc(FuncPtr func, int x) {
return func(x);
}
fn char ptrFunc2(FuncPtr[30] funcTab, int num) {
return (char)funcTab[num]('b');
}
extern fn char smallArgs2(char w, char x, long zrrk, char y, char z);
extern fn int someFuncA();
fn char smallArgs(char w, char x, char y, char z) {
someFuncA();
return smallArgs2(w-1, x+1, y, z, w);
}
private fn int f0(Quad q, int i) { /* Pass Q by value */
Quad r = void;
if (i) r.ss = q.ss;
q.ssp = &r.ss;
q.w = q.y = q.c = 1;
return q.ss.y + i + r.y - q.c;
}
fn int f1(Quad *q, int i) { /* Pass Q by address */
Quad r = void;
if (i) r = *q;
q.w = q.y = q.c = 1;
return q.ss.y+i+r.y-q.c;
}
fn int badFunc(float val) {
int result = void;
if (val > 12.345) result = 4;
return result; /* Test use of undefined value */
}
extern fn int ef1(int *, char *, int *);
fn int func(int param, long param2) {
int result = param;
{{{{
char c = void; int x = void;
ef1(&result, &c, &x);
}}}
{ // c & X are duplicate names!
char c; int x;
ef1(&result, &c, &x);
}
}
return result;
}
fn short funFunc(long x, char z) {
return (short)(x+z);
}
fn uint castTest(int x) { return x; }
fn double testAdd(double x, float y) {
return x+y+0.5;
}
fn int funcZ(int i, int j) {
while (i != 20) i += 2;
j += funcZ(2, i);
return (i * 3 + j*2)*j;
}
fn int sumArray(int* array, int num) {
int i = void;
int result = 0;
for (i = 0; i < num; ++i)
result += array[i];
return result;
}
fn int arrayParam(int* values) {
return ef1((int*)(iptr)values[50], (char*)1, &values[50]);
}
fn int arrayToSum() {
int[100] a = void;
int i;
for (i = 0; i < 100; ++i)
a[i] = i*4;
return a[a[0]]; //SumArray(A, 100);
}
fn int externFunc(long, uint*, short, char);
fn int main(int argc, char **argv) {
uint i = void;
puts("Hello world!\n");
externFunc(-1, null, (short)argc, 2);
//func(argc, argc);
for (i = 0; i < 10; i++) puts(argv[3]);
return 0;
}
fn double mathFunc(double x, double y, double z,
double aa, double bb, double cc, double dd,
double ee, double ff, double gg, double hh,
double aaa, double abb, double acc, double add,
double aee, double aff) {
return x + y + z + aa + bb + cc + dd + ee + ff + gg + hh
+ aaa + abb + acc + add + aee + aff;
}
fn void strcpy(char *s1, char *s2) {
while (*s1++ = *s2++);
}
fn void strcat(char *s1, char *s2) {
while (*s1++);
s1--;
while (*s1++ = *s2++);
}
fn int strcmp(char *s1, char *s2) {
while (*s1++ == *s2++);
if (*s1 == 0) {
if (*s2 == 0) {
return 0;
} else {
return -1;
}
} else {
if (*s2 == 0) {
return 1;
} else {
return (*(--s1) - *(--s2));
}
}
}
/* #expect: foo.ll
@foo_data = local_unnamed_addr global ptr null, align 8
@foo_listNode3 = global %List { i32 4, ptr null }, align 8
@foo_listNode2 = global %List { i32 3, ptr @foo_listNode3 }, align 8
@foo_listNode0 = local_unnamed_addr global %List { i32 1, ptr @foo_listNode1 }, align 8
@foo_listNode1 = global %List { i32 2, ptr @foo_listNode2 }, align 8
@foo_listArray = local_unnamed_addr global [10 x %List] zeroinitializer, align 16
@foo_temp = protected unnamed_addr global ptr null, align 8
@foo_remaining = protected unnamed_addr global i32 0, align 4
@foo_ext = local_unnamed_addr global ptr null, align 8
@foo_globalQuad = local_unnamed_addr global %Quad { i32 4, %SubStruct { i16 1, i16 2 }, ptr null, i8 3, i32 156 }, align 8
@"foo$foo" = internal unnamed_addr global i32 0, align 4
define ptr @foo_passThroughList(ptr %0) #0 {
entry:
ret ptr %0
}
define void @foo_foo() #0 {
entry:
%0 = load i32, ptr @"foo$foo", align 4
%add = add i32 %0, 1
store i32 %add, ptr @"foo$foo", align 4
%1 = call ptr @malloc(i32 12)
store ptr %1, ptr @foo_data, align 8
ret void
}
define void @foo_insertIntoListTail(ptr %0, i32 %1) #0 {
entry:
%l = alloca ptr, align 8
store ptr %0, ptr %l, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load ptr, ptr %l, align 8
%3 = load ptr, ptr %2, align 8
%ptrbool = icmp ne ptr %3, null
br i1 %ptrbool, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%4 = load ptr, ptr %l, align 8
%5 = load ptr, ptr %4, align 8
%6 = getelementptr inbounds %List, ptr %5, i32 0, i32 1
store ptr %6, ptr %l, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%7 = load ptr, ptr %l, align 8
%8 = call ptr @malloc(i32 16)
store ptr %8, ptr %7, align 8
%9 = load ptr, ptr %l, align 8
%10 = load ptr, ptr %9, align 8
%11 = getelementptr inbounds %List, ptr %10, i32 0, i32 0
store i32 %1, ptr %11, align 8
%12 = load ptr, ptr %l, align 8
%13 = load ptr, ptr %12, align 8
%14 = getelementptr inbounds %List, ptr %13, i32 0, i32 1
store ptr null, ptr %14, align 8
ret void
}
define ptr @foo_findData(ptr %0, i32 %1) #0 {
entry:
%not = icmp eq ptr %0, null
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %entry
ret ptr null
if.exit: ; preds = %entry
%2 = getelementptr inbounds %List, ptr %0, i32 0, i32 0
%3 = load i32, ptr %2, align 8
%eq = icmp eq i32 %3, %1
br i1 %eq, label %if.then1, label %if.exit2
if.then1: ; preds = %if.exit
ret ptr %0
if.exit2: ; preds = %if.exit
%4 = getelementptr inbounds %List, ptr %0, i32 0, i32 1
%5 = load ptr, ptr %4, align 8
%6 = call ptr @foo_findData(ptr %5, i32 %1)
ret ptr %6
}
define void @foo_doListStuff() #0 {
entry:
%myList = alloca ptr, align 8
store ptr null, ptr %myList, align 8
call void @foo_insertIntoListTail(ptr %myList, i32 100)
call void @foo_insertIntoListTail(ptr %myList, i32 12)
call void @foo_insertIntoListTail(ptr %myList, i32 42)
call void @foo_insertIntoListTail(ptr %myList, i32 1123)
call void @foo_insertIntoListTail(ptr %myList, i32 1213)
%0 = load ptr, ptr %myList, align 8
%1 = call ptr @foo_findData(ptr %0, i32 75)
%ptrbool = icmp ne ptr %1, null
br i1 %ptrbool, label %if.then, label %if.exit
if.then: ; preds = %entry
call void @foundIt()
br label %if.exit
if.exit: ; preds = %if.then, %entry
%2 = load ptr, ptr %myList, align 8
%3 = call ptr @foo_findData(ptr %2, i32 42)
%ptrbool1 = icmp ne ptr %3, null
br i1 %ptrbool1, label %if.then2, label %if.exit3
if.then2: ; preds = %if.exit
call void @foundIt()
br label %if.exit3
if.exit3: ; preds = %if.then2, %if.exit
%4 = load ptr, ptr %myList, align 8
%5 = call ptr @foo_findData(ptr %4, i32 700)
%ptrbool4 = icmp ne ptr %5, null
br i1 %ptrbool4, label %if.then5, label %if.exit6
if.then5: ; preds = %if.exit3
call void @foundIt()
br label %if.exit6
if.exit6: ; preds = %if.then5, %if.exit3
ret void
}
define i32 @foo_floatcomptest(ptr %0, ptr %1, ptr %2, ptr %3) #0 {
entry:
%4 = load double, ptr %0, align 8
%5 = load double, ptr %1, align 8
%lt = fcmp olt double %4, %5
br i1 %lt, label %or.phi, label %or.rhs
or.rhs: ; preds = %entry
%6 = load float, ptr %2, align 4
%7 = load float, ptr %3, align 4
%lt1 = fcmp olt float %6, %7
br label %or.phi
or.phi: ; preds = %or.rhs, %entry
%val = phi i1 [ true, %entry ], [ %lt1, %or.rhs ]
%boolsi = zext i1 %val to i32
ret i32 %boolsi
}
define ptr @foo_memset_impl(ptr %0, i32 %1, i32 %2) #0 {
entry:
%len = alloca i32, align 4
%dstp = alloca i64, align 8
store i32 %2, ptr %len, align 4
%ptrxi = ptrtoint ptr %0 to i64
store i64 %ptrxi, ptr %dstp, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i64, ptr %dstp, align 8
%smod = srem i64 %3, 4
%neq = icmp ne i64 %smod, 0
br i1 %neq, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%4 = load i64, ptr %dstp, align 8
%xiptr = inttoptr i64 %4 to ptr
%ptroffset = getelementptr inbounds i8, ptr %xiptr, i64 0
%siuitrunc = trunc i32 %1 to i8
store i8 %siuitrunc, ptr %ptroffset, align 1
%5 = load i64, ptr %dstp, align 8
%add = add i64 %5, 1
store i64 %add, ptr %dstp, align 8
%6 = load i32, ptr %len, align 4
%sub = sub i32 %6, 1
store i32 %sub, ptr %len, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret ptr %0
}
define internal ptr @foo_localmalloc(i32 %0) #0 {
entry:
%blah = alloca ptr, align 8
store ptr null, ptr %blah, align 8
%1 = load i32, ptr @foo_remaining, align 4
%gt = icmp sgt i32 %0, %1
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
%2 = call ptr @malloc(i32 32768)
store ptr %2, ptr @foo_temp, align 8
store i32 32768, ptr @foo_remaining, align 4
%3 = load ptr, ptr @foo_temp, align 8
ret ptr %3
if.exit: ; preds = %entry
ret ptr null
}
define void @foo_testRetStruct(ptr noalias sret(%PBVTest) align 8 %0, float %1, double %2, i32 %3) #0 {
entry:
%t = alloca %PBVTest, align 8
%4 = getelementptr inbounds %PBVTest, ptr %t, i32 0, i32 0
%fpfpext = fpext float %1 to double
store double %fpfpext, ptr %4, align 8
%5 = getelementptr inbounds %PBVTest, ptr %t, i32 0, i32 1
store double %2, ptr %5, align 8
%6 = getelementptr inbounds %PBVTest, ptr %t, i32 0, i32 2
store i32 %3, ptr %6, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %t, i32 24, i1 false)
ret void
}
define double @foo_callRetStruct(float %0, double %1, i32 %2) #0 {
entry:
%t = alloca %PBVTest, align 8
call void @testRetStruct2(ptr sret(%PBVTest) align 8 %t)
%3 = getelementptr inbounds %PBVTest, ptr %t, i32 0, i32 0
%4 = load double, ptr %3, align 8
%fpfpext = fpext float %0 to double
%fadd = fadd double %4, %fpfpext
%fadd1 = fadd double %fadd, %1
%sifp = sitofp i32 %2 to double
%fadd2 = fadd double %fadd1, %sifp
ret double %fadd2
}
define void @foo___bb_exit_func() #0 {
entry:
%0 = load ptr, ptr @foo_ext, align 8
%ptrbool = icmp ne ptr %0, null
br i1 %ptrbool, label %cond.lhs, label %cond.rhs
cond.lhs: ; preds = %entry
%1 = load ptr, ptr @foo_ext, align 8
br label %cond.phi
cond.rhs: ; preds = %entry
br label %cond.phi
cond.phi: ; preds = %cond.rhs, %cond.lhs
%val = phi ptr [ %1, %cond.lhs ], [ @.str, %cond.rhs ]
%2 = call i32 @fp(i32 12, ptr %val)
ret void
}
define i32 @foo_ptrFunc(ptr %0, i32 %1) #0 {
entry:
%2 = call i32 %0(i32 %1)
ret i32 %2
}
define zeroext i8 @foo_ptrFunc2(ptr byval([30 x ptr]) align 8 %0, i32 %1) #0 {
entry:
%sisiext = sext i32 %1 to i64
%2 = getelementptr inbounds [30 x ptr], ptr %0, i64 0, i64 %sisiext
%3 = load ptr, ptr %2, align 8
%4 = call i32 %3(i32 98)
%siuitrunc = trunc i32 %4 to i8
ret i8 %siuitrunc
}
define zeroext i8 @foo_smallArgs(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) #0 {
entry:
%4 = call i32 @someFuncA()
%uisiext = zext i8 %0 to i32
%sub = sub i32 %uisiext, 1
%siuitrunc = trunc i32 %sub to i8
%uisiext1 = zext i8 %1 to i32
%add = add i32 %uisiext1, 1
%siuitrunc2 = trunc i32 %add to i8
%uisiext3 = zext i8 %2 to i64
%5 = call i8 @smallArgs2(i8 %siuitrunc, i8 %siuitrunc2, i64 %uisiext3, i8 %3, i8 %0)
ret i8 %5
}
define internal i32 @foo_f0(ptr byval(%Quad) align 8 %0, i32 %1) #0 {
entry:
%r = alloca %Quad, align 8
%intbool = icmp ne i32 %1, 0
br i1 %intbool, label %if.then, label %if.exit
if.then: ; preds = %entry
%2 = getelementptr inbounds %Quad, ptr %r, i32 0, i32 1
%3 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 1
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %2, ptr align 4 %3, i32 4, i1 false)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%4 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 2
%5 = getelementptr inbounds %Quad, ptr %r, i32 0, i32 1
store ptr %5, ptr %4, align 8
%6 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 0
%7 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 4
%8 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 3
store i8 1, ptr %8, align 8
store i32 1, ptr %7, align 4
store i32 1, ptr %6, align 8
%9 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 1
%10 = getelementptr inbounds %SubStruct, ptr %9, i32 0, i32 1
%11 = load i16, ptr %10, align 2
%sisiext = sext i16 %11 to i32
%add = add i32 %sisiext, %1
%12 = getelementptr inbounds %Quad, ptr %r, i32 0, i32 4
%13 = load i32, ptr %12, align 4
%add1 = add i32 %add, %13
%14 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 3
%15 = load i8, ptr %14, align 8
%uisiext = zext i8 %15 to i32
%sub = sub i32 %add1, %uisiext
ret i32 %sub
}
define i32 @foo_f1(ptr %0, i32 %1) #0 {
entry:
%r = alloca %Quad, align 8
%intbool = icmp ne i32 %1, 0
br i1 %intbool, label %if.then, label %if.exit
if.then: ; preds = %entry
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %r, ptr align 8 %0, i32 24, i1 false)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%2 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 0
%3 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 4
%4 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 3
store i8 1, ptr %4, align 8
store i32 1, ptr %3, align 4
store i32 1, ptr %2, align 8
%5 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 1
%6 = getelementptr inbounds %SubStruct, ptr %5, i32 0, i32 1
%7 = load i16, ptr %6, align 2
%sisiext = sext i16 %7 to i32
%add = add i32 %sisiext, %1
%8 = getelementptr inbounds %Quad, ptr %r, i32 0, i32 4
%9 = load i32, ptr %8, align 4
%add1 = add i32 %add, %9
%10 = getelementptr inbounds %Quad, ptr %0, i32 0, i32 3
%11 = load i8, ptr %10, align 8
%uisiext = zext i8 %11 to i32
%sub = sub i32 %add1, %uisiext
ret i32 %sub
}
define i32 @foo_badFunc(float %0) #0 {
entry:
%result = alloca i32, align 4
%fpfpext = fpext float %0 to double
%gt = fcmp ogt double %fpfpext, 1.234500e+01
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
store i32 4, ptr %result, align 4
br label %if.exit
if.exit: ; preds = %if.then, %entry
%1 = load i32, ptr %result, align 4
ret i32 %1
}
define i32 @foo_func(i32 %0, i64 %1) #0 {
entry:
%result = alloca i32, align 4
%c = alloca i8, align 1
%x = alloca i32, align 4
%c1 = alloca i8, align 1
%x2 = alloca i32, align 4
store i32 %0, ptr %result, align 4
%2 = call i32 @ef1(ptr %result, ptr %c, ptr %x)
store i8 0, ptr %c1, align 1
store i32 0, ptr %x2, align 4
%3 = call i32 @ef1(ptr %result, ptr %c1, ptr %x2)
%4 = load i32, ptr %result, align 4
ret i32 %4
}
define signext i16 @foo_funFunc(i64 %0, i8 zeroext %1) #0 {
entry:
%uisiext = zext i8 %1 to i64
%add = add i64 %0, %uisiext
%sisitrunc = trunc i64 %add to i16
ret i16 %sisitrunc
}
define i32 @foo_castTest(i32 %0) #0 {
entry:
ret i32 %0
}
define double @foo_testAdd(double %0, float %1) #0 {
entry:
%fpfpext = fpext float %1 to double
%fadd = fadd double %0, %fpfpext
%fadd1 = fadd double %fadd, 5.000000e-01
ret double %fadd1
}
define i32 @foo_funcZ(i32 %0, i32 %1) #0 {
entry:
%i = alloca i32, align 4
%j = alloca i32, align 4
store i32 %0, ptr %i, align 4
store i32 %1, ptr %j, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load i32, ptr %i, align 4
%neq = icmp ne i32 %2, 20
br i1 %neq, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%3 = load i32, ptr %i, align 4
%add = add i32 %3, 2
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%4 = load i32, ptr %j, align 4
%5 = load i32, ptr %i, align 4
%6 = call i32 @foo_funcZ(i32 2, i32 %5)
%add1 = add i32 %4, %6
store i32 %add1, ptr %j, align 4
%7 = load i32, ptr %i, align 4
%mul = mul i32 %7, 3
%8 = load i32, ptr %j, align 4
%mul2 = mul i32 %8, 2
%add3 = add i32 %mul, %mul2
%9 = load i32, ptr %j, align 4
%mul4 = mul i32 %add3, %9
ret i32 %mul4
}
define i32 @foo_sumArray(ptr %0, i32 %1) #0 {
entry:
%i = alloca i32, align 4
%result = alloca i32, align 4
store i32 0, ptr %result, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load i32, ptr %i, align 4
%lt = icmp slt i32 %2, %1
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%3 = load i32, ptr %result, align 4
%4 = load i32, ptr %i, align 4
%sisiext = sext i32 %4 to i64
%ptroffset = getelementptr inbounds i32, ptr %0, i64 %sisiext
%5 = load i32, ptr %ptroffset, align 4
%add = add i32 %3, %5
store i32 %add, ptr %result, align 4
%6 = load i32, ptr %i, align 4
%add1 = add i32 %6, 1
store i32 %add1, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%7 = load i32, ptr %result, align 4
ret i32 %7
}
define i32 @foo_arrayParam(ptr %0) #0 {
entry:
%ptroffset = getelementptr inbounds i32, ptr %0, i64 50
%1 = load i32, ptr %ptroffset, align 4
%sisiext = sext i32 %1 to i64
%xiptr = inttoptr i64 %sisiext to ptr
%ptroffset1 = getelementptr inbounds i32, ptr %0, i64 50
%2 = call i32 @ef1(ptr %xiptr, ptr inttoptr (i64 1 to ptr), ptr %ptroffset1)
ret i32 %2
}
define i32 @foo_arrayToSum() #0 {
entry:
%a = alloca [100 x i32], align 16
%i = alloca i32, align 4
store i32 0, ptr %i, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%0 = load i32, ptr %i, align 4
%lt = icmp slt i32 %0, 100
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%1 = load i32, ptr %i, align 4
%sisiext = sext i32 %1 to i64
%2 = getelementptr inbounds [100 x i32], ptr %a, i64 0, i64 %sisiext
%3 = load i32, ptr %i, align 4
%mul = mul i32 %3, 4
store i32 %mul, ptr %2, align 4
%4 = load i32, ptr %i, align 4
%add = add i32 %4, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%5 = getelementptr inbounds [100 x i32], ptr %a, i64 0, i64 0
%6 = load i32, ptr %5, align 4
%sisiext1 = sext i32 %6 to i64
%7 = getelementptr inbounds [100 x i32], ptr %a, i64 0, i64 %sisiext1
%8 = load i32, ptr %7, align 4
ret i32 %8
}
define i32 @main(i32 %0, ptr %1) #0 {
entry:
%i = alloca i32, align 4
%2 = call i32 @puts(ptr @.str.10)
%sisitrunc = trunc i32 %0 to i16
%3 = call i32 @foo_externFunc(i64 -1, ptr null, i16 %sisitrunc, i8 2)
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%4 = load i32, ptr %i, align 4
%gt = icmp ugt i32 10, %4
br i1 %gt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%ptroffset = getelementptr inbounds ptr, ptr %1, i64 3
%5 = load ptr, ptr %ptroffset, align 8
%6 = call i32 @puts(ptr %5)
%7 = load i32, ptr %i, align 4
%add = add i32 %7, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret i32 0
}
define double @foo_mathFunc(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, double %9, double %10, double %11, double %12, double %13, double %14, double %15, double %16) #0 {
entry:
%fadd = fadd double %0, %1
%fadd1 = fadd double %fadd, %2
%fadd2 = fadd double %fadd1, %3
%fadd3 = fadd double %fadd2, %4
%fadd4 = fadd double %fadd3, %5
%fadd5 = fadd double %fadd4, %6
%fadd6 = fadd double %fadd5, %7
%fadd7 = fadd double %fadd6, %8
%fadd8 = fadd double %fadd7, %9
%fadd9 = fadd double %fadd8, %10
%fadd10 = fadd double %fadd9, %11
%fadd11 = fadd double %fadd10, %12
%fadd12 = fadd double %fadd11, %13
%fadd13 = fadd double %fadd12, %14
%fadd14 = fadd double %fadd13, %15
%fadd15 = fadd double %fadd14, %16
ret double %fadd15
}
define void @foo_strcpy(ptr %0, ptr %1) #0 {
entry:
%s1 = alloca ptr, align 8
%s2 = alloca ptr, align 8
store ptr %0, ptr %s1, align 8
store ptr %1, ptr %s2, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load ptr, ptr %s1, align 8
%ptroffset = getelementptr i8, ptr %2, i8 1
store ptr %ptroffset, ptr %s1, align 8
%3 = load ptr, ptr %s2, align 8
%ptroffset1 = getelementptr i8, ptr %3, i8 1
store ptr %ptroffset1, ptr %s2, align 8
%4 = load i8, ptr %3, align 1
store i8 %4, ptr %2, align 1
%intbool = icmp ne i8 %4, 0
br i1 %intbool, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret void
}
define void @foo_strcat(ptr %0, ptr %1) #0 {
entry:
%s1 = alloca ptr, align 8
%s2 = alloca ptr, align 8
store ptr %0, ptr %s1, align 8
store ptr %1, ptr %s2, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load ptr, ptr %s1, align 8
%ptroffset = getelementptr i8, ptr %2, i8 1
store ptr %ptroffset, ptr %s1, align 8
%3 = load i8, ptr %2, align 1
%intbool = icmp ne i8 %3, 0
br i1 %intbool, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
%4 = load ptr, ptr %s1, align 8
%ptroffset1 = getelementptr i8, ptr %4, i8 -1
store ptr %ptroffset1, ptr %s1, align 8
br label %loop.cond2
loop.cond2: ; preds = %loop.body6, %loop.exit
%5 = load ptr, ptr %s1, align 8
%ptroffset3 = getelementptr i8, ptr %5, i8 1
store ptr %ptroffset3, ptr %s1, align 8
%6 = load ptr, ptr %s2, align 8
%ptroffset4 = getelementptr i8, ptr %6, i8 1
store ptr %ptroffset4, ptr %s2, align 8
%7 = load i8, ptr %6, align 1
store i8 %7, ptr %5, align 1
%intbool5 = icmp ne i8 %7, 0
br i1 %intbool5, label %loop.body6, label %loop.exit7
loop.body6: ; preds = %loop.cond2
br label %loop.cond2
loop.exit7: ; preds = %loop.cond2
ret void
}
define i32 @foo_strcmp(ptr %0, ptr %1) #0 {
entry:
%s1 = alloca ptr, align 8
%s2 = alloca ptr, align 8
store ptr %0, ptr %s1, align 8
store ptr %1, ptr %s2, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load ptr, ptr %s1, align 8
%ptroffset = getelementptr i8, ptr %2, i8 1
store ptr %ptroffset, ptr %s1, align 8
%3 = load i8, ptr %2, align 1
%4 = load ptr, ptr %s2, align 8
%ptroffset1 = getelementptr i8, ptr %4, i8 1
store ptr %ptroffset1, ptr %s2, align 8
%5 = load i8, ptr %4, align 1
%eq = icmp eq i8 %3, %5
br i1 %eq, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
%6 = load ptr, ptr %s1, align 8
%7 = load i8, ptr %6, align 1
%zext = zext i8 %7 to i32
%eq2 = icmp eq i32 0, %zext
br i1 %eq2, label %if.then, label %if.else6
if.then: ; preds = %loop.exit
%8 = load ptr, ptr %s2, align 8
%9 = load i8, ptr %8, align 1
%zext3 = zext i8 %9 to i32
%eq4 = icmp eq i32 0, %zext3
br i1 %eq4, label %if.then5, label %if.else
if.then5: ; preds = %if.then
ret i32 0
if.else: ; preds = %if.then
ret i32 -1
if.else6: ; preds = %loop.exit
%10 = load ptr, ptr %s2, align 8
%11 = load i8, ptr %10, align 1
%zext7 = zext i8 %11 to i32
%eq8 = icmp eq i32 0, %zext7
br i1 %eq8, label %if.then9, label %if.else10
if.then9: ; preds = %if.else6
ret i32 1
if.else10: ; preds = %if.else6
%12 = load ptr, ptr %s1, align 8
%ptroffset11 = getelementptr i8, ptr %12, i8 -1
store ptr %ptroffset11, ptr %s1, align 8
%13 = load i8, ptr %ptroffset11, align 1
%uisiext = zext i8 %13 to i32
%14 = load ptr, ptr %s2, align 8
%ptroffset12 = getelementptr i8, ptr %14, i8 -1
store ptr %ptroffset12, ptr %s2, align 8
%15 = load i8, ptr %ptroffset12, align 1
%uisiext13 = zext i8 %15 to i32
%sub = sub i32 %uisiext, %uisiext13
ret i32 %sub
}

View File

@@ -103,16 +103,14 @@ fn void main()
define void @test_hello(i32 %0, double %1, i64 %2, i64 %3, ptr %4, i64 %5) #0 {
entry:
%d = alloca [4 x i32], align 4
%d = alloca [4 x i32], align 8
%args = alloca %"variant[]", align 8
%6 = getelementptr inbounds { i64, i64 }, ptr %d, i32 0, i32 0
store i64 %2, ptr %6, align 4
%7 = getelementptr inbounds { i64, i64 }, ptr %d, i32 0, i32 1
store i64 %3, ptr %7, align 4
%8 = getelementptr inbounds { ptr, i64 }, ptr %args, i32 0, i32 0
store ptr %4, ptr %8, align 8
%9 = getelementptr inbounds { ptr, i64 }, ptr %args, i32 0, i32 1
store i64 %5, ptr %9, align 8
store i64 %2, ptr %d, align 8
%ptroffset = getelementptr inbounds i64, ptr %d, i64 1
store i64 %3, ptr %ptroffset, align 8
store ptr %4, ptr %args, align 8
%ptroffset1 = getelementptr inbounds i64, ptr %args, i64 1
store i64 %5, ptr %ptroffset1, align 8
ret void
}

View File

@@ -54,25 +54,24 @@ entry:
%retparam = alloca i64, align 8
%varargslots = alloca [3 x %variant], align 16
store i64 %0, ptr %a, align 4
%4 = getelementptr inbounds { ptr, i64 }, ptr %b, i32 0, i32 0
store ptr %1, ptr %4, align 8
%5 = getelementptr inbounds { ptr, i64 }, ptr %b, i32 0, i32 1
store i64 %2, ptr %5, align 8
store ptr %1, ptr %b, align 8
%ptroffset = getelementptr inbounds i64, ptr %b, i64 1
store i64 %2, ptr %ptroffset, align 8
store double %3, ptr %c, align 8
%6 = insertvalue %variant undef, ptr %a, 0
%7 = insertvalue %variant %6, i64 ptrtoint (ptr @"ct$a2$int" to i64), 1
%8 = getelementptr inbounds [3 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %7, ptr %8, align 16
%9 = insertvalue %variant undef, ptr %b, 0
%10 = insertvalue %variant %9, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1
%11 = getelementptr inbounds [3 x %variant], ptr %varargslots, i64 0, i64 1
store %variant %10, ptr %11, align 16
%12 = insertvalue %variant undef, ptr %c, 0
%13 = insertvalue %variant %12, i64 ptrtoint (ptr @"ct$v2$int" to i64), 1
%14 = getelementptr inbounds [3 x %variant], ptr %varargslots, i64 0, i64 2
store %variant %13, ptr %14, align 16
%15 = call i64 @std_io_printfn(ptr %retparam, ptr @.str, i64 8, ptr %varargslots, i64 3)
%not_err = icmp eq i64 %15, 0
%4 = insertvalue %variant undef, ptr %a, 0
%5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$a2$int" to i64), 1
%6 = getelementptr inbounds [3 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %5, ptr %6, align 16
%7 = insertvalue %variant undef, ptr %b, 0
%8 = insertvalue %variant %7, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1
%9 = getelementptr inbounds [3 x %variant], ptr %varargslots, i64 0, i64 1
store %variant %8, ptr %9, align 16
%10 = insertvalue %variant undef, ptr %c, 0
%11 = insertvalue %variant %10, i64 ptrtoint (ptr @"ct$v2$int" to i64), 1
%12 = getelementptr inbounds [3 x %variant], ptr %varargslots, i64 0, i64 2
store %variant %11, ptr %12, align 16
%13 = call i64 @std_io_printfn(ptr %retparam, ptr @.str, i64 8, ptr %varargslots, i64 3)
%not_err = icmp eq i64 %13, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry

View File

@@ -59,22 +59,21 @@ entry:
%z = alloca %"char[]", align 8
%retparam = alloca i64, align 8
%varargslots = alloca [1 x %variant], align 16
%2 = getelementptr inbounds { ptr, i64 }, ptr %args, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %args, i32 0, i32 1
store i64 %1, ptr %3, align 8
store ptr %0, ptr %args, align 8
%ptroffset = getelementptr inbounds i64, ptr %args, i64 1
store i64 %1, ptr %ptroffset, align 8
store i64 ptrtoint (ptr @"ct$abc_Abc" to i64), ptr %y, align 8
store ptr @abc_dabc, ptr %x, align 8
store i32 1, ptr %a, align 4
%4 = load i32, ptr %a, align 4
%5 = getelementptr inbounds [2 x %"char[]"], ptr @"abc_Foo$val", i32 0, i32 %4
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %z, ptr align 8 %5, i32 16, i1 false)
%6 = insertvalue %variant undef, ptr %z, 0
%7 = insertvalue %variant %6, i64 ptrtoint (ptr @"ct$sa$char" to i64), 1
%8 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %7, ptr %8, align 16
%9 = call i64 @std_io_printfn(ptr %retparam, ptr @.str.2, i64 2, ptr %varargslots, i64 1)
%not_err = icmp eq i64 %9, 0
%2 = load i32, ptr %a, align 4
%3 = getelementptr inbounds [2 x %"char[]"], ptr @"abc_Foo$val", i32 0, i32 %2
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %z, ptr align 8 %3, i32 16, i1 false)
%4 = insertvalue %variant undef, ptr %z, 0
%5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$sa$char" to i64), 1
%6 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %5, ptr %6, align 16
%7 = call i64 @std_io_printfn(ptr %retparam, ptr @.str.2, i64 2, ptr %varargslots, i64 1)
%not_err = icmp eq i64 %7, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry

View File

@@ -191,69 +191,67 @@ entry:
%len = alloca i64, align 8
%needle_len = alloca i64, align 8
%i = alloca i64, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %haystack, i32 0, i32 0
store ptr %0, ptr %4, align 8
%5 = getelementptr inbounds { ptr, i64 }, ptr %haystack, i32 0, i32 1
store i64 %1, ptr %5, align 8
%6 = getelementptr inbounds { ptr, i64 }, ptr %needle, i32 0, i32 0
store ptr %2, ptr %6, align 8
%7 = getelementptr inbounds { ptr, i64 }, ptr %needle, i32 0, i32 1
store i64 %3, ptr %7, align 8
%8 = getelementptr inbounds %"char[]", ptr %haystack, i32 0, i32 1
%9 = load i64, ptr %8, align 8
store i64 %9, ptr %len, align 8
%10 = getelementptr inbounds %"char[]", ptr %needle, i32 0, i32 1
%11 = load i64, ptr %10, align 8
store i64 %11, ptr %needle_len, align 8
%12 = load i64, ptr %len, align 8
%13 = load i64, ptr %needle_len, align 8
%lt = icmp ult i64 %12, %13
store ptr %0, ptr %haystack, align 8
%ptroffset = getelementptr inbounds i64, ptr %haystack, i64 1
store i64 %1, ptr %ptroffset, align 8
store ptr %2, ptr %needle, align 8
%ptroffset1 = getelementptr inbounds i64, ptr %needle, i64 1
store i64 %3, ptr %ptroffset1, align 8
%4 = getelementptr inbounds %"char[]", ptr %haystack, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %len, align 8
%6 = getelementptr inbounds %"char[]", ptr %needle, i32 0, i32 1
%7 = load i64, ptr %6, align 8
store i64 %7, ptr %needle_len, align 8
%8 = load i64, ptr %len, align 8
%9 = load i64, ptr %needle_len, align 8
%lt = icmp ult i64 %8, %9
br i1 %lt, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i8 0
if.exit: ; preds = %entry
%14 = load i64, ptr %needle_len, align 8
%not = icmp eq i64 %14, 0
br i1 %not, label %if.then1, label %if.exit2
%10 = load i64, ptr %needle_len, align 8
%not = icmp eq i64 %10, 0
br i1 %not, label %if.then2, label %if.exit3
if.then1: ; preds = %if.exit
if.then2: ; preds = %if.exit
ret i8 1
if.exit2: ; preds = %if.exit
%15 = load i64, ptr %len, align 8
%16 = load i64, ptr %needle_len, align 8
%sub = sub i64 %16, 1
%sub3 = sub i64 %15, %sub
store i64 %sub3, ptr %len, align 8
if.exit3: ; preds = %if.exit
%11 = load i64, ptr %len, align 8
%12 = load i64, ptr %needle_len, align 8
%sub = sub i64 %12, 1
%sub4 = sub i64 %11, %sub
store i64 %sub4, ptr %len, align 8
store i64 0, ptr %i, align 8
br label %loop.cond
loop.cond: ; preds = %if.exit6, %if.exit2
%17 = load i64, ptr %i, align 8
%18 = load i64, ptr %len, align 8
%lt4 = icmp ult i64 %17, %18
br i1 %lt4, label %loop.body, label %loop.exit
loop.cond: ; preds = %if.exit8, %if.exit3
%13 = load i64, ptr %i, align 8
%14 = load i64, ptr %len, align 8
%lt5 = icmp ult i64 %13, %14
br i1 %lt5, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%19 = getelementptr inbounds %"char[]", ptr %haystack, i32 0, i32 0
%20 = load ptr, ptr %19, align 8
%21 = load i64, ptr %i, align 8
%ptroffset = getelementptr inbounds i8, ptr %20, i64 %21
%22 = getelementptr inbounds %"char[]", ptr %needle, i32 0, i32 0
%23 = load ptr, ptr %22, align 8
%24 = load i64, ptr %needle_len, align 8
%25 = call i32 @memcmp(ptr %ptroffset, ptr %23, i64 %24)
%eq = icmp eq i32 %25, 0
br i1 %eq, label %if.then5, label %if.exit6
%15 = getelementptr inbounds %"char[]", ptr %haystack, i32 0, i32 0
%16 = load ptr, ptr %15, align 8
%17 = load i64, ptr %i, align 8
%ptroffset6 = getelementptr inbounds i8, ptr %16, i64 %17
%18 = getelementptr inbounds %"char[]", ptr %needle, i32 0, i32 0
%19 = load ptr, ptr %18, align 8
%20 = load i64, ptr %needle_len, align 8
%21 = call i32 @memcmp(ptr %ptroffset6, ptr %19, i64 %20)
%eq = icmp eq i32 %21, 0
br i1 %eq, label %if.then7, label %if.exit8
if.then5: ; preds = %loop.body
if.then7: ; preds = %loop.body
ret i8 1
if.exit6: ; preds = %loop.body
%26 = load i64, ptr %i, align 8
%add = add i64 %26, 1
if.exit8: ; preds = %loop.body
%22 = load i64, ptr %i, align 8
%add = add i64 %22, 1
store i64 %add, ptr %i, align 8
br label %loop.cond
@@ -291,56 +289,55 @@ entry:
%literal47 = alloca %Head, align 8
%error_var48 = alloca i64, align 8
%value49 = alloca %"char[]", align 8
%temp50 = alloca ptr, align 8
%temp56 = alloca ptr, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %url, i32 0, i32 0
store ptr %1, ptr %3, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %url, i32 0, i32 1
store i64 %2, ptr %4, align 8
%5 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %5, align 8
%6 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi = load i64, ptr %6, align 8
%7 = call i8 @test_contains(ptr %lo, i64 %hi, ptr @.str, i64 4)
%8 = trunc i8 %7 to i1
br i1 %8, label %if.then, label %if.exit
%temp51 = alloca ptr, align 8
%temp57 = alloca ptr, align 8
store ptr %1, ptr %url, align 8
%ptroffset = getelementptr inbounds i64, ptr %url, i64 1
store i64 %2, ptr %ptroffset, align 8
%3 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %3, align 8
%4 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi = load i64, ptr %4, align 8
%5 = call i8 @test_contains(ptr %lo, i64 %hi, ptr @.str, i64 4)
%6 = trunc i8 %5 to i1
br i1 %6, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i64 ptrtoint (ptr @"test_ReadError$BAD_READ" to i64)
if.exit: ; preds = %entry
%9 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo1 = load ptr, ptr %9, align 8
%10 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi2 = load i64, ptr %10, align 8
%11 = call i8 @test_contains(ptr %lo1, i64 %hi2, ptr @.str.3, i64 12)
%12 = trunc i8 %11 to i1
br i1 %12, label %if.then3, label %if.exit4
%7 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo1 = load ptr, ptr %7, align 8
%8 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi2 = load i64, ptr %8, align 8
%9 = call i8 @test_contains(ptr %lo1, i64 %hi2, ptr @.str.3, i64 12)
%10 = trunc i8 %9 to i1
br i1 %10, label %if.then3, label %if.exit4
if.then3: ; preds = %if.exit
%13 = getelementptr inbounds %Doc, ptr %literal, i32 0, i32 0
store ptr null, ptr %13, align 8
%11 = getelementptr inbounds %Doc, ptr %literal, i32 0, i32 0
store ptr null, ptr %11, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal, i32 8, i1 false)
ret i64 0
if.exit4: ; preds = %if.exit
%14 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo5 = load ptr, ptr %14, align 8
%15 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi6 = load i64, ptr %15, align 8
%16 = call i8 @test_contains(ptr %lo5, i64 %hi6, ptr @.str.4, i64 13)
%17 = trunc i8 %16 to i1
br i1 %17, label %if.then7, label %if.exit13
%12 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo5 = load ptr, ptr %12, align 8
%13 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi6 = load i64, ptr %13, align 8
%14 = call i8 @test_contains(ptr %lo5, i64 %hi6, ptr @.str.4, i64 13)
%15 = trunc i8 %14 to i1
br i1 %15, label %if.then7, label %if.exit13
if.then7: ; preds = %if.exit4
%18 = getelementptr inbounds %Doc, ptr %literal9, i32 0, i32 0
%19 = getelementptr inbounds %Head, ptr %literal10, i32 0, i32 0
store ptr null, ptr %19, align 8
%16 = getelementptr inbounds %Doc, ptr %literal9, i32 0, i32 0
%17 = getelementptr inbounds %Head, ptr %literal10, i32 0, i32 0
store ptr null, ptr %17, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value, ptr align 8 %literal10, i32 8, i1 false)
%20 = call ptr @std_core_mem_malloc(i64 8) #2
store ptr %20, ptr %temp, align 8
%21 = load ptr, ptr %temp, align 8
%not = icmp eq ptr %21, null
%18 = call ptr @std_core_mem_malloc(i64 8) #2
store ptr %18, ptr %temp, align 8
%19 = load ptr, ptr %temp, align 8
%not = icmp eq ptr %19, null
br i1 %not, label %if.then11, label %if.exit12
if.then11: ; preds = %if.then7
@@ -348,38 +345,38 @@ if.then11: ; preds = %if.then7
br label %guard_block
if.exit12: ; preds = %if.then7
%22 = load ptr, ptr %temp, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %22, ptr align 8 %value, i32 8, i1 false)
%20 = load ptr, ptr %temp, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %20, ptr align 8 %value, i32 8, i1 false)
br label %noerr_block
guard_block: ; preds = %if.then11
%23 = load i64, ptr %error_var, align 8
ret i64 %23
%21 = load i64, ptr %error_var, align 8
ret i64 %21
noerr_block: ; preds = %if.exit12
%24 = load ptr, ptr %temp, align 8
store ptr %24, ptr %18, align 8
%22 = load ptr, ptr %temp, align 8
store ptr %22, ptr %16, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal9, i32 8, i1 false)
ret i64 0
if.exit13: ; preds = %if.exit4
%25 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo14 = load ptr, ptr %25, align 8
%26 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi15 = load i64, ptr %26, align 8
%27 = call i8 @test_contains(ptr %lo14, i64 %hi15, ptr @.str.5, i64 11)
%28 = trunc i8 %27 to i1
br i1 %28, label %if.then16, label %if.exit36
%23 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo14 = load ptr, ptr %23, align 8
%24 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi15 = load i64, ptr %24, align 8
%25 = call i8 @test_contains(ptr %lo14, i64 %hi15, ptr @.str.5, i64 11)
%26 = trunc i8 %25 to i1
br i1 %26, label %if.then16, label %if.exit36
if.then16: ; preds = %if.exit13
%29 = getelementptr inbounds %Doc, ptr %literal18, i32 0, i32 0
%27 = getelementptr inbounds %Doc, ptr %literal18, i32 0, i32 0
store ptr null, ptr %literal21, align 8
%30 = getelementptr inbounds %Head, ptr %literal21, i32 0, i32 0
%28 = getelementptr inbounds %Head, ptr %literal21, i32 0, i32 0
store %"char[]" zeroinitializer, ptr %value23, align 8
%31 = call ptr @std_core_mem_malloc(i64 16) #2
store ptr %31, ptr %temp24, align 8
%32 = load ptr, ptr %temp24, align 8
%not25 = icmp eq ptr %32, null
%29 = call ptr @std_core_mem_malloc(i64 16) #2
store ptr %29, ptr %temp24, align 8
%30 = load ptr, ptr %temp24, align 8
%not25 = icmp eq ptr %30, null
br i1 %not25, label %if.then26, label %if.exit27
if.then26: ; preds = %if.then16
@@ -387,22 +384,22 @@ if.then26: ; preds = %if.then16
br label %guard_block28
if.exit27: ; preds = %if.then16
%33 = load ptr, ptr %temp24, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %33, ptr align 8 %value23, i32 16, i1 false)
%31 = load ptr, ptr %temp24, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %31, ptr align 8 %value23, i32 16, i1 false)
br label %noerr_block29
guard_block28: ; preds = %if.then26
%34 = load i64, ptr %error_var22, align 8
ret i64 %34
%32 = load i64, ptr %error_var22, align 8
ret i64 %32
noerr_block29: ; preds = %if.exit27
%35 = load ptr, ptr %temp24, align 8
store ptr %35, ptr %30, align 8
%33 = load ptr, ptr %temp24, align 8
store ptr %33, ptr %28, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value20, ptr align 8 %literal21, i32 8, i1 false)
%36 = call ptr @std_core_mem_malloc(i64 8) #2
store ptr %36, ptr %temp30, align 8
%37 = load ptr, ptr %temp30, align 8
%not31 = icmp eq ptr %37, null
%34 = call ptr @std_core_mem_malloc(i64 8) #2
store ptr %34, ptr %temp30, align 8
%35 = load ptr, ptr %temp30, align 8
%not31 = icmp eq ptr %35, null
br i1 %not31, label %if.then32, label %if.exit33
if.then32: ; preds = %noerr_block29
@@ -410,109 +407,109 @@ if.then32: ; preds = %noerr_block29
br label %guard_block34
if.exit33: ; preds = %noerr_block29
%38 = load ptr, ptr %temp30, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %38, ptr align 8 %value20, i32 8, i1 false)
%36 = load ptr, ptr %temp30, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %36, ptr align 8 %value20, i32 8, i1 false)
br label %noerr_block35
guard_block34: ; preds = %if.then32
%39 = load i64, ptr %error_var19, align 8
ret i64 %39
%37 = load i64, ptr %error_var19, align 8
ret i64 %37
noerr_block35: ; preds = %if.exit33
%40 = load ptr, ptr %temp30, align 8
store ptr %40, ptr %29, align 8
%38 = load ptr, ptr %temp30, align 8
store ptr %38, ptr %27, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal18, i32 8, i1 false)
ret i64 0
if.exit36: ; preds = %if.exit13
%41 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%42 = load i64, ptr %41, align 8
%uisitrunc = trunc i64 %42 to i32
%43 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%44 = load ptr, ptr %43, align 8
%45 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %uisitrunc, ptr %44)
store i32 %45, ptr %len, align 4
%46 = load i32, ptr %len, align 4
%siuiext = sext i32 %46 to i64
%39 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%40 = load i64, ptr %39, align 8
%uisitrunc = trunc i64 %40 to i32
%41 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%42 = load ptr, ptr %41, align 8
%43 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %uisitrunc, ptr %42)
store i32 %43, ptr %len, align 4
%44 = load i32, ptr %len, align 4
%siuiext = sext i32 %44 to i64
%add = add i64 %siuiext, 1
%47 = call ptr @std_core_mem_malloc(i64 %add) #2
store ptr %47, ptr %str, align 8
%48 = load ptr, ptr %str, align 8
%not37 = icmp eq ptr %48, null
%45 = call ptr @std_core_mem_malloc(i64 %add) #2
store ptr %45, ptr %str, align 8
%46 = load ptr, ptr %str, align 8
%not37 = icmp eq ptr %46, null
br i1 %not37, label %if.then38, label %if.exit39
if.then38: ; preds = %if.exit36
ret i64 ptrtoint (ptr @"test_ReadError$OUT_OF_MEMORY" to i64)
if.exit39: ; preds = %if.exit36
%49 = load ptr, ptr %str, align 8
%50 = load i32, ptr %len, align 4
%siuiext40 = sext i32 %50 to i64
%47 = load ptr, ptr %str, align 8
%48 = load i32, ptr %len, align 4
%siuiext40 = sext i32 %48 to i64
%add41 = add i64 %siuiext40, 1
%51 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%52 = load i64, ptr %51, align 8
%uisitrunc42 = trunc i64 %52 to i32
%53 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%54 = load ptr, ptr %53, align 8
%55 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %49, i64 %add41, ptr @.str.8, i32 %uisitrunc42, ptr %54)
%56 = getelementptr inbounds %Doc, ptr %literal44, i32 0, i32 0
%49 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%50 = load i64, ptr %49, align 8
%uisitrunc42 = trunc i64 %50 to i32
%51 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%52 = load ptr, ptr %51, align 8
%53 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %47, i64 %add41, ptr @.str.8, i32 %uisitrunc42, ptr %52)
%54 = getelementptr inbounds %Doc, ptr %literal44, i32 0, i32 0
store ptr null, ptr %literal47, align 8
%57 = getelementptr inbounds %Head, ptr %literal47, i32 0, i32 0
%58 = load ptr, ptr %str, align 8
%59 = load i32, ptr %len, align 4
%sub = sub i32 %59, 1
%55 = getelementptr inbounds %Head, ptr %literal47, i32 0, i32 0
%56 = load ptr, ptr %str, align 8
%57 = load i32, ptr %len, align 4
%sub = sub i32 %57, 1
%sisiext = sext i32 %sub to i64
%60 = add i64 %sisiext, 1
%size = sub i64 %60, 0
%ptroffset = getelementptr inbounds i8, ptr %58, i64 0
%61 = insertvalue %"char[]" undef, ptr %ptroffset, 0
%62 = insertvalue %"char[]" %61, i64 %size, 1
store %"char[]" %62, ptr %value49, align 8
%63 = call ptr @std_core_mem_malloc(i64 16) #2
store ptr %63, ptr %temp50, align 8
%64 = load ptr, ptr %temp50, align 8
%not51 = icmp eq ptr %64, null
br i1 %not51, label %if.then52, label %if.exit53
%58 = add i64 %sisiext, 1
%size = sub i64 %58, 0
%ptroffset50 = getelementptr inbounds i8, ptr %56, i64 0
%59 = insertvalue %"char[]" undef, ptr %ptroffset50, 0
%60 = insertvalue %"char[]" %59, i64 %size, 1
store %"char[]" %60, ptr %value49, align 8
%61 = call ptr @std_core_mem_malloc(i64 16) #2
store ptr %61, ptr %temp51, align 8
%62 = load ptr, ptr %temp51, align 8
%not52 = icmp eq ptr %62, null
br i1 %not52, label %if.then53, label %if.exit54
if.then52: ; preds = %if.exit39
if.then53: ; preds = %if.exit39
store i64 ptrtoint (ptr @"test_ReadError$OUT_OF_MEMORY" to i64), ptr %error_var48, align 8
br label %guard_block54
br label %guard_block55
if.exit53: ; preds = %if.exit39
%65 = load ptr, ptr %temp50, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %65, ptr align 8 %value49, i32 16, i1 false)
br label %noerr_block55
if.exit54: ; preds = %if.exit39
%63 = load ptr, ptr %temp51, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %63, ptr align 8 %value49, i32 16, i1 false)
br label %noerr_block56
guard_block54: ; preds = %if.then52
%66 = load i64, ptr %error_var48, align 8
ret i64 %66
guard_block55: ; preds = %if.then53
%64 = load i64, ptr %error_var48, align 8
ret i64 %64
noerr_block55: ; preds = %if.exit53
%67 = load ptr, ptr %temp50, align 8
store ptr %67, ptr %57, align 8
noerr_block56: ; preds = %if.exit54
%65 = load ptr, ptr %temp51, align 8
store ptr %65, ptr %55, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value46, ptr align 8 %literal47, i32 8, i1 false)
%68 = call ptr @std_core_mem_malloc(i64 8) #2
store ptr %68, ptr %temp56, align 8
%69 = load ptr, ptr %temp56, align 8
%not57 = icmp eq ptr %69, null
br i1 %not57, label %if.then58, label %if.exit59
%66 = call ptr @std_core_mem_malloc(i64 8) #2
store ptr %66, ptr %temp57, align 8
%67 = load ptr, ptr %temp57, align 8
%not58 = icmp eq ptr %67, null
br i1 %not58, label %if.then59, label %if.exit60
if.then58: ; preds = %noerr_block55
if.then59: ; preds = %noerr_block56
store i64 ptrtoint (ptr @"test_ReadError$OUT_OF_MEMORY" to i64), ptr %error_var45, align 8
br label %guard_block60
br label %guard_block61
if.exit59: ; preds = %noerr_block55
%70 = load ptr, ptr %temp56, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %70, ptr align 8 %value46, i32 8, i1 false)
br label %noerr_block61
if.exit60: ; preds = %noerr_block56
%68 = load ptr, ptr %temp57, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %68, ptr align 8 %value46, i32 8, i1 false)
br label %noerr_block62
guard_block60: ; preds = %if.then58
%71 = load i64, ptr %error_var45, align 8
ret i64 %71
guard_block61: ; preds = %if.then59
%69 = load i64, ptr %error_var45, align 8
ret i64 %69
noerr_block61: ; preds = %if.exit59
%72 = load ptr, ptr %temp56, align 8
store ptr %72, ptr %56, align 8
noerr_block62: ; preds = %if.exit60
%70 = load ptr, ptr %temp57, align 8
store ptr %70, ptr %54, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal44, i32 8, i1 false)
ret i64 0
}
@@ -522,35 +519,34 @@ define { ptr, i8 } @test_buildSummary(ptr %0) #0 {
entry:
%doc = alloca %Doc, align 8
%literal = alloca %Summary, align 8
%1 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
store ptr %0, ptr %1, align 8
%2 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 0
store ptr null, ptr %2, align 8
%3 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 1
store i8 0, ptr %3, align 8
%4 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 0
%5 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
%ptrbool = icmp ne ptr %6, null
store ptr %0, ptr %doc, align 8
%1 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 0
store ptr null, ptr %1, align 8
%2 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 1
store i8 0, ptr %2, align 8
%3 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 0
%4 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%ptrbool = icmp ne ptr %5, null
br i1 %ptrbool, label %cond.lhs, label %cond.rhs
cond.lhs: ; preds = %entry
%7 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
%9 = getelementptr inbounds %Head, ptr %8, i32 0, i32 0
%10 = load ptr, ptr %9, align 8
%6 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%8 = getelementptr inbounds %Head, ptr %7, i32 0, i32 0
%9 = load ptr, ptr %8, align 8
br label %cond.phi
cond.rhs: ; preds = %entry
br label %cond.phi
cond.phi: ; preds = %cond.rhs, %cond.lhs
%val = phi ptr [ %10, %cond.lhs ], [ null, %cond.rhs ]
store ptr %val, ptr %4, align 8
%11 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 1
store i8 1, ptr %11, align 8
%12 = load { ptr, i8 }, ptr %literal, align 8
ret { ptr, i8 } %12
%val = phi ptr [ %9, %cond.lhs ], [ null, %cond.rhs ]
store ptr %val, ptr %3, align 8
%10 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 1
store i8 1, ptr %10, align 8
%11 = load { ptr, i8 }, ptr %literal, align 8
ret { ptr, i8 } %11
}
; Function Attrs: nounwind
@@ -561,39 +557,37 @@ entry:
%result = alloca %Summary, align 8
%literal = alloca %Summary, align 8
%taddr = alloca %Summary, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %url, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %url, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %4, align 8
%5 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi = load i64, ptr %5, align 8
%6 = call i64 @test_readDoc(ptr %retparam, ptr %lo, i64 %hi)
%not_err = icmp eq i64 %6, 0
store ptr %0, ptr %url, align 8
%ptroffset = getelementptr inbounds i64, ptr %url, i64 1
store i64 %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %2, align 8
%3 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi = load i64, ptr %3, align 8
%4 = call i64 @test_readDoc(ptr %retparam, ptr %lo, i64 %hi)
%not_err = icmp eq i64 %4, 0
br i1 %not_err, label %after_check, label %else_block
after_check: ; preds = %entry
%7 = getelementptr inbounds %Doc, ptr %retparam, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
%9 = call { ptr, i8 } @test_buildSummary(ptr %8)
store { ptr, i8 } %9, ptr %result, align 8
%10 = load %Summary, ptr %result, align 8
%5 = load ptr, ptr %retparam, align 8
%6 = call { ptr, i8 } @test_buildSummary(ptr %5)
store { ptr, i8 } %6, ptr %result, align 8
%7 = load %Summary, ptr %result, align 8
br label %phi_block
else_block: ; preds = %entry
%11 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 0
store ptr null, ptr %11, align 8
%12 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 1
store i8 0, ptr %12, align 8
%13 = load %Summary, ptr %literal, align 8
%8 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 0
store ptr null, ptr %8, align 8
%9 = getelementptr inbounds %Summary, ptr %literal, i32 0, i32 1
store i8 0, ptr %9, align 8
%10 = load %Summary, ptr %literal, align 8
br label %phi_block
phi_block: ; preds = %else_block, %after_check
%val = phi %Summary [ %10, %after_check ], [ %13, %else_block ]
%val = phi %Summary [ %7, %after_check ], [ %10, %else_block ]
store %Summary %val, ptr %taddr, align 8
%14 = load { ptr, i8 }, ptr %taddr, align 8
ret { ptr, i8 } %14
%11 = load { ptr, i8 }, ptr %taddr, align 8
ret { ptr, i8 } %11
}
; Function Attrs: nounwind
@@ -602,36 +596,35 @@ entry:
%doc = alloca %Doc, align 8
%head = alloca ptr, align 8
%reterr = alloca i64, align 8
store ptr %1, ptr %doc, align 8
%2 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
store ptr %1, ptr %2, align 8
%3 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%4 = load ptr, ptr %3, align 8
%not = icmp eq ptr %4, null
%3 = load ptr, ptr %2, align 8
%not = icmp eq ptr %3, null
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i64 ptrtoint (ptr @"test_TitleResult$TITLE_MISSING" to i64)
if.exit: ; preds = %entry
%5 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
%7 = getelementptr inbounds %Head, ptr %6, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
store ptr %8, ptr %head, align 8
%9 = load ptr, ptr %head, align 8
%not1 = icmp eq ptr %9, null
%4 = getelementptr inbounds %Doc, ptr %doc, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%6 = getelementptr inbounds %Head, ptr %5, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
store ptr %7, ptr %head, align 8
%8 = load ptr, ptr %head, align 8
%not1 = icmp eq ptr %8, null
br i1 %not1, label %if.then2, label %if.exit3
if.then2: ; preds = %if.exit
ret i64 ptrtoint (ptr @"test_TitleResult$TITLE_MISSING" to i64)
if.exit3: ; preds = %if.exit
%10 = load ptr, ptr %head, align 8
%11 = getelementptr inbounds %"char[]", ptr %10, i32 0, i32 1
%12 = load i64, ptr %11, align 8
%lt = icmp ult i64 0, %12
%13 = zext i1 %lt to i8
store i8 %13, ptr %0, align 1
%9 = load ptr, ptr %head, align 8
%10 = getelementptr inbounds %"char[]", ptr %9, i32 0, i32 1
%11 = load i64, ptr %10, align 8
%lt = icmp ult i64 0, %11
%12 = zext i1 %lt to i8
store i8 %12, ptr %0, align 1
ret i64 0
}
@@ -642,41 +635,39 @@ entry:
%reterr = alloca i64, align 8
%retparam = alloca i8, align 1
%retparam1 = alloca %Doc, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %url, i32 0, i32 0
store ptr %1, ptr %3, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %url, i32 0, i32 1
store i64 %2, ptr %4, align 8
%5 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %5, align 8
%6 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi = load i64, ptr %6, align 8
%7 = call i64 @test_readDoc(ptr %retparam1, ptr %lo, i64 %hi)
%not_err = icmp eq i64 %7, 0
store ptr %1, ptr %url, align 8
%ptroffset = getelementptr inbounds i64, ptr %url, i64 1
store i64 %2, ptr %ptroffset, align 8
%3 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%lo = load ptr, ptr %3, align 8
%4 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%hi = load i64, ptr %4, align 8
%5 = call i64 @test_readDoc(ptr %retparam1, ptr %lo, i64 %hi)
%not_err = icmp eq i64 %5, 0
br i1 %not_err, label %after_check, label %assign_optional
assign_optional: ; preds = %entry
store i64 %7, ptr %reterr, align 8
store i64 %5, ptr %reterr, align 8
br label %err_retblock
after_check: ; preds = %entry
%8 = getelementptr inbounds %Doc, ptr %retparam1, i32 0, i32 0
%9 = load ptr, ptr %8, align 8
%10 = call i64 @test_isTitleNonEmpty(ptr %retparam, ptr %9)
%not_err2 = icmp eq i64 %10, 0
%6 = load ptr, ptr %retparam1, align 8
%7 = call i64 @test_isTitleNonEmpty(ptr %retparam, ptr %6)
%not_err2 = icmp eq i64 %7, 0
br i1 %not_err2, label %after_check4, label %assign_optional3
assign_optional3: ; preds = %after_check
store i64 %10, ptr %reterr, align 8
store i64 %7, ptr %reterr, align 8
br label %err_retblock
after_check4: ; preds = %after_check
%11 = load i8, ptr %retparam, align 1
store i8 %11, ptr %0, align 1
%8 = load i8, ptr %retparam, align 1
store i8 %8, ptr %0, align 1
ret i64 0
err_retblock: ; preds = %assign_optional3, %assign_optional
%12 = load i64, ptr %reterr, align 8
ret i64 %12
%9 = load i64, ptr %reterr, align 8
ret i64 %9
}
; Function Attrs: nounwind

View File

@@ -234,323 +234,319 @@ fn Type getValue(Blob blob)
/* #expect: test.ll
%Blob = type { i32 }
%Blob.0 = type { double }
%Foo2 = type { i32 }
%Bobo = type { i16, float, i16, i16, float, i16 }
%"int[]" = type { ptr, i64 }
%LinkedList = type { i64, ptr, ptr }
%List = type { i64, i64, ptr, ptr }
%Foo = type { i32, i32 }
%Blob = type { i32 }
%Blob.0 = type { double }
%Foo2 = type { i32 }
%Bobo = type { i16, float, i16, i16, float, i16 }
%"int[]" = type { ptr, i64 }
%LinkedList = type { i64, ptr, ptr }
%List = type { i64, i64, ptr, ptr }
%Foo = type { i32, i32 }
@"ct$test_Bobo" = linkonce constant %.introspect { i8 10, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8
@"ct$test_Blob" = linkonce constant %.introspect { i8 10, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"ct$test_Foor" = linkonce constant %.introspect { i8 11, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"ct$test_Foo2" = linkonce constant %.introspect { i8 10, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
@"ct$test_Foo" = linkonce constant %.introspect { i8 10, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"ct$int" = linkonce constant %.introspect { i8 2, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@"ct$test_MyEnum" = linkonce constant { i8, i64, i64, i64, [3 x %"char[]"] } { i8 8, i64 4, i64 ptrtoint (ptr @"ct$int" to i64), i64 3, [3 x %"char[]"] [%"char[]" { ptr @.enum.0, i64 4 }, %"char[]" { ptr @.enum.1, i64 5 }, %"char[]" { ptr @.enum.2, i64 3 }] }, align 8
@"test_static$x" = internal unnamed_addr global i32 1, align 4
@"ct$test_Bobo" = linkonce constant %.introspect { i8 10, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8
@"ct$test_Blob" = linkonce constant %.introspect { i8 10, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"ct$test_Foor" = linkonce constant %.introspect { i8 11, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"ct$test_Foo2" = linkonce constant %.introspect { i8 10, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
@"ct$test_Foo" = linkonce constant %.introspect { i8 10, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"ct$int" = linkonce constant %.introspect { i8 2, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@"ct$test_MyEnum" = linkonce constant { i8, i64, i64, i64, [3 x %"char[]"] } { i8 8, i64 4, i64 ptrtoint (ptr @"ct$int" to i64), i64 3, [3 x %"char[]"] [%"char[]" { ptr @.enum.0, i64 4 }, %"char[]" { ptr @.enum.1, i64 5 }, %"char[]" { ptr @.enum.2, i64 3 }] }, align 8
@"test_static$x" = internal unnamed_addr global i32 1, align 4
define void @test_Foo2_printme(ptr %0) #0 {
entry:
%1 = getelementptr inbounds %Foo2, ptr %0, i32 0, i32 0
%2 = load i32, ptr %1, align 4
%3 = call i32 (ptr, ...) @printf(ptr @.str.21, i32 %2)
ret void
}
define void @test_Foo2_printme(ptr %0) #0 {
entry:
%1 = getelementptr inbounds %Foo2, ptr %0, i32 0, i32 0
%2 = load i32, ptr %1, align 4
%3 = call i32 (ptr, ...) @printf(ptr @.str.21, i32 %2)
ret void
}
; Function Attrs: nounwind
define i32 @test_Foo2_mutate(ptr %0) #0 {
entry:
%1 = call i32 (ptr, ...) @printf(ptr @.str.22)
%2 = getelementptr inbounds %Foo2, ptr %0, i32 0, i32 0
%3 = load i32, ptr %2, align 4
%add = add i32 %3, 1
store i32 %add, ptr %2, align 4
ret i32 %add
}
; Function Attrs: nounwind
define i32 @test_Foo2_mutate(ptr %0) #0 {
entry:
%1 = call i32 (ptr, ...) @printf(ptr @.str.22)
%2 = getelementptr inbounds %Foo2, ptr %0, i32 0, i32 0
%3 = load i32, ptr %2, align 4
%add = add i32 %3, 1
store i32 %add, ptr %2, align 4
ret i32 %add
}
; Function Attrs: nounwind
declare i32 @printf(ptr, ...) #0
; Function Attrs: nounwind
declare i32 @printf(ptr, ...) #0
; Function Attrs: nounwind
define void @test_helloWorld() #0 {
entry:
%0 = call i32 (ptr, ...) @printf(ptr @.str)
ret void
}
; Function Attrs: nounwind
define void @test_helloWorld() #0 {
entry:
%0 = call i32 (ptr, ...) @printf(ptr @.str)
ret void
}
; Function Attrs: nounwind
define i32 @test_test_static() #0 {
entry:
%0 = load i32, ptr @"test_static$x", align 4
%add = add i32 %0, 1
store i32 %add, ptr @"test_static$x", align 4
%1 = load i32, ptr @"test_static$x", align 4
%2 = call i32 (ptr, ...) @printf(ptr @.str.1, i32 %1)
%3 = load i32, ptr @"test_static$x", align 4
ret i32 %3
}
; Function Attrs: nounwind
define i32 @test_test_static() #0 {
entry:
%0 = load i32, ptr @"test_static$x", align 4
%add = add i32 %0, 1
store i32 %add, ptr @"test_static$x", align 4
%1 = load i32, ptr @"test_static$x", align 4
%2 = call i32 (ptr, ...) @printf(ptr @.str.1, i32 %1)
%3 = load i32, ptr @"test_static$x", align 4
ret i32 %3
}
; Function Attrs: nounwind
define i32 @test_helo(double %0, ptr byval(%Bobo) align 8 %1) #0 {
entry:
%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 %de, ptr align 4 @.__const, i32 12, 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
}
; Function Attrs: nounwind
define i32 @test_helo(double %0, ptr byval(%Bobo) align 8 %1) #0 {
entry:
%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 %de, ptr align 4 @.__const, i32 12, 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
}
; Function Attrs: nounwind
define i32 @test_test1(i32 %0, i32 %1) #0 {
entry:
%a = alloca i32, align 4
store i32 %0, ptr %a, align 4
%2 = load i32, ptr %a, align 4
%ashr = ashr i32 %2, %1
%3 = freeze i32 %ashr
store i32 %3, ptr %a, align 4
%gt = icmp sgt i32 %1, 128
br i1 %gt, label %if.then, label %if.exit
; Function Attrs: nounwind
define i32 @test_test1(i32 %0, i32 %1) #0 {
entry:
%a = alloca i32, align 4
store i32 %0, ptr %a, align 4
%2 = load i32, ptr %a, align 4
%ashr = ashr i32 %2, %1
%3 = freeze i32 %ashr
store i32 %3, ptr %a, align 4
%gt = icmp sgt i32 %1, 128
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 -1
if.then: ; preds = %entry
ret i32 -1
if.exit: ; preds = %entry
%4 = load i32, ptr %a, align 4
ret i32 %4
}
if.exit: ; preds = %entry
%4 = load i32, ptr %a, align 4
ret i32 %4
}
; Function Attrs: nounwind
define i32 @test_sum_us(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%2 = getelementptr inbounds { ptr, i64 }, ptr %x, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %x, i32 0, i32 1
store i64 %1, ptr %3, align 8
store i32 0, ptr %sum, align 4
%4 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%5 = load i64, ptr %4, align 8
%eq = icmp eq i64 0, %5
br i1 %eq, label %if.then, label %if.exit
; Function Attrs: nounwind
define i32 @test_sum_us(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
store ptr %0, ptr %x, align 8
%ptroffset = getelementptr inbounds i64, ptr %x, i64 1
store i64 %1, ptr %ptroffset, align 8
store i32 0, ptr %sum, align 4
%2 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%3 = load i64, ptr %2, align 8
%eq = icmp eq i64 0, %3
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 0
if.then: ; preds = %entry
ret i32 0
if.exit: ; preds = %entry
%6 = load i32, ptr %sum, align 4
%7 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
%ptroffset = getelementptr inbounds i32, ptr %8, i64 0
%9 = load i32, ptr %ptroffset, align 4
%10 = load %"int[]", ptr %x, align 8
%11 = extractvalue %"int[]" %10, 0
%12 = extractvalue %"int[]" %10, 1
%sub = sub i64 %12, 1
%13 = add i64 %sub, 1
%size = sub i64 %13, 1
%ptroffset1 = getelementptr inbounds i32, ptr %11, i64 1
%14 = call i32 @test_sum_us(ptr %ptroffset1, i64 %size)
%add = add i32 %9, %14
%add2 = add i32 %6, %add
store i32 %add2, ptr %sum, align 4
%15 = load i32, ptr %sum, align 4
ret i32 %15
}
if.exit: ; preds = %entry
%4 = load i32, ptr %sum, align 4
%5 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
%ptroffset1 = getelementptr inbounds i32, ptr %6, i64 0
%7 = load i32, ptr %ptroffset1, align 4
%8 = load %"int[]", ptr %x, align 8
%9 = extractvalue %"int[]" %8, 0
%10 = extractvalue %"int[]" %8, 1
%sub = sub i64 %10, 1
%11 = add i64 %sub, 1
%size = sub i64 %11, 1
%ptroffset2 = getelementptr inbounds i32, ptr %9, i64 1
%12 = call i32 @test_sum_us(ptr %ptroffset2, i64 %size)
%add = add i32 %7, %12
%add3 = add i32 %4, %add
store i32 %add3, ptr %sum, align 4
%13 = load i32, ptr %sum, align 4
ret i32 %13
}
; Function Attrs: nounwind
define i32 @test_sumd(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%i = alloca i32, align 4
%2 = getelementptr inbounds { ptr, i64 }, ptr %x, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %x, i32 0, i32 1
store i64 %1, ptr %3, align 8
store i32 0, ptr %sum, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
; Function Attrs: nounwind
define i32 @test_sumd(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%i = alloca i32, align 4
store ptr %0, ptr %x, align 8
%ptroffset = getelementptr inbounds i64, ptr %x, i64 1
store i64 %1, ptr %ptroffset, align 8
store i32 0, ptr %sum, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%4 = load i32, ptr %i, align 4
%sisiext = sext i32 %4 to i64
%5 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%6 = load i64, ptr %5, align 8
%lt = icmp slt i64 %sisiext, %6
%check = icmp slt i64 %6, 0
%siui-lt = or i1 %check, %lt
br i1 %siui-lt, label %loop.body, label %loop.exit
loop.cond: ; preds = %loop.body, %entry
%2 = load i32, ptr %i, align 4
%sisiext = sext i32 %2 to i64
%3 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%4 = load i64, ptr %3, align 8
%lt = icmp slt i64 %sisiext, %4
%check = icmp slt i64 %4, 0
%siui-lt = or i1 %check, %lt
br i1 %siui-lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%7 = load i32, ptr %sum, align 4
%8 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%9 = load ptr, ptr %8, align 8
%10 = load i32, ptr %i, align 4
%sisiext1 = sext i32 %10 to i64
%ptroffset = getelementptr inbounds i32, ptr %9, i64 %sisiext1
%11 = load i32, ptr %ptroffset, align 4
%add = add i32 %7, %11
store i32 %add, ptr %sum, align 4
%12 = load i32, ptr %i, align 4
%add2 = add i32 %12, 1
store i32 %add2, ptr %i, align 4
br label %loop.cond
loop.body: ; preds = %loop.cond
%5 = load i32, ptr %sum, align 4
%6 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%8 = load i32, ptr %i, align 4
%sisiext1 = sext i32 %8 to i64
%ptroffset2 = getelementptr inbounds i32, ptr %7, i64 %sisiext1
%9 = load i32, ptr %ptroffset2, align 4
%add = add i32 %5, %9
store i32 %add, ptr %sum, align 4
%10 = load i32, ptr %i, align 4
%add3 = add i32 %10, 1
store i32 %add3, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%13 = load i32, ptr %sum, align 4
ret i32 %13
}
loop.exit: ; preds = %loop.cond
%11 = load i32, ptr %sum, align 4
ret i32 %11
}
; Function Attrs: nounwind
define void @test_main() #0 {
entry:
%list = alloca %LinkedList, align 8
%i = alloca i32, align 4
%elements = alloca i32, align 4
%array = alloca %List, align 8
%i1 = alloca i32, align 4
%a = alloca %Blob, align 4
%b = alloca %Blob.0, align 8
%ddx = alloca %Foo, align 4
%fro = alloca i32, align 4
%x = alloca [4 x i32], align 16
%z = alloca %"int[]", align 8
%de = alloca [3 x i32], align 4
%varargslots = alloca [4 x i32], align 16
%varargslots10 = alloca [1 x i32], align 4
%a1 = alloca ptr, align 8
%b2 = alloca ptr, align 8
%0 = call i32 @test_test_static()
%1 = call i32 @test_test_static()
%2 = call i32 @test_test_static()
call void @hello_world_hello()
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 24, i1 false)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 10)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 15)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 30)
store i32 0, ptr %i, align 4
br label %loop.cond
; Function Attrs: nounwind
define void @test_main() #0 {
entry:
%list = alloca %LinkedList, align 8
%i = alloca i32, align 4
%elements = alloca i32, align 4
%array = alloca %List, align 8
%i1 = alloca i32, align 4
%a = alloca %Blob, align 4
%b = alloca %Blob.0, align 8
%ddx = alloca %Foo, align 4
%fro = alloca i32, align 4
%x = alloca [4 x i32], align 16
%z = alloca %"int[]", align 8
%de = alloca [3 x i32], align 4
%varargslots = alloca [4 x i32], align 16
%varargslots10 = alloca [1 x i32], align 4
%a1 = alloca ptr, align 8
%b2 = alloca ptr, align 8
%0 = call i32 @test_test_static()
%1 = call i32 @test_test_static()
%2 = call i32 @test_test_static()
call void @hello_world_hello()
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 24, i1 false)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 10)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 15)
call void @"std_array_linkedlist$$int_LinkedList_push"(ptr %list, i32 30)
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, ptr %i, align 4
%4 = call i64 @"std_array_linkedlist$$int_LinkedList_len"(ptr %list) #3
%uisitrunc = trunc i64 %4 to i32
%lt = icmp slt i32 %3, %uisitrunc
br i1 %lt, label %loop.body, label %loop.exit
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, ptr %i, align 4
%4 = call i64 @"std_array_linkedlist$$int_LinkedList_len"(ptr %list) #3
%uisitrunc = trunc i64 %4 to i32
%lt = icmp slt i32 %3, %uisitrunc
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%5 = load i32, ptr %i, align 4
%6 = load i32, ptr %i, align 4
%siuiext = sext i32 %6 to i64
%7 = call i32 @"std_array_linkedlist$$int_LinkedList_get"(ptr %list, i64 %siuiext)
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %5, i32 %7)
%9 = load i32, ptr %i, align 4
%add = add i32 %9, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.body: ; preds = %loop.cond
%5 = load i32, ptr %i, align 4
%6 = load i32, ptr %i, align 4
%siuiext = sext i32 %6 to i64
%7 = call i32 @"std_array_linkedlist$$int_LinkedList_get"(ptr %list, i64 %siuiext)
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %5, i32 %7)
%9 = load i32, ptr %i, align 4
%add = add i32 %9, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
call void @"std_array_linkedlist$$int_LinkedList_free"(ptr %list)
%10 = call i32 (ptr, ...) @printf(ptr @.str.3, i32 3)
store i32 3, ptr %elements, align 4
%11 = call i32 (ptr, ...) @printf(ptr @.str.4)
call void @llvm.memset.p0.i64(ptr align 8 %array, i8 0, i64 32, i1 false)
call void @"std_array_list$$int_List_append"(ptr %array, i32 100)
call void @"std_array_list$$int_List_append"(ptr %array, i32 200)
call void @"std_array_list$$int_List_append"(ptr %array, i32 400)
call void @"std_array_list$$int_List_push"(ptr %array, i32 600) #3
call void @"std_array_list$$int_List_insert_at"(ptr %array, i64 2, i32 300)
store i32 0, ptr %i1, align 4
br label %loop.cond2
loop.exit: ; preds = %loop.cond
call void @"std_array_linkedlist$$int_LinkedList_free"(ptr %list)
%10 = call i32 (ptr, ...) @printf(ptr @.str.3, i32 3)
store i32 3, ptr %elements, align 4
%11 = call i32 (ptr, ...) @printf(ptr @.str.4)
call void @llvm.memset.p0.i64(ptr align 8 %array, i8 0, i64 32, i1 false)
call void @"std_array_list$$int_List_append"(ptr %array, i32 100)
call void @"std_array_list$$int_List_append"(ptr %array, i32 200)
call void @"std_array_list$$int_List_append"(ptr %array, i32 400)
call void @"std_array_list$$int_List_push"(ptr %array, i32 600) #3
call void @"std_array_list$$int_List_insert_at"(ptr %array, i64 2, i32 300)
store i32 0, ptr %i1, align 4
br label %loop.cond2
loop.cond2: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %i1, align 4
%13 = call i64 @"std_array_list$$int_List_len"(ptr %array)
%uisitrunc3 = trunc i64 %13 to i32
%lt4 = icmp slt i32 %12, %uisitrunc3
br i1 %lt4, label %loop.body5, label %loop.exit8
loop.cond2: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %i1, align 4
%13 = call i64 @"std_array_list$$int_List_len"(ptr %array)
%uisitrunc3 = trunc i64 %13 to i32
%lt4 = icmp slt i32 %12, %uisitrunc3
br i1 %lt4, label %loop.body5, label %loop.exit8
loop.body5: ; preds = %loop.cond2
%14 = load i32, ptr %i1, align 4
%15 = load i32, ptr %i1, align 4
%siuiext6 = sext i32 %15 to i64
%16 = call i32 @"std_array_list$$int_List_get"(ptr %array, i64 %siuiext6)
%17 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %14, i32 %16)
%18 = load i32, ptr %i1, align 4
%add7 = add i32 %18, 1
store i32 %add7, ptr %i1, align 4
br label %loop.cond2
loop.body5: ; preds = %loop.cond2
%14 = load i32, ptr %i1, align 4
%15 = load i32, ptr %i1, align 4
%siuiext6 = sext i32 %15 to i64
%16 = call i32 @"std_array_list$$int_List_get"(ptr %array, i64 %siuiext6)
%17 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %14, i32 %16)
%18 = load i32, ptr %i1, align 4
%add7 = add i32 %18, 1
store i32 %add7, ptr %i1, align 4
br label %loop.cond2
loop.exit8: ; preds = %loop.cond2
call void @"std_array_list$$int_List_free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = getelementptr inbounds %Blob, ptr %a, i32 0, i32 0
%20 = load i32, ptr %19, align 4
%21 = call i32 @"test2$$int_getValue"(i32 %20)
%22 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %21)
%23 = getelementptr inbounds %Blob.0, ptr %b, i32 0, i32 0
%24 = load double, ptr %23, align 8
%25 = call double @"test2$$double_getValue"(double %24)
%26 = call i32 (ptr, ...) @printf(ptr @.str.9, double %25)
%27 = call i32 @"test2$$int_getMult"(i32 25)
%28 = call i32 (ptr, ...) @printf(ptr @.str.10, i32 %27)
%29 = call double @"test2$$double_getMult"(double 3.300000e+00)
%30 = call i32 (ptr, ...) @printf(ptr @.str.11, double %29)
call void @test_helloWorld()
%31 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 0
store i32 0, ptr %31, align 4
%32 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 1
store i32 0, ptr %32, align 4
store i32 3, ptr %fro, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %x, ptr align 16 @.__const.12, i32 16, i1 false)
%33 = load i32, ptr %fro, align 4
%34 = call i32 @test_sum_us(ptr %x, i64 4)
%35 = call i32 (ptr, ...) @printf(ptr @.str.13, i32 %34)
%add9 = add i32 %33, %35
store i32 %add9, ptr %fro, align 4
%36 = load i32, ptr %fro, align 4
%37 = call i32 (ptr, ...) @printf(ptr @.str.14, i32 %36)
%38 = insertvalue %"int[]" undef, ptr %x, 0
%39 = insertvalue %"int[]" %38, i64 4, 1
store %"int[]" %39, ptr %z, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const.15, i32 12, i1 false)
%40 = call i32 @test_sum_us(ptr %x, i64 4)
%41 = call i32 (ptr, ...) @printf(ptr @.str.16, i32 %40)
%42 = getelementptr inbounds %"int[]", ptr %z, i32 0, i32 0
%lo = load ptr, ptr %42, align 8
%43 = getelementptr inbounds %"int[]", ptr %z, i32 0, i32 1
%hi = load i64, ptr %43, align 8
%44 = call i32 @test_sum_us(ptr %lo, i64 %hi)
%45 = call i32 (ptr, ...) @printf(ptr @.str.17, i32 %44)
%46 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 0
store i32 1, ptr %46, align 4
%47 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 1
store i32 2, ptr %47, align 4
%48 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 2
store i32 4, ptr %48, align 4
%49 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 3
store i32 5, ptr %49, align 4
%50 = call i32 @test_sum_us(ptr %varargslots, i64 4)
%51 = call i32 (ptr, ...) @printf(ptr @.str.18, i32 %50)
%52 = getelementptr inbounds [1 x i32], ptr %varargslots10, i64 0, i64 0
store i32 1, ptr %52, align 4
%53 = call i32 @test_sum_us(ptr %varargslots10, i64 1)
%54 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %53)
%55 = call i32 @test_sum_us(ptr null, i64 0)
%56 = call i32 (ptr, ...) @printf(ptr @.str.20, i32 %55)
store ptr null, ptr %a1, align 8
store ptr null, ptr %b2, align 8
ret void
}
loop.exit8: ; preds = %loop.cond2
call void @"std_array_list$$int_List_free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = load i32, ptr %a, align 4
%20 = call i32 @"test2$$int_getValue"(i32 %19)
%21 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %20)
%22 = load double, ptr %b, align 8
%23 = call double @"test2$$double_getValue"(double %22)
%24 = call i32 (ptr, ...) @printf(ptr @.str.9, double %23)
%25 = call i32 @"test2$$int_getMult"(i32 25)
%26 = call i32 (ptr, ...) @printf(ptr @.str.10, i32 %25)
%27 = call double @"test2$$double_getMult"(double 3.300000e+00)
%28 = call i32 (ptr, ...) @printf(ptr @.str.11, double %27)
call void @test_helloWorld()
%29 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 0
store i32 0, ptr %29, align 4
%30 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 1
store i32 0, ptr %30, align 4
store i32 3, ptr %fro, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %x, ptr align 16 @.__const.12, i32 16, i1 false)
%31 = load i32, ptr %fro, align 4
%32 = call i32 @test_sum_us(ptr %x, i64 4)
%33 = call i32 (ptr, ...) @printf(ptr @.str.13, i32 %32)
%add9 = add i32 %31, %33
store i32 %add9, ptr %fro, align 4
%34 = load i32, ptr %fro, align 4
%35 = call i32 (ptr, ...) @printf(ptr @.str.14, i32 %34)
%36 = insertvalue %"int[]" undef, ptr %x, 0
%37 = insertvalue %"int[]" %36, i64 4, 1
store %"int[]" %37, ptr %z, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const.15, i32 12, i1 false)
%38 = call i32 @test_sum_us(ptr %x, i64 4)
%39 = call i32 (ptr, ...) @printf(ptr @.str.16, i32 %38)
%40 = getelementptr inbounds %"int[]", ptr %z, i32 0, i32 0
%lo = load ptr, ptr %40, align 8
%41 = getelementptr inbounds %"int[]", ptr %z, i32 0, i32 1
%hi = load i64, ptr %41, align 8
%42 = call i32 @test_sum_us(ptr %lo, i64 %hi)
%43 = call i32 (ptr, ...) @printf(ptr @.str.17, i32 %42)
%44 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 0
store i32 1, ptr %44, align 4
%45 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 1
store i32 2, ptr %45, align 4
%46 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 2
store i32 4, ptr %46, align 4
%47 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 3
store i32 5, ptr %47, align 4
%48 = call i32 @test_sum_us(ptr %varargslots, i64 4)
%49 = call i32 (ptr, ...) @printf(ptr @.str.18, i32 %48)
%50 = getelementptr inbounds [1 x i32], ptr %varargslots10, i64 0, i64 0
store i32 1, ptr %50, align 4
%51 = call i32 @test_sum_us(ptr %varargslots10, i64 1)
%52 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %51)
%53 = call i32 @test_sum_us(ptr null, i64 0)
%54 = call i32 (ptr, ...) @printf(ptr @.str.20, i32 %53)
store ptr null, ptr %a1, align 8
store ptr null, ptr %b2, align 8
ret void
}
// #expect: hello_world.ll
define void @hello_world_hello()
@@ -587,11 +583,10 @@ entry:
define i32 @"test2$$int_getValue"(i32 %0) #0 {
entry:
%blob = alloca %Blob, align 4
store i32 %0, ptr %blob, align 4
%1 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
store i32 %0, ptr %1, align 4
%2 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
%3 = load i32, ptr %2, align 4
ret i32 %3
%2 = load i32, ptr %1, align 4
ret i32 %2
}
// #expect: test2.double.ll
@@ -609,10 +604,9 @@ entry:
ret i32 1
define double @"test2$$double_getValue"(double %0)
entry:
entry:
%blob = alloca %Blob, align 8
store double %0, ptr %blob, align 8
%1 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
store double %0, ptr %1, align 8
%2 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
%3 = load double, ptr %2, align 8
ret double %3
%2 = load double, ptr %1, align 8
ret double %2

View File

@@ -534,70 +534,68 @@ loop.exit8: ; preds = %loop.cond2
call void @"std_array_list$$int_List_free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = getelementptr inbounds %Blob, ptr %a, i32 0, i32 0
%20 = load i32, ptr %19, align 4
%21 = call i32 @"test2$$int_getValue"(i32 %20)
%22 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %21)
%23 = getelementptr inbounds %Blob.0, ptr %b, i32 0, i32 0
%24 = load i64, ptr %23, align 8
%25 = call double @"test2$$double_getValue"(i64 %24)
%26 = call i32 (ptr, ...) @printf(ptr @.str.9, double %25)
%27 = call i32 @"test2$$int_getMult"(i32 25)
%28 = call i32 (ptr, ...) @printf(ptr @.str.10, i32 %27)
%29 = call double @"test2$$double_getMult"(double 3.300000e+00)
%30 = call i32 (ptr, ...) @printf(ptr @.str.11, double %29)
%19 = load i32, ptr %a, align 4
%20 = call i32 @"test2$$int_getValue"(i32 %19)
%21 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %20)
%22 = load i64, ptr %b, align 8
%23 = call double @"test2$$double_getValue"(i64 %22)
%24 = call i32 (ptr, ...) @printf(ptr @.str.9, double %23)
%25 = call i32 @"test2$$int_getMult"(i32 25)
%26 = call i32 (ptr, ...) @printf(ptr @.str.10, i32 %25)
%27 = call double @"test2$$double_getMult"(double 3.300000e+00)
%28 = call i32 (ptr, ...) @printf(ptr @.str.11, double %27)
call void @test_helloWorld()
%31 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 0
store i32 0, ptr %31, align 4
%32 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 1
store i32 0, ptr %32, align 4
%29 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 0
store i32 0, ptr %29, align 4
%30 = getelementptr inbounds %Foo, ptr %ddx, i32 0, i32 1
store i32 0, ptr %30, align 4
store i32 3, ptr %fro, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %x, ptr align 16 @.__const.12, i32 16, i1 false)
%33 = load i32, ptr %fro, align 4
%34 = insertvalue %"int[]" undef, ptr %x, 0
%35 = insertvalue %"int[]" %34, i64 4, 1
store %"int[]" %35, ptr %indirectarg, align 8
%36 = call i32 @test_sum_us(ptr align 8 %indirectarg)
%37 = call i32 (ptr, ...) @printf(ptr @.str.13, i32 %36)
%add9 = add i32 %33, %37
%31 = load i32, ptr %fro, align 4
%32 = insertvalue %"int[]" undef, ptr %x, 0
%33 = insertvalue %"int[]" %32, i64 4, 1
store %"int[]" %33, ptr %indirectarg, align 8
%34 = call i32 @test_sum_us(ptr align 8 %indirectarg)
%35 = call i32 (ptr, ...) @printf(ptr @.str.13, i32 %34)
%add9 = add i32 %31, %35
store i32 %add9, ptr %fro, align 4
%38 = load i32, ptr %fro, align 4
%39 = call i32 (ptr, ...) @printf(ptr @.str.14, i32 %38)
%36 = load i32, ptr %fro, align 4
%37 = call i32 (ptr, ...) @printf(ptr @.str.14, i32 %36)
%38 = insertvalue %"int[]" undef, ptr %x, 0
%39 = insertvalue %"int[]" %38, i64 4, 1
store %"int[]" %39, ptr %z, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const.15, i32 12, i1 false)
%40 = insertvalue %"int[]" undef, ptr %x, 0
%41 = insertvalue %"int[]" %40, i64 4, 1
store %"int[]" %41, ptr %z, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const.15, i32 12, i1 false)
%42 = insertvalue %"int[]" undef, ptr %x, 0
%43 = insertvalue %"int[]" %42, i64 4, 1
store %"int[]" %43, ptr %indirectarg10, align 8
%44 = call i32 @test_sum_us(ptr align 8 %indirectarg10)
%45 = call i32 (ptr, ...) @printf(ptr @.str.16, i32 %44)
store %"int[]" %41, ptr %indirectarg10, align 8
%42 = call i32 @test_sum_us(ptr align 8 %indirectarg10)
%43 = call i32 (ptr, ...) @printf(ptr @.str.16, i32 %42)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg11, ptr align 8 %z, i32 16, i1 false)
%46 = call i32 @test_sum_us(ptr align 8 %indirectarg11)
%47 = call i32 (ptr, ...) @printf(ptr @.str.17, i32 %46)
%48 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 0
store i32 1, ptr %48, align 4
%49 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 1
store i32 2, ptr %49, align 4
%50 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 2
store i32 4, ptr %50, align 4
%51 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 3
store i32 5, ptr %51, align 4
%52 = insertvalue %"int[]" undef, ptr %varargslots, 0
%53 = insertvalue %"int[]" %52, i64 4, 1
store %"int[]" %53, ptr %indirectarg12, align 8
%54 = call i32 @test_sum_us(ptr align 8 %indirectarg12)
%55 = call i32 (ptr, ...) @printf(ptr @.str.18, i32 %54)
%56 = getelementptr inbounds [1 x i32], ptr %varargslots13, i64 0, i64 0
store i32 1, ptr %56, align 4
%57 = insertvalue %"int[]" undef, ptr %varargslots13, 0
%58 = insertvalue %"int[]" %57, i64 1, 1
store %"int[]" %58, ptr %indirectarg14, align 8
%59 = call i32 @test_sum_us(ptr align 8 %indirectarg14)
%60 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %59)
%44 = call i32 @test_sum_us(ptr align 8 %indirectarg11)
%45 = call i32 (ptr, ...) @printf(ptr @.str.17, i32 %44)
%46 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 0
store i32 1, ptr %46, align 4
%47 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 1
store i32 2, ptr %47, align 4
%48 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 2
store i32 4, ptr %48, align 4
%49 = getelementptr inbounds [4 x i32], ptr %varargslots, i64 0, i64 3
store i32 5, ptr %49, align 4
%50 = insertvalue %"int[]" undef, ptr %varargslots, 0
%51 = insertvalue %"int[]" %50, i64 4, 1
store %"int[]" %51, ptr %indirectarg12, align 8
%52 = call i32 @test_sum_us(ptr align 8 %indirectarg12)
%53 = call i32 (ptr, ...) @printf(ptr @.str.18, i32 %52)
%54 = getelementptr inbounds [1 x i32], ptr %varargslots13, i64 0, i64 0
store i32 1, ptr %54, align 4
%55 = insertvalue %"int[]" undef, ptr %varargslots13, 0
%56 = insertvalue %"int[]" %55, i64 1, 1
store %"int[]" %56, ptr %indirectarg14, align 8
%57 = call i32 @test_sum_us(ptr align 8 %indirectarg14)
%58 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %57)
store %"int[]" zeroinitializer, ptr %indirectarg15, align 8
%61 = call i32 @test_sum_us(ptr align 8 %indirectarg15)
%62 = call i32 (ptr, ...) @printf(ptr @.str.20, i32 %61)
%59 = call i32 @test_sum_us(ptr align 8 %indirectarg15)
%60 = call i32 (ptr, ...) @printf(ptr @.str.20, i32 %59)
store ptr null, ptr %a1, align 8
store ptr null, ptr %b2, align 8
ret void
@@ -666,11 +664,10 @@ entry:
define i32 @"test2$$int_getValue"(i32 %0)
entry:
%blob = alloca %Blob, align 4
store i32 %0, ptr %blob, align 4
%1 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
store i32 %0, ptr %1, align 4
%2 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
%3 = load i32, ptr %2, align 4
ret i32 %3
%2 = load i32, ptr %1, align 4
ret i32 %2
// #expect: test2.double.ll
@@ -691,9 +688,8 @@ entry:
define double @"test2$$double_getValue"(i64 %0)
entry:
%blob = alloca %Blob, align 8
store i64 %0, ptr %blob, align 8
%1 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
store i64 %0, ptr %1, align 8
%2 = getelementptr inbounds %Blob, ptr %blob, i32 0, i32 0
%3 = load double, ptr %2, align 8
ret double %3
%2 = load double, ptr %1, align 8
ret double %2

View File

@@ -27,14 +27,13 @@ fn int main()
define void @test_retest(ptr %0, i64 %1) #0 {
entry:
%foo = alloca %"variant[]", align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %foo, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %foo, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds %"variant[]", ptr %foo, i32 0, i32 0
%lo = load ptr, ptr %4, align 8
%5 = getelementptr inbounds %"variant[]", ptr %foo, i32 0, i32 1
%hi = load i64, ptr %5, align 8
store ptr %0, ptr %foo, align 8
%ptroffset = getelementptr inbounds i64, ptr %foo, i64 1
store i64 %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %"variant[]", ptr %foo, i32 0, i32 0
%lo = load ptr, ptr %2, align 8
%3 = getelementptr inbounds %"variant[]", ptr %foo, i32 0, i32 1
%hi = load i64, ptr %3, align 8
call void @test_test(ptr %lo, i64 %hi)
ret void
}
@@ -42,17 +41,16 @@ entry:
define void @test_test(ptr %0, i64 %1) #0 {
entry:
%foo = alloca %"variant[]", align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %foo, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %foo, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds %"variant[]", ptr %foo, i32 0, i32 0
store ptr %0, ptr %foo, align 8
%ptroffset = getelementptr inbounds i64, ptr %foo, i64 1
store i64 %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %"variant[]", ptr %foo, i32 0, i32 0
%3 = load ptr, ptr %2, align 8
%ptroffset1 = getelementptr inbounds %variant, ptr %3, i64 0
%4 = getelementptr inbounds %variant, ptr %ptroffset1, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%ptroffset = getelementptr inbounds %variant, ptr %5, i64 0
%6 = getelementptr inbounds %variant, ptr %ptroffset, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%8 = load i32, ptr %7, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %8)
%6 = load i32, ptr %5, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %6)
ret void
}

View File

@@ -25,18 +25,17 @@ fn void main()
define void @foo_test(i32 %0, ptr %1, i64 %2, i32 %3) #0 {
entry:
%y = alloca %"int[]", align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %y, i32 0, i32 0
store ptr %1, ptr %4, align 8
%5 = getelementptr inbounds { ptr, i64 }, ptr %y, i32 0, i32 1
store i64 %2, ptr %5, align 8
%6 = getelementptr inbounds %"int[]", ptr %y, i32 0, i32 1
%7 = load i64, ptr %6, align 8
%uisitrunc = trunc i64 %7 to i32
%8 = getelementptr inbounds %"int[]", ptr %y, i32 0, i32 0
%9 = load ptr, ptr %8, align 8
%ptroffset = getelementptr inbounds i32, ptr %9, i64 0
%10 = load i32, ptr %ptroffset, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %0, i32 %uisitrunc, i32 %3, i32 %10)
store ptr %1, ptr %y, align 8
%ptroffset = getelementptr inbounds i64, ptr %y, i64 1
store i64 %2, ptr %ptroffset, align 8
%4 = getelementptr inbounds %"int[]", ptr %y, i32 0, i32 1
%5 = load i64, ptr %4, align 8
%uisitrunc = trunc i64 %5 to i32
%6 = getelementptr inbounds %"int[]", ptr %y, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%ptroffset1 = getelementptr inbounds i32, ptr %7, i64 0
%8 = load i32, ptr %ptroffset1, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %0, i32 %uisitrunc, i32 %3, i32 %8)
ret void
}
@@ -44,13 +43,12 @@ entry:
define void @foo_test2(i32 %0, ptr %1, i64 %2, i32 %3) #0 {
entry:
%y = alloca %"variant[]", align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %y, i32 0, i32 0
store ptr %1, ptr %4, align 8
%5 = getelementptr inbounds { ptr, i64 }, ptr %y, i32 0, i32 1
store i64 %2, ptr %5, align 8
%6 = getelementptr inbounds %"variant[]", ptr %y, i32 0, i32 1
%7 = load i64, ptr %6, align 8
%uisitrunc = trunc i64 %7 to i32
store ptr %1, ptr %y, align 8
%ptroffset = getelementptr inbounds i64, ptr %y, i64 1
store i64 %2, ptr %ptroffset, align 8
%4 = getelementptr inbounds %"variant[]", ptr %y, i32 0, i32 1
%5 = load i64, ptr %4, align 8
%uisitrunc = trunc i64 %5 to i32
call void (ptr, ...) @printf(ptr @.str.1, i32 %0, i32 %uisitrunc, i32 %3)
ret void
}

View File

@@ -161,35 +161,34 @@ entry:
%seq = alloca %"char[]", align 8
%len = alloca i64, align 8
%i = alloca i32, align 4
%3 = getelementptr inbounds { ptr, i64 }, ptr %seq, i32 0, i32 0
store ptr %0, ptr %3, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %seq, i32 0, i32 1
store i64 %1, ptr %4, align 8
%5 = getelementptr inbounds %"char[]", ptr %seq, i32 0, i32 1
%6 = load i64, ptr %5, align 8
store i64 %6, ptr %len, align 8
store ptr %0, ptr %seq, align 8
%ptroffset = getelementptr inbounds i64, ptr %seq, i64 1
store i64 %1, ptr %ptroffset, align 8
%3 = getelementptr inbounds %"char[]", ptr %seq, i32 0, i32 1
%4 = load i64, ptr %3, align 8
store i64 %4, ptr %len, align 8
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %if.exit, %entry
%7 = load i32, ptr %i, align 4
%lt = icmp slt i32 %7, %2
%5 = load i32, ptr %i, align 4
%lt = icmp slt i32 %5, %2
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%8 = getelementptr inbounds %"char[]", ptr %seq, i32 0, i32 0
%9 = load ptr, ptr %8, align 8
%10 = load i32, ptr %i, align 4
%sisiext = sext i32 %10 to i64
%11 = load i64, ptr %len, align 8
%smod = srem i64 %sisiext, %11
%ptroffset = getelementptr inbounds i8, ptr %9, i64 %smod
%12 = load i8, ptr %ptroffset, align 1
%uisiext = zext i8 %12 to i32
%6 = getelementptr inbounds %"char[]", ptr %seq, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%8 = load i32, ptr %i, align 4
%sisiext = sext i32 %8 to i64
%9 = load i64, ptr %len, align 8
%smod = srem i64 %sisiext, %9
%ptroffset1 = getelementptr inbounds i8, ptr %7, i64 %smod
%10 = load i8, ptr %ptroffset1, align 1
%uisiext = zext i8 %10 to i32
call void @putchar(i32 %uisiext)
%13 = load i32, ptr %i, align 4
%smod1 = srem i32 %13, 60
%eq = icmp eq i32 %smod1, 59
%11 = load i32, ptr %i, align 4
%smod2 = srem i32 %11, 60
%eq = icmp eq i32 %smod2, 59
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %loop.body
@@ -197,22 +196,22 @@ if.then: ; preds = %loop.body
br label %if.exit
if.exit: ; preds = %if.then, %loop.body
%14 = load i32, ptr %i, align 4
%add = add i32 %14, 1
%12 = load i32, ptr %i, align 4
%add = add i32 %12, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%15 = load i32, ptr %i, align 4
%smod2 = srem i32 %15, 60
%neq = icmp ne i32 %smod2, 0
br i1 %neq, label %if.then3, label %if.exit4
%13 = load i32, ptr %i, align 4
%smod3 = srem i32 %13, 60
%neq = icmp ne i32 %smod3, 0
br i1 %neq, label %if.then4, label %if.exit5
if.then3: ; preds = %loop.exit
if.then4: ; preds = %loop.exit
call void @putchar(i32 10)
br label %if.exit4
br label %if.exit5
if.exit4: ; preds = %if.then3, %loop.exit
if.exit5: ; preds = %if.then4, %loop.exit
ret void
}
@@ -225,104 +224,102 @@ entry:
%i = alloca i32, align 4
%v = alloca double, align 8
%j = alloca i32, align 4
%5 = getelementptr inbounds { ptr, i64 }, ptr %symb, i32 0, i32 0
store ptr %0, ptr %5, align 8
%6 = getelementptr inbounds { ptr, i64 }, ptr %symb, i32 0, i32 1
store i64 %1, ptr %6, align 8
%7 = getelementptr inbounds { ptr, i64 }, ptr %probability, i32 0, i32 0
store ptr %2, ptr %7, align 8
%8 = getelementptr inbounds { ptr, i64 }, ptr %probability, i32 0, i32 1
store i64 %3, ptr %8, align 8
%9 = getelementptr inbounds %"char[]", ptr %symb, i32 0, i32 1
%10 = load i64, ptr %9, align 8
%11 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 1
%12 = load i64, ptr %11, align 8
%eq = icmp eq i64 %10, %12
store ptr %0, ptr %symb, align 8
%ptroffset = getelementptr inbounds i64, ptr %symb, i64 1
store i64 %1, ptr %ptroffset, align 8
store ptr %2, ptr %probability, align 8
%ptroffset1 = getelementptr inbounds i64, ptr %probability, i64 1
store i64 %3, ptr %ptroffset1, align 8
%5 = getelementptr inbounds %"char[]", ptr %symb, i32 0, i32 1
%6 = load i64, ptr %5, align 8
%7 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 1
%8 = load i64, ptr %7, align 8
%eq = icmp eq i64 %6, %8
call void @llvm.assume(i1 %eq)
%13 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 1
%14 = load i64, ptr %13, align 8
%uisitrunc = trunc i64 %14 to i32
%9 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 1
%10 = load i64, ptr %9, align 8
%uisitrunc = trunc i64 %10 to i32
store i32 %uisitrunc, ptr %len, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %if.exit9, %entry
%15 = load i32, ptr %i, align 4
%lt = icmp slt i32 %15, %4
br i1 %lt, label %loop.body, label %loop.exit11
loop.cond: ; preds = %if.exit11, %entry
%11 = load i32, ptr %i, align 4
%lt = icmp slt i32 %11, %4
br i1 %lt, label %loop.body, label %loop.exit13
loop.body: ; preds = %loop.cond
%16 = call float @fasta_fasta_rand(float 1.000000e+00)
%fpfpext = fpext float %16 to double
%12 = call float @fasta_fasta_rand(float 1.000000e+00)
%fpfpext = fpext float %12 to double
store double %fpfpext, ptr %v, align 8
store i32 0, ptr %j, align 4
br label %loop.cond1
br label %loop.cond2
loop.cond1: ; preds = %if.exit, %loop.body
%17 = load i32, ptr %j, align 4
%18 = load i32, ptr %len, align 4
%sub = sub i32 %18, 1
%lt2 = icmp slt i32 %17, %sub
br i1 %lt2, label %loop.body3, label %loop.exit
loop.cond2: ; preds = %if.exit, %loop.body
%13 = load i32, ptr %j, align 4
%14 = load i32, ptr %len, align 4
%sub = sub i32 %14, 1
%lt3 = icmp slt i32 %13, %sub
br i1 %lt3, label %loop.body4, label %loop.exit
loop.body3: ; preds = %loop.cond1
%19 = load double, ptr %v, align 8
%20 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 0
%21 = load ptr, ptr %20, align 8
%22 = load i32, ptr %j, align 4
%sisiext = sext i32 %22 to i64
%ptroffset = getelementptr inbounds double, ptr %21, i64 %sisiext
%23 = load double, ptr %ptroffset, align 8
%fsub = fsub double %19, %23
loop.body4: ; preds = %loop.cond2
%15 = load double, ptr %v, align 8
%16 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 0
%17 = load ptr, ptr %16, align 8
%18 = load i32, ptr %j, align 4
%sisiext = sext i32 %18 to i64
%ptroffset5 = getelementptr inbounds double, ptr %17, i64 %sisiext
%19 = load double, ptr %ptroffset5, align 8
%fsub = fsub double %15, %19
store double %fsub, ptr %v, align 8
%24 = load double, ptr %v, align 8
%lt4 = fcmp olt double %24, 0.000000e+00
br i1 %lt4, label %if.then, label %if.exit
%20 = load double, ptr %v, align 8
%lt6 = fcmp olt double %20, 0.000000e+00
br i1 %lt6, label %if.then, label %if.exit
if.then: ; preds = %loop.body3
if.then: ; preds = %loop.body4
br label %loop.exit
if.exit: ; preds = %loop.body3
%25 = load i32, ptr %j, align 4
%add = add i32 %25, 1
if.exit: ; preds = %loop.body4
%21 = load i32, ptr %j, align 4
%add = add i32 %21, 1
store i32 %add, ptr %j, align 4
br label %loop.cond1
br label %loop.cond2
loop.exit: ; preds = %if.then, %loop.cond1
%26 = getelementptr inbounds %"char[]", ptr %symb, i32 0, i32 0
%27 = load ptr, ptr %26, align 8
%28 = load i32, ptr %j, align 4
%sisiext5 = sext i32 %28 to i64
%ptroffset6 = getelementptr inbounds i8, ptr %27, i64 %sisiext5
%29 = load i8, ptr %ptroffset6, align 1
%uisiext = zext i8 %29 to i32
loop.exit: ; preds = %if.then, %loop.cond2
%22 = getelementptr inbounds %"char[]", ptr %symb, i32 0, i32 0
%23 = load ptr, ptr %22, align 8
%24 = load i32, ptr %j, align 4
%sisiext7 = sext i32 %24 to i64
%ptroffset8 = getelementptr inbounds i8, ptr %23, i64 %sisiext7
%25 = load i8, ptr %ptroffset8, align 1
%uisiext = zext i8 %25 to i32
call void @putchar(i32 %uisiext)
%30 = load i32, ptr %i, align 4
%smod = srem i32 %30, 60
%eq7 = icmp eq i32 %smod, 59
br i1 %eq7, label %if.then8, label %if.exit9
%26 = load i32, ptr %i, align 4
%smod = srem i32 %26, 60
%eq9 = icmp eq i32 %smod, 59
br i1 %eq9, label %if.then10, label %if.exit11
if.then8: ; preds = %loop.exit
if.then10: ; preds = %loop.exit
call void @putchar(i32 10)
br label %if.exit9
br label %if.exit11
if.exit9: ; preds = %if.then8, %loop.exit
%31 = load i32, ptr %i, align 4
%add10 = add i32 %31, 1
store i32 %add10, ptr %i, align 4
if.exit11: ; preds = %if.then10, %loop.exit
%27 = load i32, ptr %i, align 4
%add12 = add i32 %27, 1
store i32 %add12, ptr %i, align 4
br label %loop.cond
loop.exit11: ; preds = %loop.cond
%32 = load i32, ptr %i, align 4
%smod12 = srem i32 %32, 60
%neq = icmp ne i32 %smod12, 0
br i1 %neq, label %if.then13, label %if.exit14
loop.exit13: ; preds = %loop.cond
%28 = load i32, ptr %i, align 4
%smod14 = srem i32 %28, 60
%neq = icmp ne i32 %smod14, 0
br i1 %neq, label %if.then15, label %if.exit16
if.then13: ; preds = %loop.exit11
if.then15: ; preds = %loop.exit13
call void @putchar(i32 10)
br label %if.exit14
br label %if.exit16
if.exit14: ; preds = %if.then13, %loop.exit11
if.exit16: ; preds = %if.then15, %loop.exit13
ret void
}

View File

@@ -35,16 +35,15 @@ define void @foo_test1(i64 %0, ptr %1) #0 {
entry:
%z = alloca %variant, align 8
%w = alloca ptr, align 8
%2 = getelementptr inbounds { i64, ptr }, ptr %z, i32 0, i32 0
store i64 %0, ptr %2, align 8
%3 = getelementptr inbounds { i64, ptr }, ptr %z, i32 0, i32 1
store ptr %1, ptr %3, align 8
%4 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
store ptr %5, ptr %w, align 8
%6 = load ptr, ptr %w, align 8
%7 = load i32, ptr %6, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %7)
store i64 %0, ptr %z, align 8
%ptroffset = getelementptr inbounds ptr, ptr %z, i64 1
store ptr %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%3 = load ptr, ptr %2, align 8
store ptr %3, ptr %w, align 8
%4 = load ptr, ptr %w, align 8
%5 = load i32, ptr %4, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %5)
ret void
}
@@ -52,16 +51,15 @@ define void @foo_test2(ptr %0, i64 %1) #0 {
entry:
%z = alloca %"int[]", align 8
%w = alloca ptr, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %z, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %z, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds %"int[]", ptr %z, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
store ptr %5, ptr %w, align 8
%6 = load ptr, ptr %w, align 8
%7 = load i32, ptr %6, align 4
call void (ptr, ...) @printf(ptr @.str.1, i32 %7)
store ptr %0, ptr %z, align 8
%ptroffset = getelementptr inbounds i64, ptr %z, i64 1
store i64 %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %"int[]", ptr %z, i32 0, i32 0
%3 = load ptr, ptr %2, align 8
store ptr %3, ptr %w, align 8
%4 = load ptr, ptr %w, align 8
%5 = load i32, ptr %4, align 4
call void (ptr, ...) @printf(ptr @.str.1, i32 %5)
ret void
}

View File

@@ -65,7 +65,7 @@ entry:
if.then: ; preds = %entry
%1 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(ptr @std_io_tostring_functions, i32
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(ptr @std_io_tostring_functions, i32 64, float 7.500000e-01, ptr %1)
br label %if.exit
if.exit: ; preds = %if.then, %entry
@@ -131,7 +131,7 @@ entry:
%retparam36 = alloca i64, align 8
%varargslots37 = alloca [1 x %variant], align 16
%result = alloca %"Foo[]", align 8
%map2 = alloca %HashMap.3, align 8
%map2 = alloca %HashMap.2, align 8
%retparam41 = alloca i64, align 8
%varargslots42 = alloca [1 x %variant], align 16
%taddr43 = alloca i8, align 1
@@ -148,7 +148,7 @@ entry:
%error_var = alloca i64, align 8
%retparam65 = alloca ptr, align 8
%mark = alloca i64, align 8
%map3 = alloca %HashMap.3, align 8
%map3 = alloca %HashMap.2, align 8
%retparam68 = alloca i64, align 8
%varargslots69 = alloca [1 x %variant], align 16
%result70 = alloca %"int[]", align 8

View File

@@ -41,7 +41,6 @@ cond.rhs: ; preds = %entry
cond.phi: ; preds = %cond.rhs, %cond.lhs
%val = phi %Event [ %1, %cond.lhs ], [ %2, %cond.rhs ]
store %Event %val, ptr %taddr, align 4
%3 = getelementptr inbounds %Event, ptr %taddr, i32 0, i32 0
%4 = load i32, ptr %3, align 4
ret i32 %4
%3 = load i32, ptr %taddr, align 4
ret i32 %3
}

View File

@@ -36,7 +36,6 @@ cond.rhs: ; preds = %entry
cond.phi: ; preds = %cond.rhs, %cond.lhs
%val = phi %Event [ %1, %cond.lhs ], [ %2, %cond.rhs ]
store %Event %val, ptr %taddr, align 4
%3 = getelementptr inbounds %Event, ptr %taddr, i32 0, i32 0
%4 = load i32, ptr %3, align 4
ret i32 %4
%3 = load i32, ptr %taddr, align 4
ret i32 %3
}

View File

@@ -68,40 +68,39 @@ entry:
%switch = alloca i64, align 8
%z1 = alloca ptr, align 8
%z4 = alloca ptr, align 8
%2 = getelementptr inbounds { i64, ptr }, ptr %z, i32 0, i32 0
store i64 %0, ptr %2, align 8
%3 = getelementptr inbounds { i64, ptr }, ptr %z, i32 0, i32 1
store ptr %1, ptr %3, align 8
%4 = getelementptr inbounds %variant, ptr %z, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %switch, align 8
store i64 %0, ptr %z, align 8
%ptroffset = getelementptr inbounds ptr, ptr %z, i64 1
store ptr %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %variant, ptr %z, i32 0, i32 1
%3 = load i64, ptr %2, align 8
store i64 %3, ptr %switch, align 8
br label %switch.entry
switch.entry: ; preds = %entry
%6 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %6
%4 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %4
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
%7 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
store ptr %8, ptr %z1, align 8
%9 = load ptr, ptr %z1, align 8
%10 = load i32, ptr %9, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %10)
%5 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
store ptr %6, ptr %z1, align 8
%7 = load ptr, ptr %z1, align 8
%8 = load i32, ptr %7, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %8)
br label %switch.exit
next_if: ; preds = %switch.entry
%eq2 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %6
%eq2 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %4
br i1 %eq2, label %switch.case3, label %next_if5
switch.case3: ; preds = %next_if
%11 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%12 = load ptr, ptr %11, align 8
store ptr %12, ptr %z4, align 8
%13 = load ptr, ptr %z4, align 8
%14 = load double, ptr %13, align 8
call void (ptr, ...) @printf(ptr @.str.1, double %14)
%9 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%10 = load ptr, ptr %9, align 8
store ptr %10, ptr %z4, align 8
%11 = load ptr, ptr %z4, align 8
%12 = load double, ptr %11, align 8
call void (ptr, ...) @printf(ptr @.str.1, double %12)
br label %switch.exit
next_if5: ; preds = %next_if
@@ -123,45 +122,44 @@ entry:
%z = alloca ptr, align 8
%taddr = alloca i32, align 4
%z3 = alloca ptr, align 8
%2 = getelementptr inbounds { i64, ptr }, ptr %y, i32 0, i32 0
store i64 %0, ptr %2, align 8
%3 = getelementptr inbounds { i64, ptr }, ptr %y, i32 0, i32 1
store ptr %1, ptr %3, align 8
store i64 %0, ptr %y, align 8
%ptroffset = getelementptr inbounds ptr, ptr %y, i64 1
store ptr %1, ptr %ptroffset, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %.anon, ptr align 8 %y, i32 16, i1 false)
%4 = getelementptr inbounds %variant, ptr %y, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %switch, align 8
%2 = getelementptr inbounds %variant, ptr %y, i32 0, i32 1
%3 = load i64, ptr %2, align 8
store i64 %3, ptr %switch, align 8
br label %switch.entry
switch.entry: ; preds = %entry
%6 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %6
%4 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %4
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
%7 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
store ptr %8, ptr %z, align 8
%5 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
store ptr %6, ptr %z, align 8
store i32 12, ptr %taddr, align 4
%9 = insertvalue %variant undef, ptr %taddr, 0
%10 = insertvalue %variant %9, i64 ptrtoint (ptr @"ct$int" to i64), 1
store %variant %10, ptr %y, align 8
%11 = load ptr, ptr %z, align 8
%12 = load i32, ptr %11, align 4
call void (ptr, ...) @printf(ptr @.str.3, i32 %12)
%7 = insertvalue %variant undef, ptr %taddr, 0
%8 = insertvalue %variant %7, i64 ptrtoint (ptr @"ct$int" to i64), 1
store %variant %8, ptr %y, align 8
%9 = load ptr, ptr %z, align 8
%10 = load i32, ptr %9, align 4
call void (ptr, ...) @printf(ptr @.str.3, i32 %10)
br label %switch.exit
next_if: ; preds = %switch.entry
%eq1 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %6
%eq1 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %4
br i1 %eq1, label %switch.case2, label %next_if4
switch.case2: ; preds = %next_if
%13 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%14 = load ptr, ptr %13, align 8
store ptr %14, ptr %z3, align 8
%15 = load ptr, ptr %z3, align 8
%16 = load double, ptr %15, align 8
call void (ptr, ...) @printf(ptr @.str.4, double %16)
%11 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%12 = load ptr, ptr %11, align 8
store ptr %12, ptr %z3, align 8
%13 = load ptr, ptr %z3, align 8
%14 = load double, ptr %13, align 8
call void (ptr, ...) @printf(ptr @.str.4, double %14)
br label %switch.exit
next_if4: ; preds = %next_if
@@ -182,41 +180,40 @@ entry:
%switch = alloca i64, align 8
%z = alloca i32, align 4
%z3 = alloca double, align 8
%2 = getelementptr inbounds { i64, ptr }, ptr %y, i32 0, i32 0
store i64 %0, ptr %2, align 8
%3 = getelementptr inbounds { i64, ptr }, ptr %y, i32 0, i32 1
store ptr %1, ptr %3, align 8
store i64 %0, ptr %y, align 8
%ptroffset = getelementptr inbounds ptr, ptr %y, i64 1
store ptr %1, ptr %ptroffset, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %.anon, ptr align 8 %y, i32 16, i1 false)
%4 = getelementptr inbounds %variant, ptr %y, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %switch, align 8
%2 = getelementptr inbounds %variant, ptr %y, i32 0, i32 1
%3 = load i64, ptr %2, align 8
store i64 %3, ptr %switch, align 8
br label %switch.entry
switch.entry: ; preds = %entry
%6 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %6
%4 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %4
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
%7 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
%9 = load i32, ptr %8, align 4
store i32 %9, ptr %z, align 4
%10 = load i32, ptr %z, align 4
call void (ptr, ...) @printf(ptr @.str.6, i32 %10)
%5 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
%7 = load i32, ptr %6, align 4
store i32 %7, ptr %z, align 4
%8 = load i32, ptr %z, align 4
call void (ptr, ...) @printf(ptr @.str.6, i32 %8)
br label %switch.exit
next_if: ; preds = %switch.entry
%eq1 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %6
%eq1 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %4
br i1 %eq1, label %switch.case2, label %next_if4
switch.case2: ; preds = %next_if
%11 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%12 = load ptr, ptr %11, align 8
%13 = load double, ptr %12, align 8
store double %13, ptr %z3, align 8
%14 = load double, ptr %z3, align 8
call void (ptr, ...) @printf(ptr @.str.7, double %14)
%9 = getelementptr inbounds %variant, ptr %.anon, i32 0, i32 0
%10 = load ptr, ptr %9, align 8
%11 = load double, ptr %10, align 8
store double %11, ptr %z3, align 8
%12 = load double, ptr %z3, align 8
call void (ptr, ...) @printf(ptr @.str.7, double %12)
br label %switch.exit
next_if4: ; preds = %next_if

View File

@@ -40,42 +40,41 @@ entry:
%switch = alloca i64, align 8
%z1 = alloca ptr, align 8
%z4 = alloca ptr, align 8
%2 = getelementptr inbounds { i64, ptr }, ptr %z, i32 0, i32 0
store i64 %0, ptr %2, align 8
%3 = getelementptr inbounds { i64, ptr }, ptr %z, i32 0, i32 1
store ptr %1, ptr %3, align 8
%4 = getelementptr inbounds %variant, ptr %z, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %switch, align 8
store i64 %0, ptr %z, align 8
%ptroffset = getelementptr inbounds ptr, ptr %z, i64 1
store ptr %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %variant, ptr %z, i32 0, i32 1
%3 = load i64, ptr %2, align 8
store i64 %3, ptr %switch, align 8
br label %switch.entry
switch.entry: ; preds = %entry
%6 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %6
%4 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %4
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
%7 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%8 = load ptr, ptr %7, align 8
store ptr %8, ptr %z1, align 8
%5 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%6 = load ptr, ptr %5, align 8
store ptr %6, ptr %z1, align 8
%7 = load ptr, ptr %z1, align 8
%8 = load i32, ptr %7, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %8)
%9 = load ptr, ptr %z1, align 8
%10 = load i32, ptr %9, align 4
call void (ptr, ...) @printf(ptr @.str, i32 %10)
%11 = load ptr, ptr %z1, align 8
store i32 3, ptr %11, align 4
store i32 3, ptr %9, align 4
br label %switch.exit
next_if: ; preds = %switch.entry
%eq2 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %6
%eq2 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %4
br i1 %eq2, label %switch.case3, label %next_if5
switch.case3: ; preds = %next_if
%12 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%13 = load ptr, ptr %12, align 8
store ptr %13, ptr %z4, align 8
%14 = load ptr, ptr %z4, align 8
%15 = load double, ptr %14, align 8
call void (ptr, ...) @printf(ptr @.str.1, double %15)
%10 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%11 = load ptr, ptr %10, align 8
store ptr %11, ptr %z4, align 8
%12 = load ptr, ptr %z4, align 8
%13 = load double, ptr %12, align 8
call void (ptr, ...) @printf(ptr @.str.1, double %13)
br label %switch.exit
next_if5: ; preds = %next_if
@@ -86,16 +85,16 @@ switch.default: ; preds = %next_if5
br label %switch.exit
switch.exit: ; preds = %switch.default, %switch.case3, %switch.case
%16 = getelementptr inbounds %variant, ptr %z, i32 0, i32 1
%17 = load i64, ptr %16, align 8
%eq6 = icmp eq i64 %17, ptrtoint (ptr @"ct$int" to i64)
%14 = getelementptr inbounds %variant, ptr %z, i32 0, i32 1
%15 = load i64, ptr %14, align 8
%eq6 = icmp eq i64 %15, ptrtoint (ptr @"ct$int" to i64)
br i1 %eq6, label %if.then, label %if.exit
if.then: ; preds = %switch.exit
%18 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%19 = load ptr, ptr %18, align 8
%20 = load i32, ptr %19, align 4
call void (ptr, ...) @printf(ptr @.str.3, i32 %20)
%16 = getelementptr inbounds %variant, ptr %z, i32 0, i32 0
%17 = load ptr, ptr %16, align 8
%18 = load i32, ptr %17, align 4
call void (ptr, ...) @printf(ptr @.str.3, i32 %18)
br label %if.exit
if.exit: ; preds = %if.then, %switch.exit

View File

@@ -76,18 +76,17 @@ define void @foo_test(i64 %0, ptr %1) #0 {
entry:
%x = alloca %variant, align 8
%switch = alloca i64, align 8
%2 = getelementptr inbounds { i64, ptr }, ptr %x, i32 0, i32 0
store i64 %0, ptr %2, align 8
%3 = getelementptr inbounds { i64, ptr }, ptr %x, i32 0, i32 1
store ptr %1, ptr %3, align 8
%4 = getelementptr inbounds %variant, ptr %x, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %switch, align 8
store i64 %0, ptr %x, align 8
%ptroffset = getelementptr inbounds ptr, ptr %x, i64 1
store ptr %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %variant, ptr %x, i32 0, i32 1
%3 = load i64, ptr %2, align 8
store i64 %3, ptr %switch, align 8
br label %switch.entry
switch.entry: ; preds = %entry
%6 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %6
%4 = load i64, ptr %switch, align 8
%eq = icmp eq i64 ptrtoint (ptr @"ct$int" to i64), %4
br i1 %eq, label %switch.case, label %next_if
switch.case: ; preds = %switch.entry
@@ -95,7 +94,7 @@ switch.case: ; preds = %switch.entry
br label %switch.exit
next_if: ; preds = %switch.entry
%eq1 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %6
%eq1 = icmp eq i64 ptrtoint (ptr @"ct$double" to i64), %4
br i1 %eq1, label %switch.case2, label %next_if3
switch.case2: ; preds = %next_if
@@ -103,7 +102,7 @@ switch.case2: ; preds = %next_if
br label %switch.exit
next_if3: ; preds = %next_if
%eq4 = icmp eq i64 ptrtoint (ptr @"ct$variant" to i64), %6
%eq4 = icmp eq i64 ptrtoint (ptr @"ct$variant" to i64), %4
br i1 %eq4, label %switch.case5, label %next_if6
switch.case5: ; preds = %next_if3
@@ -111,7 +110,7 @@ switch.case5: ; preds = %next_if3
br label %switch.exit
next_if6: ; preds = %next_if3
%eq7 = icmp eq i64 ptrtoint (ptr @"ct$p$int" to i64), %6
%eq7 = icmp eq i64 ptrtoint (ptr @"ct$p$int" to i64), %4
br i1 %eq7, label %switch.case8, label %next_if9
switch.case8: ; preds = %next_if6
@@ -136,35 +135,34 @@ entry:
%.anon = alloca i64, align 8
%.anon1 = alloca i64, align 8
%element = alloca %variant, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %y, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %y, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds %"variant[]", ptr %y, i32 0, i32 1
%5 = load i64, ptr %4, align 8
store i64 %5, ptr %.anon, align 8
store ptr %0, ptr %y, align 8
%ptroffset = getelementptr inbounds i64, ptr %y, i64 1
store i64 %1, ptr %ptroffset, align 8
%2 = getelementptr inbounds %"variant[]", ptr %y, i32 0, i32 1
%3 = load i64, ptr %2, align 8
store i64 %3, ptr %.anon, align 8
store i64 0, ptr %.anon1, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%6 = load i64, ptr %.anon1, align 8
%7 = load i64, ptr %.anon, align 8
%lt = icmp ult i64 %6, %7
%4 = load i64, ptr %.anon1, align 8
%5 = load i64, ptr %.anon, align 8
%lt = icmp ult i64 %4, %5
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%8 = getelementptr inbounds %"variant[]", ptr %y, i32 0, i32 0
%9 = load ptr, ptr %8, align 8
%10 = load i64, ptr %.anon1, align 8
%ptroffset = getelementptr inbounds %variant, ptr %9, i64 %10
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %element, ptr align 8 %ptroffset, i32 16, i1 false)
%11 = getelementptr inbounds { i64, ptr }, ptr %element, i32 0, i32 0
%lo = load i64, ptr %11, align 8
%12 = getelementptr inbounds { i64, ptr }, ptr %element, i32 0, i32 1
%hi = load ptr, ptr %12, align 8
%6 = getelementptr inbounds %"variant[]", ptr %y, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%8 = load i64, ptr %.anon1, align 8
%ptroffset2 = getelementptr inbounds %variant, ptr %7, i64 %8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %element, ptr align 8 %ptroffset2, i32 16, i1 false)
%9 = getelementptr inbounds { i64, ptr }, ptr %element, i32 0, i32 0
%lo = load i64, ptr %9, align 8
%10 = getelementptr inbounds { i64, ptr }, ptr %element, i32 0, i32 1
%hi = load ptr, ptr %10, align 8
call void @foo_test(i64 %lo, ptr %hi)
%13 = load i64, ptr %.anon1, align 8
%add = add i64 %13, 1
%11 = load i64, ptr %.anon1, align 8
%add = add i64 %11, 1
store i64 %add, ptr %.anon1, align 8
br label %loop.cond

View File

@@ -1,34 +0,0 @@
// #target: macos-aarch64
module test;
struct Large {
void*[8] pointers;
}
extern fn void pass_large(Large);
fn void example() {
Large l = {};
pass_large(l);
pass_large(l);
}
/* #expect: test.ll
define void @test_example() #0 {
entry:
%l = alloca %Large, align 8
%indirectarg = alloca %Large, align 8
%indirectarg1 = alloca %Large, align 8
%0 = bitcast %Large* %l to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 64, i1 false)
%1 = bitcast %Large* %indirectarg to i8*
%2 = bitcast %Large* %l to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 8 %2, i32 64, i1 false)
call void @pass_large(%Large* align 8 %indirectarg)
%3 = bitcast %Large* %indirectarg1 to i8*
%4 = bitcast %Large* %l to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %3, i8* align 8 %4, i32 64, i1 false)
call void @pass_large(%Large* align 8 %indirectarg1)
ret void
}

View File

@@ -1,32 +0,0 @@
// #target: macos-aarch64
module test;
define Int8x16 = ichar[<16>];
define Float32x3 = float[<3>];
struct HFAv3
{
Float32x3[4] arr;
}
struct MixedHFAv3
{
Float32x3[3] arr;
Int8x16 b;
}
fn HFAv3 test(HFAv3 a0, HFAv3 a1, HFAv3 a2) {
return a2;
}
fn MixedHFAv3 test_mixed(MixedHFAv3 a0, MixedHFAv3 a1, MixedHFAv3 a2) {
return a2;
}
/* #expect: test.ll
%HFAv3 = type { [4 x <3 x float>] }
%MixedHFAv3 = type { [3 x <3 x float>], <16 x i8> }
define %HFAv3 @test_test([4 x <4 x float>] %0, [4 x <4 x float>] %1, [4 x <4 x float>] %2)
define %MixedHFAv3 @test_test_mixed([4 x <4 x float>] %0, [4 x <4 x float>] %1, [4 x <4 x float>] %2) #0 {

View File

@@ -1,141 +0,0 @@
// #target: macos-x64
// #opt: --x86vec=avx
module test;
define Mm256 = float[<8>];
struct St256 {
Mm256 m;
}
St256 x38;
Mm256 x37;
extern fn void f38(St256 x);
extern fn void f37(Mm256 x);
fn void f39() { f38(x38); f37(x37); }
// The two next tests make sure that the struct below is passed
// in the same way regardless of avx being used
// CHECK: declare void @func40(%struct.t128* byval(%struct.t128) align 16)
define Mm128 = float[<4>];
struct Two128 {
Mm128 m;
Mm128 n;
}
extern fn void func40(Two128 s);
fn void func41(Two128 s) {
func40(s);
}
struct Atwo128 {
Mm128[2] array;
}
struct Sa {
Atwo128 x;
}
extern fn void func42(Sa s);
fn void func43(Sa s) {
func42(s);
}
define Vec46 = float[<2>];
extern fn void f46(Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46);
fn void test46() { Vec46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
struct Vec47 { uint a; }
extern fn void f47(int,int,int,int,int,int,Vec47);
fn void test47(int a, Vec47 b) { f47(a, a, a, a, a, a, b); }
fn void test49_helper(double, ...);
fn void test49(double d, double e) { test49_helper(d, e); }
struct Complex { double i; double c; }
extern fn void test52_helper(int, ...);
Mm256 x52;
fn void test52() {
test52_helper(0, x52, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 0, 1.0 });
}
extern fn void test54_helper(Mm256, ...);
Mm256 x54;
fn void test54() {
test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 0, 1.0 });
test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 0, 1.0 });
}
define Mm512 = float[<16>];
struct St512 {
Mm512 m;
}
St512 x55;
Mm512 x56;
extern fn void f55(St512 x);
extern fn void f56(Mm512 x);
fn void f57() { f55(x55); f56(x56); }
struct Two256 {
Mm256 m;
Mm256 n;
}
extern fn void f58(Two256 s);
fn void f59(Two256 s) {
f58(s);
}
struct Atwo256 {
Mm256[2] array;
}
struct SAtwo256 {
Atwo256 x;
}
extern fn void f60(SAtwo256 s);
fn void f61(SAtwo256 s) {
f60(s);
}
/* #expect: test.ll
declare void @f38(<8 x float>)
declare void @f37(<8 x float>)
declare void @func40(%Two128* byval(%Two128) align 16)
define void @test_func41(%Two128* byval(%Two128) align 16 %0)
declare void @func42(%Sa* byval(%Sa) align 16)
define void @test_func43(%Sa* byval(%Sa) align 16 %0)
declare void @f46(double, double, double, double, double, double, double, double, <2 x float>* byval(<2 x float>) align 8, <2 x float>* byval(<2 x float>) align 8)
declare void @f47(i32, i32, i32, i32, i32, i32, i32)
declare void @test_test49_helper(double, ...)
define void @test_test49(double %0, double %1)
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 (<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, %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
declare void @f58(%Two256* byval(%Two256) align 32) #0
define void @test_f59(%Two256* byval(%Two256) align 32 %0) #0 {
declare void @f60(%SAtwo256* byval(%SAtwo256) align 32) #0
define void @test_f61(%SAtwo256* byval(%SAtwo256) align 32 %0) #0 {

View File

@@ -1,75 +0,0 @@
// #target: macos-x64
// #opt: --x86vec=avx512
module test;
define Mm256 = float[<8>];
define Mm512 = float[<16>];
struct St512 {
Mm512 m;
}
St512 x55;
Mm512 x56;
extern fn void f55(St512 x);
extern fn void f56(Mm512 x);
fn void f57() { f55(x55); f56(x56); }
struct Two256 {
Mm256 m;
Mm256 n;
}
extern fn void f58(Two256 s);
fn void f59(Two256 s) {
f58(s);
}
struct Atwo256 {
Mm256[2] array;
}
struct SAtwo256 {
Atwo256 x;
}
extern fn void f60(SAtwo256 s);
fn void f61(SAtwo256 s) {
f60(s);
}
struct Complex { double i; double c; }
// AVX512: @f62_helper(i32 0, <16 x float> {{%[a-zA-Z0-9]+}}, 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 {{%[a-zA-Z0-9]+}}, double {{%[a-zA-Z0-9]+}})
fn void f62_helper(int, ...);
Mm512 x62;
fn void f62() {
f62_helper(0, x62, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 1.0, 1.0 });
}
fn void f64_helper(Mm512, ...);
Mm512 x64;
fn void f64() {
f64_helper(x64, x64, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 1.0, 1.0 });
f64_helper(x64, x64, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 1.0, 1.0 });
}
/* #expect: test.ll
declare void @f55(<16 x float>) #0
declare void @f56(<16 x float>) #0
declare void @f58(%Two256* byval(%Two256) align 32) #0
define void @test_f59(%Two256* byval(%Two256) align 32 %0) #0 {
declare void @f60(%SAtwo256* byval(%SAtwo256) align 32) #0
define void @test_f61(%SAtwo256* byval(%SAtwo256) align 32 %0) #0 {
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, %Complex* byval(%Complex) align 8 %literal1)

View File

@@ -1,21 +0,0 @@
// #target: macos-x64
module foo;
struct SimdDouble4x4
{
double[<4>][4] columns;
}
fn SimdDouble4x4 ident(SimdDouble4x4 x) {
return x;
}
/* #expect: foo.ll
define void @foo_ident(%SimdDouble4x4* noalias sret(%SimdDouble4x4) align 32 %0, %SimdDouble4x4* byval(%SimdDouble4x4) align 32 %1) #0 {
entry:
%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)
ret void
}

View File

@@ -1,56 +0,0 @@
// #target: macos-x64
// #opt: --x86vec=sse
module test;
define Mm256 = float[<8>];
struct St256 {
Mm256 m;
}
St256 x38;
Mm256 x37;
extern fn void f38(St256 x);
extern fn void f37(Mm256 x);
fn void f39() { f38(x38); f37(x37); }
// The two next tests make sure that the struct below is passed
// in the same way regardless of avx being used
// CHECK: declare void @func40(%struct.t128* byval(%struct.t128) align 16)
define Mm128 = float[<4>];
struct Two128 {
Mm128 m;
Mm128 n;
}
extern fn void func40(Two128 s);
fn void func41(Two128 s) {
func40(s);
}
struct Atwo128 {
Mm128[2] array;
}
struct Sa {
Atwo128 x;
}
extern fn void func42(Sa s);
fn void func43(Sa s) {
func42(s);
}
/* #expect: test.ll
declare void @f38(%St256* byval(%St256) align 32)
declare void @f37(<8 x float>* byval(<8 x float>) align 32)
declare void @func40(%Two128* byval(%Two128) align 16)
define void @test_func41(%Two128* byval(%Two128) align 16 %0)
declare void @func42(%Sa* byval(%Sa) align 16)
define void @test_func43(%Sa* byval(%Sa) align 16 %0)

View File

@@ -1,26 +0,0 @@
// #target: macos-x64
module test;
struct Str
{
union
{
float128 a;
long c;
}
}
extern fn void d(Str s);
Str ss;
fn void f9122143()
{
d(ss);
}
/* #expect: test.ll
declare void @d(i64, double) #0
%lo = load i64, i64* getelementptr inbounds ({ i64, double }, { i64, double }* bitcast (%Str* @test_ss to { i64, double }*), i32 0, i32 0), align 16
%hi = load double, double* getelementptr inbounds ({ i64, double }, { i64, double }* bitcast (%Str* @test_ss to { i64, double }*), i32 0, i32 1), align 8
call void @d(i64 %lo, double %hi)
ret void

View File

@@ -1,48 +0,0 @@
// #target: macos-x64
module test;
fn char f0() {
return 0;
}
fn short f1() {
return 0;
}
fn int f2() {
return 0;
}
fn float f3() {
return 0;
}
fn double f4() {
return 0;
}
fn void f6(char a0, short a1, int a2, long a3, void *a4) {}
enum Enum7 : int { A, B, C }
fn void f7(Enum7 a0) {}
struct Struct8
{
int a;
int b;
}
fn Struct8 f8_1() { while (1) {} return Struct8 {}; }
fn void f8_2(Struct8 a0) {}
/* #expect: test.ll
define zeroext i8 @test_f0()
define signext i16 @test_f1()
define i32 @test_f2()
define float @test_f3()
define double @test_f4()
define void @test_f6(i8 zeroext %0, i16 signext %1, i32 %2, i64 %3, i8* %4)
define void @test_f7(i32 %0)
define i64 @test_f8_1()
define void @test_f8_2(i64 %0) #0 {

View File

@@ -1,186 +0,0 @@
// #target: macos-x64
module test;
import std;
struct St12
{
int a @align(16);
}
fn St12 f12_0() { while (1) {}; unreachable(); }
fn void f12_1(St12 a0) {}
struct St13_0 { long[3] f0; }
struct St13_1 { long[2] f0; }
fn St13_0 f13(int a, int b, int c, int d,
St13_1 e, int f) { while (1) {}; unreachable(); }
fn void f14(int a, int b, int c, int d, int e, int f, ichar x) {}
fn void f15(int a, int b, int c, int d, int e, int f, void *x) {}
fn void f16(float a, float b, float c, float d, float e, float f, float g, float h,
float x) {}
struct Fl18_s0 { int f0; }
fn void fl18(int a, Fl18_s0 f18_arg1) { while (1) {} }
struct St20 @align(32) {
int x;
int y;
}
fn void f20(St20 x) {}
struct StringRef
{
int x;
char* ptr;
}
fn char *f21(StringRef s) { return s.x+s.ptr; }
struct St22s @align(16)
{ ulong[2] x; }
fn void f22(St22s x, St22s y) { }
struct St23S {
short f0;
uint f1;
int f2;
}
fn void f23(int a, St23S b) {
}
struct St24s { int a; int b; }
fn St23S f24(St23S *x, St24s *p2)
{
return *x;
}
fn float[<4>] f25(float[<4>] x) {
return x+x;
}
struct Foo26 {
int *x;
float *y;
}
fn Foo26 f26(Foo26 *p) {
return *p;
}
struct V4f32wrapper {
float[<4>] v;
}
fn V4f32wrapper f27(V4f32wrapper x) {
return x;
}
// PR22563 - We should unwrap simple structs and arrays to pass
// and return them in the appropriate vector registers if possible.
define V8f32 = float[<8>];
struct V8f32wrapper {
V8f32 v;
}
fn V8f32wrapper f27a(V8f32wrapper x) {
return x;
}
struct V8f32wrapper_wrapper {
V8f32[1] v;
}
fn V8f32wrapper_wrapper f27b(V8f32wrapper_wrapper x) {
return x;
}
struct F28c {
double x;
int y;
}
fn void f28(F28c c) {
}
struct Inner
{
double x;
int y;
}
struct F29a
{
Inner[1] c;
}
fn void f29a(F29a a) {
}
struct St0 {
char[8] f0; char f2; char f3; char f4; }
fn void f30(St0 p_4) {
}
struct F31foo { float a, b, c; }
fn float f31(F31foo x) {
return x.c;
}
define V1i64 = ulong[<1>];
fn V1i64 f34(V1i64 arg) { return arg; }
define V1i64_2 = uint[<2>];
fn V1i64_2 f35(V1i64_2 arg) { return arg+arg; }
define V2i32 = float[<2>];
fn V2i32 f36(V2i32 arg) { return arg; }
/* #expect: test.ll
define i32 @test_f12_0()
define void @test_f12_1(i32 %0)
define void @test_f13(%St13_0* noalias sret(%St13_0) align 8 %0, i32 %1, i32 %2, i32 %3, i32 %4, %St13_1* byval(%St13_1) align 8 %5, i32 %6) #0 {
define void @test_f14(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 signext %6) #0 {
define void @test_f15(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8* %6)
define void @test_f16(float %0, float %1, float %2, float %3, float %4, float %5, float %6, float %7, float %8)
define void @test_fl18(i32 %0, i32 %1)
define void @test_f20(%St20* byval(%St20) align 32 %0)
define i8* @test_f21(i64 %0, i8* %1)
define void @test_f22(i64 %0, i64 %1, i64 %2, i64 %3)
entry:
%x = alloca %St22s, align 16
%y = alloca %St22s, align 16
define void @test_f23(i32 %0, i64 %1, i32 %2)
define { i64, i32 } @test_f24(%St23S* %0, %St24s* %1)
define <4 x float> @test_f25(<4 x float> %0) #0 {
entry:
%fadd = fadd <4 x float> %0, %0
ret <4 x float> %fadd
}
define { i32*, float* } @test_f26(%Foo26* %0)
define <4 x float> @test_f27(<4 x float> %0)
define <8 x float> @test_f27a(<8 x float> %0)
define <8 x float> @test_f27b(<8 x float> %0)
define void @test_f28(double %0, i32 %1)
define void @test_f29a(double %0, i32 %1)
define void @test_f30(i64 %0, i24 %1)
define float @test_f31(<2 x float> %0, float %1)
define double @test_f34(double %0)
define double @test_f35(double %0)
define double @test_f36(double %0)

View File

@@ -1,31 +0,0 @@
// #target: macos-x64
struct Test
{
int x;
}
Test foo = {};
extern fn void blorg(Test t);
fn Test creator()
{
blorg(Test{});
return Test{};
}
// #expect: literal_load.ll
%literal = alloca %Test, align 4
%literal1 = alloca %Test, align 4
%0 = bitcast %Test* %literal to i32*
store i32 0, i32* %0, align 4
%1 = getelementptr inbounds %Test, %Test* %literal, i32 0, i32 0
%2 = load i32, i32* %1, align 4
call void @blorg(i32 %2)
%3 = bitcast %Test* %literal1 to i32*
store i32 0, i32* %3, align 4
%4 = getelementptr inbounds %Test, %Test* %literal1, i32 0, i32 0
%5 = load i32, i32* %4, align 4
ret i32 %5

View File

@@ -1,38 +0,0 @@
// #target: linux-aarch64
module literal_load;
struct Test
{
int x;
}
Test foo = {};
extern fn void blorg(Test t);
fn Test creator()
{
blorg(Test{});
return Test{};
}
// #expect: literal_load.ll
declare void @blorg(i64) #0
define i32 @literal_load_creator() #0 {
entry:
%literal = alloca %Test, align 4
%literal1 = alloca %Test, align 4
%0 = bitcast %Test* %literal to i32*
store i32 0, i32* %0, align 4
%1 = getelementptr inbounds %Test, %Test* %literal, i32 0, i32 0
%2 = load i32, i32* %1, align 4
%3 = zext i32 %2 to i64
call void @blorg(i64 %3)
%4 = bitcast %Test* %literal1 to i32*
store i32 0, i32* %4, align 4
%5 = getelementptr inbounds %Test, %Test* %literal1, i32 0, i32 0
%6 = load i32, i32* %5, align 4
ret i32 %6
}

View File

@@ -1,32 +0,0 @@
// #target: mingw-x64
module literal_load;
struct Test
{
int x;
}
Test foo = {};
extern fn void blorg(Test t);
fn Test creator()
{
blorg(Test{});
return Test{};
}
// #expect: literal_load.ll
%literal = alloca %Test, align 4
%literal1 = alloca %Test, align 4
%0 = bitcast %Test* %literal to i32*
store i32 0, i32* %0, align 4
%1 = getelementptr inbounds %Test, %Test* %literal, i32 0, i32 0
%2 = load i32, i32* %1, align 4
call void @blorg(i32 %2)
%3 = bitcast %Test* %literal1 to i32*
store i32 0, i32* %3, align 4
%4 = getelementptr inbounds %Test, %Test* %literal1, i32 0, i32 0
%5 = load i32, i32* %4, align 4
ret i32 %5

View File

@@ -1,8 +0,0 @@
// #target: macos-x64
int foo @section("foo, 12345678901234567 "); // #error: Mach-o requires the section to be at the most 16 characters
int bar @section("foo, "); // #error: Mach-o requires 'segment,section' as the format, did you type it correctly?
int baz @section("foo"); // #error: Mach-o requires 'segment,section' as the format, did you type it correctly?
int abc @section("foo,b,c,d,e,f"); // #error: Too many parts to the Mach-o section description.
int def @section("foo,b,c,d");

View File

@@ -1,37 +0,0 @@
// #target: linux-aarch64
module pass_large;
struct Large
{
void*[8] pointers;
}
extern fn void pass_large(Large large);
fn void example()
{
Large l = {};
pass_large(l);
pass_large(l);
}
/* #expect: pass_large.ll
define void @pass_large_example()
entry:
%l = alloca %Large, align 8
%indirectarg = alloca %Large, align 8
%indirectarg1 = alloca %Large, align 8
%0 = bitcast %Large* %l to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 64, i1 false)
%1 = bitcast %Large* %indirectarg to i8*
%2 = bitcast %Large* %l to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 8 %2, i32 64, i1 false)
call void @pass_large(%Large* align 8 %indirectarg)
%3 = bitcast %Large* %indirectarg1 to i8*
%4 = bitcast %Large* %l to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %3, i8* align 8 %4, i32 64, i1 false)
call void @pass_large(%Large* align 8 %indirectarg1)
ret void

View File

@@ -1,55 +0,0 @@
// #target: mingw-x64
module test;
extern fn void printf(char*, ...);
struct Foo
{
float[2] x;
}
fn void test(Foo x) @regcall
{
}
fn int main()
{
test(Foo { });
return 0;
}
/* #expect: test.ll
%Foo = type { [2 x float] }
$"ct$test_Foo" = comdat any
@"ct$test_Foo" = linkonce constant %.introspect { i8 10, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8
define x86_regcallcc void @test_test(float %0, float %1) #0 {
entry:
%x = alloca %Foo, align 4
%2 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
%3 = getelementptr inbounds [2 x float], [2 x float]* %2, i64 0, i64 0
store float %0, float* %3, align 4
%4 = getelementptr inbounds [2 x float], [2 x float]* %2, i64 0, i64 1
store float %1, float* %4, align 4
ret void
}
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%literal = alloca %Foo, align 4
%0 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0
%1 = getelementptr inbounds [2 x float], [2 x float]* %0, i64 0, i64 0
store float 0.000000e+00, float* %1, align 4
%2 = getelementptr inbounds [2 x float], [2 x float]* %0, i64 0, i64 1
store float 0.000000e+00, float* %2, align 4
%3 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0
%4 = getelementptr inbounds [2 x float], [2 x float]* %3, i64 0, i64 0
%loadexpanded = load float, float* %4, align 4
%5 = getelementptr inbounds [2 x float], [2 x float]* %3, i64 0, i64 1
%loadexpanded1 = load float, float* %5, align 4
call x86_regcallcc void @test_test(float %loadexpanded, float %loadexpanded1)
ret i32 0
}

View File

@@ -1,48 +0,0 @@
// #target: linux-riscv64
module test;
struct Large {
long a, b, c, d;
}
define V32i8 = char[<32>];
fn int f_scalar_stack_1(int a, int128 b, float c, float128 d, V32i8 e,
char f, char g, char h) {
return g + h;
}
fn Large f_scalar_stack_2(double a, int128 b, float128 c, V32i8 d,
char e, ichar f, char g) {
return Large {(long)(a), e, f, g};
}
/* #expect: test.ll
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:
%uisiext = zext i8 %6 to i32
%uisiext1 = zext i8 %7 to i32
%add = add i32 %uisiext, %uisiext1
ret i32 %add
}
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:
%literal = alloca %Large, align 8
%8 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 0
%fpsi = fptosi double %1 to i64
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* %9, align 8
%10 = getelementptr inbounds %Large, %Large* %literal, i32 0, i32 2
%sisiext = sext i8 %6 to i64
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* %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

@@ -1,80 +0,0 @@
// #target: macos-x64
module test;
struct Foo
{
char a;
char b;
char c;
}
fn int testing()
{
Foo y = getFoo(Foo { 4, 5, 6 });
return y.a + y.c;
}
fn Foo getFoo(Foo f)
{
return Foo { 1, 2, 3 };
}
/* #expect: test.ll
define i32 @test_testing() #0 {
entry:
%y = alloca %Foo, align 1
%literal = alloca %Foo, align 1
%tempcoerce = alloca i24, align 4
%result = alloca %Foo, align 1
%tempcoerce1 = alloca i24, align 4
%0 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0
store i8 4, i8* %0, align 1
%1 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 1
store i8 5, i8* %1, align 1
%2 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 2
store i8 6, i8* %2, align 1
%3 = bitcast i24* %tempcoerce to i8*
%4 = bitcast %Foo* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 1 %4, i32 3, i1 false)
%5 = load i24, i24* %tempcoerce, align 4
%6 = call i24 @test_getFoo(i24 %5)
store i24 %6, i24* %tempcoerce1, align 4
%7 = bitcast %Foo* %result to i8*
%8 = bitcast i24* %tempcoerce1 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %7, i8* align 4 %8, i32 3, i1 false)
%9 = bitcast %Foo* %y to i8*
%10 = bitcast %Foo* %result to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %9, i8* align 1 %10, i32 3, i1 false)
%11 = getelementptr inbounds %Foo, %Foo* %y, i32 0, i32 0
%12 = load i8, i8* %11, align 1
%uisiext = zext i8 %12 to i32
%13 = getelementptr inbounds %Foo, %Foo* %y, i32 0, i32 2
%14 = load i8, i8* %13, align 1
%uisiext2 = zext i8 %14 to i32
%add = add i32 %uisiext, %uisiext2
ret i32 %add
}
; Function Attrs: nounwind
define i24 @test_getFoo(i24 %0) #0 {
entry:
%f = alloca %Foo, align 1
%tempcoerce = alloca i24, align 4
%literal = alloca %Foo, align 1
%tempcoerce1 = alloca i24, align 4
store i24 %0, i24* %tempcoerce, align 4
%1 = bitcast %Foo* %f to i8*
%2 = bitcast i24* %tempcoerce to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %1, i8* align 4 %2, i32 3, i1 false)
%3 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0
store i8 1, i8* %3, align 1
%4 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 1
store i8 2, i8* %4, align 1
%5 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 2
store i8 3, i8* %5, align 1
%6 = bitcast i24* %tempcoerce1 to i8*
%7 = bitcast %Foo* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %6, i8* align 1 %7, i32 3, i1 false)
%8 = load i24, i24* %tempcoerce1, align 4
ret i24 %8
}

View File

@@ -1,42 +0,0 @@
// #target: linux-x64
// #opt: --x86vec=avx512
module foo;
struct StringRef
{
char* str;
usz size;
}
char gc;
extern fn void take_stringref(StringRef s);
fn void callit()
{
StringRef s = { "asdf" , 4};
take_stringref(s);
}
extern fn float[<8>] get_m256();
extern fn void take_m256(float[<8>] x);
extern fn float[<16>] get_m512();
extern fn void take_m512(float[<16>] x);
fn void use_vectors()
{
float[<8>] v1 = get_m256();
take_m256(v1);
float[<16>] v2 = get_m512();
take_m512(v2);
}
/* #expect: foo.ll
declare void @take_stringref(i8*, i64) #0
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> %1)
%2 = call <16 x float> @get_m512()
call void @take_m512(<16 x float> %3)

View File

@@ -1,42 +0,0 @@
// #target: linux-x64
// #opt: --x86vec=none
module foo;
struct StringRef
{
char* str;
usz size;
}
char gc;
extern fn void take_stringref(StringRef s);
fn void callit()
{
StringRef s = { "asdf" , 4};
take_stringref(s);
}
extern fn float[<8>] get_m256();
extern fn void take_m256(float[<8>] x);
extern fn float[<16>] get_m512();
extern fn void take_m512(float[<16>] x);
fn void use_vectors()
{
float[<8>] v1 = get_m256();
take_m256(v1);
float[<16>] v2 = get_m512();
take_m512(v2);
}
/* #expect: foo.ll
declare void @take_stringref(i8*, i64) #0
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 %v1)
%1 = call <16 x float> @get_m512()
call void @take_m512(<16 x float>* byval(<16 x float>) align 64 %v2)

View File

@@ -1,47 +0,0 @@
// #target: macos-x64
module foo;
struct Rectangle
{
float x; // Rectangle top-left corner position x
float y; // Rectangle top-left corner position y
float width; // Rectangle width
float height; // Rectangle height
}
fn void test(Rectangle r)
{
test(Rectangle { 1, 2, 3, 4 });
}
/* #expect: foo.ll
define void @foo_test(<2 x float> %0, <2 x float> %1) #0 {
entry:
%r = alloca %Rectangle, align 4
%literal = alloca %Rectangle, align 4
%coerce = alloca %Rectangle, align 8
%pair = bitcast %Rectangle* %r to { <2 x float>, <2 x float> }*
%2 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %pair, i32 0, i32 0
store <2 x float> %0, <2 x float>* %2, align 4
%3 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %pair, i32 0, i32 1
store <2 x float> %1, <2 x float>* %3, align 4
%4 = getelementptr inbounds %Rectangle, %Rectangle* %literal, i32 0, i32 0
store float 1.000000e+00, float* %4, align 4
%5 = getelementptr inbounds %Rectangle, %Rectangle* %literal, i32 0, i32 1
store float 2.000000e+00, float* %5, align 4
%6 = getelementptr inbounds %Rectangle, %Rectangle* %literal, i32 0, i32 2
store float 3.000000e+00, float* %6, align 4
%7 = getelementptr inbounds %Rectangle, %Rectangle* %literal, i32 0, i32 3
store float 4.000000e+00, float* %7, align 4
%8 = bitcast %Rectangle* %coerce to { <2 x float>, <2 x float> }*
%9 = bitcast { <2 x float>, <2 x float> }* %8 to i8*
%10 = bitcast %Rectangle* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %9, i8* align 4 %10, i32 16, i1 false)
%11 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %8, i32 0, i32 0
%lo = load <2 x float>, <2 x float>* %11, align 8
%12 = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* %8, i32 0, i32 1
%hi = load <2 x float>, <2 x float>* %12, align 8
call void @foo_test(<2 x float> %lo, <2 x float> %hi)
ret void
}

View File

@@ -1,31 +0,0 @@
// #target: macos-x64
struct Abc {
long a;
long b;
long c;
long d;
long e;
}
extern fn Abc foo1();
extern fn Abc foo2();
fn void bar() {
Abc dummy1 = foo1();
Abc dummy2 = foo2();
}
// Cleanup for this result, since it's creating an unnecessary sret.
// #expect: test_sret.ll
declare void @foo1(%Abc* noalias sret(%Abc) align 8)
declare void @foo2(%Abc* noalias sret(%Abc) align 8)
%dummy1 = alloca %Abc, align 8
%dummy2 = alloca %Abc, align 8
call void @foo1(%Abc* sret(%Abc) align 8 %dummy1)
call void @foo2(%Abc* sret(%Abc) align 8 %dummy2)
ret void

View File

@@ -1,38 +0,0 @@
// #target: macos-x64
module unionx64;
union Foo
{
long a;
char[12] b;
}
extern fn void hello2(Foo f);
fn void hello(Foo f)
{
hello2(f);
}
/* #expect: unionx64.ll
%Foo = type { i64, [8 x i8] }
declare void @hello2(i64, i64) #0
define void @unionx64_hello(i64 %0, i64 %1) #0 {
entry:
%f = alloca %Foo, align 8
%pair = bitcast %Foo* %f to { i64, i64 }*
%2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %pair, i32 0, i32 0
store i64 %0, i64* %2, align 8
%3 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %pair, i32 0, i32 1
store i64 %1, i64* %3, align 8
%4 = bitcast %Foo* %f to { i64, i64 }*
%5 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %4, i32 0, i32 0
%lo = load i64, i64* %5, align 8
%6 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %4, i32 0, i32 1
%hi = load i64, i64* %6, align 8
call void @hello2(i64 %lo, i64 %hi)
ret void
}

View File

@@ -1,100 +0,0 @@
// #target: linux-aarch64
module abi;
struct Vector2 {
float x;
float y;
}
extern fn Vector2 vector2_zero() { return Vector2 {}; }
extern fn Vector2 vector2_one() { return Vector2 {}; }
extern fn Vector2 vector2_add(Vector2 v1, Vector2 v2) { return Vector2 {}; }
extern fn Vector2 vector2_add_value(Vector2 v, float add) { return Vector2 {}; }
extern fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) { return Vector2 {}; }
extern fn Vector2 vector2_subtract_value(Vector2 v, float sub) { return Vector2 {}; }
// #expect: abi.ll
%Vector2 = type { float, float }
define %Vector2 @vector2_zero() #0 {
entry:
%literal = alloca %Vector2, align 4
%0 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %0, align 4
%1 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %1, align 4
%2 = load %Vector2, %Vector2* %literal, align 4
ret %Vector2 %2
}
define %Vector2 @vector2_one() #0 {
entry:
%literal = alloca %Vector2, align 4
%0 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %0, align 4
%1 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %1, align 4
%2 = load %Vector2, %Vector2* %literal, align 4
ret %Vector2 %2
}
define %Vector2 @vector2_add([2 x float] %0, [2 x float] %1) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v1 to [2 x float]*
store [2 x float] %0, [2 x float]* %2, align 4
%3 = bitcast %Vector2* %v2 to [2 x float]*
store [2 x float] %1, [2 x float]* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %4, align 4
%5 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %5, align 4
%6 = load %Vector2, %Vector2* %literal, align 4
ret %Vector2 %6
}
define %Vector2 @vector2_add_value([2 x float] %0, float %1) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v to [2 x float]*
store [2 x float] %0, [2 x float]* %2, align 4
%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 = load %Vector2, %Vector2* %literal, align 4
ret %Vector2 %5
}
define %Vector2 @vector2_subtract([2 x float] %0, [2 x float] %1) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v1 to [2 x float]*
store [2 x float] %0, [2 x float]* %2, align 4
%3 = bitcast %Vector2* %v2 to [2 x float]*
store [2 x float] %1, [2 x float]* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %4, align 4
%5 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %5, align 4
%6 = load %Vector2, %Vector2* %literal, align 4
ret %Vector2 %6
}
define %Vector2 @vector2_subtract_value([2 x float] %0, float %1) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v to [2 x float]*
store [2 x float] %0, [2 x float]* %2, align 4
%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 = load %Vector2, %Vector2* %literal, align 4
ret %Vector2 %5
}

View File

@@ -1,99 +0,0 @@
// #target: wasm32
module abi;
struct Vector2 {
float x;
float y;
}
extern fn Vector2 vector2_zero() { return Vector2 {}; }
extern fn Vector2 vector2_one() { return Vector2 {}; }
extern fn Vector2 vector2_add(Vector2 v1, Vector2 v2) { return Vector2 {}; }
extern fn Vector2 vector2_add_value(Vector2 v, float add) { return Vector2 {}; }
extern fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) { return Vector2 {}; }
extern fn Vector2 vector2_subtract_value(Vector2 v, float sub) { return Vector2 {}; }
// #expect: abi.ll
target triple = "wasm32-unknown-unknown"
%Vector2 = type { float, float }
define void @vector2_zero(%Vector2* noalias sret(%Vector2) align 4 %0) #0 {
entry:
%literal = alloca %Vector2, align 4
%1 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %1, align 4
%2 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %2, align 4
%3 = bitcast %Vector2* %0 to i8*
%4 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 8, i1 false)
ret void
}
define void @vector2_one(%Vector2* noalias sret(%Vector2) align 4 %0) #0 {
entry:
%literal = alloca %Vector2, align 4
%1 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %1, align 4
%2 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %2, align 4
%3 = bitcast %Vector2* %0 to i8*
%4 = bitcast %Vector2* %literal to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 8, i1 false)
ret void
}
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:
%literal = alloca %Vector2, align 4
%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_add_value(%Vector2* noalias sret(%Vector2) align 4 %0, %Vector2* byval(%Vector2) align 4 %1, float %2) #0 {
entry:
%literal = alloca %Vector2, align 4
%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:
%literal = alloca %Vector2, align 4
%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_value(%Vector2* noalias sret(%Vector2) align 4 %0, %Vector2* byval(%Vector2) align 4 %1, float %2) #0 {
entry:
%literal = alloca %Vector2, align 4
%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

@@ -1,110 +0,0 @@
// #target: macos-x64
module abi;
struct Vector2 {
float x;
float y;
}
extern fn Vector2 vector2_zero() { return Vector2 {}; }
extern fn Vector2 vector2_one() { return Vector2 {}; }
extern fn Vector2 vector2_add(Vector2 v1, Vector2 v2) { return Vector2 {}; }
extern fn Vector2 vector2_add_value(Vector2 v, float add) { return Vector2 {}; }
extern fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) { return Vector2 {}; }
extern fn Vector2 vector2_subtract_value(Vector2 v, float sub) { return Vector2 {}; }
/* #expect: abi.ll
%Vector2 = type { float, float }
define <2 x float> @vector2_zero() #0 {
entry:
%literal = alloca %Vector2, align 4
%0 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %0, align 4
%1 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %1, align 4
%2 = bitcast %Vector2* %literal to <2 x float>*
%3 = load <2 x float>, <2 x float>* %2, align 4
ret <2 x float> %3
}
define <2 x float> @vector2_one() #0 {
entry:
%literal = alloca %Vector2, align 4
%0 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %0, align 4
%1 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %1, align 4
%2 = bitcast %Vector2* %literal to <2 x float>*
%3 = load <2 x float>, <2 x float>* %2, align 4
ret <2 x float> %3
}
define <2 x float> @vector2_add(<2 x float> %0, <2 x float> %1) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v1 to <2 x float>*
store <2 x float> %0, <2 x float>* %2, align 4
%3 = bitcast %Vector2* %v2 to <2 x float>*
store <2 x float> %1, <2 x float>* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %4, align 4
%5 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %5, align 4
%6 = bitcast %Vector2* %literal to <2 x float>*
%7 = load <2 x float>, <2 x float>* %6, align 4
ret <2 x float> %7
}
; Function Attrs: nounwind
define <2 x float> @vector2_add_value(<2 x float> %0, float %1) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v to <2 x float>*
store <2 x float> %0, <2 x float>* %2, align 4
%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* %literal to <2 x float>*
%6 = load <2 x float>, <2 x float>* %5, align 4
ret <2 x float> %6
}
; Function Attrs: nounwind
define <2 x float> @vector2_subtract(<2 x float> %0, <2 x float> %1) #0 {
entry:
%v1 = alloca %Vector2, align 4
%v2 = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v1 to <2 x float>*
store <2 x float> %0, <2 x float>* %2, align 4
%3 = bitcast %Vector2* %v2 to <2 x float>*
store <2 x float> %1, <2 x float>* %3, align 4
%4 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 0
store float 0.000000e+00, float* %4, align 4
%5 = getelementptr inbounds %Vector2, %Vector2* %literal, i32 0, i32 1
store float 0.000000e+00, float* %5, align 4
%6 = bitcast %Vector2* %literal to <2 x float>*
%7 = load <2 x float>, <2 x float>* %6, align 4
ret <2 x float> %7
}
; Function Attrs: nounwind
define <2 x float> @vector2_subtract_value(<2 x float> %0, float %1) #0 {
entry:
%v = alloca %Vector2, align 4
%literal = alloca %Vector2, align 4
%2 = bitcast %Vector2* %v to <2 x float>*
store <2 x float> %0, <2 x float>* %2, align 4
%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* %literal to <2 x float>*
%6 = load <2 x float>, <2 x float>* %5, align 4
ret <2 x float> %6
}

View File

@@ -1,28 +0,0 @@
// #target: macos-x64
module test;
extern fn void test1_f(void *);
fn void test1_g()
{
float[4] x;
test1_f(&x);
}
/* #expect: test.ll
define void @test_test1_g() #0 {
entry:
%x = alloca [4 x float], align 16
%0 = getelementptr inbounds [4 x float], [4 x float]* %x, i64 0, i64 0
store float 0.000000e+00, float* %0, align 4
%1 = getelementptr inbounds [4 x float], [4 x float]* %x, i64 0, i64 1
store float 0.000000e+00, float* %1, align 4
%2 = getelementptr inbounds [4 x float], [4 x float]* %x, i64 0, i64 2
store float 0.000000e+00, float* %2, align 4
%3 = getelementptr inbounds [4 x float], [4 x float]* %x, i64 0, i64 3
store float 0.000000e+00, float* %3, align 4
%ptrptr = bitcast [4 x float]* %x to i8*
call void @test1_f(i8* %ptrptr)
ret void
}

View File

@@ -1,34 +0,0 @@
// #target: macos-x64
module array_casts;
fn void test()
{
int[3] x;
int *y = &x;
int[] z = &x;
}
// #expect: array_casts.ll
%"int[]" = type { i32*, i64 }
define void @array_casts_test() #0 {
entry:
%x = alloca [3 x i32], align 4
%y = alloca i32*, align 8
%z = alloca %"int[]", align 8
%0 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 0
store i32 0, i32* %0, align 4
%1 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 1
store i32 0, i32* %1, align 4
%2 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 2
store i32 0, i32* %2, align 4
%ptrptr = bitcast [3 x i32]* %x to i32*
store i32* %ptrptr, i32** %y, align 8
%3 = bitcast [3 x i32]* %x to i32*
%4 = insertvalue %"int[]" undef, i32* %3, 0
%5 = insertvalue %"int[]" %4, i64 3, 1
store %"int[]" %5, %"int[]"* %z, align 8
ret void
}

View File

@@ -1,11 +0,0 @@
enum Foo : int
{
TEST
}
int[100] a = { [Foo.TEST] = 123 };
fn void test()
{
a[Foo.TEST] = 33;
}

View File

@@ -1,12 +0,0 @@
fn void test()
{
int[3] x;
double *y = &x; // #error: 'int[3]*' to 'double*
}
fn void test2()
{
int[3] x;
double[] z = &x; // #error: 'int[3]*' to 'double[]'
}

View File

@@ -1,28 +0,0 @@
// #target: macos-x64
module array_literal;
fn double test(uint x)
{
double[30] student_t = { 0.0 , 12.706 , 4.303 , 3.182 , 2.776 , 2.571 ,
2.447 , 2.365 , 2.306 , 2.262 , 2.228 ,
2.201 , 2.179 , 2.160 , 2.145 , 2.131 ,
2.120 , 2.110 , 2.101 , 2.093 , 2.086 ,
2.080 , 2.074 , 2.069 , 2.064 , 2.060 ,
2.056 , 2.052 , 2.048 , 2.045 };
return student_t[x];
}
/* #expect: array_literal.ll
@.__const = private unnamed_addr constant [30 x double] [double 0.000000e+00, double 1.270600e+01, double 4.303000e+00, double 3.182000e+00, double 2.776000e+00, double 2.571000e+00, double 2.447000e+00, double 2.365000e+00, double 2.306000e+00, double 2.262000e+00, double 2.228000e+00, double 2.201000e+00, double 2.179000e+00, double 2.160000e+00, double 2.145000e+00, double 2.131000e+00, double 2.120000e+00, double 2.110000e+00, double 2.101000e+00, double 2.093000e+00, double 2.086000e+00, double 2.080000e+00, double 2.074000e+00, double 2.069000e+00, double 2.064000e+00, double 2.060000e+00, double 2.056000e+00, double 2.052000e+00, double 2.048000e+00, double 2.045000e+00], align 16
define double @array_literal_test(i32 %0) #0 {
entry:
%student_t = alloca [30 x double], align 16
%1 = bitcast [30 x double]* %student_t to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 16 %1, i8* align 16 bitcast ([30 x double]* @.__const to i8*), i32 240, i1 false)
%zext = zext i32 %0 to i64
%2 = getelementptr inbounds [30 x double], [30 x double]* %student_t, i64 0, i64 %zext
%3 = load double, double* %2, align 8
ret double %3
}

View File

@@ -1,13 +0,0 @@
// #target: macos-x64
module test;
struct Foo
{
int x, y;
}
private Foo[10] array;
// #expect: test.ll
@test_array = protected unnamed_addr global [10 x %Foo] zeroinitializer, align 16

View File

@@ -1,21 +0,0 @@
// #target: macos-x64
module test;
struct Connection
{
long to;
char* type;
long length;
}
private Connection[3] link
= { {1, "link1", 10},
{2, "link2", 20},
{3, "link3", 30} };
// #expect: test.ll
@.str = private unnamed_addr constant [6 x i8] c"link1\00", align 1
@.str.1 = private unnamed_addr constant [6 x i8] c"link2\00", align 1
@.str.2 = private unnamed_addr constant [6 x i8] c"link3\00", align 1
@test_link = protected unnamed_addr global [3 x %Connection] [%Connection { i64 1, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i64 10 }, %Connection { i64 2, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i64 20 }, %Connection { i64 3, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.2, i32 0, i32 0), i64 30 }], align 16

View File

@@ -1,17 +0,0 @@
const int CONSTANT = 1;
int[CONSTANT] a2;
int[3] a3 = { [CONSTANT] = 1 };
const bool B = true;
int[B] c2; // #error: Expected an integer
int non_constant = 10;
int[non_constant] b; // #error: Expected a constant value as
fn int foo()
{
return 10;
}
int[foo()] c; // #error: Expected a constant value as

View File

@@ -1,71 +0,0 @@
// #target: macos-x64
module test;
int* foo = &&3;
int a;
int c;
int d;
int[3] abc;
int *b = (&((&a + 1)[2]) + 1 - 2) + 5;
int *bf = &abc[2] + 2;
int *bf2 = &abc[2];
int *bf3 = &abc[2] + 2;
fn void main() {
int *bf34 = (&abc[2] + 2) + 3;
static variant[3] x = { &&42, &&'c', &&"for" };
variant[3] y = { &&42, &&'c', &&"for" };
}
/* #expect: test.ll
@.taddr = private global i32 3, align 4
@test_foo = local_unnamed_addr global i32* @.taddr, align 8
@test_a = global i32 0, align 4
@test_c = local_unnamed_addr global i32 0, align 4
@test_d = local_unnamed_addr global i32 0, align 4
@test_abc = local_unnamed_addr global [3 x i32] zeroinitializer, align 4
@test_b = local_unnamed_addr global i32* getelementptr (i32, i32* @test_a, i64 7), align 8
@test_bf = local_unnamed_addr global i32* getelementptr ([3 x i32], [3 x i32]* @test_abc, i64 1, i64 1), align 8
@test_bf2 = local_unnamed_addr global i32* getelementptr inbounds ([3 x i32], [3 x i32]* @test_abc, i64 0, i64 2), align 8
@test_bf3 = local_unnamed_addr global i32* getelementptr ([3 x i32], [3 x i32]* @test_abc, i64 1, i64 1), align 8
@.taddr.9 = private global i32 42, align 4
@"ct$int" = linkonce constant %.introspect { i8 2, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@.taddr.10 = private global i8 99, align 1
@"ct$char" = linkonce constant %.introspect { i8 3, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@.str = private unnamed_addr constant [4 x i8] c"for\00", align 1
@.taddr.11 = private global [3 x i8]* bitcast ([4 x i8]* @.str to [3 x i8]*), align 8
@"ct$a3$char" = linkonce constant %.introspect { i8 15, i64 3, i64 ptrtoint (%.introspect* @"ct$char" to i64), i64 3, [0 x i64] zeroinitializer }, align 8
@"ct$p$a3$char" = linkonce constant %.introspect { i8 19, i64 8, i64 ptrtoint (%.introspect* @"ct$a3$char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8
@"main$x" = internal unnamed_addr global [3 x %variant] [%variant { i8* bitcast (i32* @.taddr.9 to i8*), i64 ptrtoint (%.introspect* @"ct$int" to i64) }, %variant { i8* @.taddr.10, i64 ptrtoint (%.introspect* @"ct$char" to i64) }, %variant { i8* bitcast ([3 x i8]** @.taddr.11 to i8*), i64 ptrtoint (%.introspect* @"ct$p$a3$char" to i64) }], align 16
@.str.12 = private unnamed_addr constant [4 x i8] c"for\00", align 1
; Function Attrs: nounwind
define void @test_main() #0 {
entry:
%bf34 = alloca i32*, align 8
%y = alloca [3 x %variant], align 16
%taddr = alloca i32, align 4
%taddr1 = alloca i8, align 1
%taddr2 = alloca [3 x i8]*, align 8
store i32* getelementptr
%0 = getelementptr inbounds [3 x %variant], [3 x %variant]* %y, i64 0, i64 0
store i32 42, i32* %taddr, align 4
%1 = bitcast i32* %taddr to i8*
%2 = insertvalue %variant undef, i8* %1, 0
%3 = insertvalue %variant %2, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
store %variant %3, %variant* %0, align 16
%4 = getelementptr inbounds [3 x %variant], [3 x %variant]* %y, i64 0, i64 1
store i8 99, i8* %taddr1, align 1
%5 = insertvalue %variant undef, i8* %taddr1, 0
%6 = insertvalue %variant %5, i64 ptrtoint (%.introspect* @"ct$char" to i64), 1
store %variant %6, %variant* %4, align 16
%7 = getelementptr inbounds [3 x %variant], [3 x %variant]* %y, i64 0, i64 2
store [3 x i8]* bitcast ([4 x i8]* @.str.12 to [3 x i8]*), [3 x i8]** %taddr2, align 8
%8 = bitcast [3 x i8]** %taddr2 to i8*
%9 = insertvalue %variant undef, i8* %8, 0
%10 = insertvalue %variant %9, i64 ptrtoint (%.introspect* @"ct$p$a3$char" to i64), 1
store %variant %10, %variant* %7, align 16
ret void
}

View File

@@ -1,2 +0,0 @@
int[3] abc;
int *bf3 = (&abc[4]) + 2; // #error: An index of '4' is out of range, a value between 0 and 2 was expected

View File

@@ -1,53 +0,0 @@
// #target: macos-x64
module test;
fn void test(int[10] x, int[<10>] y)
{
int a = x[4];
int b = x[^2];
int c = y[4];
int d = y[^2];
int j = 3;
int e = y[^j];
int f = x[^j];
}
/* #expect: test.ll
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:
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
%d = alloca i32, align 4
%j = alloca i32, align 4
%e = alloca i32, align 4
%f = alloca i32, 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
%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,33 +0,0 @@
// #target: macos-x64
module foo;
struct Bar {
int a;
}
Bar[6] bar;
fn int main()
{
test_bar(0);
return 0;
}
fn void test_bar(int idx)
{
bar[idx].a = 0;
bar[0].a = idx;
}
/* #expect: foo.ll
define void @foo_test_bar(i32 %0) #0 {
entry:
%sisiext = sext i32 %0 to i64
%1 = getelementptr inbounds [6 x %Bar], [6 x %Bar]* @foo_bar, i64 0, i64 %sisiext
%2 = getelementptr inbounds %Bar, %Bar* %1, i32 0, i32 0
store i32 0, i32* %2, align 4
store i32 %0, i32* getelementptr inbounds ([6 x %Bar], [6 x %Bar]* @foo_bar, i64 0, i64 0, i32 0), align 4
ret void
}

View File

@@ -1,7 +0,0 @@
fn int[*] hello() // #error: Inferred array types can only be used in declarations with initializers
{
return int[3] { 1, 2, 3};
}
int[*] c; // #error: Inferred array types can only be used in declarations with initializers

View File

@@ -1,5 +0,0 @@
fn void test()
{
int[3] z;
(int[*])(z); // #error: Inferred array types can only be used in declarations with initializers
}

View File

@@ -1,5 +0,0 @@
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

@@ -1,7 +0,0 @@
fn void test()
{
int[3] x = { 1, 2, 3 };
int[] z = &x;
z[1];
// z.size();
}

View File

@@ -1,36 +0,0 @@
// #target: macos-x64
module test;
fn void main(char[][] args)
{
int x;
if (args.len < 10) return;
asm
{
in $eax, 3;
in $ax, $dx;
incb $al;
incw $bx;
incl $eax;
incq $rax;
incl [&x];
insb;
insw;
insl;
int 0x08;
int3;
// int1; Broken in LLVM
invd;
invlpg [&x];
invpcid $rax, [&x];
invlpga $ecx, $rax;
iret;
iretl;
iretw;
iretq;
}
}
/* #expect: test.ll
"in $$3, %eax\0Ain %dx, %ax\0Aincb %al\0Aincw %bx\0Aincl %eax\0Aincq %rax\0Aincl $0\0Ainsb \0Ainsw \0Ainsl \0Aint $$8\0Aint3 \0Ainvd \0Ainvlpg $0\0Ainvpcid $1, %rax\0Ainvlpga %rax, %ecx\0Airet \0Airetl \0Airetw \0Airetq \0A", "=*&m,*m,~{cc},~{rax},~{rbx},~{flags},~{dirflag},~{fspr}"

View File

@@ -1,30 +0,0 @@
// #target: macos-x64
module test;
fn void main(char[][] args)
{
int foo;
asm
{
adcxl $eax, $ecx;
adcxq $rax, $rcx;
addpd $xmm1, $xmm2;
addps $xmm1, $xmm2;
addsd $xmm1, $xmm2;
addss $xmm1, $xmm2;
vaddpd $xmm1, $xmm2, $xmm3;
vaddpd $ymm1, $ymm2, $ymm3;
vaddpd $xmm1, $xmm2, [&foo];
vaddps $xmm1, $xmm2, $xmm3;
vaddps $ymm1, $ymm2, $ymm3;
vaddps $xmm1, $xmm2, [&foo];
vaddsd $xmm1, $xmm2, $xmm3;
vaddsd $xmm1, $xmm2, [&foo];
vaddss $xmm1, $xmm2, $xmm3;
vaddss $xmm1, $xmm2, [&foo];
}
}
/* #expect: test.ll
"adcxl %ecx, %eax\0Aadcxq %rcx, %rax\0Aaddpd %xmm2, %xmm1\0Aaddps %xmm2, %xmm1\0Aaddsd %xmm2, %xmm1\0Aaddss %xmm2, %xmm1\0Avaddpd %xmm3, %xmm2, %xmm1\0Avaddpd %ymm3, %ymm2, %ymm1\0Avaddpd $0, %xmm2, %xmm1\0Avaddps %xmm3, %xmm2, %xmm1\0Avaddps %ymm3, %ymm2, %ymm1\0Avaddps $0, %xmm2, %xmm1\0Avaddsd %xmm3, %xmm2, %xmm1\0Avaddsd $0, %xmm2, %xmm1\0Avaddss %xmm3, %xmm2, %xmm1\0Avaddss $0, %xmm2, %xmm1\0A", "*m,~{cc},~{rcx},~{xmm1},~{flags},~{dirflag},~{fspr}"

View File

@@ -1,50 +0,0 @@
// #target: macos-x64
module test;
import std::io;
fn void main()
{
int x = 222;
int y = 223;
long z = 0;
z = x + y;
z *= x;
int g = 0;
int* gp = &g;
int[4] a = { 3, 4, 5, 6 };
int* xa = &a;
usz asf = 1;
int aa = 3;
asm
{
movl x, 4;
movl [gp], x;
movl x, 1;
movl [xa + asf * 4 + 4], x;
movl $eax, (23 + x);
movl x, $eax;
movq [&z], 33;
addl aa, 22;
}
io::printfn("aa: %d", aa);
io::printfn("Z: %d", z);
io::printfn("x: %d", x);
io::printfn("G was: %d", g);
foreach(int abc : a) io::printfn("%d", abc);
}
/* #expect: test.ll
%5 = load i32*, i32** %gp, align 8
%6 = load i32*, i32** %xa, align 8
%7 = load i64, i64* %asf, align 8
%8 = load i32, i32* %x, align 4
%add3 = add i32 23, %8
%9 = load i32, i32* %aa, align 4
%10 = call { i32, i32 } asm alignstack "movl $$4, $0\0Amovl $0, ($3)\0Amovl $$1, $0\0Amovl $0, 4($4,$5,4)\0Amovl $6, %eax\0Amovl %eax, $0\0Amovq $$33, $1\0Aaddl $$22, $2\0A", "=&r,=*&m,=r,r,r,r,r,2,~{cc},~{rax},~{flags},~{dirflag},~{fspr}"
%11 = extractvalue { i32, i32 } %10, 0
store i32 %11, i32* %x, align 4
%12 = extractvalue { i32, i32 } %10, 1
store i32 %12, i32* %aa, align 4

View File

@@ -1,62 +0,0 @@
// #target: windows-x64
fn int foo()
{
return 1;
}
fn void test()
{
int x = foo();
int y = foo();
int z = foo();
assert(x > 0);
assert(y > 0 && z > 0);
assert(x > 0 && y > 0 && z > 0);
assert(foo() > 0);
assert(x > 0 && foo() > 0);
assert(!(x < 1 || y < 1), "Foo");
}
// #expect: assert_variants.ll
%x = alloca i32, align 4
%y = alloca i32, align 4
%z = alloca i32, align 4
%0 = call i32 @assert_variants_foo()
store i32 %0, i32* %x, align 4
%1 = call i32 @assert_variants_foo()
store i32 %1, i32* %y, align 4
%2 = call i32 @assert_variants_foo()
store i32 %2, i32* %z, align 4
%3 = load i32, i32* %x, align 4
%gt = icmp sgt i32 %3, 0
call void @llvm.assume(i1 %gt)
%4 = load i32, i32* %y, align 4
%gt1 = icmp sgt i32 %4, 0
call void @llvm.assume(i1 %gt1)
%5 = load i32, i32* %z, align 4
%gt2 = icmp sgt i32 %5, 0
call void @llvm.assume(i1 %gt2)
%6 = load i32, i32* %x, align 4
%gt3 = icmp sgt i32 %6, 0
call void @llvm.assume(i1 %gt3)
%7 = load i32, i32* %y, align 4
%gt4 = icmp sgt i32 %7, 0
call void @llvm.assume(i1 %gt4)
%8 = load i32, i32* %z, align 4
%gt5 = icmp sgt i32 %8, 0
call void @llvm.assume(i1 %gt5)
%9 = load i32, i32* %x, align 4
%gt6 = icmp sgt i32 %9, 0
call void @llvm.assume(i1 %gt6)
%10 = load i32, i32* %x, align 4
%lt = icmp slt i32 %10, 1
%not = xor i1 %lt, true
call void @llvm.assume(i1 %not)
%11 = load i32, i32* %y, align 4
%lt7 = icmp slt i32 %11, 1
%not8 = xor i1 %lt7, true
call void @llvm.assume(i1 %not8)
ret void

View File

@@ -1,3 +0,0 @@
int x = 3;
$assert(x == 3); // #error: Compile time evaluation requires a compile time constant value.

View File

@@ -1,20 +0,0 @@
int x = 3;
fn void test()
{
$assert(x == 3); // #error: Compile time evaluation requires a compile time constant value.
}
fn void test2()
{
int i = 0;
$assert(1);
$assert(i == 0); // #error: Compile time evaluation requires a compile time constant value.
}
fn int foo();
fn void test3()
{
int i = 0;
$assert(foo() == 0); // #error: Compile time evaluation requires a compile time constant value.
}

View File

@@ -1,8 +0,0 @@
const int FOO = 2;
fn void test()
{
$assert(FOO == 2, "Bad");
$assert(FOO == 0, "Good"); // #error: Compile time assert - Good
}

View File

@@ -1,40 +0,0 @@
// #target: macos-x64
fn int foo()
{
return 1;
}
fn void test()
{
int x = foo();
if (x > 0) return;
unreachable();
x++;
}
/* #expect: unreachable.ll
define void @unreachable_test() #0 {
entry:
%x = alloca i32, align 4
%0 = call i32 @unreachable_foo()
store i32 %0, i32* %x, align 4
%1 = load i32, i32* %x, align 4
%gt = icmp sgt i32 %1, 0
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
ret void
if.exit: ; preds = %entry
%2 = load void (i8*, i64, i8*, i64, i8*, i64, i32)*, void (i8*, i64, i8*, i64, i8*, i64, i32)** @std_core_builtin_panic, align 8
call void %2(i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str, i32 0, i32 0), i64 30, i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.1, i32 0, i32 0), i64 14, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0), i64 4, i32 10)
unreachable
after.unreachable: ; No predecessors!
%3 = load i32, i32* %x, align 4
%add = add i32 %3, 1
store i32 %add, i32* %x, align 4
ret void
}

View File

@@ -1,69 +0,0 @@
module test;
fn int foo()
{
int x = 0;
int y;
x += y;
x -= y;
x %= y;
x /= y;
x *= y;
x <<= y;
x >>= y;
x ^= y;
x |= y;
x &= y;
return x;
}
// #expect: test.ll
%x = alloca i32, align 4
%y = alloca i32, align 4
store i32 0, i32* %x, align 4
store i32 0, i32* %y, align 4
%0 = load i32, i32* %x, align 4
%1 = load i32, i32* %y, align 4
%add = add i32 %0, %1
store i32 %add, i32* %x, align 4
%2 = load i32, i32* %x, align 4
%3 = load i32, i32* %y, align 4
%sub = sub i32 %2, %3
store i32 %sub, i32* %x, align 4
%4 = load i32, i32* %x, align 4
%5 = load i32, i32* %y, align 4
%smod = srem i32 %4, %5
store i32 %smod, i32* %x, align 4
%6 = load i32, i32* %x, align 4
%7 = load i32, i32* %y, align 4
%sdiv = sdiv i32 %6, %7
store i32 %sdiv, i32* %x, align 4
%8 = load i32, i32* %x, align 4
%9 = load i32, i32* %y, align 4
%mul = mul i32 %8, %9
store i32 %mul, i32* %x, align 4
%10 = load i32, i32* %x, align 4
%11 = load i32, i32* %y, align 4
%shl = shl i32 %10, %11
%12 = freeze i32 %shl
store i32 %12, i32* %x, align 4
%13 = load i32, i32* %x, align 4
%14 = load i32, i32* %y, align 4
%ashr = ashr i32 %13, %14
%15 = freeze i32 %ashr
store i32 %15, i32* %x, align 4
%16 = load i32, i32* %x, align 4
%17 = load i32, i32* %y, align 4
%xor = xor i32 %16, %17
store i32 %xor, i32* %x, align 4
%18 = load i32, i32* %x, align 4
%19 = load i32, i32* %y, align 4
%or = or i32 %18, %19
store i32 %or, i32* %x, align 4
%20 = load i32, i32* %x, align 4
%21 = load i32, i32* %y, align 4
%and = and i32 %20, %21
store i32 %and, i32* %x, align 4
%22 = load i32, i32* %x, align 4

View File

@@ -1,40 +0,0 @@
module test;
import std::io;
macro @foo(;@body)
{
var i = 1.0;
@body();
}
fn void main()
{
@foo() { int j = 1; };
@foo() { var j = 1.0; }; // #error: is only allowed inside
}
fn void test()
{
var g = 1; // #error: is only allowed inside
}
macro void test2m()
{
var h = { 1, 2 }; // #error: cannot be inferred
}
fn void test2()
{
test2m();
}
struct Foo { int a; }
macro void test3m()
{
var $foo = Foo.membersof;
var h = $foo[0]; // #error: compile time type
}
fn void test3()
{
test3m();
}

View File

@@ -1,12 +0,0 @@
// #target: macos-x64
module test;
private const int FOO = 4;
define @Align(x) = @align(x * FOO);
module test2;
import test;
int black @Align(16) = 123;
// #expect: test2.ll
@test2_black = local_unnamed_addr global i32 123, align 64

View File

@@ -1,25 +0,0 @@
module test;
define @Align(y) = @Align16(y / 2);
// This one is directly recursive
define @Align16(x) = @align(4), @Align(8 * x); // #error: Recursive declaration of attribute
// This one uses a recursive attribute
define @AlignIndirect(x) = @Align16(x); // #error: Recursive declaration of attribute
define @Test = @noinline;
struct Foo
{
int z;
int xy @Align16(8);
}
Foo f;
fn void testme() @Test
{
int x;
}
struct Bar
{
int abc @AlignIndirect(8);
}

View File

@@ -1,45 +0,0 @@
// #target: macos-x64
module test;
define @Align(y) = @align(y);
define @Align16(x) = @Align(8 * x), @align(1024);
define @Test = @noinline;
define @TestZero;
struct Foo
{
int z;
int xy @Align16(8);
}
Foo f;
fn void testme() @Test
{
int x;
}
fn void main() @TestZero
{
testme();
}
/* #expect: test.ll
%Foo = type { i32, [1020 x i8], i32, [1020 x i8] }
@"ct$test_Foo" = linkonce constant %.introspect { i8 10, i64 2048, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@test_f = local_unnamed_addr global %Foo zeroinitializer, align 1024
define void @test_testme() #0 {
entry:
%x = alloca i32, align 4
store i32 0, i32* %x, align 4
ret void
}
define void @test_main() #1 {
entry:
call void @test_testme()
ret void
}

View File

@@ -1,15 +0,0 @@
bitstruct BitField : char
{
int a : 0..2;
int b : 4..5;
int c : 6..7;
}
fn void test()
{
BitField x;
BitField* z = &x;
x.a;
z.a;
&x.a; // #error: You cannot take the address of a bitstruct member
}

View File

@@ -1,71 +0,0 @@
// #target: macos-x64
module foo;
bitstruct BitField : char[3]
{
int a : 0..2;
int b : 3..8;
int c : 9..18;
bool d : 19;
bool e : 20;
}
extern fn void printf(char*, ...);
fn void main()
{
BitField xx = { 2, 3, 15, true, false };
BitField xy = { 2, 3, 15, false, true };
printf("%x, %x, %x, %d, %d\n", xx.a, xx.b, xx.c, xx.d, xx.e);
}
/* #expect: foo.ll
define void @foo_main() #0 {
entry:
%xx = alloca [3 x i8], align 1
%xy = alloca [3 x i8], align 1
store [3 x i8] c"\1A\1E\08", [3 x i8]* %xx, align 1
store [3 x i8] c"\1A\1E\10", [3 x i8]* %xy, align 1
%0 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%1 = load i8, i8* %0, align 1
%zext = zext i8 %1 to i32
%shl = shl i32 %zext, 29
%ashr = ashr i32 %shl, 29
%2 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%3 = load i8, i8* %2, align 1
%zext1 = zext i8 %3 to i32
%lshrl = lshr i32 %zext1, 3
%4 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 1
%5 = load i8, i8* %4, align 1
%zext2 = zext i8 %5 to i32
%shl3 = shl i32 %zext2, 5
%6 = or i32 %shl3, %lshrl
%shl4 = shl i32 %6, 26
%ashr5 = ashr i32 %shl4, 26
%7 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 1
%8 = load i8, i8* %7, align 1
%zext6 = zext i8 %8 to i32
%lshrl7 = lshr i32 %zext6, 1
%9 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 2
%10 = load i8, i8* %9, align 1
%zext8 = zext i8 %10 to i32
%shl9 = shl i32 %zext8, 7
%11 = or i32 %shl9, %lshrl7
%shl10 = shl i32 %11, 22
%ashr11 = ashr i32 %shl10, 22
%12 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 2
%13 = load i8, i8* %12, align 1
%lshrl12 = lshr i8 %13, 3
%14 = trunc i8 %lshrl12 to i1
%boolsi = zext i1 %14 to i32
%15 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 2
%16 = load i8, i8* %15, align 1
%lshrl13 = lshr i8 %16, 4
%17 = trunc i8 %lshrl13 to i1
%boolsi14 = zext i1 %17 to i32
call void (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i32 0, i32 0), i32 %ashr, i32 %ashr5, i32 %ashr11, i32 %boolsi, i32 %boolsi14)
ret void
}

View File

@@ -1,180 +0,0 @@
// #target: macos-x64
module foo;
bitstruct BitField : char
{
int a : 0..2;
int b : 4..5;
int c : 6..7;
}
bitstruct BitFieldI : ushort
{
int a : 0..4;
int b : 5..10;
int c : 11..15;
}
struct Packet
{
bitstruct : int
{
int a : 0..2;
int b : 3..5;
int c : 6..10;
}
int packet_id;
}
bitstruct BitField3 : char[3]
{
int a : 0..2;
int b : 3..8;
int c : 9..18;
int d : 19..23;
}
bitstruct BitField3u : char[3]
{
uint a : 0..2;
uint b : 3..8;
uint c : 9..18;
uint d : 19..23;
}
bitstruct BitField4 : char[3]
{
int a : 0..2;
int b : 3..7;
int c : 8..15;
int d : 16..19;
}
bitstruct BitFieldCross : char[5]
{
uint a : 5..22;
}
BitField c = { 2, -1, 1 };
extern fn void printf(char*, ...);
fn void main()
{
BitField b = { 3, -1, 1 };
BitFieldI c1 = { 5, 0, 0 };
BitFieldI c2 = { 0, 3, 0 };
BitFieldI c3 = { 0, 0, 9 };
BitFieldI c4 = { -5, 7, 9 };
BitFieldI c5 = { -5, 0, 0 };
BitFieldI c6 = { 5, 0, 0 };
BitFieldI c7 = { 0, 0, 5 };
BitField3 e1 = { 3, 1, 3, 4 };
BitField3 e2 = { 1, 1, 3, 4 };
BitField3 e3 = { 2, 1, 3, 4 };
BitField d = { };
printf("%d\n", e1.a);
printf("%d\n", e2.a);
printf("%d\n", e3.a);
BitField3u z1 = { 3, 1, 3, 4 };
BitField3u z2 = { 4, 1, 3, 4 };
BitField3u z3 = { 7, 1, 3, 4 };
printf("%u\n", z1.a);
printf("%u\n", z2.a);
printf("%u\n", z3.a);
BitFieldCross xx = { 0x1238 };
printf("%x\n", xx.a);
}
/* #expect: foo.ll
define void @foo_main() #0 {
entry:
%b = alloca i8, align 1
%c1 = alloca i16, align 2
%c2 = alloca i16, align 2
%c3 = alloca i16, align 2
%c4 = alloca i16, align 2
%c5 = alloca i16, align 2
%c6 = alloca i16, align 2
%c7 = alloca i16, align 2
%e1 = alloca [3 x i8], align 1
%e2 = alloca [3 x i8], align 1
%e3 = alloca [3 x i8], align 1
%d = alloca i8, align 1
%z1 = alloca [3 x i8], align 1
%z2 = alloca [3 x i8], align 1
%z3 = alloca [3 x i8], align 1
%xx = alloca [5 x i8], align 1
store i8 115, i8* %b, align 1
store i16 5, i16* %c1, align 2
store i16 96, i16* %c2, align 2
store i16 18432, i16* %c3, align 2
store i16 18683, i16* %c4, align 2
store i16 27, i16* %c5, align 2
store i16 5, i16* %c6, align 2
store i16 10240, i16* %c7, align 2
store [3 x i8] c"\0B\06 ", [3 x i8]* %e1, align 1
store [3 x i8] c"\09\06 ", [3 x i8]* %e2, align 1
store [3 x i8] c"\0A\06 ", [3 x i8]* %e3, align 1
store i8 0, i8* %d, align 1
%0 = getelementptr inbounds [3 x i8], [3 x i8]* %e1, i64 0, i64 0
%1 = load i8, i8* %0, align 1
%zext = zext i8 %1 to i32
%shl = shl i32 %zext, 29
%ashr = ashr i32 %shl, 29
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %ashr)
%2 = getelementptr inbounds [3 x i8], [3 x i8]* %e2, i64 0, i64 0
%3 = load i8, i8* %2, align 1
%zext1 = zext i8 %3 to i32
%shl2 = shl i32 %zext1, 29
%ashr3 = ashr i32 %shl2, 29
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 %ashr3)
%4 = getelementptr inbounds [3 x i8], [3 x i8]* %e3, i64 0, i64 0
%5 = load i8, i8* %4, align 1
%zext4 = zext i8 %5 to i32
%shl5 = shl i32 %zext4, 29
%ashr6 = ashr i32 %shl5, 29
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), i32 %ashr6)
store [3 x i8] c"\0B\06 ", [3 x i8]* %z1, align 1
store [3 x i8] c"\0C\06 ", [3 x i8]* %z2, align 1
store [3 x i8] c"\0F\06 ", [3 x i8]* %z3, align 1
%6 = getelementptr inbounds [3 x i8], [3 x i8]* %z1, i64 0, i64 0
%7 = load i8, i8* %6, align 1
%zext7 = zext i8 %7 to i32
%8 = and i32 7, %zext7
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i32 0, i32 0), i32 %8)
%9 = getelementptr inbounds [3 x i8], [3 x i8]* %z2, i64 0, i64 0
%10 = load i8, i8* %9, align 1
%zext8 = zext i8 %10 to i32
%11 = and i32 7, %zext8
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), i32 %11)
%12 = getelementptr inbounds [3 x i8], [3 x i8]* %z3, i64 0, i64 0
%13 = load i8, i8* %12, align 1
%zext9 = zext i8 %13 to i32
%14 = and i32 7, %zext9
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.5, i32 0, i32 0), i32 %14)
store [5 x i8] c"\00G\02\00\00", [5 x i8]* %xx, align 1
%15 = getelementptr inbounds [5 x i8], [5 x i8]* %xx, i64 0, i64 0
%16 = load i8, i8* %15, align 1
%zext10 = zext i8 %16 to i32
%lshrl = lshr i32 %zext10, 5
%17 = getelementptr inbounds [5 x i8], [5 x i8]* %xx, i64 0, i64 1
%18 = load i8, i8* %17, align 1
%zext11 = zext i8 %18 to i32
%shl12 = shl i32 %zext11, 3
%19 = or i32 %shl12, %lshrl
%20 = getelementptr inbounds [5 x i8], [5 x i8]* %xx, i64 0, i64 2
%21 = load i8, i8* %20, align 1
%zext13 = zext i8 %21 to i32
%shl14 = shl i32 %zext13, 11
%22 = or i32 %shl14, %19
%23 = and i32 262143, %22
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i32 0, i32 0), i32 %23)
ret void
}

Some files were not shown because too many files have changed in this diff Show More