From 1d572f3e7c3ae5298961afc6d23a94ef2fa41b7d Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 21 Jul 2022 17:49:34 +0200 Subject: [PATCH] Allow distinct printthrough in printf. Added tests. --- lib/std/io_printf.c3 | 4 +-- test/test_suite/abi/darwin64_sret.c3t | 25 ++++++++++++++ .../2002-02-13-ConditionalInCall.c3t | 16 +++++++++ .../expressions/bool_conversions.c3t | 33 +++++++++++++++++++ test/test_suite/functions/simple_test.c3t | 30 +++++++++++++++++ test/test_suite/struct/sret.c3t | 26 +++++++++++++++ test/test_suite2/abi/darwin64_sret.c3t | 21 ++++++++++++ .../2002-02-13-ConditionalInCall.c3t | 16 +++++++++ .../expressions/bool_conversions.c3t | 33 +++++++++++++++++++ test/test_suite2/functions/simple_test.c3t | 30 +++++++++++++++++ test/test_suite2/struct/sret.c3t | 26 +++++++++++++++ 11 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 test/test_suite/abi/darwin64_sret.c3t create mode 100644 test/test_suite/expressions/2002-02-13-ConditionalInCall.c3t create mode 100644 test/test_suite/expressions/bool_conversions.c3t create mode 100644 test/test_suite/functions/simple_test.c3t create mode 100644 test/test_suite/struct/sret.c3t create mode 100644 test/test_suite2/abi/darwin64_sret.c3t create mode 100644 test/test_suite2/expressions/2002-02-13-ConditionalInCall.c3t create mode 100644 test/test_suite2/expressions/bool_conversions.c3t create mode 100644 test/test_suite2/functions/simple_test.c3t create mode 100644 test/test_suite2/struct/sret.c3t diff --git a/lib/std/io_printf.c3 b/lib/std/io_printf.c3 index 31bd03526..393921206 100644 --- a/lib/std/io_printf.c3 +++ b/lib/std/io_printf.c3 @@ -68,9 +68,9 @@ private fn void! out_str(PrintParam* param, variant arg) case FUNC: return out_substr(param, ""); case FAILABLE: - return out_substr(param, ""); + unreachable(); case DISTINCT: - return out_substr(param, ""); + return out_str(param, variant { arg.ptr, arg.type.inner }); case POINTER: typeid inner = arg.type.inner; if (inner.kind == TypeKind.ARRAY && inner.inner == char.typeid) diff --git a/test/test_suite/abi/darwin64_sret.c3t b/test/test_suite/abi/darwin64_sret.c3t new file mode 100644 index 000000000..4dd895a0e --- /dev/null +++ b/test/test_suite/abi/darwin64_sret.c3t @@ -0,0 +1,25 @@ +// #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: + %x = alloca %SimdDouble4x4, align 32 + %2 = bitcast %SimdDouble4x4* %x 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) + %4 = bitcast %SimdDouble4x4* %0 to i8* + %5 = bitcast %SimdDouble4x4* %x to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 32 %4, i8* align 32 %5, i32 128, i1 false) + ret void +} diff --git a/test/test_suite/expressions/2002-02-13-ConditionalInCall.c3t b/test/test_suite/expressions/2002-02-13-ConditionalInCall.c3t new file mode 100644 index 000000000..e922e42b5 --- /dev/null +++ b/test/test_suite/expressions/2002-02-13-ConditionalInCall.c3t @@ -0,0 +1,16 @@ +// #target: macos-x64 + +module test; + +extern fn void foo(int, double, float); + +fn void bar(int x) +{ + foo(x, x ? 1.0 : 12.5, 1.0); +} + +/* #expect: test.ll + + %intbool = icmp ne i32 %0, 0 + %ternary = select i1 %intbool, double 1.000000e+00, double 1.250000e+01 + call void @foo(i32 %0, double %ternary, float 1.000000e+00) diff --git a/test/test_suite/expressions/bool_conversions.c3t b/test/test_suite/expressions/bool_conversions.c3t new file mode 100644 index 000000000..ef1cb53e1 --- /dev/null +++ b/test/test_suite/expressions/bool_conversions.c3t @@ -0,0 +1,33 @@ +// #target: macos-x64 + +private fn bool f0_0(void* a0) { return (bool)a0; } + +fn int f0() { return (int)f0_0((void*)0x2); } + +define Test = fn void(); + +fn bool f1() { return (bool){| Test x = void; return x = (Test)0; |}; } + +/* #expect: bool_conversions.ll + +define internal zeroext i8 @bool_conversions_f0_0(i8* %0) #0 { +entry: + %ptrbool = icmp ne i8* %0, null + %1 = zext i1 %ptrbool to i8 + ret i8 %1 +} + +define i32 @bool_conversions_f0() #0 { +entry: + %0 = call i8 @bool_conversions_f0_0(i8* inttoptr (i64 2 to i8*)) + %1 = trunc i8 %0 to i1 + %boolsi = zext i1 %1 to i32 + ret i32 %boolsi +} + +define zeroext i8 @bool_conversions_f1() #0 { +entry: + %x = alloca void ()*, align 8 + store void ()* null, void ()** %x, align 8 + ret i8 0 +} diff --git a/test/test_suite/functions/simple_test.c3t b/test/test_suite/functions/simple_test.c3t new file mode 100644 index 000000000..a026ffb2b --- /dev/null +++ b/test/test_suite/functions/simple_test.c3t @@ -0,0 +1,30 @@ +// #target: macos-x64 + +fn int foo() +{ + char *pp; + uint w_cnt; + + w_cnt += *pp; + + return w_cnt; +} + +/* #expect: simple_test.ll + + +define i32 @simple_test_foo() #0 { +entry: + %pp = alloca i8*, align 8 + %w_cnt = alloca i32, align 4 + store i8* null, i8** %pp, align 8 + store i32 0, i32* %w_cnt, align 4 + %0 = load i32, i32* %w_cnt, align 4 + %1 = load i8*, i8** %pp, align 8 + %2 = load i8, i8* %1, align 8 + %uiuiext = zext i8 %2 to i32 + %add = add i32 %0, %uiuiext + store i32 %add, i32* %w_cnt, align 4 + %3 = load i32, i32* %w_cnt, align 4 + ret i32 %3 +} \ No newline at end of file diff --git a/test/test_suite/struct/sret.c3t b/test/test_suite/struct/sret.c3t new file mode 100644 index 000000000..a96701630 --- /dev/null +++ b/test/test_suite/struct/sret.c3t @@ -0,0 +1,26 @@ +// #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(); +} + + +/* #expect: sret.ll + +sret(%Abc) +sret(%Abc) +sret(%Abc) +sret(%Abc) \ No newline at end of file diff --git a/test/test_suite2/abi/darwin64_sret.c3t b/test/test_suite2/abi/darwin64_sret.c3t new file mode 100644 index 000000000..a829d828a --- /dev/null +++ b/test/test_suite2/abi/darwin64_sret.c3t @@ -0,0 +1,21 @@ +// #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(ptr noalias sret(%SimdDouble4x4) align 32 %0, ptr byval(%SimdDouble4x4) align 32 %1) #0 { +entry: + %x = alloca %SimdDouble4x4, align 32 + call void @llvm.memcpy.p0.p0.i32(ptr align 32 %x, ptr align 32 %1, i32 128, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 32 %0, ptr align 32 %x, i32 128, i1 false) + ret void +} diff --git a/test/test_suite2/expressions/2002-02-13-ConditionalInCall.c3t b/test/test_suite2/expressions/2002-02-13-ConditionalInCall.c3t new file mode 100644 index 000000000..e922e42b5 --- /dev/null +++ b/test/test_suite2/expressions/2002-02-13-ConditionalInCall.c3t @@ -0,0 +1,16 @@ +// #target: macos-x64 + +module test; + +extern fn void foo(int, double, float); + +fn void bar(int x) +{ + foo(x, x ? 1.0 : 12.5, 1.0); +} + +/* #expect: test.ll + + %intbool = icmp ne i32 %0, 0 + %ternary = select i1 %intbool, double 1.000000e+00, double 1.250000e+01 + call void @foo(i32 %0, double %ternary, float 1.000000e+00) diff --git a/test/test_suite2/expressions/bool_conversions.c3t b/test/test_suite2/expressions/bool_conversions.c3t new file mode 100644 index 000000000..657a2b3f7 --- /dev/null +++ b/test/test_suite2/expressions/bool_conversions.c3t @@ -0,0 +1,33 @@ +// #target: macos-x64 + +private fn bool f0_0(void* a0) { return (bool)a0; } + +fn int f0() { return (int)f0_0((void*)0x2); } + +define Test = fn void(); + +fn bool f1() { return (bool){| Test x = void; return x = (Test)0; |}; } + +/* #expect: bool_conversions.ll + +define internal zeroext i8 @bool_conversions_f0_0(ptr %0) #0 { +entry: + %ptrbool = icmp ne ptr %0, null + %1 = zext i1 %ptrbool to i8 + ret i8 %1 +} + +define i32 @bool_conversions_f0() #0 { +entry: + %0 = call i8 @bool_conversions_f0_0(ptr inttoptr (i64 2 to ptr)) + %1 = trunc i8 %0 to i1 + %boolsi = zext i1 %1 to i32 + ret i32 %boolsi +} + +define zeroext i8 @bool_conversions_f1() #0 { +entry: + %x = alloca ptr, align 8 + store ptr null, ptr %x, align 8 + ret i8 0 +} diff --git a/test/test_suite2/functions/simple_test.c3t b/test/test_suite2/functions/simple_test.c3t new file mode 100644 index 000000000..af119919c --- /dev/null +++ b/test/test_suite2/functions/simple_test.c3t @@ -0,0 +1,30 @@ +// #target: macos-x64 + +fn int foo() +{ + char *pp; + uint w_cnt; + + w_cnt += *pp; + + return w_cnt; +} + +/* #expect: simple_test.ll + + +define i32 @simple_test_foo() #0 { +entry: + %pp = alloca ptr, align 8 + %w_cnt = alloca i32, align 4 + store ptr null, ptr %pp, align 8 + store i32 0, ptr %w_cnt, align 4 + %0 = load i32, ptr %w_cnt, align 4 + %1 = load ptr, ptr %pp, align 8 + %2 = load i8, ptr %1, align 8 + %uiuiext = zext i8 %2 to i32 + %add = add i32 %0, %uiuiext + store i32 %add, ptr %w_cnt, align 4 + %3 = load i32, ptr %w_cnt, align 4 + ret i32 %3 +} \ No newline at end of file diff --git a/test/test_suite2/struct/sret.c3t b/test/test_suite2/struct/sret.c3t new file mode 100644 index 000000000..a96701630 --- /dev/null +++ b/test/test_suite2/struct/sret.c3t @@ -0,0 +1,26 @@ +// #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(); +} + + +/* #expect: sret.ll + +sret(%Abc) +sret(%Abc) +sret(%Abc) +sret(%Abc) \ No newline at end of file