Files
c3c/test/test_suite/functions/test_regression.c3t

577 lines
16 KiB
Plaintext

// #target: macos-x64
module test;
import test2;
import std::collections::list;
import std::collections::linkedlist;
import hello_world;
extern fn int printf(char *, ...);
fn void helloWorld()
{
printf("helloWorld!\n");
}
fn int test_static()
{
static int x = 1;
x++;
printf("Test static %d\n", x);
return x;
}
struct Bobo { short b; float c; short d; short e; float f; short g; }
struct Blob { int z; int f; }
union Foor
{
long a;
char[12] b;
}
fn int helo(double d, Bobo b)
{
int[3] de = { 1, 2, 3 };
Bobo c = b;
helo(1.0, c);
return 1;
}
fn int test1(int a, int b)
{
a = a >> b;
if (b > 128) return -1;
return a;
}
struct Foo2
{
int x;
}
fn void Foo2.printme(Foo2 *foo)
{
printf("Foo is: %d\n", foo.x);
}
fn int Foo2.mutate(Foo2 *foo)
{
printf("Mutating");
return ++foo.x;
}
alias oopsInt = test2::argh{int};
alias oopsDouble = test2::argh{int};
alias Argh = fn int(double, Bobo);
alias Argh2 = fn int(double, Bobo);
fn int sum_us(int... x)
{
int sum = 0;
if (x.len == 0) return 0;
sum += x[0] + sum_us(...x[1..^1]);
return sum;
}
alias Frob = long;
fn int sumd(int[] x)
{
int sum = 0;
for (int i = 0; i < x.len; i++) sum += x[i];
return sum;
}
struct Foo
{
int a;
int b;
}
alias getValueInt = test2::getValue{int};
alias getValueDouble = test2::getValue{double};
alias IntBlob = test2::Blob{int};
alias DoubleBlob = Blob{double};
alias getMultInt = test2::getMult{int};
alias getMultDouble = test2::getMult{double};
alias IntArray = List{int};
alias IntList = LinkedList{int};
enum MyEnum : int
{
HELO,
WORLD,
BYE
}
fn void main()
{
test_static();
test_static();
test_static();
hello_world::hello();
IntList list;
list.push(10);
list.push(15);
list.push(30);
for (int i = 0; i < (int)(list.len()); i++)
{
printf("Element[%d]: %d\n", i, list.get(i));
}
list.free();
printf("Elements: %d\n", (int)(MyEnum.values.len));
int elements = MyEnum.values.len;
printf("Hello\n");
IntArray array;
array.push(100);
array.push(200);
array.push(400);
array.push(600);
array.insert_at(2, 300);
for (int i = 0; i < (int)(array.len()); i++)
{
printf("Element[%d]: %d\n", i, array.get(i));
}
array.free();
IntBlob a = { 42 };
DoubleBlob b = { 33.3 };
printf("a was %d\n", getValueInt(a));
printf("b was %f\n", getValueDouble(b));
printf("Mult int was %d\n", getMultInt(25));
printf("Mult double was %f\n", getMultDouble(3.3));
helloWorld();
Foo ddx;
int fro = 3;
int[4] x = { 1, 2, 3, 3 };
fro += printf("1Vararg4splatA: %d\n", sum_us(...x));
printf("%d\n", fro);
int[] z = &x;
int[3] de = { 1, 2, 3 };
printf("Vararg4splatB: %d\n", sum_us(...&x));
printf("Vararg4splatC: %d\n", sum_us(...z));
printf("Vararg4: %d\n", sum_us(1, 2, 4, 5));
printf("Vararg1: %d\n", sum_us(1));
printf("Vararg0: %d\n", sum_us());
Argh a1;
Argh2 b2;
}
module hello_world;
import foo;
extern fn int printf(char *, ...);
alias doubleMult = foo::check{double};
fn void hello()
{
printf("Hello baby\n");
printf("Mult %f\n", doubleMult(11.1));
}
module foo{Type};
fn Type check(Type i)
{
return i * i;
}
module test2{Type};
struct Blob
{
Type a;
}
fn Type getMult(Type a)
{
return a * a;
}
Type argh = 234;
enum Hello : int
{
FOO,
BAR,
}
macro Hello wut()
{
return Hello.FOO;
}
alias Bye = Hello;
alias wat = wut;
alias byebye = hello;
fn int hello()
{
return 1;
}
fn Type getValue(Blob blob)
{
return blob.a;
}
/* #expect: test.ll
%Blob = type { i32 }
%Blob.0 = type { double }
%Bobo = type { i16, float, i16, i16, float, i16 }
%"int[]" = type { ptr, i64 }
%LinkedList = type { %any, i64, ptr, ptr }
%any = type { ptr, i64 }
%List = type { i64, i64, %any, ptr }
%Foo = type { i32, i32 }
@"$ct.test.Bobo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Blob" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Foor" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Foo2" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@"$ct.test.MyEnum" = linkonce global { i8, i64, ptr, i64, i64, i64, [3 x %"char[]"] } { i8 8, i64 0, ptr null, i64 4, i64 ptrtoint (ptr @"$ct.int" to i64), i64 3, [3 x %"char[]"] [%"char[]" { ptr @.enum.HELO, i64 4 }, %"char[]" { ptr @.enum.WORLD, i64 5 }, %"char[]" { ptr @.enum.BYE, i64 3 }] }, align 8
@test_static.x = internal unnamed_addr global i32 1, align 4
define void @test.Foo2.printme(ptr %0) #0 {
entry:
%1 = load i32, ptr %0, align 4
%2 = call i32 (ptr, ...) @printf(ptr @.str.21, i32 %1)
ret void
}
; Function Attrs:
define i32 @test.Foo2.mutate(ptr %0) #0 {
entry:
%1 = call i32 (ptr, ...) @printf(ptr @.str.22)
%2 = load i32, ptr %0, align 4
%add = add i32 %2, 1
store i32 %add, ptr %0, align 4
ret i32 %add
}
; Function Attrs:
declare i32 @printf(ptr, ...) #0
; Function Attrs:
define void @test.helloWorld() #0 {
entry:
%0 = call i32 (ptr, ...) @printf(ptr @.str)
ret void
}
; Function Attrs:
define i32 @test.test_static() #0 {
entry:
%0 = load i32, ptr @test_static.x, align 4
%add = add i32 %0, 1
store i32 %add, ptr @test_static.x, align 4
%1 = load i32, ptr @test_static.x, align 4
%2 = call i32 (ptr, ...) @printf(ptr @.str.1, i32 %1)
%3 = load i32, ptr @test_static.x, align 4
ret i32 %3
}
; Function Attrs:
define i32 @test.helo(double %0, ptr byval(%Bobo) align 8 %1) #0 {
entry:
%de = alloca [3 x i32], align 4
%c = alloca %Bobo, align 4
%indirectarg = alloca %Bobo, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const, i32 12, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %c, ptr align 4 %1, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %indirectarg, ptr align 4 %c, i32 20, i1 false)
%2 = call i32 @test.helo(double 1.000000e+00, ptr byval(%Bobo) align 8 %indirectarg)
ret i32 1
}
; Function Attrs:
define i32 @test.test1(i32 %0, i32 %1) #0 {
entry:
%a = alloca i32, align 4
store i32 %0, ptr %a, align 4
%2 = load i32, ptr %a, align 4
%ashr = ashr i32 %2, %1
%3 = freeze i32 %ashr
store i32 %3, ptr %a, align 4
%gt = icmp sgt i32 %1, 128
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 -1
if.exit: ; preds = %entry
%4 = load i32, ptr %a, align 4
ret i32 %4
}
; Function Attrs:
define i32 @test.sum_us(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
store ptr %0, ptr %x, align 8
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
store i64 %1, ptr %ptradd, align 8
store i32 0, ptr %sum, align 4
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
%2 = load i64, ptr %ptradd1, align 8
%eq = icmp eq i64 0, %2
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
ret i32 0
if.exit: ; preds = %entry
%3 = load i32, ptr %sum, align 4
%4 = load ptr, ptr %x, align 8
%5 = load i32, ptr %4, align 4
%6 = load %"int[]", ptr %x, align 8
%7 = extractvalue %"int[]" %6, 0
%8 = extractvalue %"int[]" %6, 1
%sub = sub i64 %8, 1
%9 = add i64 %sub, 1
%size = sub i64 %9, 1
%ptradd2 = getelementptr inbounds i8, ptr %7, i64 4
%10 = insertvalue %"int[]" undef, ptr %ptradd2, 0
%11 = insertvalue %"int[]" %10, i64 %size, 1
%12 = call i32 @test.sum_us(ptr %ptradd2, i64 %size)
%add = add i32 %5, %12
%add3 = add i32 %3, %add
store i32 %add3, ptr %sum, align 4
%13 = load i32, ptr %sum, align 4
ret i32 %13
}
; Function Attrs:
define i32 @test.sumd(ptr %0, i64 %1) #0 {
entry:
%x = alloca %"int[]", align 8
%sum = alloca i32, align 4
%i = alloca i32, align 4
store ptr %0, ptr %x, align 8
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
store i64 %1, ptr %ptradd, align 8
store i32 0, ptr %sum, align 4
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%2 = load i32, ptr %i, align 4
%sext = sext i32 %2 to i64
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
%3 = load i64, ptr %ptradd1, align 8
%lt = icmp slt i64 %sext, %3
%check = icmp slt i64 %3, 0
%siui-lt = or i1 %check, %lt
br i1 %siui-lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%4 = load i32, ptr %sum, align 4
%5 = load ptr, ptr %x, align 8
%6 = load i32, ptr %i, align 4
%sext2 = sext i32 %6 to i64
%ptroffset = getelementptr inbounds [4 x i8], ptr %5, i64 %sext2
%7 = load i32, ptr %ptroffset, align 4
%add = add i32 %4, %7
store i32 %add, ptr %sum, align 4
%8 = load i32, ptr %i, align 4
%add3 = add i32 %8, 1
store i32 %add3, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
%9 = load i32, ptr %sum, align 4
ret i32 %9
}
; Function Attrs:
define void @test.main() #0 {
entry:
%list = alloca %LinkedList, align 8
%i = alloca i32, align 4
%elements = alloca i32, align 4
%array = alloca %List, align 8
%i1 = alloca i32, align 4
%a = alloca %Blob, align 4
%b = alloca %Blob.0, align 8
%ddx = alloca %Foo, align 4
%fro = alloca i32, align 4
%x = alloca [4 x i32], align 16
%z = alloca %"int[]", align 8
%de = alloca [3 x i32], align 4
%varargslots = alloca [4 x i32], align 16
%varargslots14 = alloca [1 x i32], align 4
%a1 = alloca ptr, align 8
%b2 = alloca ptr, align 8
%0 = call i32 @test.test_static()
%1 = call i32 @test.test_static()
%2 = call i32 @test.test_static()
call void @hello_world.hello()
call void @llvm.memset.p0.i64(ptr align 8 %list, i8 0, i64 40, i1 false)
call void @"std_collections_linkedlist$int$.LinkedList.push"(ptr %list, i32 10)
call void @"std_collections_linkedlist$int$.LinkedList.push"(ptr %list, i32 15)
call void @"std_collections_linkedlist$int$.LinkedList.push"(ptr %list, i32 30)
store i32 0, ptr %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%3 = load i32, ptr %i, align 4
%4 = call i64 @"std_collections_linkedlist$int$.LinkedList.len"(ptr %list) #3
%trunc = trunc i64 %4 to i32
%lt = icmp slt i32 %3, %trunc
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%5 = load i32, ptr %i, align 4
%sext = sext i32 %5 to i64
%6 = call i32 @"std_collections_linkedlist$int$.LinkedList.get"(ptr %list, i64 %sext)
%7 = load i32, ptr %i, align 4
%8 = call i32 (ptr, ...) @printf(ptr @.str.2, i32 %7, i32 %6)
%9 = load i32, ptr %i, align 4
%add = add i32 %9, 1
store i32 %add, ptr %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
call void @"std_collections_linkedlist$int$.LinkedList.free"(ptr %list)
%10 = call i32 (ptr, ...) @printf(ptr @.str.3, i32 3)
store i32 3, ptr %elements, align 4
%11 = call i32 (ptr, ...) @printf(ptr @.str.4)
call void @llvm.memset.p0.i64(ptr align 8 %array, i8 0, i64 40, i1 false)
call void @"std_collections_list$int$.List.push"(ptr %array, i32 100)
call void @"std_collections_list$int$.List.push"(ptr %array, i32 200)
call void @"std_collections_list$int$.List.push"(ptr %array, i32 400)
call void @"std_collections_list$int$.List.push"(ptr %array, i32 600) #3
call void @"std_collections_list$int$.List.insert_at"(ptr %array, i64 2, i32 300)
store i32 0, ptr %i1, align 4
br label %loop.cond2
loop.cond2: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %i1, align 4
%13 = call i64 @"std_collections_list$int$.List.len"(ptr %array) #3
%trunc3 = trunc i64 %13 to i32
%lt4 = icmp slt i32 %12, %trunc3
br i1 %lt4, label %loop.body5, label %loop.exit8
loop.body5: ; preds = %loop.cond2
%14 = load i32, ptr %i1, align 4
%sext6 = sext i32 %14 to i64
%15 = call i32 @"std_collections_list$int$.List.get"(ptr %array, i64 %sext6) #3
%16 = load i32, ptr %i1, align 4
%17 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %16, i32 %15)
%18 = load i32, ptr %i1, align 4
%add7 = add i32 %18, 1
store i32 %add7, ptr %i1, align 4
br label %loop.cond2
loop.exit8: ; preds = %loop.cond2
call void @"std_collections_list$int$.List.free"(ptr %array)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %a, ptr align 4 @.__const.6, i32 4, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %b, ptr align 8 @.__const.7, i32 8, i1 false)
%19 = load i32, ptr %a, align 4
%20 = call i32 @"test2$int$.getValue"(i32 %19)
%21 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %20)
%22 = load double, ptr %b, align 8
%23 = call double @"test2$double$.getValue"(double %22)
%24 = call i32 (ptr, ...) @printf(ptr @.str.9, double %23)
%25 = call i32 @"test2$int$.getMult"(i32 25)
%26 = call i32 (ptr, ...) @printf(ptr @.str.10, i32 %25)
%27 = call double @"test2$double$.getMult"(double 3.300000e+00)
%28 = call i32 (ptr, ...) @printf(ptr @.str.11, double %27)
call void @test.helloWorld()
store i32 0, ptr %ddx, align 4
%ptradd = getelementptr inbounds i8, ptr %ddx, i64 4
store i32 0, ptr %ptradd, 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)
%29 = load i32, ptr %fro, align 4
%30 = insertvalue %"int[]" undef, ptr %x, 0
%31 = insertvalue %"int[]" %30, i64 4, 1
%32 = call i32 @test.sum_us(ptr %x, i64 4)
%33 = call i32 (ptr, ...) @printf(ptr @.str.13, i32 %32)
%add9 = add i32 %29, %33
store i32 %add9, ptr %fro, align 4
%34 = load i32, ptr %fro, align 4
%35 = call i32 (ptr, ...) @printf(ptr @.str.14, i32 %34)
%36 = insertvalue %"int[]" undef, ptr %x, 0
%37 = insertvalue %"int[]" %36, i64 4, 1
store %"int[]" %37, ptr %z, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %de, ptr align 4 @.__const.15, i32 12, i1 false)
%38 = insertvalue %"int[]" undef, ptr %x, 0
%39 = insertvalue %"int[]" %38, i64 4, 1
%40 = call i32 @test.sum_us(ptr %x, i64 4)
%41 = call i32 (ptr, ...) @printf(ptr @.str.16, i32 %40)
%lo = load ptr, ptr %z, align 8
%ptradd10 = getelementptr inbounds i8, ptr %z, i64 8
%hi = load i64, ptr %ptradd10, align 8
%42 = call i32 @test.sum_us(ptr %lo, i64 %hi)
%43 = call i32 (ptr, ...) @printf(ptr @.str.17, i32 %42)
store i32 1, ptr %varargslots, align 4
%ptradd11 = getelementptr inbounds i8, ptr %varargslots, i64 4
store i32 2, ptr %ptradd11, align 4
%ptradd12 = getelementptr inbounds i8, ptr %varargslots, i64 8
store i32 4, ptr %ptradd12, align 4
%ptradd13 = getelementptr inbounds i8, ptr %varargslots, i64 12
store i32 5, ptr %ptradd13, align 4
%44 = call i32 @test.sum_us(ptr %varargslots, i64 4)
%45 = call i32 (ptr, ...) @printf(ptr @.str.18, i32 %44)
store i32 1, ptr %varargslots14, align 4
%46 = call i32 @test.sum_us(ptr %varargslots14, i64 1)
%47 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %46)
%48 = call i32 @test.sum_us(ptr null, i64 0)
%49 = call i32 (ptr, ...) @printf(ptr @.str.20, i32 %48)
store ptr null, ptr %a1, align 8
store ptr null, ptr %b2, align 8
ret void
}
// #expect: hello_world.ll
define void @hello_world.hello()
entry:
%0 = call i32 (ptr, ...) @printf(ptr @.str)
%1 = call double @"foo$double$.check"(double 1.110000e+01)
%2 = call i32 (ptr, ...) @printf(ptr @.str.1, double %1)
ret void
// #expect: foo.double.ll
define weak double @"foo$double$.check"(double %0)
entry:
%fmul = fmul double %0, %0
ret double %fmul
// #expect: test2.double.ll
%Blob = type { double }
@"test2$double$.argh" = weak local_unnamed_addr global double 2.340000e+02, align 8
define weak double @"test2$double$.getMult"(double %0)
entry:
%fmul = fmul double %0, %0
ret double %fmul
define weak i32 @"test2$double$.hello"()
entry:
ret i32 1
define weak double @"test2$double$.getValue"(double %0)
entry:
%blob = alloca %Blob, align 8
store double %0, ptr %blob, align 8
%1 = load double, ptr %blob, align 8
ret double %1