[PATCH] D50361: [NFC] Test automatic variable initialization
jfb added a comment. Further fixes in r339090 and r339093. Repository: rC Clang https://reviews.llvm.org/D50361 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50361: [NFC] Test automatic variable initialization
This revision was automatically updated to reflect the committed changes. Closed by commit rC339089: [NFC] Test automatic variable initialization (authored by jfb, committed by ). Changed prior to commit: https://reviews.llvm.org/D50361?vs=159397=159448#toc Repository: rC Clang https://reviews.llvm.org/D50361 Files: test/CodeGenCXX/auto-var-init.cpp Index: test/CodeGenCXX/auto-var-init.cpp === --- test/CodeGenCXX/auto-var-init.cpp +++ test/CodeGenCXX/auto-var-init.cpp @@ -0,0 +1,999 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s + +template void used(T &) noexcept; + +#define TEST_UNINIT(NAME, TYPE) \ + using type_##NAME = TYPE; \ + void test_##NAME##_uninit() { \ +type_##NAME uninit; \ +used(uninit); \ + } + +// Value initialization on scalars, aggregate initialization on aggregates. +#define TEST_BRACES(NAME, TYPE) \ + using type_##NAME = TYPE; \ + void test_##NAME##_braces() { \ +type_##NAME braces = {};\ +used(braces); \ + } + +#define TEST_CUSTOM(NAME, TYPE, ...)\ + using type_##NAME = TYPE; \ + void test_##NAME##_custom() { \ +type_##NAME custom __VA_ARGS__; \ +used(custom); \ + } + +struct empty {}; +struct small { char c; }; +struct smallinit { char c = 42; }; +struct smallpartinit { char c = 42, d; }; +struct nullinit { char* null = nullptr; }; +struct padded { char c; int i; }; +struct paddednullinit { char c = 0; int i = 0; }; +struct bitfield { int i : 4; int j : 2; }; +struct bitfieldaligned { int i : 4; int : 0; int j : 2; }; +struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; }; +struct arraytail { int i; int arr[]; }; +struct tailpad { short s; char c; }; +struct notlockfree { long long a[4]; }; +struct semivolatile { int i; volatile int vi; }; +struct semivolatileinit { int i = 0x; volatile int vi = 0x; }; +struct base { virtual ~base(); }; +struct derived : public base {}; +struct virtualderived : public virtual base, public virtual derived {}; +union matching { int i; float f; }; +union matchingreverse { float f; int i; }; +union unmatched { char c; int i; }; +union unmatchedreverse { int i; char c; }; +union unmatchedfp { float f; double d; }; +enum emptyenum {}; +enum smallenum { VALUE }; + +extern "C" { + +TEST_UNINIT(char, char); +// CHECK-LABEL: @test_char_uninit() +// CHECK: %uninit = alloca i8, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(char, char); +// CHECK-LABEL: @test_char_braces() +// CHECK: %braces = alloca i8, align 1 +// CHECK-NEXT: store i8 0, i8* %braces, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(uchar, unsigned char); +// CHECK-LABEL: @test_uchar_uninit() +// CHECK: %uninit = alloca i8, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(uchar, unsigned char); +// CHECK-LABEL: @test_uchar_braces() +// CHECK: %braces = alloca i8, align 1 +// CHECK-NEXT: store i8 0, i8* %braces, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(schar, signed char); +// CHECK-LABEL: @test_schar_uninit() +// CHECK: %uninit = alloca i8, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(schar, signed char); +// CHECK-LABEL: @test_schar_braces() +// CHECK: %braces = alloca i8, align 1 +// CHECK-NEXT: store i8 0, i8* %braces, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(wchar_t, wchar_t); +// CHECK-LABEL: @test_wchar_t_uninit() +// CHECK: %uninit = alloca i32, align 4 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(wchar_t, wchar_t); +// CHECK-LABEL: @test_wchar_t_braces() +// CHECK: %braces = alloca i32, align 4 +// CHECK-NEXT: store i32 0, i32* %braces, align 4 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(short, short); +// CHECK-LABEL: @test_short_uninit() +// CHECK: %uninit = alloca i16, align 2 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(short, short); +// CHECK-LABEL: @test_short_braces() +// CHECK: %braces = alloca i16, align 2 +// CHECK-NEXT: store i16 0, i16* %braces, align 2 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(ushort, unsigned short); +// CHECK-LABEL: @test_ushort_uninit() +// CHECK: %uninit = alloca i16, align 2 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(ushort, unsigned short); +// CHECK-LABEL: @test_ushort_braces() +// CHECK: %braces = alloca i16, align 2 +//
[PATCH] D50361: [NFC] Test automatic variable initialization
jfb added a comment. I'm honestly not sure there's anything to review here since it's just showing us what the current behavior is. LMK if I'm not testing something that I should. I'd much rather test current behavior as one patch first, because then the follow-ups show a clear before / after diff instead of leaving you guessing as to what the previous behavior was. Repository: rC Clang https://reviews.llvm.org/D50361 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50361: [NFC] Test automatic variable initialization
jfb created this revision. Herald added subscribers: cfe-commits, dexonsmith. r337887 started using memset for automatic variable initialization where sensible. A follow-up discussion leads me to believe that we should better test automatic variable initialization, and that there are probably follow-up patches in clang and LLVM to improve codegen. It’ll be important to measure -O0 compile time, and figure out which transforms should be in the frontend versus the backend. This patch is just a test of the current behavior, no questions asked. Follow-up patches will tune the code generation. rdar://problem/42981573 Repository: rC Clang https://reviews.llvm.org/D50361 Files: test/CodeGenCXX/auto-var-init.cpp Index: test/CodeGenCXX/auto-var-init.cpp === --- /dev/null +++ test/CodeGenCXX/auto-var-init.cpp @@ -0,0 +1,999 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s + +template void used(T &) noexcept; + +#define TEST_UNINIT(NAME, TYPE) \ + using type_##NAME = TYPE; \ + void test_##NAME##_uninit() { \ +type_##NAME uninit; \ +used(uninit); \ + } + +// Value initialization on scalars, aggregate initialization on aggregates. +#define TEST_BRACES(NAME, TYPE) \ + using type_##NAME = TYPE; \ + void test_##NAME##_braces() { \ +type_##NAME braces = {};\ +used(braces); \ + } + +#define TEST_CUSTOM(NAME, TYPE, ...)\ + using type_##NAME = TYPE; \ + void test_##NAME##_custom() { \ +type_##NAME custom __VA_ARGS__; \ +used(custom); \ + } + +struct empty {}; +struct small { char c; }; +struct smallinit { char c = 42; }; +struct smallpartinit { char c = 42, d; }; +struct nullinit { char* null = nullptr; }; +struct padded { char c; int i; }; +struct paddednullinit { char c = 0; int i = 0; }; +struct bitfield { int i : 4; int j : 2; }; +struct bitfieldaligned { int i : 4; int : 0; int j : 2; }; +struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; }; +struct arraytail { int i; int arr[]; }; +struct tailpad { short s; char c; }; +struct notlockfree { long long a[4]; }; +struct semivolatile { int i; volatile int vi; }; +struct semivolatileinit { int i = 0x; volatile int vi = 0x; }; +struct base { virtual ~base(); }; +struct derived : public base {}; +struct virtualderived : public virtual base, public virtual derived {}; +union matching { int i; float f; }; +union matchingreverse { float f; int i; }; +union unmatched { char c; int i; }; +union unmatchedreverse { int i; char c; }; +union unmatchedfp { float f; double d; }; +enum emptyenum {}; +enum smallenum { VALUE }; + +extern "C" { + +TEST_UNINIT(char, char); +// CHECK-LABEL: @test_char_uninit() +// CHECK: %uninit = alloca i8, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(char, char); +// CHECK-LABEL: @test_char_braces() +// CHECK: %braces = alloca i8, align 1 +// CHECK-NEXT: store i8 0, i8* %braces, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(uchar, unsigned char); +// CHECK-LABEL: @test_uchar_uninit() +// CHECK: %uninit = alloca i8, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(uchar, unsigned char); +// CHECK-LABEL: @test_uchar_braces() +// CHECK: %braces = alloca i8, align 1 +// CHECK-NEXT: store i8 0, i8* %braces, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(schar, signed char); +// CHECK-LABEL: @test_schar_uninit() +// CHECK: %uninit = alloca i8, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(schar, signed char); +// CHECK-LABEL: @test_schar_braces() +// CHECK: %braces = alloca i8, align 1 +// CHECK-NEXT: store i8 0, i8* %braces, align 1 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(wchar_t, wchar_t); +// CHECK-LABEL: @test_wchar_t_uninit() +// CHECK: %uninit = alloca i32, align 4 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(wchar_t, wchar_t); +// CHECK-LABEL: @test_wchar_t_braces() +// CHECK: %braces = alloca i32, align 4 +// CHECK-NEXT: store i32 0, i32* %braces, align 4 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces) + +TEST_UNINIT(short, short); +// CHECK-LABEL: @test_short_uninit() +// CHECK: %uninit = alloca i16, align 2 +// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) + +TEST_BRACES(short, short); +// CHECK-LABEL: @test_short_braces() +// CHECK: %braces = alloca i16, align 2 +// CHECK-NEXT: store i16 0, i16* %braces, align 2 +// CHECK-NEXT: call void