Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / utils / update_cc_test_checks / Inputs / explicit-template-instantiation.cpp.expected
blob00d8dd4fd956f715a4feb745f4d7106683932fb4
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
4 template <typename T>
5 struct Foo {
6 private:
7   T x;
9 public:
10   Foo(T x) : x(x) {}
11   ~Foo() {}
13   T get() { return x; }
14   void set(T _x) { x = _x; }
17 template <typename T>
18 struct Bar {
19 private:
20   struct Foo<T> foo;
22 public:
23   Bar(T x) : foo(x) {}
24   ~Bar() {}
26   T get() { return foo.get(); }
27   void set(T _x) { foo.set(_x); }
30 template <typename T>
31 struct Baz : Foo<T> {
32 public:
33   Baz(T x) : Foo<T>(x) {}
34   ~Baz() {}
37 // These two specializations should generate lines for all of Foo's methods.
39 // CHECK-LABEL: @_ZN3FooIcEC1Ec(
40 // CHECK-NEXT:  entry:
41 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
42 // CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i8, align 1
43 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
44 // CHECK-NEXT:    store i8 [[X:%.*]], ptr [[X_ADDR]], align 1
45 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
46 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[X_ADDR]], align 1
47 // CHECK-NEXT:    call void @_ZN3FooIcEC2Ec(ptr noundef nonnull align 1 dereferenceable(1) [[THIS1]], i8 noundef signext [[TMP0]])
48 // CHECK-NEXT:    ret void
50 // CHECK-LABEL: @_ZN3FooIcED1Ev(
51 // CHECK-NEXT:  entry:
52 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
53 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
54 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
55 // CHECK-NEXT:    call void @_ZN3FooIcED2Ev(ptr noundef nonnull align 1 dereferenceable(1) [[THIS1]]) #[[ATTR2:[0-9]+]]
56 // CHECK-NEXT:    ret void
58 // CHECK-LABEL: @_ZN3FooIcE3getEv(
59 // CHECK-NEXT:  entry:
60 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
61 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
62 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
63 // CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[THIS1]], i32 0, i32 0
64 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[X]], align 1
65 // CHECK-NEXT:    ret i8 [[TMP0]]
67 // CHECK-LABEL: @_ZN3FooIcE3setEc(
68 // CHECK-NEXT:  entry:
69 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
70 // CHECK-NEXT:    [[_X_ADDR:%.*]] = alloca i8, align 1
71 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
72 // CHECK-NEXT:    store i8 [[_X:%.*]], ptr [[_X_ADDR]], align 1
73 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
74 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[_X_ADDR]], align 1
75 // CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[THIS1]], i32 0, i32 0
76 // CHECK-NEXT:    store i8 [[TMP0]], ptr [[X]], align 1
77 // CHECK-NEXT:    ret void
79 template struct Foo<char>;
81 // CHECK-LABEL: @_ZN3FooIsEC1Es(
82 // CHECK-NEXT:  entry:
83 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
84 // CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i16, align 2
85 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
86 // CHECK-NEXT:    store i16 [[X:%.*]], ptr [[X_ADDR]], align 2
87 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
88 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr [[X_ADDR]], align 2
89 // CHECK-NEXT:    call void @_ZN3FooIsEC2Es(ptr noundef nonnull align 2 dereferenceable(2) [[THIS1]], i16 noundef signext [[TMP0]])
90 // CHECK-NEXT:    ret void
92 // CHECK-LABEL: @_ZN3FooIsED1Ev(
93 // CHECK-NEXT:  entry:
94 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
95 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
96 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
97 // CHECK-NEXT:    call void @_ZN3FooIsED2Ev(ptr noundef nonnull align 2 dereferenceable(2) [[THIS1]]) #[[ATTR2]]
98 // CHECK-NEXT:    ret void
100 // CHECK-LABEL: @_ZN3FooIsE3getEv(
101 // CHECK-NEXT:  entry:
102 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
103 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
104 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
105 // CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO_0:%.*]], ptr [[THIS1]], i32 0, i32 0
106 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr [[X]], align 2
107 // CHECK-NEXT:    ret i16 [[TMP0]]
109 // CHECK-LABEL: @_ZN3FooIsE3setEs(
110 // CHECK-NEXT:  entry:
111 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
112 // CHECK-NEXT:    [[_X_ADDR:%.*]] = alloca i16, align 2
113 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
114 // CHECK-NEXT:    store i16 [[_X:%.*]], ptr [[_X_ADDR]], align 2
115 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
116 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr [[_X_ADDR]], align 2
117 // CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_FOO_0:%.*]], ptr [[THIS1]], i32 0, i32 0
118 // CHECK-NEXT:    store i16 [[TMP0]], ptr [[X]], align 2
119 // CHECK-NEXT:    ret void
121 template struct Foo<short>;
123 // This should not generate lines for the implicit specialization of Foo, but
124 // should generate lines for the explicit specialization of Bar.
126 // CHECK-LABEL: @_ZN3BarIiEC1Ei(
127 // CHECK-NEXT:  entry:
128 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
129 // CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
130 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
131 // CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
132 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
133 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
134 // CHECK-NEXT:    call void @_ZN3BarIiEC2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]])
135 // CHECK-NEXT:    ret void
137 // CHECK-LABEL: @_ZN3BarIiED1Ev(
138 // CHECK-NEXT:  entry:
139 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
140 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
141 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
142 // CHECK-NEXT:    call void @_ZN3BarIiED2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR2]]
143 // CHECK-NEXT:    ret void
145 // CHECK-LABEL: @_ZN3BarIiE3getEv(
146 // CHECK-NEXT:  entry:
147 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
148 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
149 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
150 // CHECK-NEXT:    [[FOO:%.*]] = getelementptr inbounds [[STRUCT_BAR:%.*]], ptr [[THIS1]], i32 0, i32 0
151 // CHECK-NEXT:    [[CALL:%.*]] = call noundef i32 @_ZN3FooIiE3getEv(ptr noundef nonnull align 4 dereferenceable(4) [[FOO]])
152 // CHECK-NEXT:    ret i32 [[CALL]]
154 // CHECK-LABEL: @_ZN3BarIiE3setEi(
155 // CHECK-NEXT:  entry:
156 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
157 // CHECK-NEXT:    [[_X_ADDR:%.*]] = alloca i32, align 4
158 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
159 // CHECK-NEXT:    store i32 [[_X:%.*]], ptr [[_X_ADDR]], align 4
160 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
161 // CHECK-NEXT:    [[FOO:%.*]] = getelementptr inbounds [[STRUCT_BAR:%.*]], ptr [[THIS1]], i32 0, i32 0
162 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[_X_ADDR]], align 4
163 // CHECK-NEXT:    call void @_ZN3FooIiE3setEi(ptr noundef nonnull align 4 dereferenceable(4) [[FOO]], i32 noundef [[TMP0]])
164 // CHECK-NEXT:    ret void
166 template struct Bar<int>;
168 // This should not generate lines for the implicit specialization of Foo, but
169 // should generate lines for the explicit specialization of Baz.
171 // CHECK-LABEL: @_ZN3BazIlEC1El(
172 // CHECK-NEXT:  entry:
173 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
174 // CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i64, align 8
175 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
176 // CHECK-NEXT:    store i64 [[X:%.*]], ptr [[X_ADDR]], align 8
177 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
178 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[X_ADDR]], align 8
179 // CHECK-NEXT:    call void @_ZN3BazIlEC2El(ptr noundef nonnull align 8 dereferenceable(8) [[THIS1]], i64 noundef [[TMP0]])
180 // CHECK-NEXT:    ret void
182 // CHECK-LABEL: @_ZN3BazIlED1Ev(
183 // CHECK-NEXT:  entry:
184 // CHECK-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, align 8
185 // CHECK-NEXT:    store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8
186 // CHECK-NEXT:    [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
187 // CHECK-NEXT:    call void @_ZN3BazIlED2Ev(ptr noundef nonnull align 8 dereferenceable(8) [[THIS1]]) #[[ATTR2]]
188 // CHECK-NEXT:    ret void
190 template struct Baz<long>;