forked from OSchip/llvm-project
[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:
parent
8f9a3f2d7e
commit
f3e67de85a
|
@ -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);
|
||||
|
|
|
@ -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 ¶m) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue