<div dir="ltr">I suspect this caused PR23165, can you investigate? Looks like the global constant we emit for the temporary in that case has the wrong vptr!</div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Mar 7, 2015 at 5:37 AM, Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@googlemail.com" target="_blank">benny.kra@googlemail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: d0k<br>
Date: Sat Mar 7 07:37:13 2015<br>
New Revision: 231564<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=231564&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=231564&view=rev</a><br>
Log:<br>
Reapply r231508 "CodeGen: Emit constant temporaries into read-only globals."<br>
<br>
I disabled putting the new global into the same COMDAT as the function for now.<br>
There's a fundamental problem when we inline references to the global but still<br>
have the global in a COMDAT linked to the inlined function. Since this is only<br>
an optimization there may be other versions of the COMDAT around that are<br>
missing the new global and hell breaks loose at link time.<br>
<br>
I hope the chromium build doesn't break this time :)<br>
<br>
Modified:<br>
cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
cfe/trunk/test/CodeGenCXX/compound-literals.cpp<br>
cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp<br>
cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp<br>
cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=231564&r1=231563&r2=231564&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=231564&r1=231563&r2=231564&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Mar 7 07:37:13 2015<br>
@@ -301,6 +301,23 @@ createReferenceTemporary(CodeGenFunction<br>
switch (M->getStorageDuration()) {<br>
case SD_FullExpression:<br>
case SD_Automatic:<br>
+ // If we have a constant temporary array or record try to promote it into a<br>
+ // constant global under the same rules a normal constant would've been<br>
+ // promoted. This is easier on the optimizer and generally emits fewer<br>
+ // instructions.<br>
+ if (CGF.CGM.getCodeGenOpts().MergeAllConstants &&<br>
+ (M->getType()->isArrayType() || M->getType()->isRecordType()) &&<br>
+ CGF.CGM.isTypeConstant(M->getType(), true))<br>
+ if (llvm::Constant *Init =<br>
+ CGF.CGM.EmitConstantExpr(Inner, M->getType(), &CGF)) {<br>
+ auto *GV = new llvm::GlobalVariable(<br>
+ CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,<br>
+ llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");<br>
+ GV->setAlignment(<br>
+ CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity());<br>
+ // FIXME: Should we put the new global into a COMDAT?<br>
+ return GV;<br>
+ }<br>
return CGF.CreateMemTemp(Inner->getType(), "ref.tmp");<br>
<br>
case SD_Thread:<br>
@@ -370,8 +387,9 @@ EmitMaterializeTemporaryExpr(const Mater<br>
// Create and initialize the reference temporary.<br>
llvm::Value *Object = createReferenceTemporary(*this, M, E);<br>
if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) {<br>
- // If the temporary is a global and has a constant initializer, we may<br>
- // have already initialized it.<br>
+ // If the temporary is a global and has a constant initializer or is a<br>
+ // constant temporary that we promoted to a global, we may have already<br>
+ // initialized it.<br>
if (!Var->hasInitializer()) {<br>
Var->setInitializer(CGM.EmitNullConstant(E->getType()));<br>
EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/compound-literals.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/compound-literals.cpp?rev=231564&r1=231563&r2=231564&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/compound-literals.cpp?rev=231564&r1=231563&r2=231564&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/compound-literals.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/compound-literals.cpp Sat Mar 7 07:37:13 2015<br>
@@ -28,7 +28,7 @@ int f() {<br>
<br>
// CHECK-LABEL: define i32 @_Z1gv()<br>
int g() {<br>
- // CHECK: store [2 x i32]* %{{[a-z0-9.]+}}, [2 x i32]** [[V:%[a-z0-9.]+]]<br>
+ // CHECK: store [2 x i32]* @{{.*}}, [2 x i32]** [[V:%[a-z0-9.]+]]<br>
const int (&v)[2] = (int [2]) {1,2};<br>
<br>
// CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]*, [2 x i32]** [[V]]<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp?rev=231564&r1=231563&r2=231564&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp?rev=231564&r1=231563&r2=231564&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp Sat Mar 7 07:37:13 2015<br>
@@ -42,10 +42,11 @@ namespace ValueInitArrayOfMemPtr {<br>
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* bitcast ([3 x i32]* @[[THREE_NULL_MEMPTRS]] to i8*), i32 12, i32 4, i1 false)<br>
}<br>
<br>
- // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEv<br>
- void g() {<br>
+ // Test dynamic initialization.<br>
+ // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEMNS_1SEi<br>
+ void g(p ptr) {<br>
// CHECK: store i32 -1,<br>
- f(a{});<br>
+ f(a{ptr});<br>
}<br>
}<br>
<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp?rev=231564&r1=231563&r2=231564&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp?rev=231564&r1=231563&r2=231564&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp Sat Mar 7 07:37:13 2015<br>
@@ -35,22 +35,30 @@ namespace reference {<br>
// CHECK-NEXT: ret<br>
}<br>
<br>
- void reference_to_aggregate() {<br>
+ void reference_to_aggregate(int i) {<br>
// CHECK: getelementptr {{.*}}, i32 0, i32 0<br>
// CHECK-NEXT: store i32 1<br>
// CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1<br>
- // CHECK-NEXT: store i32 2<br>
+ // CHECK-NEXT: %[[I1:.*]] = load i32, i32*<br>
+ // CHECK-NEXT: store i32 %[[I1]]<br>
// CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align<br>
- const A &ra1{1, 2};<br>
+ const A &ra1{1, i};<br>
<br>
// CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0<br>
// CHECK-NEXT: store i32 1<br>
// CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1<br>
// CHECK-NEXT: store i32 2<br>
// CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1<br>
- // CHECK-NEXT: store i32 3<br>
+ // CHECK-NEXT: %[[I2:.*]] = load i32, i32*<br>
+ // CHECK-NEXT: store i32 %[[I2]]<br>
// CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align<br>
- const int (&arrayRef)[] = {1, 2, 3};<br>
+ const int (&arrayRef)[] = {1, 2, i};<br>
+<br>
+ // CHECK: store %{{.*}}* @{{.*}}, %{{.*}}** %{{.*}}, align<br>
+ const A &constra1{1, 2};<br>
+<br>
+ // CHECK-NEXT: store [3 x i32]* @{{.*}}, [3 x i32]** %{{.*}}, align<br>
+ const int (&constarrayRef)[] = {1, 2, 3};<br>
<br>
// CHECK-NEXT: ret<br>
}<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=231564&r1=231563&r2=231564&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=231564&r1=231563&r2=231564&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp Sat Mar 7 07:37:13 2015<br>
@@ -72,6 +72,9 @@ namespace thread_local_global_array {<br>
// CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = internal global [2 x i32] zeroinitializer, align 4<br>
// CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4<br>
<br>
+// CHECK: @[[REFTMP1:.*]] = private constant [2 x i32] [i32 42, i32 43], align 4<br>
+// CHECK: @[[REFTMP2:.*]] = private constant [3 x %{{.*}}] [%{{.*}} { i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4<br>
+<br>
// CHECK: appending global<br>
<br>
<br>
@@ -215,17 +218,16 @@ void fn9() {<br>
<br>
struct haslist1 {<br>
std::initializer_list<int> il;<br>
- haslist1();<br>
+ haslist1(int i);<br>
};<br>
<br>
-// CHECK-LABEL: define void @_ZN8haslist1C2Ev<br>
-haslist1::haslist1()<br>
+// CHECK-LABEL: define void @_ZN8haslist1C2Ei<br>
+haslist1::haslist1(int i)<br>
// CHECK: alloca [3 x i32]<br>
-// CHECK: store i32 1<br>
+// CHECK: store i32 %<br>
// CHECK: store i32 2<br>
// CHECK: store i32 3<br>
-// CHECK: store i{{32|64}} 3<br>
- : il{1, 2, 3}<br>
+ : il{i, 2, 3}<br>
{<br>
destroyme2 dm2;<br>
}<br>
@@ -244,16 +246,15 @@ haslist2::haslist2()<br>
// CHECK: call void @_ZN10destroyme1D1Ev<br>
}<br>
<br>
-void fn10() {<br>
- // CHECK-LABEL: define void @_Z4fn10v<br>
+void fn10(int i) {<br>
+ // CHECK-LABEL: define void @_Z4fn10i<br>
// CHECK: alloca [3 x i32]<br>
// CHECK: call noalias i8* @_Znw{{[jm]}}<br>
- // CHECK: store i32 1<br>
+ // CHECK: store i32 %<br>
// CHECK: store i32 2<br>
// CHECK: store i32 3<br>
// CHECK: store i32*<br>
- // CHECK: store i{{32|64}} 3<br>
- (void) new std::initializer_list<int> {1, 2, 3};<br>
+ (void) new std::initializer_list<int> {i, 2, 3};<br>
}<br>
<br>
void fn11() {<br>
@@ -462,6 +463,22 @@ namespace PR20445 {<br>
template<int x> void f() { new MyClass({42, 43}); }<br>
template void f<0>();<br>
// CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(<br>
+ // CHECK: store i32* getelementptr inbounds ([2 x i32]* @[[REFTMP1]], i64 0, i64 0)<br>
// CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(<br>
// CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(<br>
}<br>
+<br>
+namespace ConstExpr {<br>
+ class C {<br>
+ int x;<br>
+ public:<br>
+ constexpr C(int x) : x(x) {}<br>
+ };<br>
+ void f(std::initializer_list<C>);<br>
+ void g() {<br>
+// CHECK-LABEL: _ZN9ConstExpr1gEv<br>
+// CHECK: store %"class.ConstExpr::C"* getelementptr inbounds ([3 x %"class.ConstExpr::C"]* @[[REFTMP2]], i64 0, i64 0)<br>
+// CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE<br>
+ f({C(1), C(2), C(3)});<br>
+ }<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>