Extend memset-to-zero optimization to C++11 aggregate functional casts

Aggr{...}.

We previously missed these cases due to not stepping over the additional
AST nodes representing their syntactic form.
This commit is contained in:
Richard Smith 2020-10-16 13:18:52 -07:00
parent c36c0fabd1
commit 48c70c1664
2 changed files with 25 additions and 2 deletions

View File

@ -1759,7 +1759,9 @@ void AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E)
/// non-zero bytes that will be stored when outputting the initializer for the
/// specified initializer expression.
static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
E = E->IgnoreParens();
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
E = MTE->getSubExpr();
E = E->IgnoreParenNoopCasts(CGF.getContext());
// 0 and 0.0 won't require any non-zero stores!
if (isSimpleZero(E, CGF)) return CharUnits::Zero();
@ -1808,7 +1810,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
}
}
// FIXME: This overestimates the number of non-zero bytes for bit-fields.
CharUnits NumNonZeroBytes = CharUnits::Zero();
for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF);

View File

@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s -triple x86_64-linux-gnu | FileCheck %s
// RUN: %clang_cc1 -std=c++17 -S -emit-llvm -o - %s -triple x86_64-linux-gnu | FileCheck %s
struct A { int a, b; int f(); };
@ -118,4 +119,24 @@ namespace ZeroInit {
// This variable must be initialized elementwise.
Filler data_e1[1024] = {};
// CHECK: getelementptr inbounds {{.*}} @_ZN8ZeroInit7data_e1E
struct Largeish {
long a, b, c;
};
// CHECK: define {{.*}}@_ZN8ZeroInit9largeish1Ev(
// CHECK-NOT }
// CHECK: call {{.*}}memset
Largeish largeish1() { return {}; }
// CHECK: define {{.*}}@_ZN8ZeroInit9largeish2Ev(
// CHECK-NOT }
// CHECK: call {{.*}}memset
Largeish largeish2() { return Largeish(); }
// CHECK: define {{.*}}@_ZN8ZeroInit9largeish3Ev(
// CHECK-NOT }
// CHECK: call {{.*}}memset
Largeish largeish3() { return Largeish{}; }
// CHECK: define {{.*}}@_ZN8ZeroInit9largeish4Ev(
// CHECK-NOT }
// CHECK: call {{.*}}memset
Largeish largeish4() { return (Largeish){}; }
}