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