mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
443 lines
15 KiB
Plaintext
443 lines
15 KiB
Plaintext
// #target: macos-x64
|
|
module foo;
|
|
|
|
struct Foo
|
|
{
|
|
int[3] a;
|
|
}
|
|
|
|
extern fn void printf(char*, ...);
|
|
|
|
macro int* Foo.@operator_element_at_ref(&f, int a) @operator(&[])
|
|
{
|
|
return &f.a[a];
|
|
}
|
|
|
|
macro int Foo.@operator_len(&f) @operator(len)
|
|
{
|
|
return 3;
|
|
}
|
|
|
|
macro int Foo.@operator_element_at(&f, int a) @operator([])
|
|
{
|
|
return f.a[a];
|
|
}
|
|
|
|
fn int[5] getFields()
|
|
{
|
|
printf("getFields\n");
|
|
return (int[5]) { 3, 5, 2, 10, 111};
|
|
}
|
|
fn Foo *call(Foo* f)
|
|
{
|
|
printf("Call made\n");
|
|
return f;
|
|
}
|
|
fn void main()
|
|
{
|
|
Foo x = { { 1, 5, 7} };
|
|
printf("%d %d %d\n", x[0], x[1], x[2]);
|
|
foreach (i, int y : *call(&x))
|
|
{
|
|
printf("Hello %d: %d\n", i, y);
|
|
}
|
|
foreach (i, int* &y : x)
|
|
{
|
|
*y += 1;
|
|
printf("Hello %d: %d\n", i, *y);
|
|
}
|
|
foreach (i, int y : x)
|
|
{
|
|
printf("After one %d: %d\n", i, y);
|
|
}
|
|
|
|
foreach (i, int y : &x)
|
|
{
|
|
printf("By pointer %d: %d\n", i, y);
|
|
}
|
|
|
|
foreach (i, int y : x)
|
|
{
|
|
printf("Adding %d: %d\n", i, y);
|
|
i++;
|
|
}
|
|
|
|
foreach(i, y : (int[5]) { 1, 2, 10, 111, 123 } )
|
|
{
|
|
printf("Adding %d: %d\n", i, y);
|
|
i++;
|
|
}
|
|
foreach(i, y : getFields() )
|
|
{
|
|
printf("Pull value %d: %d\n", i, y);
|
|
}
|
|
foreach(i, y : &&getFields())
|
|
{
|
|
printf("Pull value tempptr %d: %d\n", i, y);
|
|
}
|
|
printf("%d %d\n", x[0], x[1]);
|
|
int* y = &x[1];
|
|
*y += 1;
|
|
printf("%d %d\n", x[0], x[1]);
|
|
}
|
|
|
|
/* #expect: foo.ll
|
|
|
|
%Foo = type { [3 x i32] }
|
|
|
|
@"$ct.foo.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 12, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
|
|
@.str = private unnamed_addr constant [11 x i8] c"getFields\0A\00", align 1
|
|
@.__const = private unnamed_addr constant [5 x i32] [i32 3, i32 5, i32 2, i32 10, i32 111], align 16
|
|
@.str.1 = private unnamed_addr constant [11 x i8] c"Call made\0A\00", align 1
|
|
@.__const.2 = private unnamed_addr constant %Foo { [3 x i32] [i32 1, i32 5, i32 7] }, align 4
|
|
@.str.3 = private unnamed_addr constant [10 x i8] c"%d %d %d\0A\00", align 1
|
|
@.str.4 = private unnamed_addr constant [14 x i8] c"Hello %d: %d\0A\00", align 1
|
|
@.str.5 = private unnamed_addr constant [14 x i8] c"Hello %d: %d\0A\00", align 1
|
|
@.str.6 = private unnamed_addr constant [18 x i8] c"After one %d: %d\0A\00", align 1
|
|
@.str.7 = private unnamed_addr constant [19 x i8] c"By pointer %d: %d\0A\00", align 1
|
|
@.str.8 = private unnamed_addr constant [15 x i8] c"Adding %d: %d\0A\00", align 1
|
|
@.__const.9 = private unnamed_addr constant [5 x i32] [i32 1, i32 2, i32 10, i32 111, i32 123], align 16
|
|
@.str.10 = private unnamed_addr constant [15 x i8] c"Adding %d: %d\0A\00", align 1
|
|
@.str.11 = private unnamed_addr constant [19 x i8] c"Pull value %d: %d\0A\00", align 1
|
|
@.str.12 = private unnamed_addr constant [27 x i8] c"Pull value tempptr %d: %d\0A\00", align 1
|
|
@.str.13 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
|
|
@.str.14 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
|
|
|
|
; Function Attrs:
|
|
declare void @printf(ptr, ...) #0
|
|
|
|
; Function Attrs:
|
|
define void @foo.getFields(ptr noalias sret([5 x i32]) align 4 %0) #0 {
|
|
entry:
|
|
%literal = alloca [5 x i32], align 16
|
|
call void (ptr, ...) @printf(ptr @.str)
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal, ptr align 16 @.__const, i32 20, i1 false)
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %0, ptr align 4 %literal, i32 20, i1 false)
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
define ptr @foo.call(ptr %0) #0 {
|
|
entry:
|
|
call void (ptr, ...) @printf(ptr @.str.1)
|
|
ret ptr %0
|
|
}
|
|
|
|
; Function Attrs:
|
|
define void @foo.main() #0 {
|
|
entry:
|
|
%x = alloca %Foo, align 4
|
|
%.anon = alloca i32, align 4
|
|
%i = alloca i32, align 4
|
|
%y = alloca i32, align 4
|
|
%a = alloca i32, align 4
|
|
%.anon7 = alloca i32, align 4
|
|
%i11 = alloca i32, align 4
|
|
%y12 = alloca ptr, align 8
|
|
%a13 = alloca i32, align 4
|
|
%.anon20 = alloca i32, align 4
|
|
%i24 = alloca i32, align 4
|
|
%y25 = alloca i32, align 4
|
|
%a26 = alloca i32, align 4
|
|
%.anon33 = alloca i32, align 4
|
|
%i37 = alloca i32, align 4
|
|
%y38 = alloca i32, align 4
|
|
%a39 = alloca i32, align 4
|
|
%.anon46 = alloca i32, align 4
|
|
%i50 = alloca i32, align 4
|
|
%y51 = alloca i32, align 4
|
|
%a52 = alloca i32, align 4
|
|
%.anon59 = alloca [5 x i32], align 16
|
|
%.anon60 = alloca i64, align 8
|
|
%i63 = alloca i64, align 8
|
|
%y64 = alloca i32, align 4
|
|
%.anon68 = alloca [5 x i32], align 16
|
|
%.anon69 = alloca i64, align 8
|
|
%i73 = alloca i64, align 8
|
|
%y74 = alloca i32, align 4
|
|
%sretparam = alloca [5 x i32], align 4
|
|
%.anon78 = alloca i64, align 8
|
|
%i82 = alloca i64, align 8
|
|
%y83 = alloca i32, align 4
|
|
%y90 = alloca ptr, align 8
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const.2, i32 12, i1 false)
|
|
%neq = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq)
|
|
%neq1 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq1)
|
|
%ptradd = getelementptr inbounds i8, ptr %x, i64 4
|
|
%neq2 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq2)
|
|
%ptradd3 = getelementptr inbounds i8, ptr %x, i64 8
|
|
%0 = load i32, ptr %x, align 4
|
|
%1 = load i32, ptr %ptradd, align 4
|
|
%2 = load i32, ptr %ptradd3, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.3, i32 %0, i32 %1, i32 %2)
|
|
%3 = call ptr @foo.call(ptr %x)
|
|
%neq4 = icmp ne ptr %3, null
|
|
call void @llvm.assume(i1 %neq4)
|
|
store i32 0, ptr %.anon, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%4 = load i32, ptr %.anon, align 4
|
|
%lt = icmp slt i32 %4, 3
|
|
br i1 %lt, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%5 = load i32, ptr %.anon, align 4
|
|
store i32 %5, ptr %i, align 4
|
|
%6 = load i32, ptr %.anon, align 4
|
|
store i32 %6, ptr %a, align 4
|
|
%neq5 = icmp ne ptr %3, null
|
|
call void @llvm.assume(i1 %neq5)
|
|
%7 = load i32, ptr %a, align 4
|
|
%sext = sext i32 %7 to i64
|
|
%ptroffset = getelementptr inbounds [4 x i8], ptr %3, i64 %sext
|
|
%8 = load i32, ptr %ptroffset, align 4
|
|
store i32 %8, ptr %y, align 4
|
|
%9 = load i32, ptr %i, align 4
|
|
%10 = load i32, ptr %y, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.4, i32 %9, i32 %10)
|
|
%11 = load i32, ptr %.anon, align 4
|
|
%addnsw = add nsw i32 %11, 1
|
|
store i32 %addnsw, ptr %.anon, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%neq6 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq6)
|
|
store i32 0, ptr %.anon7, align 4
|
|
br label %loop.cond8
|
|
|
|
loop.cond8: ; preds = %loop.body10, %loop.exit
|
|
%12 = load i32, ptr %.anon7, align 4
|
|
%lt9 = icmp slt i32 %12, 3
|
|
br i1 %lt9, label %loop.body10, label %loop.exit18
|
|
|
|
loop.body10: ; preds = %loop.cond8
|
|
%13 = load i32, ptr %.anon7, align 4
|
|
store i32 %13, ptr %i11, align 4
|
|
%14 = load i32, ptr %.anon7, align 4
|
|
store i32 %14, ptr %a13, align 4
|
|
%neq14 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq14)
|
|
%15 = load i32, ptr %a13, align 4
|
|
%sext15 = sext i32 %15 to i64
|
|
%ptroffset16 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext15
|
|
store ptr %ptroffset16, ptr %y12, align 8
|
|
%16 = load ptr, ptr %y12, align 8
|
|
%17 = load i32, ptr %16, align 4
|
|
%add = add i32 %17, 1
|
|
store i32 %add, ptr %16, align 4
|
|
%18 = load ptr, ptr %y12, align 8
|
|
%19 = load i32, ptr %i11, align 4
|
|
%20 = load i32, ptr %18, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.5, i32 %19, i32 %20)
|
|
%21 = load i32, ptr %.anon7, align 4
|
|
%addnsw17 = add nsw i32 %21, 1
|
|
store i32 %addnsw17, ptr %.anon7, align 4
|
|
br label %loop.cond8
|
|
|
|
loop.exit18: ; preds = %loop.cond8
|
|
%neq19 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq19)
|
|
store i32 0, ptr %.anon20, align 4
|
|
br label %loop.cond21
|
|
|
|
loop.cond21: ; preds = %loop.body23, %loop.exit18
|
|
%22 = load i32, ptr %.anon20, align 4
|
|
%lt22 = icmp slt i32 %22, 3
|
|
br i1 %lt22, label %loop.body23, label %loop.exit31
|
|
|
|
loop.body23: ; preds = %loop.cond21
|
|
%23 = load i32, ptr %.anon20, align 4
|
|
store i32 %23, ptr %i24, align 4
|
|
%24 = load i32, ptr %.anon20, align 4
|
|
store i32 %24, ptr %a26, align 4
|
|
%neq27 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq27)
|
|
%25 = load i32, ptr %a26, align 4
|
|
%sext28 = sext i32 %25 to i64
|
|
%ptroffset29 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext28
|
|
%26 = load i32, ptr %ptroffset29, align 4
|
|
store i32 %26, ptr %y25, align 4
|
|
%27 = load i32, ptr %i24, align 4
|
|
%28 = load i32, ptr %y25, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.6, i32 %27, i32 %28)
|
|
%29 = load i32, ptr %.anon20, align 4
|
|
%addnsw30 = add nsw i32 %29, 1
|
|
store i32 %addnsw30, ptr %.anon20, align 4
|
|
br label %loop.cond21
|
|
|
|
loop.exit31: ; preds = %loop.cond21
|
|
%neq32 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq32)
|
|
store i32 0, ptr %.anon33, align 4
|
|
br label %loop.cond34
|
|
|
|
loop.cond34: ; preds = %loop.body36, %loop.exit31
|
|
%30 = load i32, ptr %.anon33, align 4
|
|
%lt35 = icmp slt i32 %30, 3
|
|
br i1 %lt35, label %loop.body36, label %loop.exit44
|
|
|
|
loop.body36: ; preds = %loop.cond34
|
|
%31 = load i32, ptr %.anon33, align 4
|
|
store i32 %31, ptr %i37, align 4
|
|
%32 = load i32, ptr %.anon33, align 4
|
|
store i32 %32, ptr %a39, align 4
|
|
%neq40 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq40)
|
|
%33 = load i32, ptr %a39, align 4
|
|
%sext41 = sext i32 %33 to i64
|
|
%ptroffset42 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext41
|
|
%34 = load i32, ptr %ptroffset42, align 4
|
|
store i32 %34, ptr %y38, align 4
|
|
%35 = load i32, ptr %i37, align 4
|
|
%36 = load i32, ptr %y38, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.7, i32 %35, i32 %36)
|
|
%37 = load i32, ptr %.anon33, align 4
|
|
%addnsw43 = add nsw i32 %37, 1
|
|
store i32 %addnsw43, ptr %.anon33, align 4
|
|
br label %loop.cond34
|
|
|
|
loop.exit44: ; preds = %loop.cond34
|
|
%neq45 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq45)
|
|
store i32 0, ptr %.anon46, align 4
|
|
br label %loop.cond47
|
|
|
|
loop.cond47: ; preds = %loop.body49, %loop.exit44
|
|
%38 = load i32, ptr %.anon46, align 4
|
|
%lt48 = icmp slt i32 %38, 3
|
|
br i1 %lt48, label %loop.body49, label %loop.exit58
|
|
|
|
loop.body49: ; preds = %loop.cond47
|
|
%39 = load i32, ptr %.anon46, align 4
|
|
store i32 %39, ptr %i50, align 4
|
|
%40 = load i32, ptr %.anon46, align 4
|
|
store i32 %40, ptr %a52, align 4
|
|
%neq53 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq53)
|
|
%41 = load i32, ptr %a52, align 4
|
|
%sext54 = sext i32 %41 to i64
|
|
%ptroffset55 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext54
|
|
%42 = load i32, ptr %ptroffset55, align 4
|
|
store i32 %42, ptr %y51, align 4
|
|
%43 = load i32, ptr %i50, align 4
|
|
%44 = load i32, ptr %y51, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.8, i32 %43, i32 %44)
|
|
%45 = load i32, ptr %i50, align 4
|
|
%add56 = add i32 %45, 1
|
|
store i32 %add56, ptr %i50, align 4
|
|
%46 = load i32, ptr %.anon46, align 4
|
|
%addnsw57 = add nsw i32 %46, 1
|
|
store i32 %addnsw57, ptr %.anon46, align 4
|
|
br label %loop.cond47
|
|
|
|
loop.exit58: ; preds = %loop.cond47
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %.anon59, ptr align 16 @.__const.9, i32 20, i1 false)
|
|
store i64 0, ptr %.anon60, align 8
|
|
br label %loop.cond61
|
|
|
|
loop.cond61: ; preds = %loop.body62, %loop.exit58
|
|
%47 = load i64, ptr %.anon60, align 8
|
|
%gt = icmp ugt i64 5, %47
|
|
br i1 %gt, label %loop.body62, label %loop.exit67
|
|
|
|
loop.body62: ; preds = %loop.cond61
|
|
%48 = load i64, ptr %.anon60, align 8
|
|
store i64 %48, ptr %i63, align 8
|
|
%49 = load i64, ptr %.anon60, align 8
|
|
%ptroffset65 = getelementptr inbounds [4 x i8], ptr %.anon59, i64 %49
|
|
%50 = load i32, ptr %ptroffset65, align 4
|
|
store i32 %50, ptr %y64, align 4
|
|
%51 = load i64, ptr %i63, align 8
|
|
%52 = load i32, ptr %y64, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.10, i64 %51, i32 %52)
|
|
%53 = load i64, ptr %i63, align 8
|
|
%add66 = add i64 %53, 1
|
|
store i64 %add66, ptr %i63, align 8
|
|
%54 = load i64, ptr %.anon60, align 8
|
|
%addnuw = add nuw i64 %54, 1
|
|
store i64 %addnuw, ptr %.anon60, align 8
|
|
br label %loop.cond61
|
|
|
|
loop.exit67: ; preds = %loop.cond61
|
|
call void @foo.getFields(ptr sret([5 x i32]) align 4 %.anon68)
|
|
store i64 0, ptr %.anon69, align 8
|
|
br label %loop.cond70
|
|
|
|
loop.cond70: ; preds = %loop.body72, %loop.exit67
|
|
%55 = load i64, ptr %.anon69, align 8
|
|
%gt71 = icmp ugt i64 5, %55
|
|
br i1 %gt71, label %loop.body72, label %loop.exit77
|
|
|
|
loop.body72: ; preds = %loop.cond70
|
|
%56 = load i64, ptr %.anon69, align 8
|
|
store i64 %56, ptr %i73, align 8
|
|
%57 = load i64, ptr %.anon69, align 8
|
|
%ptroffset75 = getelementptr inbounds [4 x i8], ptr %.anon68, i64 %57
|
|
%58 = load i32, ptr %ptroffset75, align 4
|
|
store i32 %58, ptr %y74, align 4
|
|
%59 = load i64, ptr %i73, align 8
|
|
%60 = load i32, ptr %y74, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.11, i64 %59, i32 %60)
|
|
%61 = load i64, ptr %.anon69, align 8
|
|
%addnuw76 = add nuw i64 %61, 1
|
|
store i64 %addnuw76, ptr %.anon69, align 8
|
|
br label %loop.cond70
|
|
|
|
loop.exit77: ; preds = %loop.cond70
|
|
call void @foo.getFields(ptr sret([5 x i32]) align 4 %sretparam)
|
|
store i64 0, ptr %.anon78, align 8
|
|
br label %loop.cond79
|
|
|
|
loop.cond79: ; preds = %loop.body81, %loop.exit77
|
|
%62 = load i64, ptr %.anon78, align 8
|
|
%gt80 = icmp ugt i64 5, %62
|
|
br i1 %gt80, label %loop.body81, label %loop.exit86
|
|
|
|
loop.body81: ; preds = %loop.cond79
|
|
%63 = load i64, ptr %.anon78, align 8
|
|
store i64 %63, ptr %i82, align 8
|
|
%64 = load i64, ptr %.anon78, align 8
|
|
%ptroffset84 = getelementptr inbounds [4 x i8], ptr %sretparam, i64 %64
|
|
%65 = load i32, ptr %ptroffset84, align 4
|
|
store i32 %65, ptr %y83, align 4
|
|
%66 = load i64, ptr %i82, align 8
|
|
%67 = load i32, ptr %y83, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.12, i64 %66, i32 %67)
|
|
%68 = load i64, ptr %.anon78, align 8
|
|
%addnuw85 = add nuw i64 %68, 1
|
|
store i64 %addnuw85, ptr %.anon78, align 8
|
|
br label %loop.cond79
|
|
|
|
loop.exit86: ; preds = %loop.cond79
|
|
%neq87 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq87)
|
|
%neq88 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq88)
|
|
%ptradd89 = getelementptr inbounds i8, ptr %x, i64 4
|
|
%69 = load i32, ptr %x, align 4
|
|
%70 = load i32, ptr %ptradd89, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.13, i32 %69, i32 %70)
|
|
%neq91 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq91)
|
|
%ptradd92 = getelementptr inbounds i8, ptr %x, i64 4
|
|
store ptr %ptradd92, ptr %y90, align 8
|
|
%71 = load ptr, ptr %y90, align 8
|
|
%72 = load i32, ptr %71, align 4
|
|
%add93 = add i32 %72, 1
|
|
store i32 %add93, ptr %71, align 4
|
|
%neq94 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq94)
|
|
%neq95 = icmp ne ptr %x, null
|
|
call void @llvm.assume(i1 %neq95)
|
|
%ptradd96 = getelementptr inbounds i8, ptr %x, i64 4
|
|
%73 = load i32, ptr %x, align 4
|
|
%74 = load i32, ptr %ptradd96, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.14, i32 %73, i32 %74)
|
|
ret void
|
|
}
|