[CodeGen] Do a more principled fix for PR231653, always use the inner type.

We were still using the MaterializeTemporaryExpr's type to check if the
transform is legal. Always use the inner Expr type.

llvm-svn: 234543
This commit is contained in:
Benjamin Kramer 2015-04-09 22:50:07 +00:00
parent 8f9a3f2d7e
commit f3e67de85a
3 changed files with 22 additions and 14 deletions

View File

@ -300,27 +300,26 @@ createReferenceTemporary(CodeGenFunction &CGF,
const MaterializeTemporaryExpr *M, const Expr *Inner) {
switch (M->getStorageDuration()) {
case SD_FullExpression:
case SD_Automatic:
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.
QualType Ty = Inner->getType();
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, Inner->getType(), &CGF)) {
(Ty->isArrayType() || Ty->isRecordType()) &&
CGF.CGM.isTypeConstant(Ty, true))
if (llvm::Constant *Init = CGF.CGM.EmitConstantExpr(Inner, Ty, &CGF)) {
auto *GV = new llvm::GlobalVariable(
CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");
GV->setAlignment(CGF.getContext()
.getTypeAlignInChars(Inner->getType())
.getQuantity());
GV->setAlignment(
CGF.getContext().getTypeAlignInChars(Ty).getQuantity());
// FIXME: Should we put the new global into a COMDAT?
return GV;
}
return CGF.CreateMemTemp(Inner->getType(), "ref.tmp");
return CGF.CreateMemTemp(Ty, "ref.tmp");
}
case SD_Thread:
case SD_Static:
return CGF.CGM.GetAddrOfGlobalTemporary(M, Inner);

View File

@ -1,7 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
// CHECK: private constant { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN7PR2316510ChildClassE, i64 0, i64 2) }, align 4
namespace reference {
struct A {
int i1, i2;
@ -96,7 +94,18 @@ void helper(const AbstractClass &param) {
}
void foo() {
// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE(%{{.*}} bitcast ({ i8** }* @{{.*}} to %{{.*}}*))
// CHECK-LABEL: @_ZN7PR231653fooEv
// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev
// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE
helper(ChildClass());
}
struct S { struct T { int a; } t; mutable int b; };
void f() {
// CHECK-LABEL: _ZN7PR231651fEv
// CHECK: alloca
// CHECK: alloca
// CHECK: store
const S::T &r = S().t;
}
}

View File

@ -510,7 +510,7 @@ namespace B19773010 {
void PR22940_helper(const pair<void*, int>&) { }
void PR22940() {
// CHECK-LABEL: @_ZN9B197730107PR22940Ev
// CHECK-NOT: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
// CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
// CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE(
PR22940_helper(pair<void*, int>());
}