[clang] 48c70c1 - Extend memset-to-zero optimization to C++11 aggregate functional casts

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 16 13:21:19 PDT 2020


Author: Richard Smith
Date: 2020-10-16T13:21:08-07:00
New Revision: 48c70c1664aa4512cb7e08352dd8eb33dde4807c

URL: https://github.com/llvm/llvm-project/commit/48c70c1664aa4512cb7e08352dd8eb33dde4807c
DIFF: https://github.com/llvm/llvm-project/commit/48c70c1664aa4512cb7e08352dd8eb33dde4807c.diff

LOG: 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.

Added: 
    

Modified: 
    clang/lib/CodeGen/CGExprAgg.cpp
    clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 43e23d986ae0..625b9116ff25 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -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);

diff  --git a/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp b/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
index 6b10efd34f92..3e9d936a16f8 100644
--- a/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
+++ b/clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
@@ -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){}; }
 }


        


More information about the cfe-commits mailing list