xref: /llvm-project/clang/test/CodeGenCXX/trivial-auto-var-init-skip-scalar-with-nonconst-init.cpp (revision 0cf1e662b13fb20d3897c5b9055c60b0de50beca)
1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s -check-prefix=UNINIT
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
3 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
4 
5 template<typename T> void used(T &) noexcept;
6 
7 extern "C" {
8 
9 extern int get_int(int) noexcept;
10 struct C {
11   int x;
12   int y;
13 };
14 extern C make_c() noexcept;
15 
16 // Scalar with a self-reference: does need auto-init.
17 // UNINIT-LABEL:  test_selfinit_call(
18 // ZERO-LABEL:    test_selfinit_call(
19 // ZERO: store i32 0, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
20 // PATTERN-LABEL: test_selfinit_call(
21 // PATTERN: store i32 -1431655766, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
test_selfinit_call()22 void test_selfinit_call() {
23   int self = get_int(self);
24   used(self);
25 }
26 
27 // Scalar without a self-reference: no auto-init needed.
28 // UNINIT-LABEL:  test_nonself_call(
29 // ZERO-LABEL:    test_nonself_call(
30 // ZERO-NOT: !annotation [[AUTO_INIT:!.+]]
31 // PATTERN-LABEL: test_nonself_call(
32 // PATTERN-NOT: !annotation [[AUTO_INIT:!.+]]
test_nonself_call()33 void test_nonself_call() {
34   int x = get_int(2);
35   used(x);
36 }
37 
38 // Scalar with a self-reference: does need auto-init.
39 // UNINIT-LABEL:  test_selfinit_lambda_call(
40 // ZERO-LABEL:    test_selfinit_lambda_call(
41 // ZERO: store i32 0, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
42 // PATTERN-LABEL: test_selfinit_lambda_call(
43 // PATTERN: store i32 -1431655766, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
test_selfinit_lambda_call()44 void test_selfinit_lambda_call() {
45   int self = [&](){ return self; }();
46   used(self);
47 }
48 
49 // Scalar with a self-reference: does need auto-init.
50 // UNINIT-LABEL:  test_selfinit_gnu_stmt_expression(
51 // ZERO-LABEL:    test_selfinit_gnu_stmt_expression(
52 // ZERO: store i32 0, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
53 // PATTERN-LABEL: test_selfinit_gnu_stmt_expression(
54 // PATTERN: store i32 -1431655766, ptr %self, align 4, !annotation [[AUTO_INIT:!.+]]
test_selfinit_gnu_stmt_expression()55 void test_selfinit_gnu_stmt_expression() {
56   int self = ({int x = self; x + 1; });
57   used(self);
58 }
59 
60 // Not a scalar: auto-init just in case
61 // UNINIT-LABEL:  test_nonscalar_call(
62 // ZERO-LABEL:    test_nonscalar_call(
63 // ZERO: call void @llvm.memset{{.*}}, i8 0, i64 8, {{.*}} !annotation [[AUTO_INIT:!.+]]
64 // PATTERN-LABEL: test_nonscalar_call(
65 // PATTERN: call void @llvm.memcpy{{.*}}, i64 8, {{.*}} !annotation [[AUTO_INIT:!.+]]
test_nonscalar_call()66 void test_nonscalar_call() {
67   C c = make_c();
68   used(c);
69 }
70 
71 // Scalar with a self-reference: does need auto-init.
72 // UNINIT-LABEL:  test_self_ptr(
73 // ZERO-LABEL:    test_self_ptr(
74 // ZERO: store ptr null, ptr %self, align 8, !annotation [[AUTO_INIT:!.+]]
75 // PATTERN-LABEL: test_self_ptr(
76 // PATTERN: store ptr inttoptr (i64 -6148914691236517206 to ptr), ptr %self, align 8, !annotation [[AUTO_INIT:!.+]]
test_self_ptr()77 void test_self_ptr() {
78   void* self = self;
79   used(self);
80 }
81 
82 // Scalar without a self-reference: no auto-init needed.
83 // UNINIT-LABEL:  test_nonself_ptr(
84 // ZERO-LABEL:    test_nonself_ptr(
85 // ZERO-NOT: !annotation [[AUTO_INIT:!.+]]
86 // PATTERN-LABEL: test_nonself_ptr(
87 // PATTERN-NOT: !annotation [[AUTO_INIT:!.+]]
test_nonself_ptr()88 void test_nonself_ptr() {
89   int y = 0;
90   void* x = &y;
91   used(x);
92 }
93 
94 // Scalar with a self-reference: does need auto-init.
95 // UNINIT-LABEL:  test_self_complex(
96 // ZERO-LABEL:    test_self_complex(
97 // ZERO: call void @llvm.memset{{.*}} !annotation [[AUTO_INIT:!.+]]
98 // PATTERN-LABEL: test_self_complex(
99 // PATTERN: call void @llvm.memcpy{{.*}} !annotation [[AUTO_INIT:!.+]]
test_self_complex()100 void test_self_complex() {
101   _Complex float self = 3.0 * 3.0 * self;
102   used(self);
103 }
104 
105 // Scalar without a self-reference: no auto-init needed.
106 // UNINIT-LABEL:  test_nonself_complex(
107 // ZERO-LABEL:    test_nonself_complex(
108 // ZERO-NOT: !annotation [[AUTO_INIT:!.+]]
109 // PATTERN-LABEL: test_nonself_complex(
110 // PATTERN-NOT: !annotation [[AUTO_INIT:!.+]]
test_nonself_complex()111 void test_nonself_complex() {
112   _Complex float y = 0.0;
113   _Complex float x = 3.0 * 3.0 * y;
114   used(x);
115 }
116 
117 } // extern "C"
118 
119 // ZERO: [[AUTO_INIT]] = !{!"auto-init"}
120 // PATTERN: [[AUTO_INIT]] = !{!"auto-init"}
121 
122