On Wed, Apr 8, 2015 at 8:09 PM, Richard Smith <[email protected]> wrote:
> 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)) { >> > This is using the wrong type; you're assuming that M's type and Inner's type are the same, and they're not in general (M can refer to a subobject of the object initialized by Inner). You shouldn't be looking at M at all in this code; it's passed in so that the static / thread storage cases can work out the linkage and mangled name for their global. > + 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
