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

View File

@@ -46,7 +46,7 @@ if (NOT WIN32)
find_package(CURL) find_package(CURL)
endif() endif()
if (NOT C3_LLVM_VERSION STREQUAL "auto") 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!") message(FATAL_ERROR "LLVM ${C3_LLVM_VERSION} is not supported!")
endif() endif()
endif() endif()
@@ -68,7 +68,7 @@ endif()
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
if (C3_LLVM_VERSION STREQUAL "auto") if (C3_LLVM_VERSION STREQUAL "auto")
set(C3_LLVM_VERSION "14") set(C3_LLVM_VERSION "15")
endif() endif()
FetchContent_Declare( FetchContent_Declare(
LLVM_Windows LLVM_Windows
@@ -131,12 +131,9 @@ set(LLVM_LINK_COMPONENTS
Target Target
TransformUtils TransformUtils
WindowsManifest 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}) llvm_map_components_to_libnames(llvm_libs ${LLVM_LINK_COMPONENTS})
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/lib) file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/lib)
file(COPY ${CMAKE_SOURCE_DIR}/lib DESTINATION ${CMAKE_BINARY_DIR}) 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_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_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) 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 lldMachO.lib lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
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_MINGW NAMES lldMinGW.lib lldMinGW.a liblldMinGW.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) 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) 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) find_library(LLD_LOONG NAMES libLLVMLoongArchCodeGen.lib libLLVMLoongArchAsmParser.lib libLLVMLoongArchCodeGen.a libLLVMLoongArchAsmParser.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
set(lld_libs 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 abort();
extern fn void atexit(TerminateFunction f); extern fn void atexit(TerminateFunction f);
extern fn void exit(int status); 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 int system(char* str);
extern fn void bsearch(void* key, void *base, usz items, usz size, CompareFunction compare); 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); 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 Time = long;
define Clock = ulong; define Clock = ulong;
extern fn char* asctime(Tm *timeptr); extern fn ZString asctime(Tm *timeptr);
extern fn Clock clock(); 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 double difftime(Time time1, Time time2);
extern fn Tm* gmtime(Time *timer); extern fn Tm* gmtime(Time *timer);
extern fn Tm* localtime(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) switch (source_expr->expr_kind)
{ {
case EXPR_VARIANTSWITCH: case EXPR_VARIANTSWITCH:
case EXPR_ARGV_TO_SUBARRAY:
UNREACHABLE UNREACHABLE
case EXPR_MACRO_BODY_EXPANSION: case EXPR_MACRO_BODY_EXPANSION:
MACRO_COPY_EXPR_LIST(expr->body_expansion_expr.values); MACRO_COPY_EXPR_LIST(expr->body_expansion_expr.values);

View File

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

View File

@@ -82,7 +82,6 @@ bool expr_may_addr(Expr *expr)
return true; return true;
case EXPR_TEST_HOOK: case EXPR_TEST_HOOK:
return false; return false;
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_ASM: case EXPR_ASM:
case EXPR_BINARY: case EXPR_BINARY:
case EXPR_BITASSIGN: case EXPR_BITASSIGN:
@@ -327,7 +326,6 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
case EXPR_FLATPATH: case EXPR_FLATPATH:
case EXPR_COMPOUND_LITERAL: case EXPR_COMPOUND_LITERAL:
case EXPR_POISONED: case EXPR_POISONED:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_CT_ARG: case EXPR_CT_ARG:
case EXPR_ASM: case EXPR_ASM:
case EXPR_SUBSCRIPT_ASSIGN: case EXPR_SUBSCRIPT_ASSIGN:
@@ -670,7 +668,6 @@ bool expr_is_pure(Expr *expr)
return true; return true;
case EXPR_VASPLAT: case EXPR_VASPLAT:
return true; return true;
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_BITASSIGN: case EXPR_BITASSIGN:
return false; return false;
case EXPR_VARIANTSWITCH: 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) 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); 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; break;
} }
if (init_value && LLVMTypeOf(init_value) != llvm_get_type(c, var_type)) decl->backend_ref = global_ref;
{
decl->backend_ref = global_ref = llvm_emit_bitcast_ptr(c, global_ref, var_type);
}
LLVMReplaceAllUsesWith(old, global_ref); LLVMReplaceAllUsesWith(old, global_ref);
LLVMDeleteGlobal(old); LLVMDeleteGlobal(old);
@@ -1173,7 +1167,7 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC
if (test_count) if (test_count)
{ {
LLVMValueRef array_of_names = LLVMConstArray(c->chars_type, names, 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); LLVMTypeRef arr_type = LLVMTypeOf(array_of_names);
name_ref = llvm_add_global_raw(c, ".test_names", arr_type, 0); 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); 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); LLVMSetGlobalConstant(decl_ref, 1);
LLVMSetInitializer(name_ref, array_of_names); LLVMSetInitializer(name_ref, array_of_names);
LLVMSetInitializer(decl_ref, array_of_decls); 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 else
{ {
name_ref = LLVMConstNull(llvm_get_ptr_type(c, type_chars)); name_ref = LLVMConstNull(c->ptr_type);
decl_ref = LLVMConstNull(llvm_get_ptr_type(c, type_voidptr)); decl_ref = LLVMConstNull(c->ptr_type);
} }
LLVMValueRef count = llvm_const_int(c, type_usize, test_count); LLVMValueRef count = llvm_const_int(c, type_usize, test_count);
Type *chars_array = type_get_subarray(type_chars); 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); llvm_value_set(result_value, llvm_get_zero(c, type_voidptr), type_voidptr);
return; 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) 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; Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[4]; LLVMValueRef arg_slots[4];
llvm_emit_intrinsic_args(c, args, 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]; LLVMTypeRef call_type[3];
call_type[0] = call_type[1] = llvm_get_type(c, type_voidptr); call_type[0] = call_type[1] = llvm_get_type(c, type_voidptr);
call_type[2] = llvm_get_type(c, type_usize); 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; Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[4]; LLVMValueRef arg_slots[4];
llvm_emit_intrinsic_args(c, args, 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]; LLVMTypeRef call_type[3];
call_type[0] = call_type[1] = llvm_get_type(c, type_voidptr); call_type[0] = call_type[1] = llvm_get_type(c, type_voidptr);
call_type[2] = llvm_get_type(c, type_usize); 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; Expr **args = expr->call_expr.arguments;
LLVMValueRef arg_slots[4]; LLVMValueRef arg_slots[4];
llvm_emit_intrinsic_args(c, args, 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) }; 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); LLVMValueRef result = llvm_emit_call_intrinsic(c, intrinsic, call_type, 2, arg_slots, 4);
assert(args[4]->const_expr.const_kind == CONST_INTEGER); 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_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 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 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_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_builtin_access(GenContext *c, BEValue *be_value, Expr *expr);
static inline void llvm_emit_const_initialize_reference(GenContext *c, BEValue *ref, 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_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_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_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); 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); 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 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) 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"); // COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef target = LLVMBuildBitCast(c->builder, cast, LLVMPointerType(coerce_type, 0), ""); 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); llvm_store_to_ptr_aligned(c, target, be_value, target_alignment);
*resulting_alignment = target_alignment; *resulting_alignment = target_alignment;
return target; return target;
} }
*resulting_alignment = be_value->alignment; *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) 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"); 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) while (1)
{ {
if (LLVMGetTypeKind(*type) != LLVMStructTypeKind) return; if (LLVMGetTypeKind(type) != LLVMStructTypeKind) break;
if (!LLVMCountStructElementTypes(*type)) return; if (!LLVMCountStructElementTypes(type)) break;
LLVMTypeRef first_element = LLVMStructGetTypeAtIndex(*type, 0); LLVMTypeRef first_element = LLVMStructGetTypeAtIndex(type, 0);
ByteSize first_element_size = llvm_store_size(c, first_element); 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 // If the size is smaller than the total size and smaller than the destination size
// then we're done. // then we're done.
if (first_element_size < dest_size && first_element_size < llvm_store_size(c, *type)) if (first_element_size < dest_size && first_element_size < llvm_store_size(c, type)) break;
{
return;
}
AlignSize dummy; AlignSize dummy;
LLVMValueRef ref = llvm_emit_struct_gep_raw(c, *struct_ptr, *type, 0, llvm_abi_alignment(c, *type), &dummy); type = first_element;
*struct_ptr = ref;
*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) 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; bool to_is_pointer = LLVMGetTypeKind(to) == LLVMPointerTypeKind;
if (LLVMGetTypeKind(from) == LLVMPointerTypeKind) if (LLVMGetTypeKind(from) == LLVMPointerTypeKind)
{ {
// 2a. Destination is a pointer, perform a bitcast. assert(!to_is_pointer && "ptr<->ptr should never happen in LLVM 15+");
if (to_is_pointer)
{
return LLVMBuildBitCast(c->builder, value, to, "coerce.val");
}
// 2b. Otherwise perform ptr -> int
from = llvm_get_type(c, type_iptr); from = llvm_get_type(c, type_iptr);
value = LLVMBuildPtrToInt(c->builder, value, from, ""); 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. // 3. If this is a struct, we index into it.
if (LLVMGetTypeKind(llvm_source_type) == LLVMStructTypeKind) 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. // --> 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) if (source_size >= target_size && source_type_kind != LLVMScalableVectorTypeKind && coerced_type_kind != LLVMScalableVectorTypeKind)
{ {
LLVMValueRef val = LLVMBuildBitCast(c->builder, addr, LLVMPointerType(coerced, 0), ""); // COERCE UPDATE bitcast removed, check for ways to optimize
return llvm_load(c, coerced, val, value->alignment, ""); return llvm_load(c, coerced, addr, value->alignment, "");
} }
if (coerced_type_kind == LLVMScalableVectorTypeKind) 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. // 3. Enter into a struct in case the result is a struct.
if (LLVMGetTypeKind(target_type) == LLVMStructTypeKind) 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 // 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); ByteSize target_size = llvm_alloc_size(c, target_type);
if (src_size <= target_size && coerced_type_kind != LLVMScalableVectorTypeKind && source_type_kind != LLVMScalableVectorTypeKind) if (src_size <= target_size && coerced_type_kind != LLVMScalableVectorTypeKind && source_type_kind != LLVMScalableVectorTypeKind)
{ {
LLVMValueRef val = LLVMBuildBitCast(c->builder, addr, LLVMPointerType(coerced, 0), ""); // COERCE UPDATE bitcast removed, check for ways to optimize
llvm_store_to_ptr_raw_aligned(c, val, value, alignment); llvm_store_to_ptr_raw_aligned(c, addr, value, alignment);
return; 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 *pointer = exprptr(expr->pointer_offset_expr.ptr);
Expr *offset_expr = exprptr(expr->pointer_offset_expr.offset); Expr *offset_expr = exprptr(expr->pointer_offset_expr.offset);
LLVMTypeRef pointee_type = llvm_get_pointee_type(c, pointer->type);
// Emit the pointer // Emit the pointer
llvm_emit_expr(c, value, 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) if (expr->pointer_offset_expr.raw_offset)
{ {
LLVMValueRef raw_pointer = llvm_emit_bitcast_ptr(c, value->value, type_char); // COERCE UPDATE bitcast removed, check for ways to optimize
LLVMValueRef pointer_offset = llvm_emit_pointer_gep_raw(c, c->byte_type, raw_pointer, offset.value); value->value = llvm_emit_pointer_gep_raw(c, c->byte_type, value->value, offset.value);
value->value = LLVMBuildBitCast(c->builder, pointer_offset, pointee_type, ""); return;
}
else
{
value->value = llvm_emit_pointer_gep_raw(c, pointee_type, value->value, offset.value);
} }
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) if (size)
{ {
llvm_value_rvalue(c, value); llvm_value_rvalue(c, value);
pointer = llvm_emit_bitcast_ptr(c, value->value, array_type); pointer = value->value;
} }
else else
{ {
@@ -1207,10 +1193,9 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
case CAST_PTRANY: case CAST_PTRANY:
{ {
llvm_value_rvalue(c, value); llvm_value_rvalue(c, value);
LLVMValueRef pointer = llvm_emit_bitcast(c, value->value, type_voidptr);
BEValue typeid; BEValue typeid;
llvm_emit_typeid(c, &typeid, from_type->pointer); 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; return;
} }
case CAST_BSARRY: case CAST_BSARRY:
@@ -1242,14 +1227,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
break; break;
case CAST_ANYPTR: case CAST_ANYPTR:
llvm_emit_any_pointer(c, value, value); 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; break;
case CAST_XIERR: case CAST_XIERR:
to_type = type_lowering(to_type); to_type = type_lowering(to_type);
@@ -1277,17 +1254,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
break; break;
case CAST_SAPTR: case CAST_SAPTR:
llvm_emit_subarray_pointer(c, value, value); 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; break;
case CAST_EREU: case CAST_EREU:
// This is a no op. // This is a no op.
@@ -1388,7 +1354,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
break; break;
case CAST_STST: case CAST_STST:
llvm_value_addr(c, value); llvm_value_addr(c, value);
value->value = LLVMBuildBitCast(c->builder, value->value, llvm_get_ptr_type(c, to_type), "");
value->type = to_type; value->type = to_type;
return; return;
case CAST_INTENUM: case CAST_INTENUM:
@@ -1523,11 +1488,6 @@ void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref,
// Ensure we have a reference. // Ensure we have a reference.
llvm_value_addr(c, ref); llvm_value_addr(c, ref);
if (expected_type != type)
{
global_copy = LLVMBuildBitCast(c->builder, global_copy, LLVMPointerType(expected_type, 0), "");
}
// Perform the memcpy. // Perform the memcpy.
llvm_emit_memcpy(c, ref->value, ref->alignment, global_copy, alignment, type_size(expr->type)); 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); assert(vec_size(elements) == 1);
real_type = type_lowering(real_type->decl->strukt.members[0]->type); 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; 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) if (ref->type->type_kind == TYPE_UNION)
{ {
llvm_value_set_address(&value, llvm_value_set_address(&value,
llvm_emit_bitcast_ptr(c, ref->value, type), ref->value,
type, type,
type_min_alignment(offset, decl_alignment)); type_min_alignment(offset, decl_alignment));
} }
@@ -2741,7 +2699,6 @@ static void gencontext_emit_slice(GenContext *c, BEValue *be_value, Expr *expr)
// Move pointer // Move pointer
AlignSize alignment; 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_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; break;
} }
case TYPE_SUBARRAY: case TYPE_SUBARRAY:
@@ -4288,7 +4245,6 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
LLVMSetGlobalConstant(global_name, 1); LLVMSetGlobalConstant(global_name, 1);
LLVMSetInitializer(global_name, llvm_get_bytes(c, expr->const_expr.bytes.ptr, expr->const_expr.bytes.len)); 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); llvm_value_set_address_abi_aligned(be_value, global_name, type);
return; return;
} }
@@ -4357,12 +4313,10 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
LLVMSetInitializer(global_name, string); LLVMSetInitializer(global_name, string);
if (is_array) if (is_array)
{ {
global_name = llvm_emit_bitcast_ptr(c, global_name, type);
llvm_value_set_address(be_value, global_name, type, 1); llvm_value_set_address(be_value, global_name, type, 1);
} }
else else
{ {
global_name = llvm_emit_bitcast(c, global_name, type);
llvm_value_set(be_value, global_name, type); llvm_value_set(be_value, global_name, type);
} }
return; return;
@@ -4786,7 +4740,7 @@ static void llvm_emit_splatted_variadic_arg(GenContext *c, Expr *expr, Type *var
case TYPE_POINTER: case TYPE_POINTER:
// Load the pointer // Load the pointer
llvm_value_rvalue(c, &value); 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; return;
case TYPE_SUBARRAY: case TYPE_SUBARRAY:
*subarray = value; *subarray = value;
@@ -4877,7 +4831,7 @@ static inline void llvm_emit_vararg_parameter(GenContext *c, BEValue *value, Typ
&store_alignment); &store_alignment);
llvm_store_to_ptr_aligned(c, slot, &temp_value, 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. // { lo, hi } set into { pad, lo, pad, hi } -> original type.
// 15a. Create memory to hold the return type. // 15a. Create memory to hold the return type.
LLVMValueRef ret = llvm_emit_alloca_aligned(c, call_return_type, ""); // COERCE UPDATE bitcast removed, check for ways to optimize
llvm_value_set_address_abi_aligned(result_value, ret, call_return_type); 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); 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 // 15d. Find the address to the low value
AlignSize alignment; AlignSize alignment;
@@ -5721,7 +5676,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
llvm_value_rvalue(c, value); llvm_value_rvalue(c, value);
LLVMValueRef kind; 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 align = llvm_abi_alignment(c, c->introspect_type);
AlignSize alignment; AlignSize alignment;
if (active_target.feature.safe_mode || expr->typeid_info_expr.kind == TYPEID_INFO_KIND) 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); 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"); 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 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); 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; break;
case TYPEID_INFO_LEN: 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); 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) static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Expr *expr)
{ {
Expr *inner = exprptr(expr->builtin_access_expr.inner); 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_br(c, exit_block);
llvm_emit_block(c, ok_block); llvm_emit_block(c, ok_block);
LLVMValueRef fault_data = LLVMBuildIntToPtr(c->builder, be_value->value, 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, ""); LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->fault_type, fault_data, 1, "");
llvm_emit_br(c, exit_block); llvm_emit_br(c, exit_block);
llvm_emit_block(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 }; LLVMValueRef values[] = { zero.value, ptr };
LLVMBasicBlockRef blocks[] = { zero_block, ok_block }; LLVMBasicBlockRef blocks[] = { zero_block, ok_block };
LLVMAddIncoming(phi, values, blocks, 2); 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); LLVMTypeRef subarray = llvm_get_type(c, type_chars);
LLVMValueRef to_introspect = LLVMBuildIntToPtr(c->builder, inner_type->backend_typeid, 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 = 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)); 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)); type_chars, llvm_abi_alignment(c, subarray));
return; return;
} }
@@ -6166,9 +6037,6 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
case EXPR_VARIANT: case EXPR_VARIANT:
llvm_emit_variant(c, value, expr); llvm_emit_variant(c, value, expr);
return; return;
case EXPR_ARGV_TO_SUBARRAY:
llvm_emit_argv_to_subarray(c, value, expr);
return;
case EXPR_TRY_UNWRAP_CHAIN: case EXPR_TRY_UNWRAP_CHAIN:
llvm_emit_try_unwrap_chain(c, value, expr); llvm_emit_try_unwrap_chain(c, value, expr);
return; return;

View File

@@ -98,8 +98,8 @@ static void llvm_expand_from_args(GenContext *c, Type *type, LLVMValueRef ref, u
case TYPE_UNION: case TYPE_UNION:
{ {
Type *largest_type = type_find_largest_union_element(type); Type *largest_type = type_find_largest_union_element(type);
LLVMValueRef cast_addr = llvm_emit_bitcast_ptr(c, ref, largest_type); // COERCE UPDATE bitcast removed, check for ways to optimize
llvm_expand_from_args(c, largest_type, cast_addr, index, alignment); llvm_expand_from_args(c, largest_type, ref, index, alignment);
return; return;
} }
default: default:
@@ -128,7 +128,8 @@ static inline void llvm_process_parameter_value(GenContext *c, Decl *decl, ABIAr
{ {
// Create the expand type: // Create the expand type:
LLVMTypeRef coerce_type = llvm_get_coerce_type(c, info); 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); llvm_emit_and_set_decl_alloca(c, decl);
AlignSize alignment = decl->alignment; 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: case ABI_ARG_DIRECT_PAIR:
{ {
// Create the two abi types.
LLVMTypeRef lo = llvm_abi_type(c, info->direct_pair.lo); LLVMTypeRef lo = llvm_abi_type(c, info->direct_pair.lo);
LLVMTypeRef hi = llvm_abi_type(c, info->direct_pair.hi); LLVMTypeRef hi = llvm_abi_type(c, info->direct_pair.hi);
LLVMTypeRef struct_type = llvm_get_twostruct(c, lo, hi);
AlignSize decl_alignment = decl->alignment; AlignSize decl_alignment = decl->alignment;
LLVMValueRef coerce; AlignSize hi_alignment = llvm_abi_alignment(c, hi);
if (llvm_store_size(c, struct_type) > type_size(decl->type)) AlignSize lo_alignment = llvm_abi_alignment(c, lo);
{ ByteSize hi_aligned_size = aligned_offset(llvm_store_size(c, hi), hi_alignment);
AlignSize struct_alignment = llvm_abi_alignment(c, struct_type); AlignSize pref_align = MAX(hi_alignment, lo_alignment);
if (decl_alignment < struct_alignment) decl->alignment = decl_alignment = struct_alignment;
coerce = llvm_emit_alloca(c, struct_type, decl_alignment, ""); // Realign to best alignment.
decl->backend_ref = LLVMBuildBitCast(c->builder, coerce, llvm_get_ptr_type(c, decl->type), decl->name ? decl->name : ".anon"); if (pref_align > decl_alignment) decl_alignment = decl->alignment = pref_align;
} AlignSize hi_offset = aligned_offset(llvm_store_size(c, lo), hi_alignment);
else assert(hi_offset + llvm_store_size(c, hi) <= type_size(decl->type));
{
llvm_emit_and_set_decl_alloca(c, decl); // Emit decl
// Here we do the following transform: llvm_emit_and_set_decl_alloca(c, decl);
// lo, hi -> { lo, hi } -> struct LLVMValueRef addr = decl->backend_ref;
// Cast to { lo, hi }
coerce = LLVMBuildBitCast(c->builder, decl->backend_ref, LLVMPointerType(struct_type, 0), "pair"); // Store it in the lo position.
} llvm_store_to_ptr_raw_aligned(c, addr, llvm_get_next_param(c, index), decl_alignment);
// Point to the lo value.
AlignSize element_align; // Calculate the address
LLVMValueRef lo_ptr = llvm_emit_struct_gep_raw(c, coerce, struct_type, 0, decl_alignment, &element_align); 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 struct.
llvm_store_to_ptr_raw_aligned(c, lo_ptr, llvm_get_next_param(c, index), element_align); // Store it in the hi location
// Point to the hi value. llvm_store_to_ptr_raw_aligned(c, addr, llvm_get_next_param(c, index), type_min_alignment(decl_alignment, hi_offset));
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);
return; return;
} }
case ABI_ARG_DIRECT: 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); llvm_emit_and_set_decl_alloca(c, decl);
// Cast to the coerce type. // 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; AlignSize decl_alignment = decl->alignment;
// Store each expanded parameter. // 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); LLVMTypeRef coerce_type = llvm_get_coerce_type(c, info);
// Create the new pointer // Create the new pointer
assert(return_value); 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. // We might have only one value, in that case, build a GEP to that one.
LLVMValueRef lo_val; LLVMValueRef lo_val;
AlignSize alignment; AlignSize alignment;
@@ -476,13 +477,12 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
if (c->debug.enable_stacktrace) if (c->debug.enable_stacktrace)
{ {
LLVMTypeRef slot_type = c->debug.stack_type; LLVMTypeRef slot_type = c->debug.stack_type;
LLVMTypeRef ptr_to_slot_type = LLVMPointerType(slot_type, 0);
if (!c->debug.last_ptr) if (!c->debug.last_ptr)
{ {
const char *name = ".$last_stack"; 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); 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); llvm_set_weak(c, last_stack);
} }
AlignSize alignment = llvm_abi_alignment(c, slot_type); 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); 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, llvm_store_to_ptr_raw_aligned(c,
prev_ptr, 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); align_to_use);
LLVMValueRef func_name = llvm_emit_struct_gep_raw(c, c->debug.stack_slot, slot_type, 1, alignment, &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); 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 fault_type;
LLVMTypeRef size_type; LLVMTypeRef size_type;
LLVMTypeRef char_ptr_type; LLVMTypeRef char_ptr_type;
LLVMTypeRef ptr_type;
LLVMTypeRef chars_type; LLVMTypeRef chars_type;
Decl *panic_var; Decl *panic_var;
struct struct
@@ -276,7 +277,7 @@ TypeSize llvm_abi_size(GenContext *c, LLVMTypeRef type);
BitSize llvm_bitsize(GenContext *c, LLVMTypeRef type); BitSize llvm_bitsize(GenContext *c, LLVMTypeRef type);
AlignSize llvm_abi_alignment(GenContext *c, LLVMTypeRef type); AlignSize llvm_abi_alignment(GenContext *c, LLVMTypeRef type);
LLVMTypeRef llvm_func_type(GenContext *context, FunctionPrototype *prototype); 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_get_twostruct(GenContext *context, LLVMTypeRef lo, LLVMTypeRef hi);
LLVMTypeRef llvm_const_padding_type(GenContext *c, TypeSize size); LLVMTypeRef llvm_const_padding_type(GenContext *c, TypeSize size);
LLVMMetadataRef llvm_get_debug_type(GenContext *c, Type *type); 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_function_decl(GenContext *c, Decl *decl);
void llvm_emit_xxlizer(GenContext *c, Decl *decl); void llvm_emit_xxlizer(GenContext *c, Decl *decl);
bool llvm_types_are_similar(LLVMTypeRef original, LLVMTypeRef coerce); bool llvm_types_are_similar(LLVMTypeRef original, LLVMTypeRef coerce);
INLINE LLVMTypeRef llvm_get_ptr_type(GenContext *c, Type *type);
// -- Attributes --- // -- Attributes ---
void llvm_attribute_add_range(GenContext *c, LLVMValueRef value_to_add_attribute_to, unsigned attribute, int index_start, int index_end); 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 void llvm_set_alignment(LLVMValueRef alloca, AlignSize alignment);
INLINE AlignSize llvm_type_or_alloca_align(LLVMValueRef dest, Type *type); 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); INLINE LLVMValueRef llvm_zext_trunc(GenContext *c, LLVMValueRef data, LLVMTypeRef type);
// -- Constants -- // -- 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)); 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) INLINE void llvm_value_bitcast(GenContext *c, BEValue *value, Type *type)
{ {
assert(llvm_value_is_addr(value)); assert(llvm_value_is_addr(value));
type = type_lowering(type); type = type_lowering(type);
value->value = llvm_emit_bitcast(c, value->value, type_get_ptr(type));
value->type = 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) INLINE LLVMValueRef llvm_emit_shl(GenContext *c, LLVMValueRef value, LLVMValueRef shift)
{ {
return LLVMBuildShl(c->builder, value, shift, "shl"); 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) INLINE LLVMValueRef llvm_emit_and_raw(GenContext *c, LLVMValueRef lhs, LLVMValueRef rhs)
{ {
if (llvm_is_const_null(lhs)) return lhs; 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->bool_type = LLVMInt1TypeInContext(c->context);
c->byte_type = LLVMInt8TypeInContext(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->chars_type = llvm_get_type(c, type_chars);
c->introspect_type = create_introspection_type(c); c->introspect_type = create_introspection_type(c);
c->fault_type = create_fault_type(c); c->fault_type = create_fault_type(c);
c->size_type = llvm_get_type(c, type_usize); 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 (c->panic_var) c->panic_var->backend_ref = NULL;
if (active_target.debug_info != DEBUG_INFO_NONE) 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) if (active_target.debug_info == DEBUG_INFO_FULL && active_target.feature.safe_mode)
{ {
c->debug.stack_type = LLVMStructCreateNamed(c->context, ".$callstack"); 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,
c->chars_type, c->chars_type,
llvm_get_type(c, type_uint) }; 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)); LLVMSetInitializer(global_string, llvm_get_zstring(c, str, len));
AlignSize alignment; AlignSize alignment;
LLVMValueRef string = llvm_emit_array_gep_raw(c, global_string, char_array_type, 0, 1, &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. // Here we do an optimized(?) memcopy.
ByteSize size = type_size(value->type); ByteSize size = type_size(value->type);
LLVMValueRef copy_size = llvm_const_int(c, size <= UINT32_MAX ? type_uint : type_usize, size); 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, LLVMValueRef copy = LLVMBuildMemCpy(c->builder,
destination, destination,
alignment, alignment,
source, value->value,
value->alignment ? value->alignment : type_abi_alignment(value->type), value->alignment ? value->alignment : type_abi_alignment(value->type),
copy_size); copy_size);
return copy; return copy;

View File

@@ -5,10 +5,10 @@
#include "llvm_codegen_internal.h" #include "llvm_codegen_internal.h"
static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl); 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 inline LLVMTypeRef llvm_type_from_array(GenContext *context, Type *type);
static void param_expand(GenContext *context, LLVMTypeRef** params_ref, 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) 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 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) 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); arg_info->param_index_start = (MemberIndex)vec_size(*params);
switch (arg_info->kind) 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: case ABI_ARG_IGNORE:
break; break;
case ABI_ARG_INDIRECT: case ABI_ARG_INDIRECT:
vec_add(*params, llvm_get_ptr_type(context, param_type)); vec_add(*params, c->ptr_type);
break; break;
case ABI_ARG_EXPAND_COERCE: 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)) 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; break;
case ABI_ARG_EXPAND: case ABI_ARG_EXPAND:
// Expanding a structs // 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 we have padding, add it here.
if (arg_info->expand.padding_type) 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; break;
case ABI_ARG_DIRECT: case ABI_ARG_DIRECT:
vec_add(*params, llvm_get_type(context, param_type)); vec_add(*params, llvm_get_type(c, param_type));
break; break;
case ABI_ARG_DIRECT_SPLIT_STRUCT: case ABI_ARG_DIRECT_SPLIT_STRUCT:
{ {
// Normal direct. // 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++) for (unsigned idx = 0; idx < arg_info->direct_struct_expand.elements; idx++)
{ {
vec_add(*params, coerce_type); 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: case ABI_ARG_DIRECT_COERCE_INT:
{ {
// Normal direct. // 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); vec_add(*params, coerce_type);
break; break;
} }
case ABI_ARG_DIRECT_COERCE: case ABI_ARG_DIRECT_COERCE:
{ {
// Normal direct. // 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); vec_add(*params, coerce_type);
break; break;
} }
case ABI_ARG_DIRECT_PAIR: case ABI_ARG_DIRECT_PAIR:
// Pairs are passed by param. // Pairs are passed by param.
vec_add(*params, llvm_abi_type(context, arg_info->direct_pair.lo)); vec_add(*params, llvm_abi_type(c, 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.hi));
break; break;
} }
arg_info->param_index_end = (MemberIndex)vec_size(*params); 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; LLVMTypeRef retval = NULL;
Type *call_return_type = prototype->abi_ret_type; 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: case ABI_ARG_EXPAND:
UNREACHABLE; UNREACHABLE;
case ABI_ARG_INDIRECT: case ABI_ARG_INDIRECT:
vec_add(*params, llvm_get_ptr_type(context, call_return_type)); vec_add(*params, c->ptr_type);
retval = llvm_get_type(context, type_void); retval = llvm_get_type(c, type_void);
break; break;
case ABI_ARG_EXPAND_COERCE: 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)) if (!abi_type_is_valid(ret_arg_info->direct_pair.hi))
{ {
retval = lo; retval = lo;
break; break;
} }
LLVMTypeRef hi = llvm_abi_type(context, ret_arg_info->direct_pair.hi); LLVMTypeRef hi = llvm_abi_type(c, ret_arg_info->direct_pair.hi);
retval = llvm_get_twostruct(context, lo, hi); retval = llvm_get_twostruct(c, lo, hi);
break; break;
} }
case ABI_ARG_IGNORE: case ABI_ARG_IGNORE:
retval = llvm_get_type(context, type_void); retval = llvm_get_type(c, type_void);
break; break;
case ABI_ARG_DIRECT_PAIR: case ABI_ARG_DIRECT_PAIR:
{ {
LLVMTypeRef lo = llvm_abi_type(context, ret_arg_info->direct_pair.lo); LLVMTypeRef lo = llvm_abi_type(c, ret_arg_info->direct_pair.lo);
LLVMTypeRef hi = llvm_abi_type(context, ret_arg_info->direct_pair.hi); LLVMTypeRef hi = llvm_abi_type(c, ret_arg_info->direct_pair.hi);
retval = llvm_get_twostruct(context, lo, hi); retval = llvm_get_twostruct(c, lo, hi);
break; break;
} }
case ABI_ARG_DIRECT: case ABI_ARG_DIRECT:
retval = llvm_get_type(context, call_return_type); retval = llvm_get_type(c, call_return_type);
break; break;
case ABI_ARG_DIRECT_SPLIT_STRUCT: case ABI_ARG_DIRECT_SPLIT_STRUCT:
UNREACHABLE UNREACHABLE
case ABI_ARG_DIRECT_COERCE_INT: 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; break;
case ABI_ARG_DIRECT_COERCE: 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; break;
} }
// If it's optional and it's not void (meaning ret_abi_info will be NULL) // If it's optional and it's not void (meaning ret_abi_info will be NULL)
if (prototype->ret_by_ref) 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. // Add in all of the required arguments.
VECEACH(prototype->param_types, i) 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) 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; return retval;
} }
@@ -377,7 +364,8 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type)
case TYPE_BOOL: case TYPE_BOOL:
return any_type->backend_type = LLVMIntTypeInContext(c->context, 8U); return any_type->backend_type = LLVMIntTypeInContext(c->context, 8U);
case TYPE_POINTER: 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_ARRAY:
case TYPE_FLEXIBLE_ARRAY: case TYPE_FLEXIBLE_ARRAY:
return any_type->backend_type = llvm_type_from_array(c, any_type); 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); llvm_set_linkonce(c, global_ref);
LLVMSetInitializer(global_ref, associated_value_arr); LLVMSetInitializer(global_ref, associated_value_arr);
LLVMSetGlobalConstant(global_ref, true); LLVMSetGlobalConstant(global_ref, true);
if (mixed) associated_value->backend_ref = global_ref;
{
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;
}
} }
return val; return val;
} }
@@ -668,11 +649,10 @@ static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type)
llvm_set_linkonce(c, global_name); llvm_set_linkonce(c, global_name);
val->backend_ref = LLVMBuildPointerCast(c->builder, global_name, llvm_get_type(c, type_typeid), ""); 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; LLVMValueRef* values = elements ? MALLOC(sizeof(LLVMValueRef) * elements) : NULL;
for (unsigned i = 0; i < elements; i++) 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); 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); LLVMValueRef ref = llvm_add_global_raw(c, ".taddr", LLVMTypeOf(val), 0);
llvm_set_private_linkage(ref); llvm_set_private_linkage(ref);
LLVMSetInitializer(ref, val); 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 else
{ {

View File

@@ -757,7 +757,6 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type)
case EXPR_TRY_UNWRAP_CHAIN: case EXPR_TRY_UNWRAP_CHAIN:
case EXPR_SUBSCRIPT_ADDR: case EXPR_SUBSCRIPT_ADDR:
case EXPR_VARIANTSWITCH: case EXPR_VARIANTSWITCH:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_COMPILER_CONST: case EXPR_COMPILER_CONST:
case EXPR_STRINGIFY: case EXPR_STRINGIFY:
case EXPR_CT_EVAL: 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:
case EXPR_TRY_UNWRAP_CHAIN: case EXPR_TRY_UNWRAP_CHAIN:
case EXPR_SUBSCRIPT_ADDR: case EXPR_SUBSCRIPT_ADDR:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_VARIANTSWITCH: case EXPR_VARIANTSWITCH:
case EXPR_COMPILER_CONST: case EXPR_COMPILER_CONST:
case EXPR_STRINGIFY: 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; if (!vec_size(expr->expression_list)) return false;
return sema_binary_is_expr_lvalue(top_expr, VECLAST(expr->expression_list)); return sema_binary_is_expr_lvalue(top_expr, VECLAST(expr->expression_list));
case EXPR_POISONED: case EXPR_POISONED:
case EXPR_ARGV_TO_SUBARRAY:
case EXPR_ASM: case EXPR_ASM:
case EXPR_BINARY: case EXPR_BINARY:
case EXPR_BITASSIGN: case EXPR_BITASSIGN:
@@ -7020,9 +7019,6 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr)
case EXPR_STRINGIFY: case EXPR_STRINGIFY:
if (!sema_expr_analyse_ct_stringify(context, expr)) return false; if (!sema_expr_analyse_ct_stringify(context, expr)) return false;
return true; return true;
case EXPR_ARGV_TO_SUBARRAY:
expr->type = type_get_subarray(global_context_string_type());
return true;
case EXPR_DECL: case EXPR_DECL:
if (!sema_analyse_var_decl(context, expr->decl_expr, true)) return false; if (!sema_analyse_var_decl(context, expr->decl_expr, true)) return false;
expr->type = expr->decl_expr->type; 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 #if IS_GCC || IS_CLANG
#define MAX(_a, _b) ({ \ #define MAX(_a, _b) ({ \
typeof(_a) __a__ = (_a); \ __auto_type __a__ = (_a); \
typeof(_b) __b__ = (_b); \ __auto_type __b__ = (_b); \
__a__ > __b__ ? __a__ : __b__; }) __a__ > __b__ ? __a__ : __b__; })
#define MIN(_a, _b) ({ \ #define MIN(_a, _b) ({ \
typeof(_a) __a__ = (_a); \ __auto_type __a__ = (_a); \
typeof(_b) __b__ = (_b); \ __auto_type __b__ = (_b); \
__a__ < __b__ ? __a__ : __b__; }) __a__ < __b__ ? __a__ : __b__; })
#else #else

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,15 +23,15 @@ declare void @hello2(i64, i64) #0
define void @unionx64_hello(i64 %0, i64 %1) #0 { define void @unionx64_hello(i64 %0, i64 %1) #0 {
entry: entry:
%f = alloca %Foo, align 8 %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 %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 %3 = getelementptr inbounds { i64, i64 }, ptr %f, i32 0, i32 1
store i64 %1, ptr %3, align 8 %hi = load i64, 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
call void @hello2(i64 %lo, i64 %hi) call void @hello2(i64 %lo, i64 %hi)
ret void ret void
} }
attributes #0 = { nounwind }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -65,7 +65,7 @@ entry:
if.then: ; preds = %entry if.then: ; preds = %entry
%1 = load ptr, ptr @std_core_mem_thread_allocator, align 8 %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 br label %if.exit
if.exit: ; preds = %if.then, %entry if.exit: ; preds = %if.then, %entry
@@ -131,7 +131,7 @@ entry:
%retparam36 = alloca i64, align 8 %retparam36 = alloca i64, align 8
%varargslots37 = alloca [1 x %variant], align 16 %varargslots37 = alloca [1 x %variant], align 16
%result = alloca %"Foo[]", align 8 %result = alloca %"Foo[]", align 8
%map2 = alloca %HashMap.3, align 8 %map2 = alloca %HashMap.2, align 8
%retparam41 = alloca i64, align 8 %retparam41 = alloca i64, align 8
%varargslots42 = alloca [1 x %variant], align 16 %varargslots42 = alloca [1 x %variant], align 16
%taddr43 = alloca i8, align 1 %taddr43 = alloca i8, align 1
@@ -148,7 +148,7 @@ entry:
%error_var = alloca i64, align 8 %error_var = alloca i64, align 8
%retparam65 = alloca ptr, align 8 %retparam65 = alloca ptr, align 8
%mark = alloca i64, align 8 %mark = alloca i64, align 8
%map3 = alloca %HashMap.3, align 8 %map3 = alloca %HashMap.2, align 8
%retparam68 = alloca i64, align 8 %retparam68 = alloca i64, align 8
%varargslots69 = alloca [1 x %variant], align 16 %varargslots69 = alloca [1 x %variant], align 16
%result70 = alloca %"int[]", align 8 %result70 = alloca %"int[]", align 8

View File

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

View File

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

View File

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

View File

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

View File

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