llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: None (haopliu)

<details>
<summary>Changes</summary>

Add a clang flag, "-ftrivial-auto-var-init-size-bound=" so that clang skips 
auto-init a variable if its size exceeds the flag setting. Note that this 
skipping doesn't apply to runtime-sized variables like VLA. 

Considerations: "__attribute__((uninitialized))" can be used to manually opt 
variables out. However, there are thousands of large variables (e.g., &gt;=1KB, 
most of them are arrays and used as buffers) in big codebase. Manually opting 
them out one by one is not efficient.

---
Full diff: https://github.com/llvm/llvm-project/pull/74777.diff


7 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+7) 
- (modified) clang/include/clang/Basic/LangOptions.def (+2) 
- (modified) clang/include/clang/Driver/Options.td (+4) 
- (modified) clang/lib/CodeGen/CGDecl.cpp (+9) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+15) 
- (added) clang/test/CodeGenCXX/auto-var-init-size-bound.cpp (+82) 
- (modified) clang/test/Driver/clang_f_opts.c (+13) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 676f1a62b49dd..5fd097154d0fa 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -656,6 +656,13 @@ def 
err_drv_trivial_auto_var_init_stop_after_missing_dependency : Error<
 def err_drv_trivial_auto_var_init_stop_after_invalid_value : Error<
   "'-ftrivial-auto-var-init-stop-after=*' only accepts positive integers">;
 
+def err_drv_trivial_auto_var_init_size_bound_missing_dependency : Error<
+  "'-ftrivial-auto-var-init-size-bound=*' is used without "
+  "'-ftrivial-auto-var-init=zero' or '-ftrivial-auto-var-init=pattern'">;
+
+def err_drv_trivial_auto_var_init_size_bound_invalid_value : Error<
+  "'-ftrivial-auto-var-init-size-bound=*' only accepts positive integers (in 
bytes)">;
+
 def warn_drv_msp430_hwmult_unsupported : Warning<
   "the given MCU does not support hardware multiply, but '-mhwmult' is set to "
   "%0">, InGroup<InvalidCommandLineArgument>;
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index c3d5399905a3f..8325561fc6d23 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -376,6 +376,8 @@ ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, 
TrivialAutoVarInitKi
              "trivial automatic variable initialization")
 VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0,
              "stop trivial automatic variable initialization after the 
specified number of instances. Must be greater than 0.")
+VALUE_LANGOPT(TrivialAutoVarInitSizeBound, 32, 0,
+             "stop trivial automatic variable initialization if var size 
exceeds the specified number of instances (in bytes). Must be greater than 0.")
 ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, 
SOB_Undefined,
              "signed integer overflow handling")
 ENUM_LANGOPT(ThreadModel  , ThreadModelKind, 2, ThreadModelKind::POSIX, 
"Thread Model")
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 0eec2b3526376..f92dbd07de20d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3627,6 +3627,10 @@ def ftrivial_auto_var_init_stop_after : Joined<["-"], 
"ftrivial-auto-var-init-st
   Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
   HelpText<"Stop initializing trivial automatic stack variables after the 
specified number of instances">,
   MarshallingInfoInt<LangOpts<"TrivialAutoVarInitStopAfter">>;
+def ftrivial_auto_var_init_size_bound : Joined<["-"], 
"ftrivial-auto-var-init-size-bound=">, Group<f_Group>,
+  Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+  HelpText<"Stop initializing trivial automatic stack variables if var size 
exceeds the specified number of instances (in bytes)">,
+  MarshallingInfoInt<LangOpts<"TrivialAutoVarInitSizeBound">>;
 def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>,
   Visibility<[ClangOption, CLOption, DXCOption]>,
   HelpText<"Emit full debug info for all types used by the program">;
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index a5da0aa2965a0..1f9650e60d5e0 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1759,20 +1759,29 @@ void 
CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,
                                                       const VarDecl &D,
                                                       Address Loc) {
   auto trivialAutoVarInit = getContext().getLangOpts().getTrivialAutoVarInit();
+  auto trivialAutoVarInitSizeBound = 
+      getContext().getLangOpts().TrivialAutoVarInitSizeBound;
   CharUnits Size = getContext().getTypeSizeInChars(type);
   bool isVolatile = type.isVolatileQualified();
   if (!Size.isZero()) {
+    auto allocSize = 
CGM.getDataLayout().getTypeAllocSize(Loc.getElementType());
     switch (trivialAutoVarInit) {
     case LangOptions::TrivialAutoVarInitKind::Uninitialized:
       llvm_unreachable("Uninitialized handled by caller");
     case LangOptions::TrivialAutoVarInitKind::Zero:
       if (CGM.stopAutoInit())
         return;
+      if (trivialAutoVarInitSizeBound > 0 &&
+          allocSize >= trivialAutoVarInitSizeBound)
+        return;
       emitStoresForZeroInit(CGM, D, Loc, isVolatile, Builder);
       break;
     case LangOptions::TrivialAutoVarInitKind::Pattern:
       if (CGM.stopAutoInit())
         return;
+      if (trivialAutoVarInitSizeBound > 0 &&
+          allocSize >= trivialAutoVarInitSizeBound)
+        return;
       emitStoresForPatternInit(CGM, D, Loc, isVolatile, Builder);
       break;
     }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index f02f7c841b91f..669c85c8c7722 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3436,6 +3436,21 @@ static void RenderTrivialAutoVarInitOptions(const Driver 
&D,
     CmdArgs.push_back(
         Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val));
   }
+
+  if (Arg *A =
+          Args.getLastArg(options::OPT_ftrivial_auto_var_init_size_bound)) {
+    if (!Args.hasArg(options::OPT_ftrivial_auto_var_init) ||
+        StringRef(
+            Args.getLastArg(options::OPT_ftrivial_auto_var_init)->getValue()) 
==
+            "uninitialized")
+      
D.Diag(diag::err_drv_trivial_auto_var_init_size_bound_missing_dependency);
+    A->claim();
+    StringRef Val = A->getValue();
+    if (std::stoi(Val.str()) <= 0)
+      D.Diag(diag::err_drv_trivial_auto_var_init_size_bound_invalid_value);
+    CmdArgs.push_back(
+        Args.MakeArgString("-ftrivial-auto-var-init-size-bound=" + Val));
+  }
 }
 
 static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
diff --git a/clang/test/CodeGenCXX/auto-var-init-size-bound.cpp 
b/clang/test/CodeGenCXX/auto-var-init-size-bound.cpp
new file mode 100644
index 0000000000000..1f6c2b143d397
--- /dev/null
+++ b/clang/test/CodeGenCXX/auto-var-init-size-bound.cpp
@@ -0,0 +1,82 @@
+// Pattern related size bound tests: 1, 8, 4096, 4097
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown 
-ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=1 %s 
-emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON 
-check-prefix=PATTERN-BOUND-1 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown 
-ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=8 %s 
-emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON 
-check-prefix=PATTERN-BOUND-8 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown 
-ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=4096 %s 
-emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON 
-check-prefix=PATTERN-BOUND-4096 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown 
-ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=4097 %s 
-emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON 
-check-prefix=PATTERN-BOUND-4097 %s
+//
+// Zero related size bound tests: 1, 8, 4096, 4097
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero 
-ftrivial-auto-var-init-size-bound=1 %s -emit-llvm -o - | FileCheck 
-check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-1 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero 
-ftrivial-auto-var-init-size-bound=8 %s -emit-llvm -o - | FileCheck 
-check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-8 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero 
-ftrivial-auto-var-init-size-bound=4096 %s -emit-llvm -o - | FileCheck 
-check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-4096 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero 
-ftrivial-auto-var-init-size-bound=4097 %s -emit-llvm -o - | FileCheck 
-check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-4097 %s
+
+#define ARRLEN 1024
+
+int foo(unsigned n) {
+  bool var_size_1;
+  long var_size_8 = 123;
+  void *var_size_8p;
+  int var_size_4096[ARRLEN];
+  // VLA, non-constant size
+  int var_vla[n];
+  // builtin, non-constant size
+  var_size_8p = __builtin_alloca(sizeof(unsigned long long) * n);
+  // There are 6 variables: var_size_1, var_size_8, var_size_8p, var_size_4096,
+  // var_vla, and a builtin anonymous var ("%5").
+  // "var_vla" and "%5" have a non-constant size, and they should be 
auto-inited
+  //  disregarding the size bound.
+  // - Size bound 1: "var_vla" and "%5"
+  // - Size bound 8: "var_size_1", "var_vla", and "%5"
+  // - Size bound 4096: "var_size_1", "var_size_8", "var_size_8p",
+  //                    "var_vla", and "%5"
+  // - Size bound 4097: "var_size_1", "var_size_8", "var_size_8p",
+  //                    "var_size_4096", "var_vla", and "%5"
+  //
+  // PATTERN-BOUND-1-NOT: store i8 -86, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-1-NOT: store i64 -6148914691236517206, ptr %var_size_8, 
align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-1-NOT: store ptr inttoptr (i64 -6148914691236517206 to 
ptr), ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-1-NOT: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-BOUND-8: store i8 -86, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-8-NOT: store i64 -6148914691236517206, ptr %var_size_8, 
align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-8-NOT: store ptr inttoptr (i64 -6148914691236517206 to 
ptr), ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-8-NOT: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-BOUND-4096: store i8 -86, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4096: store i64 -6148914691236517206, ptr %var_size_8, 
align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4096: store ptr inttoptr (i64 -6148914691236517206 to ptr), 
ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4096-NOT: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-BOUND-4097: store i8 -86, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4097: store i64 -6148914691236517206, ptr %var_size_8, 
align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4097: store ptr inttoptr (i64 -6148914691236517206 to ptr), 
ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4097: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %vla.cur, 
ptr align 4 @__const._Z3fooj.var_vla, i64 4, i1 false), !annotation 
[[AUTO_INIT:!.+]]
+  // PATTERN-COMMON: call void @llvm.memset.p0.i64(ptr align 16 %5, i8 -86, 
i64 %mul, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-1-NOT: store i8 0, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-1-NOT: store i64 0, ptr %var_size_8, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-1-NOT: store ptr null, ptr %var_size_8p, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-1-NOT: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-8: store i8 0, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-8-NOT: store i64 0, ptr %var_size_8, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-8-NOT: store ptr null, ptr %var_size_8p, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-8-NOT: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-4096: store i8 0, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4096: store i64 0, ptr %var_size_8, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4096: store ptr null, ptr %var_size_8p, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4096-NOT: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-4097: store i8 0, ptr %var_size_1, align 1, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4097: store i64 0, ptr %var_size_8, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4097: store ptr null, ptr %var_size_8p, align 8, !annotation 
[[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4097: call void @llvm.memset.p0.i64(ptr align 16 
%var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-COMMON: call void @llvm.memset.p0.i64(ptr align 16 %vla, i8 0, i64 
%3, i1 false), !annotation [[AUTO_INIT:!.+]]
+  // ZERO-COMMON: call void @llvm.memset.p0.i64(ptr align 16 %5, i8 0, i64 
%mul, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  return 0;
+}
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index ebe8a0520bf0f..7f947d2de5c6e 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -585,6 +585,19 @@
 // CHECK-TRIVIAL-PATTERN-STOP-AFTER-INVALID-VALUE: only accepts positive 
integers
 // CHECK-TRIVIAL-ZERO-STOP-AFTER-INVALID-VALUE: only accepts positive integers
 
+// RUN: %clang -### -S -ftrivial-auto-var-init=pattern 
-ftrivial-auto-var-init-size-bound=1024 %s 2>&1 | FileCheck 
-check-prefix=CHECK-TRIVIAL-PATTERN-SIZE-BOUND %s
+// RUN: %clang -### -S -ftrivial-auto-var-init=zero 
-ftrivial-auto-var-init-size-bound=1024 %s 2>&1 | FileCheck 
-check-prefix=CHECK-TRIVIAL-ZERO-SIZE-BOUND %s
+// RUN: not %clang -### -S -ftrivial-auto-var-init-size-bound=1024 %s 2>&1 | 
FileCheck -check-prefix=CHECK-TRIVIAL-SIZE-BOUND-MISSING-DEPENDENCY %s
+// RUN: not %clang -### -S -ftrivial-auto-var-init=pattern 
-ftrivial-auto-var-init-size-bound=0 %s 2>&1 | FileCheck 
-check-prefix=CHECK-TRIVIAL-PATTERN-SIZE-BOUND-INVALID-VALUE %s
+// RUN: not %clang -### -S -ftrivial-auto-var-init=zero 
-ftrivial-auto-var-init-size-bound=0 %s 2>&1 | FileCheck 
-check-prefix=CHECK-TRIVIAL-ZERO-SIZE-BOUND-INVALID-VALUE %s
+// CHECK-TRIVIAL-PATTERN-SIZE-BOUND-NOT: is used without 
'-ftrivial-auto-var-init'
+// CHECK-TRIVIAL-PATTERN-SIZE-BOUND-NOT: only accepts positive integers (in 
bytes)
+// CHECK-TRIVIAL-ZERO-SIZE-BOUND-NOT: is used without '-ftrivial-auto-var-init'
+// CHECK-TRIVIAL-ZERO-SIZE-BOUND-NOT: only accepts positive integers (in bytes)
+// CHECK-TRIVIAL-SIZE-BOUND-MISSING-DEPENDENCY: used without 
'-ftrivial-auto-var-init=zero' or
+// CHECK-TRIVIAL-PATTERN-SIZE-BOUND-INVALID-VALUE: only accepts positive 
integers (in bytes)
+// CHECK-TRIVIAL-ZERO-SIZE-BOUND-INVALID-VALUE: only accepts positive integers 
(in bytes)
+
 // RUN: %clang -### -S -fno-temp-file %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-TEMP-FILE %s
 // CHECK-NO-TEMP-FILE: "-fno-temp-file"
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/74777
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to