Files
c3c/test/test_suite/statements/custom_foreach_with_ref.c3t
Christoffer Lerno 4e66693065 - Refactored @simd implementation.
- Regression vector ABI: npot vectors would load incorrectly from pointers and other things. #2576
2025-11-16 01:37:39 +01:00

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 10, 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 16 %literal, ptr align 16 @.__const, i32 20, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %0, ptr align 16 %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
}