Assignment evaluation order now right->left, following C++17.

This commit is contained in:
Christoffer Lerno
2025-07-31 11:49:42 +02:00
parent d600d0898c
commit 334ee975b9
13 changed files with 219 additions and 178 deletions

View File

@@ -33,6 +33,7 @@
- Place output in `out` by default for projects. Use temp folder for building at the command line.
- Allow absolute paths for `$embed`.
- Add `@try` and `@try_catch`.
- Assignment evaluation order now right->left, following C++17 and possibly C23.
### Fixes
- mkdir/rmdir would not work properly with substring paths on non-windows platforms.

View File

@@ -106,17 +106,16 @@ Expr *expr_remove_recast(Expr *expr)
return expr;
}
BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValueRef optional, bool is_init)
BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *ref_expr, Expr *expr, LLVMValueRef optional, bool is_init)
{
ASSERT(llvm_value_is_addr(ref));
assert((optional || !IS_OPTIONAL(expr)) && "Assumed an optional address if it's an optional expression.");
ASSERT(ref_expr || llvm_value_is_addr(ref));
expr = expr_remove_recast(expr);
// Special optimization of handling of optional
if (expr->expr_kind == EXPR_OPTIONAL)
{
assert(!ref_expr);
PUSH_CLEAR_CATCH();
BEValue result;
@@ -125,6 +124,9 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
llvm_value_rvalue(c, &result);
assert((optional || !IS_OPTIONAL(expr)) && "Assumed an optional address if it's an optional expression.");
LLVMValueRef err_val = result.value;
// Store it in the optional
llvm_store_to_ptr(c, optional, &result);
@@ -147,6 +149,7 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
if (IS_OPTIONAL(expr))
{
assert(!ref_expr);
assign_block = llvm_basic_block_new(c, "after_assign");
ASSERT(optional);
if (c->catch.fault)
@@ -168,10 +171,12 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
if (type_flat_is_vector(expr->type))
{
llvm_emit_expr(c, &value, expr);
if (ref_expr) llvm_emit_expr(c, ref, ref_expr);
llvm_store(c, ref, &value);
}
else if (expr_is_const_initializer(expr))
{
if (ref_expr) llvm_emit_expr(c, ref, ref_expr);
llvm_emit_const_initialize_reference(c, ref, expr);
value = *ref;
}
@@ -179,15 +184,18 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
{
if (is_init)
{
assert(!ref_expr);
llvm_emit_initialize_reference(c, ref, expr);
}
else
{
BEValue val;
AlignSize alignment = type_alloca_alignment(ref->type);
LLVMValueRef temp = llvm_emit_alloca(c, llvm_get_type(c, ref->type), alignment, ".assign_list");
llvm_value_set_address(c, &val, temp, ref->type, alignment);
Type *type = ref_expr ? type_lowering(ref_expr->type) : ref->type;
AlignSize alignment = type_alloca_alignment(type);
LLVMValueRef temp = llvm_emit_alloca(c, llvm_get_type(c, type), alignment, ".assign_list");
llvm_value_set_address(c, &val, temp, type, alignment);
llvm_emit_initialize_reference(c, &val, expr);
if (ref_expr) llvm_emit_expr(c, ref, ref_expr);
llvm_store(c, ref, &val);
}
value = *ref;
@@ -196,11 +204,13 @@ BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValue
{
if (expr->expr_kind == EXPR_CALL)
{
llvm_emit_call_expr(c, &value, expr, ref);
llvm_emit_call_expr(c, &value, expr, ref_expr ? NULL : ref);
if (ref_expr) llvm_emit_expr(c, ref, ref_expr);
}
else
{
llvm_emit_expr(c, &value, expr);
if (ref_expr) llvm_emit_expr(c, ref, ref_expr);
}
if (!c->current_block) goto AFTER_STORE;
if (value.type != type_void) llvm_store(c, ref, &value);
@@ -215,6 +225,7 @@ AFTER_STORE:;
if (assign_block)
{
assert(!ref_expr);
llvm_emit_br(c, assign_block);
if (rejump_block)
{
@@ -4493,19 +4504,18 @@ static void llvm_emit_binary_expr(GenContext *c, BEValue *be_value, Expr *expr)
if (binary_op == BINARYOP_ASSIGN)
{
Expr *left = exprptr(expr->binary_expr.left);
llvm_emit_expr(c, be_value, left);
ASSERT(llvm_value_is_addr(be_value));
LLVMValueRef optional_ref = NULL;
// If the LHS is an identifier, then we're assigning the optional value to that.
if (left->expr_kind == EXPR_IDENTIFIER)
{
optional_ref = decl_optional_ref(left->ident_expr);
be_value->kind = BE_ADDRESS;
llvm_value_set_decl(c, be_value, left->ident_expr);
*be_value = llvm_emit_assign_expr(c, be_value, NULL, exprptr(expr->binary_expr.right), decl_optional_ref(left->ident_expr), false);
return;
}
*be_value = llvm_emit_assign_expr(c, be_value, left, exprptr(expr->binary_expr.right), NULL, false);
// Emit the result.
*be_value = llvm_emit_assign_expr(c, be_value, exprptr(expr->binary_expr.right), optional_ref, false);
return;
}

View File

@@ -542,7 +542,7 @@ void llvm_emit_compound_stmt(GenContext *c, Ast *ast);
LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initializer);
void llvm_emit_function_body(GenContext *c, Decl *decl);
void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs);
BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValueRef optional, bool is_init);
BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *ref_expr, Expr *expr, LLVMValueRef optional, bool is_init);
INLINE void llvm_emit_exprid(GenContext *c, BEValue *value, ExprId expr);
INLINE void llvm_emit_statement_chain(GenContext *c, AstId current);
void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, ConstInitializer *initializer);

View File

@@ -144,7 +144,7 @@ void llvm_emit_local_decl(GenContext *c, Decl *decl, BEValue *value)
llvm_value_set_decl_address(c, value, decl);
// Pretend to be normal.
value->kind = BE_ADDRESS;
BEValue res = llvm_emit_assign_expr(c, value, decl->var.init_expr, decl->var.optional_ref, true);
BEValue res = llvm_emit_assign_expr(c, value, NULL, decl->var.init_expr, decl->var.optional_ref, true);
if (!is_optional && res.value)
{
*value = res;

View File

@@ -6726,10 +6726,14 @@ static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *lef
}
if (left->expr_kind == EXPR_SUBSCRIPT_ASSIGN)
{
Decl *temp = decl_new_generated_var(right->type, VARDECL_LOCAL, right->span);
Expr *expr_rh = expr_generate_decl(temp, right);
Expr **args = NULL;
vec_add(args, exprptr(left->subscript_assign_expr.index));
vec_add(args, right);
return sema_insert_method_call(context, expr, declptr(left->subscript_assign_expr.method), exprptr(left->subscript_assign_expr.expr), args, false);
vec_add(args, expr_variable(temp));
if (!sema_insert_method_call(context, expr, declptr(left->subscript_assign_expr.method), exprptr(left->subscript_assign_expr.expr), args, false)) return false;
expr_rewrite_two(expr, expr_rh, expr_copy(expr));
return true;
}
if (left->expr_kind == EXPR_BITACCESS)
{

View File

@@ -319,16 +319,13 @@ fn int strcmp(char *s1, char *s2) {
@.str = private unnamed_addr constant [7 x i8] c"<none>\00", align 1
@.str.11 = private unnamed_addr constant [14 x i8] c"Hello world!\0A\00", align 1
; Function Attrs:
declare ptr @malloc(i32) #0
; Function Attrs:
define ptr @foo.passThroughList(ptr %0) #0 {
entry:
ret ptr %0
}
; Function Attrs:
define void @foo.foo() #0 {
entry:
%0 = load i32, ptr @foo.foo.10, align 4
@@ -339,7 +336,6 @@ entry:
ret void
}
; Function Attrs:
define void @foo.insertIntoListTail(ptr %0, i32 %1) #0 {
entry:
%l = alloca ptr, align 8
@@ -360,9 +356,9 @@ loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
%6 = load ptr, ptr %l, align 8
%7 = call ptr @malloc(i32 16)
store ptr %7, ptr %6, align 8
%6 = call ptr @malloc(i32 16)
%7 = load ptr, ptr %l, align 8
store ptr %6, ptr %7, align 8
%8 = load ptr, ptr %l, align 8
%9 = load ptr, ptr %8, align 8
store i32 %1, ptr %9, align 8
@@ -373,7 +369,6 @@ loop.exit: ; preds = %loop.cond
ret void
}
; Function Attrs:
define ptr @foo.findData(ptr %0, i32 %1) #0 {
entry:
%i2nb = icmp eq ptr %0, null
@@ -397,10 +392,8 @@ if.exit2: ; preds = %if.exit
ret ptr %4
}
; Function Attrs:
declare void @foundIt() #0
; Function Attrs:
define void @foo.doListStuff() #0 {
entry:
%myList = alloca ptr, align 8
@@ -443,7 +436,6 @@ if.exit6: ; preds = %if.then5, %if.exit3
ret void
}
; Function Attrs:
define i32 @foo.floatcomptest(ptr %0, ptr %1, ptr %2, ptr %3) #0 {
entry:
%4 = load double, ptr %0, align 8
@@ -463,7 +455,6 @@ or.phi: ; preds = %or.rhs, %entry
ret i32 %zext
}
; Function Attrs:
define ptr @foo.memset_impl(ptr %0, i32 %1, i32 %2) #0 {
entry:
%len = alloca i32, align 4
@@ -480,9 +471,9 @@ loop.cond: ; preds = %loop.body, %entry
br i1 %neq, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%trunc = trunc i32 %1 to i8
%4 = load i64, ptr %dstp, align 8
%intptr = inttoptr i64 %4 to ptr
%trunc = trunc i32 %1 to i8
store i8 %trunc, ptr %intptr, align 1
%5 = load i64, ptr %dstp, align 8
%add = add i64 %5, 1
@@ -496,7 +487,6 @@ loop.exit: ; preds = %loop.cond
ret ptr %0
}
; Function Attrs:
define internal ptr @foo.localmalloc(i32 %0) #0 {
entry:
%blah = alloca ptr, align 8
@@ -516,7 +506,6 @@ if.exit: ; preds = %entry
ret ptr null
}
; Function Attrs:
define void @foo.testRetStruct(ptr noalias sret(%PBVTest) align 8 %0, float %1, double %2, i32 %3) #0 {
entry:
%t = alloca %PBVTest, align 8
@@ -530,10 +519,8 @@ entry:
ret void
}
; Function Attrs:
declare void @testRetStruct2(ptr noalias sret(%PBVTest) align 8) #0
; Function Attrs:
define double @foo.callRetStruct(float %0, double %1, i32 %2) #0 {
entry:
%t = alloca %PBVTest, align 8
@@ -547,10 +534,8 @@ entry:
ret double %fadd2
}
; Function Attrs:
declare i32 @fp(i32, ptr) #0
; Function Attrs:
define void @foo.__bb_exit_func() #0 {
entry:
%0 = load ptr, ptr @foo.ext, align 8
@@ -570,17 +555,14 @@ cond.phi: ; preds = %cond.rhs, %cond.lhs
ret void
}
; Function Attrs:
declare i32 @puts(ptr) #0
; Function Attrs:
define i32 @foo.ptrFunc(ptr %0, i32 %1) #0 {
entry:
%2 = call i32 %0(i32 %1)
ret i32 %2
}
; Function Attrs:
define zeroext i8 @foo.ptrFunc2(ptr byval([30 x ptr]) align 8 %0, i32 %1) #0 {
entry:
%sext = sext i32 %1 to i64
@@ -591,13 +573,10 @@ entry:
ret i8 %trunc
}
; Function Attrs:
declare zeroext i8 @smallArgs2(i8 zeroext, i8 zeroext, i64, i8 zeroext, i8 zeroext) #0
; Function Attrs:
declare i32 @someFuncA() #0
; Function Attrs:
define zeroext i8 @foo.smallArgs(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) #0 {
entry:
%4 = call i32 @someFuncA()
@@ -612,7 +591,6 @@ entry:
ret i8 %5
}
; Function Attrs:
define internal i32 @foo.f0(ptr byval(%Quad) align 8 %0, i32 %1) #0 {
entry:
%r = alloca %Quad, align 8
@@ -620,19 +598,19 @@ entry:
br i1 %i2b, label %if.then, label %if.exit
if.then: ; preds = %entry
%ptradd = getelementptr inbounds i8, ptr %r, i64 4
%ptradd1 = getelementptr inbounds i8, ptr %0, i64 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %ptradd, ptr align 4 %ptradd1, i32 4, i1 false)
%ptradd = getelementptr inbounds i8, ptr %0, i64 4
%ptradd1 = getelementptr inbounds i8, ptr %r, i64 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %ptradd1, ptr align 4 %ptradd, i32 4, i1 false)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%ptradd2 = getelementptr inbounds i8, ptr %0, i64 8
%ptradd3 = getelementptr inbounds i8, ptr %r, i64 4
store ptr %ptradd3, ptr %ptradd2, align 8
%ptradd4 = getelementptr inbounds i8, ptr %0, i64 20
%ptradd5 = getelementptr inbounds i8, ptr %0, i64 16
store i8 1, ptr %ptradd5, align 8
store i32 1, ptr %ptradd4, align 4
%ptradd2 = getelementptr inbounds i8, ptr %r, i64 4
%ptradd3 = getelementptr inbounds i8, ptr %0, i64 8
store ptr %ptradd2, ptr %ptradd3, align 8
%ptradd4 = getelementptr inbounds i8, ptr %0, i64 16
store i8 1, ptr %ptradd4, align 8
%ptradd5 = getelementptr inbounds i8, ptr %0, i64 20
store i32 1, ptr %ptradd5, align 4
store i32 1, ptr %0, align 8
%ptradd6 = getelementptr inbounds i8, ptr %0, i64 4
%ptradd7 = getelementptr inbounds i8, ptr %ptradd6, i64 2
@@ -649,7 +627,6 @@ if.exit: ; preds = %if.then, %entry
ret i32 %sub
}
; Function Attrs:
define i32 @foo.f1(ptr %0, i32 %1) #0 {
entry:
%r = alloca %Quad, align 8
@@ -661,10 +638,10 @@ if.then: ; preds = %entry
br label %if.exit
if.exit: ; preds = %if.then, %entry
%ptradd = getelementptr inbounds i8, ptr %0, i64 20
%ptradd1 = getelementptr inbounds i8, ptr %0, i64 16
store i8 1, ptr %ptradd1, align 8
store i32 1, ptr %ptradd, align 4
%ptradd = getelementptr inbounds i8, ptr %0, i64 16
store i8 1, ptr %ptradd, align 8
%ptradd1 = getelementptr inbounds i8, ptr %0, i64 20
store i32 1, ptr %ptradd1, align 4
store i32 1, ptr %0, align 8
%ptradd2 = getelementptr inbounds i8, ptr %0, i64 4
%ptradd3 = getelementptr inbounds i8, ptr %ptradd2, i64 2
@@ -681,7 +658,6 @@ if.exit: ; preds = %if.then, %entry
ret i32 %sub
}
; Function Attrs:
define i32 @foo.badFunc(float %0) #0 {
entry:
%result = alloca i32, align 4
@@ -698,10 +674,8 @@ if.exit: ; preds = %if.then, %entry
ret i32 %1
}
; Function Attrs:
declare i32 @ef1(ptr, ptr, ptr) #0
; Function Attrs:
define i32 @foo.func(i32 %0, i64 %1) #0 {
entry:
%result = alloca i32, align 4
@@ -718,7 +692,6 @@ entry:
ret i32 %4
}
; Function Attrs:
define signext i16 @foo.funFunc(i64 %0, i8 zeroext %1) #0 {
entry:
%zext = zext i8 %1 to i64
@@ -727,13 +700,11 @@ entry:
ret i16 %trunc
}
; Function Attrs:
define i32 @foo.castTest(i32 %0) #0 {
entry:
ret i32 %0
}
; Function Attrs:
define double @foo.testAdd(double %0, float %1) #0 {
entry:
%fpfpext = fpext float %1 to double
@@ -742,7 +713,6 @@ entry:
ret double %fadd1
}
; Function Attrs:
define i32 @foo.funcZ(i32 %0, i32 %1) #0 {
entry:
%i = alloca i32, align 4
@@ -778,7 +748,6 @@ loop.exit: ; preds = %loop.cond
ret i32 %mul4
}
; Function Attrs:
define i32 @foo.sumArray(ptr %0, i32 %1) #0 {
entry:
%i = alloca i32, align 4
@@ -810,7 +779,6 @@ loop.exit: ; preds = %loop.cond
ret i32 %7
}
; Function Attrs:
define i32 @foo.arrayParam(ptr %0) #0 {
entry:
%ptradd = getelementptr inbounds i8, ptr %0, i64 200
@@ -822,7 +790,6 @@ entry:
ret i32 %2
}
; Function Attrs:
define i32 @foo.arrayToSum() #0 {
entry:
%a = alloca [100 x i32], align 16
@@ -838,10 +805,10 @@ loop.cond: ; preds = %loop.body, %entry
loop.body: ; preds = %loop.cond
%1 = load i32, ptr %i, align 4
%sext = sext i32 %1 to i64
%ptroffset = getelementptr inbounds [4 x i8], ptr %a, i64 %sext
%mul = mul i32 %1, 4
%2 = load i32, ptr %i, align 4
%mul = mul i32 %2, 4
%sext = sext i32 %2 to i64
%ptroffset = getelementptr inbounds [4 x i8], ptr %a, i64 %sext
store i32 %mul, ptr %ptroffset, align 4
%3 = load i32, ptr %i, align 4
%add = add i32 %3, 1
@@ -887,7 +854,6 @@ loop.exit: ; preds = %loop.cond
ret i32 0
}
; Function Attrs:
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
@@ -909,7 +875,6 @@ entry:
ret double %fadd15
}
; Function Attrs:
define void @foo.strcpy(ptr %0, ptr %1) #0 {
entry:
%s1 = alloca ptr, align 8
@@ -919,14 +884,14 @@ entry:
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load ptr, ptr %s1, align 8
%2 = load ptr, ptr %s2, align 8
%ptradd_any = getelementptr i8, ptr %2, i64 1
store ptr %ptradd_any, ptr %s1, align 8
%3 = load ptr, ptr %s2, align 8
store ptr %ptradd_any, ptr %s2, align 8
%3 = load ptr, ptr %s1, align 8
%ptradd_any1 = getelementptr i8, ptr %3, i64 1
store ptr %ptradd_any1, ptr %s2, align 8
%4 = load i8, ptr %3, align 1
store i8 %4, ptr %2, align 1
store ptr %ptradd_any1, ptr %s1, align 8
%4 = load i8, ptr %2, align 1
store i8 %4, ptr %3, align 1
%i2b = icmp ne i8 %4, 0
br i1 %i2b, label %loop.body, label %loop.exit
@@ -964,14 +929,14 @@ loop.exit: ; preds = %loop.cond
br label %loop.cond2
loop.cond2: ; preds = %loop.body6, %loop.exit
%5 = load ptr, ptr %s1, align 8
%5 = load ptr, ptr %s2, align 8
%ptradd_any3 = getelementptr i8, ptr %5, i64 1
store ptr %ptradd_any3, ptr %s1, align 8
%6 = load ptr, ptr %s2, align 8
store ptr %ptradd_any3, ptr %s2, align 8
%6 = load ptr, ptr %s1, align 8
%ptradd_any4 = getelementptr i8, ptr %6, i64 1
store ptr %ptradd_any4, ptr %s2, align 8
%7 = load i8, ptr %6, align 1
store i8 %7, ptr %5, align 1
store ptr %ptradd_any4, ptr %s1, align 8
%7 = load i8, ptr %5, align 1
store i8 %7, ptr %6, align 1
%i2b5 = icmp ne i8 %7, 0
br i1 %i2b5, label %loop.body6, label %loop.exit7

View File

@@ -29,6 +29,7 @@ entry:
%taddr9 = alloca i64, align 8
%varargslots10 = alloca [2 x %any], align 16
%indirectarg13 = alloca %"any[]", align 8
%add = add i32 %1, 1
%checknull = icmp eq ptr %0, null
%2 = call i1 @llvm.expect.i1(i1 %checknull, i1 false)
br i1 %2, label %panic, label %checkok
@@ -41,7 +42,6 @@ checkok: ; preds = %entry
br i1 %6, label %panic1, label %checkok3
checkok3: ; preds = %checkok
%add = add i32 %1, 1
store i32 %add, ptr %0, align 4
%checknull4 = icmp eq ptr %0, null
%7 = call i1 @llvm.expect.i1(i1 %checknull4, i1 false)

View File

@@ -41,7 +41,7 @@ entry:
!15 = !{!16}
!16 = !DISubrange(count: 1, lowerBound: 0)
!17 = !DILocation(line: 5, column: 10, scope: !8)
!18 = !DILocation(line: 7, column: 18, scope: !8)
!18 = !DILocation(line: 7, column: 12, scope: !8)
!19 = distinct !DISubprogram(name: "main", linkageName: "test.main", scope: !7, file: !7, line: 11, type: !9, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6)
!20 = !DILocation(line: 12, column: 3, scope: !19)
!21 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !7, file: !7, line: 11, type: !22, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !11)

View File

@@ -380,22 +380,22 @@ entry:
%arg = alloca ptr, align 8
%len = alloca i64, align 8
%ptr = alloca ptr, align 8
%len18 = alloca i64, align 8
%len16 = alloca i64, align 8
store ptr null, ptr %.cachedtype, align 8
store i32 %0, ptr %.anon, align 4
!140
store ptr %1, ptr %.anon1, align 8
!140
%2 = load i32, ptr %.anon, align 4
store i32 %2, ptr %argc, align 4
%3 = load ptr, ptr %.anon1, align 8
store ptr %3, ptr %argv, align 8
!145
%4 = load i32, ptr %argc, align 4
store i32 %4, ptr %argc2, align 4
%5 = load ptr, ptr %argv, align 8
store ptr %5, ptr %argv3, align 8
!148
%6 = load i32, ptr %argc2, align 4, !dbg !150
%sext = sext i32 %6 to i64, !dbg !150
store i64 %sext, ptr %elements, align 8
@@ -507,38 +507,37 @@ loop.body: ; preds = %loop.cond
store ptr %37, ptr %arg, align 8, !dbg !179
store i64 0, ptr %len, align 8, !dbg !182
%38 = load ptr, ptr %list5, align 8, !dbg !183
%39 = load i32, ptr %i, align 4, !dbg !184
%sext15 = sext i32 %39 to i64, !dbg !184
%ptroffset16 = getelementptr inbounds [16 x i8], ptr %38, i64 %sext15, !dbg !184
%40 = load ptr, ptr %arg, align 8, !dbg !185
%41 = load ptr, ptr %arg, align 8
store ptr %41, ptr %ptr, align 8
%38 = load ptr, ptr %arg, align 8, !dbg !183
%39 = load ptr, ptr %arg, align 8
store ptr %39, ptr %ptr, align 8
store i64 0, ptr %len16, align 8, !dbg !188
br label %loop.cond17, !dbg !189
store i64 0, ptr %len18, align 8, !dbg !190
br label %loop.cond19, !dbg !191
loop.cond17: ; preds = %loop.body19, %loop.body
%40 = load ptr, ptr %ptr, align 8, !dbg !190
%41 = load i64, ptr %len16, align 8, !dbg !192
%ptradd18 = getelementptr inbounds i8, ptr %40, i64 %41, !dbg !192
%42 = load i8, ptr %ptradd18, align 1, !dbg !192
%i2b = icmp ne i8 %42, 0, !dbg !192
br i1 %i2b, label %loop.body19, label %loop.exit, !dbg !192
loop.cond19: ; preds = %loop.body21, %loop.body
%42 = load ptr, ptr %ptr, align 8, !dbg !192
%43 = load i64, ptr %len18, align 8, !dbg !194
%ptradd20 = getelementptr inbounds i8, ptr %42, i64 %43, !dbg !194
%44 = load i8, ptr %ptradd20, align 1, !dbg !194
%i2b = icmp ne i8 %44, 0, !dbg !194
br i1 %i2b, label %loop.body21, label %loop.exit, !dbg !194
loop.body19: ; preds = %loop.cond17
%43 = load i64, ptr %len16, align 8, !dbg !193
%add20 = add i64 %43, 1, !dbg !193
store i64 %add20, ptr %len16, align 8, !dbg !193
br label %loop.cond17, !dbg !193
loop.body21: ; preds = %loop.cond19
%45 = load i64, ptr %len18, align 8, !dbg !195
%add22 = add i64 %45, 1, !dbg !195
store i64 %add22, ptr %len18, align 8, !dbg !195
br label %loop.cond19, !dbg !195
loop.exit: ; preds = %loop.cond19
%46 = load i64, ptr %len18, align 8, !dbg !196
%add23 = add i64 0, %46, !dbg !196
%size24 = sub i64 %add23, 0, !dbg !196
%47 = insertvalue %"char[]" undef, ptr %40, 0, !dbg !196
%48 = insertvalue %"char[]" %47, i64 %size24, 1, !dbg !196
store %"char[]" %48, ptr %ptroffset16, align 8, !dbg !196
loop.exit: ; preds = %loop.cond17
%44 = load i64, ptr %len16, align 8, !dbg !194
%add21 = add i64 0, %44, !dbg !194
%size22 = sub i64 %add21, 0, !dbg !194
%45 = insertvalue %"char[]" undef, ptr %38, 0, !dbg !194
%46 = insertvalue %"char[]" %45, i64 %size22, 1, !dbg !194
%47 = load ptr, ptr %list5, align 8, !dbg !195
%48 = load i32, ptr %i, align 4, !dbg !196
%sext23 = sext i32 %48 to i64, !dbg !196
%ptroffset24 = getelementptr inbounds [16 x i8], ptr %47, i64 %sext23, !dbg !196
store %"char[]" %46, ptr %ptroffset24, align 8, !dbg !196
%49 = load i32, ptr %i, align 4, !dbg !197
%add25 = add i32 %49, 1, !dbg !197
store i32 %add25, ptr %i, align 4, !dbg !197
@@ -681,6 +680,7 @@ no_match: ; preds = %compare
!72 = !DILocation(line: 35, column: 49, scope: !66)
!73 = !DILocalVariable(name: "name", arg: 3, scope: !66, file: !7, line: 35, type: !39)
!74 = !DILocation(line: 35, column: 63, scope: !66)
!75 =
!76 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !77, file: !77
!77 = !DIFile(filename: "mem.c3", directory:
!78 = !DILocation(line: 37, column: 9, scope: !66)

View File

@@ -0,0 +1,59 @@
// #target: macos-x64
module test;
import std;
DString x;
fn int[2] a()
{
x.append("a");
return { 1, 2 };
}
fn int idx()
{
x.append("i");
return 0;
}
fn int abc()
{
x.append("abc");
return 1;
}
fn List{int} l()
{
List{int} l;
l.push(2);
return l;
}
fn int main(String[] args)
{
l()[idx()] = abc();
a()[idx()] = abc();
return 0;
}
/* #expect: test.ll
define i32 @test.main(ptr %0, i64 %1) #0 {
entry:
%args = alloca %"char[][]", align 8
%sretparam = alloca %List, align 8
%result = alloca [2 x i32], align 4
store ptr %0, ptr %args, align 8
%ptradd = getelementptr inbounds i8, ptr %args, i64 8
store i64 %1, ptr %ptradd, align 8
%2 = call i32 @test.abc()
call void @test.l(ptr sret(%List) align 8 %sretparam)
%3 = call i32 @test.idx()
%sext = sext i32 %3 to i64
call void @"std_collections_list$int$.List.set"(ptr %sretparam, i64 %sext, i32 %2)
%4 = call i32 @test.abc()
%5 = call i64 @test.a()
store i64 %5, ptr %result, align 4
%6 = call i32 @test.idx()
%sext1 = sext i32 %6 to i64
%ptroffset = getelementptr inbounds [4 x i8], ptr %result, i64 %sext1
store i32 %4, ptr %ptroffset, align 4
ret i32 0
}

View File

@@ -63,12 +63,14 @@ entry:
%result3 = alloca %Abc, align 4
%result4 = alloca %Abc, align 4
%c = alloca %Container, align 4
%.anon = alloca %Abc, align 4
%result5 = alloca %Abc, align 4
%result6 = alloca %Abc, align 4
%result7 = alloca %Abc, align 4
%result9 = alloca %Abc, align 4
%.anon9 = alloca %Abc, align 4
%result10 = alloca %Abc, align 4
%result11 = alloca %Abc, align 4
%result12 = alloca %Abc, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %b, ptr align 4 @.__const.1, i32 4, i1 false)
store i32 0, ptr %y, align 4
@@ -115,7 +117,8 @@ entry:
%21 = load i32, ptr %b, align 4
%22 = call i32 @test.Abc.add(i32 %20, i32 %21)
store i32 %22, ptr %result6, align 4
%23 = load i32, ptr %result6, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %.anon, ptr align 4 %result6, i32 4, i1 false)
%23 = load i32, ptr %.anon, align 4
%24 = call i32 @test.Container.set(ptr %c, i32 0, i32 %23)
store i32 %24, ptr %result7, align 4
%25 = load i32, ptr %c, align 4
@@ -123,15 +126,16 @@ entry:
call void @llvm.assume(i1 %eq8)
%26 = load i32, ptr %c, align 4
%27 = call i32 @test.Container.get(i32 %26, i32 0)
store i32 %27, ptr %result9, align 4
store i32 %27, ptr %result10, align 4
%28 = load i32, ptr %b, align 4
%29 = call i32 @test.Abc.sub_self(ptr %result9, i32 %28)
store i32 %29, ptr %result10, align 4
%30 = load i32, ptr %result10, align 4
%29 = call i32 @test.Abc.sub_self(ptr %result10, i32 %28)
store i32 %29, ptr %result11, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %.anon9, ptr align 4 %result11, i32 4, i1 false)
%30 = load i32, ptr %.anon9, align 4
%31 = call i32 @test.Container.set(ptr %c, i32 0, i32 %30)
store i32 %31, ptr %result11, align 4
store i32 %31, ptr %result12, align 4
%32 = load i32, ptr %c, align 4
%eq12 = icmp eq i32 %32, 5
call void @llvm.assume(i1 %eq12)
%eq13 = icmp eq i32 %32, 5
call void @llvm.assume(i1 %eq13)
ret i32 0
}

View File

@@ -113,14 +113,14 @@ loop.cond: ; preds = %loop.body, %entry
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load ptr, ptr %to, align 8
%2 = load ptr, ptr %b, align 8
%3 = load i64, ptr %i, align 8
%ptroffset = getelementptr inbounds [2 x i8], ptr %2, i64 %3
%4 = load ptr, ptr %b, align 8
%4 = load ptr, ptr %to, align 8
%5 = load i64, ptr %i, align 8
%ptroffset4 = getelementptr inbounds [2 x i8], ptr %4, i64 %5
%6 = load i16, ptr %ptroffset4, align 2
store i16 %6, ptr %ptroffset, align 2
%6 = load i16, ptr %ptroffset, align 2
store i16 %6, ptr %ptroffset4, align 2
%7 = load i64, ptr %i, align 8
%add = add i64 %7, 2
store i64 %add, ptr %i, align 8
@@ -131,7 +131,6 @@ loop.exit: ; preds = %loop.cond
ret i64 %8
}
; Function Attrs:
define i32 @userland_bitcast.test(float %0) #0 {
entry:
%expr = alloca float, align 4
@@ -151,14 +150,14 @@ loop.cond: ; preds = %loop.body, %entry
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load ptr, ptr %to, align 8
%2 = load ptr, ptr %b, align 8
%3 = load i64, ptr %i, align 8
%ptradd = getelementptr inbounds i8, ptr %2, i64 %3
%4 = load ptr, ptr %b, align 8
%4 = load ptr, ptr %to, align 8
%5 = load i64, ptr %i, align 8
%ptradd1 = getelementptr inbounds i8, ptr %4, i64 %5
%6 = load i8, ptr %ptradd1, align 1
store i8 %6, ptr %ptradd, align 1
%6 = load i8, ptr %ptradd, align 1
store i8 %6, ptr %ptradd1, align 1
%7 = load i64, ptr %i, align 8
%add = add i64 %7, 1
store i64 %add, ptr %i, align 8
@@ -169,7 +168,6 @@ loop.exit: ; preds = %loop.cond
ret i32 %8
}
; Function Attrs:
define void @userland_bitcast.main() #0 {
entry:
%f = alloca float, align 4
@@ -212,14 +210,14 @@ loop.cond: ; preds = %loop.body, %entry
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load ptr, ptr %to, align 8
%2 = load ptr, ptr %b, align 8
%3 = load i64, ptr %i1, align 8
%ptroffset = getelementptr inbounds [4 x i8], ptr %2, i64 %3
%4 = load ptr, ptr %b, align 8
%4 = load ptr, ptr %to, align 8
%5 = load i64, ptr %i1, align 8
%ptroffset2 = getelementptr inbounds [4 x i8], ptr %4, i64 %5
%6 = load i32, ptr %ptroffset2, align 4
store i32 %6, ptr %ptroffset, align 4
%6 = load i32, ptr %ptroffset, align 4
store i32 %6, ptr %ptroffset2, align 4
%7 = load i64, ptr %i1, align 8
%add = add i64 %7, 4
store i64 %add, ptr %i1, align 8
@@ -241,14 +239,14 @@ loop.cond8: ; preds = %loop.body10, %loop.
br i1 %lt9, label %loop.body10, label %loop.exit14
loop.body10: ; preds = %loop.cond8
%11 = load ptr, ptr %to6, align 8
%11 = load ptr, ptr %b5, align 8
%12 = load i64, ptr %i7, align 8
%ptroffset11 = getelementptr inbounds [4 x i8], ptr %11, i64 %12
%13 = load ptr, ptr %b5, align 8
%13 = load ptr, ptr %to6, align 8
%14 = load i64, ptr %i7, align 8
%ptroffset12 = getelementptr inbounds [4 x i8], ptr %13, i64 %14
%15 = load i32, ptr %ptroffset12, align 4
store i32 %15, ptr %ptroffset11, align 4
%15 = load i32, ptr %ptroffset11, align 4
store i32 %15, ptr %ptroffset12, align 4
%16 = load i64, ptr %i7, align 8
%add13 = add i64 %16, 4
store i64 %add13, ptr %i7, align 8
@@ -277,14 +275,14 @@ loop.cond21: ; preds = %loop.body23, %loop.
br i1 %lt22, label %loop.body23, label %loop.exit27
loop.body23: ; preds = %loop.cond21
%23 = load ptr, ptr %to19, align 8
%23 = load ptr, ptr %b18, align 8
%24 = load i64, ptr %i20, align 8
%ptroffset24 = getelementptr inbounds [8 x i8], ptr %23, i64 %24
%25 = load ptr, ptr %b18, align 8
%25 = load ptr, ptr %to19, align 8
%26 = load i64, ptr %i20, align 8
%ptroffset25 = getelementptr inbounds [8 x i8], ptr %25, i64 %26
%27 = load i64, ptr %ptroffset25, align 8
store i64 %27, ptr %ptroffset24, align 8
%27 = load i64, ptr %ptroffset24, align 8
store i64 %27, ptr %ptroffset25, align 8
%28 = load i64, ptr %i20, align 8
%add26 = add i64 %28, 8
store i64 %add26, ptr %i20, align 8
@@ -306,14 +304,14 @@ loop.cond33: ; preds = %loop.body35, %loop.
br i1 %lt34, label %loop.body35, label %loop.exit39
loop.body35: ; preds = %loop.cond33
%32 = load ptr, ptr %to31, align 8
%32 = load ptr, ptr %b30, align 8
%33 = load i64, ptr %i32, align 8
%ptroffset36 = getelementptr inbounds [8 x i8], ptr %32, i64 %33
%34 = load ptr, ptr %b30, align 8
%34 = load ptr, ptr %to31, align 8
%35 = load i64, ptr %i32, align 8
%ptroffset37 = getelementptr inbounds [8 x i8], ptr %34, i64 %35
%36 = load i64, ptr %ptroffset37, align 8
store i64 %36, ptr %ptroffset36, align 8
%36 = load i64, ptr %ptroffset36, align 8
store i64 %36, ptr %ptroffset37, align 8
%37 = load i64, ptr %i32, align 8
%add38 = add i64 %37, 8
store i64 %add38, ptr %i32, align 8

View File

@@ -152,7 +152,6 @@ entry:
%30 = insertelement <4 x float> %23, float %29, i64 2
%31 = insertelement <4 x float> %30, float 0.000000e+00, i64 3
store <4 x float> %31, ptr %a, align 16
%ptradd = getelementptr inbounds i8, ptr %a, i64 16
%32 = load float, ptr %y, align 4
%33 = load float, ptr %x, align 4
%fmul11 = fmul reassoc arcp contract float %32, %33
@@ -189,45 +188,46 @@ entry:
%51 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul20, float %fpfptrunc23, float %50)
%52 = insertelement <4 x float> %44, float %51, i64 2
%53 = insertelement <4 x float> %52, float 0.000000e+00, i64 3
%ptradd = getelementptr inbounds i8, ptr %a, i64 16
store <4 x float> %53, ptr %ptradd, align 16
%ptradd25 = getelementptr inbounds i8, ptr %a, i64 32
%54 = load float, ptr %z, align 4
%55 = load float, ptr %x, align 4
%fmul26 = fmul reassoc arcp contract float %54, %55
%fmul25 = fmul reassoc arcp contract float %54, %55
%56 = load float, ptr %cosr, align 4
%fpfpext27 = fpext
%fsub28 = fsub reassoc arcp contract double 1.000000e+00, %fpfpext27
%fpfptrunc29 = fptrunc
%fpfpext26 = fpext
%fsub27 = fsub reassoc arcp contract double 1.000000e+00, %fpfpext26
%fpfptrunc28 = fptrunc
%57 = load float, ptr %y, align 4
%58 = load float, ptr %sinr, align 4
%fmul30 = fmul reassoc arcp contract float %57, %58
%59 = fneg reassoc arcp contract float %fmul30
%60 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul26, float %fpfptrunc29, float %59)
%fmul29 = fmul reassoc arcp contract float %57, %58
%59 = fneg reassoc arcp contract float %fmul29
%60 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul25, float %fpfptrunc28, float %59)
%61 = insertelement <4 x float> undef, float %60, i64 0
%62 = load float, ptr %z, align 4
%63 = load float, ptr %y, align 4
%fmul31 = fmul reassoc arcp contract float %62, %63
%fmul30 = fmul reassoc arcp contract float %62, %63
%64 = load float, ptr %cosr, align 4
%fpfpext32 = fpext
%fsub33 = fsub reassoc arcp contract double 1.000000e+00, %fpfpext32
%fpfptrunc34 = fptrunc
%fpfpext31 = fpext
%fsub32 = fsub reassoc arcp contract double 1.000000e+00, %fpfpext31
%fpfptrunc33 = fptrunc
%65 = load float, ptr %x, align 4
%66 = load float, ptr %sinr, align 4
%fmul35 = fmul reassoc arcp contract float %65, %66
%67 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul31, float %fpfptrunc34, float %fmul35)
%fmul34 = fmul reassoc arcp contract float %65, %66
%67 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul30, float %fpfptrunc33, float %fmul34)
%68 = insertelement <4 x float> %61, float %67, i64 1
%69 = load float, ptr %cosr, align 4
%70 = load float, ptr %z, align 4
%71 = load float, ptr %z, align 4
%fmul36 = fmul reassoc arcp contract float %70, %71
%fmul35 = fmul reassoc arcp contract float %70, %71
%72 = load float, ptr %cosr, align 4
%fpfpext37 = fpext
%fsub38 = fsub reassoc arcp contract double 1.000000e+00, %fpfpext37
%fpfptrunc39 = fptrunc
%73 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul36, float %fpfptrunc39, float %69)
%fpfpext36 = fpext
%fsub37 = fsub reassoc arcp contract double 1.000000e+00, %fpfpext36
%fpfptrunc38 = fptrunc
%73 = call reassoc arcp contract float @llvm.fmuladd.f32(float %fmul35, float %fpfptrunc38, float %69)
%74 = insertelement <4 x float> %68, float %73, i64 2
%75 = insertelement <4 x float> %74, float 0.000000e+00, i64 3
store <4 x float> %75, ptr %ptradd25, align 16
%ptradd39 = getelementptr inbounds i8, ptr %a, i64 32
store <4 x float> %75, ptr %ptradd39, align 16
%ptradd40 = getelementptr inbounds i8, ptr %a, i64 48
store <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 1.000000e+00>, ptr %ptradd40, align 16
%76 = load float, ptr %cosr, align 4