public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch][version 8]add -ftrivial-auto-var-init and variable attribute "uninitialized" to gcc
@ 2021-08-21 20:07 Qing Zhao
  2021-09-03 14:47 ` Qing Zhao
  2021-09-06 10:16 ` [patch][version 8]add -ftrivial-auto-var-init and variable attribute "uninitialized" to gcc Richard Biener
  0 siblings, 2 replies; 30+ messages in thread
From: Qing Zhao @ 2021-08-21 20:07 UTC (permalink / raw)
  To: Richard Biener
  Cc: kees Cook, Nick Alcock via Gcc-patches, Richard Sandiford, Martin Jambor

[-- Attachment #1: Type: text/plain, Size: 10668 bytes --]

Hi,

This is the 8th version of the patch for the new security feature for GCC.
I have tested it with bootstrap on both x86 and aarch64, regression testing on both x86 and aarch64.
Also tested it with the kernel testing case provided by Kees.
Also compile CPU2017 (running is ongoing), without any issue.

Please take a look at this patch and let me know any issues.

thanks.

Qing

In this version:

*****Fix all issues raised by Richard B on 8/9: (compared with version 7)

  1. in "handle_uninitialized_attribute", exclude globals with additional checking and warning message. Update corresponding testing cases for this change c-c++-common/auto-init-9/10.c
  2. add more clarification on the new argument "for_auto_init" for "BUILT_IN_CLEAR_PADDING" in the comments part.
  3. use auto_var_p to replace "VAR_P && !DECL_EXTERNAL && !TREE_STATIC";
     add a new helper routine "is_var_need_auto_init" to check whether a variable need to be initialized.
  4. move the "gimple_add_padding_init_for_auto_var" inside the routine "gimplify_init_constructor";
  5. restrict gimple_add_padding_init_for_auto_var only for INIT_EXPR;
  6. in "gimplify.c" phase, generate a GENERIC call to DEFERRED_INIT + gimplfiy_assign  instead of a gimple call to fully gimplify the call to the .DEFERRED_INIT to avoid some potential issues.
  7. in "internal-fn.c" phase, use helper routines "lang_hooks.types, type_for_mode", "can_native_interpret_type_p", "native_interpret_expr" to simplify the implementation for pattern generation.
  8. move "generating tree node for __BUILTIN_CLEAR_PADDING" in tree.c;
  9. cleanup tree-cfg.c.
  10. testing cases updates.
      for address taken variable -Wuninitialized warnings, add "xfail" for C testing cases; deleting C++ testing cases since "xfail" does not work. (FIXME, add them back if something like "xfail" works for C++.)

******Known issue:

  1. -Wuninitialized warnings migh not be issued for address taken auto variables.
please see https://gcc.gnu.org/pipermail/gcc-patches/2021-August/577431.html
for details.

     Plan: add a separate patch to improve -Wuninitialized on address taken auto variables.

******NOTE:

  1. Changes in tree-sra.c  have been reviewed and approved by Martin Jambor.
  2. the code changes should be very clean now;
  3. The testing cases might need more review, I need comments and suggestions on testing cases part. (Not feel very comfortable especially on the testing cases for checking pattern initializations).

******Please see version 7 at:
https://gcc.gnu.org/pipermail/gcc-patches/2021-July/576341.html

******ChangeLog is:
gcc/ChangeLog:

2021-08-21  qing zhao  <qing.zhao@oracle.com>

        * builtins.c (expand_builtin_memset): Make external visible.
        * builtins.h (expand_builtin_memset): Declare extern.
        * common.opt (ftrivial-auto-var-init=): New option.
        * doc/extend.texi: Document the uninitialized attribute.
        * doc/invoke.texi: Document -ftrivial-auto-var-init.
        * flag-types.h (enum auto_init_type): New enumerated type
        auto_init_type.
        * gimple-fold.c (clear_padding_type): Add one new parameter.
        (clear_padding_union): Likewise.
        (clear_padding_emit_loop): Likewise.
        (clear_type_padding_in_mask): Likewise.
        (gimple_fold_builtin_clear_padding): Handle this new parameter.
        * gimplify.c (gimple_add_init_for_auto_var): New function.
        (gimple_add_padding_init_for_auto_var): New function.
        (is_var_need_auto_init): New function.
        (gimplify_decl_expr): Add initialization to automatic variables per
        users' requests.
        (gimplify_call_expr): Add one new parameter for call to
        __builtin_clear_padding.
        (gimplify_init_constructor): Add padding initialization in the end.
        * internal-fn.c (INIT_PATTERN_VALUE): New macro.
        (expand_DEFERRED_INIT): New function.
        * internal-fn.def (DEFERRED_INIT): New internal function.
        * tree-cfg.c (verify_gimple_call): Verify calls to .DEFERRED_INIT.
        * tree-sra.c (generate_subtree_deferred_init): New function.
        (scan_function): Avoid setting cannot_scalarize_away_bitmap for
        calls to .DEFERRED_INIT.
        (sra_modify_deferred_init): New function.
        (sra_modify_function_body): Handle calls to DEFERRED_INIT specially.
        * tree-ssa-structalias.c (find_func_aliases_for_call): Likewise.
        * tree-ssa-uninit.c (warn_uninit): Handle calls to DEFERRED_INIT
        specially.
        (check_defs): Likewise.
        (warn_uninitialized_vars): Likewise.
        * tree-ssa.c (ssa_undefined_value_p): Likewise.
        * tree.c (build_common_builtin_nodes): Build tree node for
        BUILT_IN_CLEAR_PADDING when needed.

gcc/c-family/ChangeLog:

2021-08-21  qing zhao  <qing.zhao@oracle.com>

        * c-attribs.c (handle_uninitialized_attribute): New function.
        (c_common_attribute_table): Add "uninitialized" attribute.

gcc/testsuite/ChangeLog:


2021-08-20  qing zhao  <qing.zhao@oracle.com>

        * c-c++-common/auto-init-1.c: New test.
        * c-c++-common/auto-init-10.c: New test.
        * c-c++-common/auto-init-11.c: New test.
        * c-c++-common/auto-init-12.c: New test.
        * c-c++-common/auto-init-13.c: New test.
        * c-c++-common/auto-init-14.c: New test.
        * c-c++-common/auto-init-15.c: New test.
        * c-c++-common/auto-init-16.c: New test.
        * c-c++-common/auto-init-2.c: New test.
        * c-c++-common/auto-init-3.c: New test.
        * c-c++-common/auto-init-4.c: New test.
        * c-c++-common/auto-init-5.c: New test.
        * c-c++-common/auto-init-6.c: New test.
        * c-c++-common/auto-init-7.c: New test.
        * c-c++-common/auto-init-8.c: New test.
        * c-c++-common/auto-init-9.c: New test.
        * c-c++-common/auto-init-esra.c: New test.
        * c-c++-common/auto-init-padding-1.c: New test.
        * c-c++-common/auto-init-padding-2.c: New test.
        * c-c++-common/auto-init-padding-3.c: New test.
        * g++.dg/auto-init-uninit-pred-1_a.C: New test.
        * g++.dg/auto-init-uninit-pred-2_a.C: New test.
        * g++.dg/auto-init-uninit-pred-3_a.C: New test.
        * g++.dg/auto-init-uninit-pred-4.C: New test.
        * gcc.dg/auto-init-sra-1.c: New test.
        * gcc.dg/auto-init-sra-2.c: New test.
        * gcc.dg/auto-init-uninit-1.c: New test.
        * gcc.dg/auto-init-uninit-12.c: New test.
        * gcc.dg/auto-init-uninit-13.c: New test.
        * gcc.dg/auto-init-uninit-14.c: New test.
        * gcc.dg/auto-init-uninit-15.c: New test.
        * gcc.dg/auto-init-uninit-16.c: New test.
        * gcc.dg/auto-init-uninit-17.c: New test.
        * gcc.dg/auto-init-uninit-18.c: New test.
        * gcc.dg/auto-init-uninit-19.c: New test.
        * gcc.dg/auto-init-uninit-2.c: New test.
        * gcc.dg/auto-init-uninit-20.c: New test.
        * gcc.dg/auto-init-uninit-21.c: New test.
        * gcc.dg/auto-init-uninit-22.c: New test.
        * gcc.dg/auto-init-uninit-23.c: New test.
        * gcc.dg/auto-init-uninit-24.c: New test.
        * gcc.dg/auto-init-uninit-25.c: New test.
        * gcc.dg/auto-init-uninit-26.c: New test.
        * gcc.dg/auto-init-uninit-3.c: New test.
        * gcc.dg/auto-init-uninit-34.c: New test.
        * gcc.dg/auto-init-uninit-36.c: New test.
        * gcc.dg/auto-init-uninit-37.c: New test.
        * gcc.dg/auto-init-uninit-4.c: New test.
        * gcc.dg/auto-init-uninit-5.c: New test.
        * gcc.dg/auto-init-uninit-6.c: New test.
        * gcc.dg/auto-init-uninit-8.c: New test.
        * gcc.dg/auto-init-uninit-9.c: New test.
        * gcc.dg/auto-init-uninit-A.c: New test.
        * gcc.dg/auto-init-uninit-B.c: New test.
        * gcc.dg/auto-init-uninit-C.c: New test.
        * gcc.dg/auto-init-uninit-H.c: New test.
        * gcc.dg/auto-init-uninit-I.c: New test.
        * gcc.target/aarch64/auto-init-1.c: New test.
        * gcc.target/aarch64/auto-init-2.c: New test.
        * gcc.target/aarch64/auto-init-3.c: New test.
        * gcc.target/aarch64/auto-init-4.c: New test.
        * gcc.target/aarch64/auto-init-5.c: New test.
        * gcc.target/aarch64/auto-init-6.c: New test.
        * gcc.target/aarch64/auto-init-7.c: New test.
        * gcc.target/aarch64/auto-init-8.c: New test.
        * gcc.target/aarch64/auto-init-padding-1.c: New test.
        * gcc.target/aarch64/auto-init-padding-10.c: New test.
        * gcc.target/aarch64/auto-init-padding-11.c: New test.
        * gcc.target/aarch64/auto-init-padding-12.c: New test.
        * gcc.target/aarch64/auto-init-padding-2.c: New test.
        * gcc.target/aarch64/auto-init-padding-3.c: New test.
        * gcc.target/aarch64/auto-init-padding-4.c: New test.
        * gcc.target/aarch64/auto-init-padding-5.c: New test.
        * gcc.target/aarch64/auto-init-padding-6.c: New test.
        * gcc.target/aarch64/auto-init-padding-7.c: New test.
        * gcc.target/aarch64/auto-init-padding-8.c: New test.
        * gcc.target/aarch64/auto-init-padding-9.c: New test.
        * gcc.target/i386/auto-init-1.c: New test.
        * gcc.target/i386/auto-init-2.c: New test.
        * gcc.target/i386/auto-init-21.c: New test.
        * gcc.target/i386/auto-init-22.c: New test.
        * gcc.target/i386/auto-init-23.c: New test.
        * gcc.target/i386/auto-init-24.c: New test.
        * gcc.target/i386/auto-init-3.c: New test.
        * gcc.target/i386/auto-init-4.c: New test.
        * gcc.target/i386/auto-init-5.c: New test.
        * gcc.target/i386/auto-init-6.c: New test.
        * gcc.target/i386/auto-init-7.c: New test.
        * gcc.target/i386/auto-init-8.c: New test.
        * gcc.target/i386/auto-init-padding-1.c: New test.
        * gcc.target/i386/auto-init-padding-10.c: New test.
        * gcc.target/i386/auto-init-padding-11.c: New test.
        * gcc.target/i386/auto-init-padding-12.c: New test.
        * gcc.target/i386/auto-init-padding-2.c: New test.
        * gcc.target/i386/auto-init-padding-3.c: New test.
        * gcc.target/i386/auto-init-padding-4.c: New test.
        * gcc.target/i386/auto-init-padding-5.c: New test.
        * gcc.target/i386/auto-init-padding-6.c: New test.
        * gcc.target/i386/auto-init-padding-7.c: New test.
        * gcc.target/i386/auto-init-padding-8.c: New test.
        * gcc.target/i386/auto-init-padding-9.c: New test.

****** The patch against the 7th patch:


******The complete 8th patch:


[-- Attachment #2: 0001-fix-all-issues-raised-by-Richard-on-8-10.patch --]
[-- Type: application/octet-stream, Size: 83229 bytes --]

From a3e1081547c0f673ebb29894935b90566dd2b2ce Mon Sep 17 00:00:00 2001
From: Qing Zhao <qing.zhao@oracle.com>
Date: Tue, 10 Aug 2021 22:43:08 +0000
Subject: [PATCH] fix all issues raised by Richard on 8/10

---
 gcc/c-family/c-attribs.c                      |  12 +-
 gcc/gimple-fold.c                             |  12 +-
 gcc/gimplify.c                                | 143 ++++++++----------
 gcc/internal-fn.c                             | 121 +++++++--------
 gcc/internal-fn.def                           |   3 +-
 gcc/testsuite/c-c++-common/auto-init-10.c     |   7 +-
 gcc/testsuite/c-c++-common/auto-init-9.c      |   5 +-
 .../g++.dg/auto-init-uninit-pred-1_a.C        |  62 +-------
 .../g++.dg/auto-init-uninit-pred-1_b.C        |  63 --------
 .../g++.dg/auto-init-uninit-pred-2_a.C        |  61 +-------
 .../g++.dg/auto-init-uninit-pred-2_b.C        |  62 --------
 .../g++.dg/auto-init-uninit-pred-3_a.C        |  76 +---------
 .../g++.dg/auto-init-uninit-pred-3_b.C        |  87 -----------
 .../g++.dg/auto-init-uninit-pred-4.C          |  15 +-
 .../g++.dg/auto-init-uninit-pred-loop-1_a.cc  |  21 ---
 .../g++.dg/auto-init-uninit-pred-loop-1_b.cc  |  21 ---
 .../g++.dg/auto-init-uninit-pred-loop-1_c.cc  |  23 ---
 .../g++.dg/auto-init-uninit-pred-loop_1.cc    |  21 ---
 gcc/testsuite/gcc.dg/auto-init-uninit-1.c     |  27 +---
 gcc/testsuite/gcc.dg/auto-init-uninit-11.c    |  42 -----
 gcc/testsuite/gcc.dg/auto-init-uninit-12.c    |  10 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-14.c    |  18 +--
 gcc/testsuite/gcc.dg/auto-init-uninit-16.c    |   4 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-18.c    |  23 +--
 gcc/testsuite/gcc.dg/auto-init-uninit-2.c     |  49 +-----
 gcc/testsuite/gcc.dg/auto-init-uninit-20.c    |  16 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-21.c    |  31 +---
 gcc/testsuite/gcc.dg/auto-init-uninit-22.c    |  68 +--------
 gcc/testsuite/gcc.dg/auto-init-uninit-24.c    |   9 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-3.c     |  30 +---
 gcc/testsuite/gcc.dg/auto-init-uninit-34.c    |   8 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-37.c    |  44 +++---
 gcc/testsuite/gcc.dg/auto-init-uninit-38.c    |  14 --
 gcc/testsuite/gcc.dg/auto-init-uninit-4.c     |  44 +-----
 gcc/testsuite/gcc.dg/auto-init-uninit-5.c     |  35 +----
 gcc/testsuite/gcc.dg/auto-init-uninit-6.c     |  42 +----
 gcc/testsuite/gcc.dg/auto-init-uninit-8.c     |  26 +---
 gcc/testsuite/gcc.dg/auto-init-uninit-9.c     |  36 +----
 gcc/testsuite/gcc.dg/auto-init-uninit-A.c     | 112 +-------------
 gcc/testsuite/gcc.dg/auto-init-uninit-B.c     |   4 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-C.c     |  18 +--
 gcc/testsuite/gcc.dg/auto-init-uninit-H.c     |  30 +---
 gcc/testsuite/gcc.dg/auto-init-uninit-I.c     |   7 +-
 .../gcc.target/aarch64/auto-init-3.c          |   4 +-
 .../gcc.target/aarch64/auto-init-4.c          |   6 +-
 .../gcc.target/aarch64/auto-init-5.c          |   4 +-
 gcc/testsuite/gcc.target/i386/auto-init-3.c   |   4 +-
 gcc/testsuite/gcc.target/i386/auto-init-4.c   |   2 +-
 gcc/testsuite/gcc.target/i386/auto-init-5.c   |   2 +-
 gcc/testsuite/gcc.target/i386/auto-init-6.c   |   2 +-
 gcc/testsuite/gcc.target/i386/auto-init-7.c   |   3 +-
 gcc/testsuite/gcc.target/i386/auto-init-8.c   |   4 +-
 .../gcc.target/i386/auto-init-padding-1.c     |   4 +-
 .../gcc.target/i386/auto-init-padding-10.c    |   2 +-
 .../gcc.target/i386/auto-init-padding-11.c    |   4 +-
 .../gcc.target/i386/auto-init-padding-12.c    |   2 +-
 .../gcc.target/i386/auto-init-padding-2.c     |   2 +-
 .../gcc.target/i386/auto-init-padding-4.c     |   2 +-
 .../gcc.target/i386/auto-init-padding-5.c     |   5 +-
 .../gcc.target/i386/auto-init-padding-6.c     |   2 +-
 .../gcc.target/i386/auto-init-padding-9.c     |   1 -
 gcc/tree-cfg.c                                |  62 +++-----
 gcc/tree.c                                    |  16 ++
 63 files changed, 274 insertions(+), 1421 deletions(-)
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-1_b.C
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-2_b.C
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-3_b.C
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_a.cc
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_b.cc
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_c.cc
 delete mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-loop_1.cc
 delete mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-11.c
 delete mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-38.c

diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 9b594006fe44..96e306fd2c30 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -1623,9 +1623,17 @@ static tree
 handle_uninitialized_attribute (tree *node, tree name, tree ARG_UNUSED (args),
 				int ARG_UNUSED (flags), bool *no_add_attrs)
 {
-  if (!VAR_P (*node))
+  tree decl = *node;
+  if (!VAR_P (decl))
     {
-      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+	       "is not a variable", name, decl);
+      *no_add_attrs = true;
+    }
+  else if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+	       "is not a local variable", name, decl);
       *no_add_attrs = true;
     }
 
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 0e8f316cdaf7..dd0e6b5daffa 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -4681,9 +4681,12 @@ clear_padding_emit_loop (clear_padding_struct *buf, tree type,
 }
 
 /* Clear padding bits for TYPE.  Called recursively from
-   gimple_fold_builtin_clear_padding. If FOR_AUTO_INIT,
-   not emit some of the error messages since doing that
-   might confuse the end user.  */
+   gimple_fold_builtin_clear_padding.  If FOR_AUTO_INIT is true,
+   the __builtin_clear_padding is not called by the end user,
+   instead, it's inserted by the compiler to initialize the
+   paddings of automatic variable.  Therefore, we should not
+   emit the error messages for flexible array members to confuse
+   the end user.  */
 
 static void
 clear_padding_type (clear_padding_struct *buf, tree type,
@@ -4921,6 +4924,9 @@ gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
   gcc_assert (gimple_call_num_args (stmt) == 3);
   tree ptr = gimple_call_arg (stmt, 0);
   tree typearg = gimple_call_arg (stmt, 1);
+  /* the 3rd argument of __builtin_clear_padding is to distinguish whether
+     this call is made by the user or by the compiler for automatic variable
+     initialization.  */
   bool for_auto_init = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
   tree type = TREE_TYPE (TREE_TYPE (typearg));
   location_t loc = gimple_location (stmt);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e214532d5338..b335748d90ee 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -249,11 +249,6 @@ static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
 static hash_map<tree, tree> *oacc_declare_returns;
 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
 					   bool (*) (tree), fallback_t, bool);
-static void gimple_add_init_for_auto_var (tree, enum auto_init_type, bool,
-					  gimple_seq *);
-static void maybe_with_size_expr (tree *);
-static void prepare_gimple_addressable (tree *, gimple_seq *);
-
 
 /* Shorter alias name for the above function for use in gimplify.c
    only.  */
@@ -1748,54 +1743,44 @@ force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
   return NULL_TREE;
 }
 
-
-/* Build a call to internal const function DEFERRED_INIT:
+/* Generate an initialization to automatic variable DECL based on INIT_TYPE.
+   Build a call to internal const function DEFERRED_INIT:
    1st argument: SIZE of the DECL;
    2nd argument: INIT_TYPE;
    3rd argument: IS_VLA, 0 NO, 1 YES;
 
-   as DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA).  */
-
-static gimple *
-build_deferred_init (tree decl,
-		     enum auto_init_type init_type,
-		     bool is_vla)
-{
-  gcc_assert ((is_vla && TREE_CODE (decl) == WITH_SIZE_EXPR)
-	      || (!is_vla && TREE_CODE (decl) != WITH_SIZE_EXPR));
-
-  tree decl_size = NULL_TREE;
-  tree init_type_node
-    = build_int_cst (integer_type_node, (int) init_type);
-  tree is_vla_node
-    = build_int_cst (integer_type_node, (int) is_vla);
-
-   if (TREE_CODE (decl) == WITH_SIZE_EXPR)
-     decl_size = TREE_OPERAND (decl, 1);
-   else
-     decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
-
-   return gimple_build_call_internal (IFN_DEFERRED_INIT, 3,
-				      decl_size, init_type_node, is_vla_node);
-}
-
-/* Generate initialization to automatic variable DECL based on INIT_TYPE.  */
+   as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
+   if IS_VLA is false, the LHS is the DECL itself,
+   if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
+   to this DECL.  */
 static void
 gimple_add_init_for_auto_var (tree decl,
 			      enum auto_init_type init_type,
 			      bool is_vla,
 			      gimple_seq *seq_p)
 {
-  gcc_assert (VAR_P (decl) && !DECL_EXTERNAL (decl) && !TREE_STATIC (decl));
+  gcc_assert (auto_var_p (decl));
   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
+  location_t loc = EXPR_LOCATION (decl);
+  tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
 
-  /* If this DECL is a variable sized type, we must remember the size.  */
-  tree orig_decl = decl;
-  maybe_with_size_expr (&decl);
+  tree init_type_node
+    = build_int_cst (integer_type_node, (int) init_type);
+  tree is_vla_node
+    = build_int_cst (integer_type_node, (int) is_vla);
 
-  gimple *call = build_deferred_init (decl, init_type, is_vla);
-  gimple_call_set_lhs (call, orig_decl);
-  gimplify_seq_add_stmt (seq_p, call);
+  tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
+		 			    TREE_TYPE (decl), 3,
+					    decl_size, init_type_node,
+					    is_vla_node);
+
+  /* If this DECL is a VLA, a temporary address variable for it has been
+     created, the replacement for DECL is recorded in DECL_VALUE_EXPR (decl),
+     we should use it as the LHS of the call.  */
+
+  tree lhs_call
+    = is_vla ? DECL_VALUE_EXPR (decl) : decl;
+  gimplify_assign (lhs_call, call, seq_p);
 }
 
 /* Generate padding initialization for automatic vairable DECL.
@@ -1806,6 +1791,9 @@ gimple_add_init_for_auto_var (tree decl,
    to zeroes regardless INIT_TYPE.
    To do the padding initialization, we insert a call to
    __BUILTIN_CLEAR_PADDING (&decl, 0, for_auto_init = true).
+   Note, we add an additional dummy argument for __BUILTIN_CLEAR_PADDING,
+   'for_auto_init' to distinguish whether this call is for automatic
+   variable initialization or not.
    */
 static void
 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
@@ -1825,28 +1813,10 @@ gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
     }
   else
     {
-      prepare_gimple_addressable (&decl, seq_p);
       mark_addressable (decl);
       addr_of_decl = build_fold_addr_expr (decl);
     }
 
-
-  /* for languages that do not support BUILT_IN_CLEAR_PADDING, create the
-     function node for padding initialization.  */
-  if (!fn)
-    {
-      tree ftype = build_function_type_list (void_type_node,
-					     ptr_type_node,
-					     ptr_type_node,
-					     integer_type_node,
-					     NULL_TREE);
-      fn = add_builtin_function ("__builtin_clear_padding", ftype,
-				 BUILT_IN_CLEAR_PADDING, BUILT_IN_NORMAL,
-				 NULL, NULL_TREE);
-      set_call_expr_flags (fn, ECF_NOTHROW | ECF_LEAF);
-      set_builtin_decl (BUILT_IN_CLEAR_PADDING, fn, false);
-    }
-
   gimple *call = gimple_build_call (fn,
 				    3, addr_of_decl,
 				    build_zero_cst (TREE_TYPE (addr_of_decl)),
@@ -1855,6 +1825,18 @@ gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
   gimplify_seq_add_stmt (seq_p, call);
 }
 
+/* Return true if the DECL need to be automaticly initialized by the
+   compiler.  */
+static bool
+is_var_need_auto_init (tree decl)
+{
+  if (auto_var_p (decl)
+      && (opt_for_fn (current_function_decl, flag_auto_var_init)
+	    > AUTO_INIT_UNINITIALIZED)
+      && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))))
+    return true;
+  return false;
+}
 
 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
    and initialization explicit.  */
@@ -1955,10 +1937,7 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
       /* When there is no explicit initializer, if the user requested,
 	 We should insert an artifical initializer for this automatic
 	 variable.  */
-      else if (opt_for_fn (current_function_decl, flag_auto_var_init)
-		 > AUTO_INIT_UNINITIALIZED
-	       && !lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))
-	       && !TREE_STATIC (decl))
+      else if (is_var_need_auto_init (decl))
 	{
 	  gimple_add_init_for_auto_var (decl,
 					opt_for_fn (current_function_decl,
@@ -5013,6 +4992,9 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   tree object, ctor, type;
   enum gimplify_status ret;
   vec<constructor_elt, va_gc> *elts;
+  bool cleared = false;
+  bool is_empty_ctor = false;
+  bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
 
   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
 
@@ -5055,7 +5037,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	struct gimplify_init_ctor_preeval_data preeval_data;
 	HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
 	HOST_WIDE_INT num_unique_nonzero_elements;
-	bool cleared, complete_p, valid_const_initializer;
+	bool complete_p, valid_const_initializer;
 
 	/* Aggregate types must lower constructors to initialization of
 	   individual elements.  The exception is that a CONSTRUCTOR node
@@ -5064,6 +5046,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  {
 	    if (notify_temp_creation)
 	      return GS_OK;
+	    is_empty_ctor = true;
 	    break;
 	  }
 
@@ -5389,13 +5372,28 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   if (want_value)
     {
       *expr_p = object;
-      return GS_OK;
+      ret = GS_OK;
     }
   else
     {
       *expr_p = NULL;
-      return GS_ALL_DONE;
-    }
+      ret = GS_ALL_DONE;
+    }
+
+  /* If the user requests to initialize automatic variables, we
+     should initialize paddings inside the variable.  Add a call to
+     __BUILTIN_CLEAR_PADDING (&object, 0, for_auto_init = true) to
+     initialize paddings of object always to zero regardless of
+     INIT_TYPE.  Note, we will not insert this call if the aggregate
+     variable has be completely cleared already or it's initialized
+     with an empty constructor.  */
+  if (is_init_expr
+      && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
+	  || !AGGREGATE_TYPE_P (type))
+      && is_var_need_auto_init (object))
+    gimple_add_padding_init_for_auto_var (object, false, pre_p);
+
+  return ret;
 }
 
 /* Given a pointer value OP0, return a simplified version of an
@@ -5422,7 +5420,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
 {
   enum gimplify_status ret = GS_UNHANDLED;
   bool changed;
-  tree object = NULL_TREE;
 
   do
     {
@@ -5538,22 +5535,10 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
 	  if (ret != GS_UNHANDLED)
 	    break;
 
-	  object = TREE_OPERAND (*expr_p, 0);
 	  /* If we're initializing from a CONSTRUCTOR, break this into
 	     individual MODIFY_EXPRs.  */
 	  ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
 					   false);
-	  /* If the user requests to initialize automatic variables, we
-	     should initialize paddings inside the variable. Add a call to
-	     __BUILTIN_CLEAR_PADDING (&object, 0, for_auto_init = true) to
-	     initialize paddings of object always to zero regardless of
-	     INIT_TYPE.  */
-	  if (opt_for_fn (current_function_decl, flag_auto_var_init)
-		> AUTO_INIT_UNINITIALIZED
-	      && VAR_P (object)
-	      && !DECL_EXTERNAL (object)
-	      && !TREE_STATIC (object))
-	    gimple_add_padding_init_for_auto_var (object, false, pre_p);
 	  return ret;
 
 	case COND_EXPR:
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 620a2f9fee2a..ada2a820ff15 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -53,6 +53,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl-iter.h"
 #include "gimple-range.h"
 
+/* For lang_hooks.types.type_for_mode.  */
+#include "langhooks.h"
+
 /* The names of each internal function, indexed by function number.  */
 const char *const internal_fn_name_array[] = {
 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
@@ -2978,13 +2981,18 @@ expand_UNIQUE (internal_fn, gcall *stmt)
 }
 
 /* Expand the IFN_DEFERRED_INIT function:
-   Initialize the LHS variable with zero/pattern according to its second
-   argument INIT_TYPE.
+   LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA);
+
+   if IS_VLA is false, the LHS is the DECL itself,
+   if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
+   to this DECL.
+
+   Initialize the LHS with zero/pattern according to its second argument
+   INIT_TYPE:
    if INIT_TYPE is AUTO_INIT_ZERO, use zeroes to initialize;
    if INIT_TYPE is AUTO_INIT_PATTERN, use 0xFE byte-repeatable pattern
      to initialize;
-   all the memory covered by this LHS variable is initialized including
-   paddings.
+   The LHS variable is initialized including paddings.
    The reasons to choose 0xFE for pattern initialization are:
      1. It is a non-canonical virtual address on x86_64, and at the
 	high end of the i386 kernel address space.
@@ -2994,43 +3002,44 @@ expand_UNIQUE (internal_fn, gcall *stmt)
 static void
 expand_DEFERRED_INIT (internal_fn, gcall *stmt)
 {
-  tree var = gimple_call_lhs (stmt);
-  tree size_of_var = gimple_call_arg (stmt, 0);
-  tree vlaaddr = NULL_TREE;
-  tree var_type = TREE_TYPE (var);
-  bool is_vla = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
+  tree lhs = gimple_call_lhs (stmt);
+  tree var_size = gimple_call_arg (stmt, 0);
   enum auto_init_type init_type
     = (enum auto_init_type) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1));
+  bool is_vla = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
+  bool reg_lhs = true;
 
+  tree var_type = TREE_TYPE (lhs);
   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
 
-  /* if this variable is a VLA, get its SIZE and ADDR first.  */
-  if (is_vla)
+  if (DECL_P (lhs))
     {
-      /* The temporary address variable for this vla should have been
-	 created during gimplification phase.  Refer to gimplify_vla_decl
-	 for details.  */
-      tree var_decl = (TREE_CODE (var) == SSA_NAME) ?
-		       SSA_NAME_VAR (var) : var;
-      gcc_assert (DECL_HAS_VALUE_EXPR_P (var_decl));
-      gcc_assert (TREE_CODE (DECL_VALUE_EXPR (var_decl)) == INDIRECT_REF);
-      /* Get the address of this vla variable.  */
-      vlaaddr = TREE_OPERAND (DECL_VALUE_EXPR (var_decl), 0);
+      rtx tem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+      reg_lhs = !MEM_P (tem);
+    }
+  else if (TREE_CODE (lhs) == SSA_NAME)
+    reg_lhs = true;
+  else
+    {
+      gcc_assert (is_vla);
+      reg_lhs = false;
     }
 
-  if (is_vla || (!use_register_for_decl (var)))
+
+  if (!reg_lhs)
     {
     /* If this is a VLA or the variable is not in register,
        expand to a memset to initialize it.  */
-      if (TREE_CODE (var) == SSA_NAME)
-	var = SSA_NAME_VAR (var);
-      tree addr = is_vla ? vlaaddr: build_fold_addr_expr (var);
+
+      mark_addressable (lhs);
+      tree var_addr = build_fold_addr_expr (lhs);
+
       tree value = (init_type == AUTO_INIT_PATTERN) ?
-		    build_int_cst (unsigned_char_type_node,
+		    build_int_cst (integer_type_node,
 				   INIT_PATTERN_VALUE) :
-		    build_zero_cst (unsigned_char_type_node);
+		    integer_zero_node;
       tree m_call = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMSET),
-				     3, addr, value, size_of_var);
+				     3, var_addr, value, var_size);
       /* Expand this memset call.  */
       expand_builtin_memset (m_call, NULL_RTX, TYPE_MODE (var_type));
     }
@@ -3038,50 +3047,32 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
     {
     /* If this variable is in a register, use expand_assignment might
        generate better code.  */
-      tree pattern = NULL_TREE;
+      tree init = build_zero_cst (var_type);
       unsigned HOST_WIDE_INT total_bytes
 	= tree_to_uhwi (TYPE_SIZE_UNIT (var_type));
 
-      if (INTEGRAL_TYPE_P (var_type) || POINTER_TYPE_P (var_type))
-	{
-	  unsigned char *ptr = (unsigned char *)xmalloc (total_bytes);
-	  for (unsigned int i = 0; i < total_bytes; i++)
-	    ptr[i] = INIT_PATTERN_VALUE;
-	  wide_int result = wi::from_buffer (ptr, total_bytes);
-	  pattern =  wide_int_to_tree (var_type, result);
-	}
-      else if (SCALAR_FLOAT_TYPE_P (var_type))
-	{
-	  unsigned int max_index = 2 + 2 * total_bytes;
-	  char *ptr= (char *)xmalloc (max_index);
-	  ptr[0] = '0';
-	  ptr[1] = 'x';
-	  for (unsigned int i = 2; i < max_index; i += 2)
-	    ptr[i] = 'F';
-	  for (unsigned int i = 3; i < max_index; i += 2)
-	    ptr[i] = 'E';
-	  REAL_VALUE_TYPE r_var;
-	  real_from_string (&r_var, ptr);
-	  pattern = build_real (var_type, r_var);
-	}
-      else
+      if (init_type == AUTO_INIT_PATTERN)
 	{
-	  tree index_type = build_index_type (size_int (total_bytes - 1));
-	  tree array_type = build_array_type (unsigned_char_type_node,
-					      index_type);
-	  tree element = build_int_cst (unsigned_char_type_node,
-					INIT_PATTERN_VALUE);
-	  vec<constructor_elt, va_gc> *elts = NULL;
-	  for (unsigned int i = 0; i < total_bytes; i++)
-	    CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, element);
-	  pattern = build_constructor (array_type, elts);
-	  pattern = build1 (VIEW_CONVERT_EXPR, var_type, pattern);
+	  tree alt_type = NULL_TREE;
+	  if (!can_native_interpret_type_p (var_type))
+	    {
+	      alt_type
+		= lang_hooks.types.type_for_mode (TYPE_MODE (var_type),
+						  TYPE_UNSIGNED (var_type));
+	      gcc_assert (can_native_interpret_type_p (alt_type));
+	    }
+
+	  unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
+	  memset (buf, INIT_PATTERN_VALUE, total_bytes);
+	  init = native_interpret_expr (alt_type ? alt_type : var_type,
+					buf, total_bytes);
+	  gcc_assert (init);
+
+	  if (alt_type)
+	    init = build1 (VIEW_CONVERT_EXPR, var_type, init);
 	}
 
-      tree init = (init_type == AUTO_INIT_PATTERN) ?
-		   pattern :
-		   build_zero_cst (TREE_TYPE (var));
-      expand_assignment (var, init, false);
+      expand_assignment (lhs, init, false);
     }
 }
 
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index dc84b7b7ca79..88169ef4656d 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -361,8 +361,7 @@ DEF_INTERNAL_FN (UNIQUE, ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (PHI, 0, NULL)
 
 /* A function to represent an artifical initialization to an uninitialized
-   automatic variable.  The first argument is the variable itself, the
-   second argument is the initialization type.  */
+   automatic variable.  */
 DEF_INTERNAL_FN (DEFERRED_INIT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 
 /* DIM_SIZE and DIM_POS return the size of a particular compute
diff --git a/gcc/testsuite/c-c++-common/auto-init-10.c b/gcc/testsuite/c-c++-common/auto-init-10.c
index 0a8841e6e0f9..f35205f2a300 100644
--- a/gcc/testsuite/c-c++-common/auto-init-10.c
+++ b/gcc/testsuite/c-c++-common/auto-init-10.c
@@ -2,12 +2,17 @@
 /* { dg-do compile } */
 /* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
 
-extern void bar (char, long long *) __attribute__ ((uninitialized)); /* { dg-warning "'uninitialized' attribute ignored" } */
+extern void bar (char, long long *) __attribute__ ((uninitialized)); /* { dg-warning "'uninitialized' attribute ignored because" "is not a variable" } */
+extern int __attribute__ ((uninitialized)) boo1; /* { dg-warning "'uninitialized' attribute ignored because 'boo1' is not a local variable" } */
+static int __attribute__ ((uninitialized)) boo2; /* { dg-warning "'uninitialized' attribute ignored because 'boo2' is not a local variable" } */
+
 
 void foo()
 {
   short temp1;
   long long __attribute__ ((uninitialized)) temp2[10];
+  static int __attribute__ ((uninitialized)) boo3; /* { dg-warning "'uninitialized' attribute ignored because 'boo3' is not a local variable" } */
+
 
   bar (temp1, temp2);
   return;
diff --git a/gcc/testsuite/c-c++-common/auto-init-9.c b/gcc/testsuite/c-c++-common/auto-init-9.c
index 90bbd8cb1afe..29acb7f86691 100644
--- a/gcc/testsuite/c-c++-common/auto-init-9.c
+++ b/gcc/testsuite/c-c++-common/auto-init-9.c
@@ -2,12 +2,15 @@
 /* { dg-do compile } */
 /* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
 
-extern void bar (char, long long *) __attribute__ ((uninitialized)); /* { dg-warning "'uninitialized' attribute ignored" } */
+extern void bar (char, long long *) __attribute__ ((uninitialized)); /* { dg-warning "'uninitialized' attribute ignored because" "is not a variable" } */
+extern int __attribute__ ((uninitialized)) boo1; /* { dg-warning "'uninitialized' attribute ignored because 'boo1' is not a local variable" } */
+static int __attribute__ ((uninitialized)) boo2; /* { dg-warning "'uninitialized' attribute ignored because 'boo2' is not a local variable" } */
 
 void foo()
 {
   short temp1;
   long long __attribute__ ((uninitialized)) temp2[10];
+  static int __attribute__ ((uninitialized)) boo3; /* { dg-warning "'uninitialized' attribute ignored because 'boo3' is not a local variable" } */
 
   bar (temp1, temp2);
   return;
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C
index 33c17441384f..43002235a53c 100644
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C
@@ -1,63 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-typedef long long int64;
-void incr ();
-bool is_valid (int);
-int  get_time ();
-
-class A 
-{
-public:
-  A ();
-  ~A () {
-    if (I) delete I;
-  }
-
-private:
-  int* I;
-};
-
-bool get_url (A *);
-
-class M {
-
- public:
-__attribute__ ((always_inline))  int GetC (int *c)  {
-
-    A details_str;
-    if (!get_url (&details_str))
-      {
-        incr ();
-        return 1;
-      }
-
-    *c = get_time ();
-    return -1;
-  }
-
-  void do_sth();
-  void do_sth2();
-   
-  void P (int64 t)
-    {
-      int cc; /* { dg-bogus "uninitialized" "uninitialized variable warning" }  */ 
-      if (GetC (&cc) >= 0 )
-        return;
-      
-      if (t && cc <= 0 )  /* { dg-bogus "uninitialized" "uninitialized variable warning" } */
-        {
-          this->do_sth();
-          return;
-        }
-
-    do_sth2();
-  }
-};
-
-M* m; 
-void foo(int x)
-{
-  m = new M;
-  m->P(x);
-}
+#include "uninit-pred-1_a.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_b.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_b.C
deleted file mode 100644
index 6b6bdaed71e0..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_b.C
+++ /dev/null
@@ -1,63 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-typedef long long int64;
-void incr ();
-bool is_valid (int);
-int  get_time ();
-
-class A 
-{
-public:
-  A ();
-  ~A () {
-    if (I) delete I;
-  }
-
-private:
-  int* I;
-};
-
-bool get_url (A *);
-
-class M {
-
- public:
-__attribute__ ((always_inline))  int GetC (int *c)  {
-
-    A details_str;
-    if (!get_url (&details_str))
-      {
-        incr ();
-        return 1;
-      }
-
-    *c = get_time ();
-    return -1;
-  }
-
-  void do_sth();
-  void do_sth2();
-   
-  void P (int64 t)
-    {
-      int cc; /* { dg-message "note: 'cc' was declared here" } */
-      if (GetC (&cc) <= 0 ) /* return flag checked wrongly */
-        return;
-      
-      if (t && cc <= 0 )  /* { dg-warning "uninitialized" "uninitialized variable warning" } */
-        {
-          this->do_sth();
-          return;
-        }
-
-    do_sth2();
-  }
-};
-
-M* m; 
-void foo(int x)
-{
-  m = new M;
-  m->P(x);
-}
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C
index fc18cb1e7c91..5551060b1225 100644
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C
@@ -1,62 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-typedef long long int64;
-void incr ();
-bool is_valid (int);
-int  get_time ();
-
-class A 
-{
-public:
-  A ();
-  ~A () {
-    if (I) delete I;
-  }
-
-private:
-  int* I;
-};
-
-bool get_url (A *);
-
-class M {
-
- public:
-__attribute__ ((always_inline))  bool GetC (int *c)  {
-
-    A details_str;
-    if (get_url (&details_str))
-      {
-        *c = get_time ();
-        return true;
-      }
-
-    return false;
-  }
-
-  void do_sth();
-  void do_sth2();
-   
-  void P (int64 t)
-    {
-      int cc; 
-      if (!GetC (&cc)) /* return flag checked properly */
-        return;
-      
-      if (cc <= 0)  /* { dg-bogus "uninitialized" "uninitialized variable warning" } */
-        {
-          this->do_sth();
-          return;
-        }
-
-    do_sth2();
-  }
-};
-
-M* m; 
-void foo(int x)
-{
-  m = new M;
-  m->P(x);
-}
+#include "uninit-pred-2_a.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_b.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_b.C
deleted file mode 100644
index e85a36f16fff..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_b.C
+++ /dev/null
@@ -1,62 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-typedef long long int64;
-void incr ();
-bool is_valid (int);
-int  get_time ();
-
-class A 
-{
-public:
-  A ();
-  ~A () {
-    if (I) delete I;
-  }
-
-private:
-  int* I;
-};
-
-bool get_url (A *);
-
-class M {
-
- public:
-__attribute__ ((always_inline))  bool GetC (int *c)  {
-
-    A details_str;
-    if (get_url (&details_str))
-      {
-        *c = get_time ();
-        return true;
-      }
-
-    return false;
-  }
-
-  void do_sth();
-  void do_sth2();
-   
-  void P (int64 t)
-    {
-      int cc; /* { dg-message "note: 'cc' was declared here" } */
-      if (GetC (&cc)) /* return flag checked wrongly */
-        return;
-      
-      if (cc <= 0)  /* { dg-warning "uninitialized" "uninitialized variable warning" } */
-        {
-          this->do_sth();
-          return;
-        }
-
-    do_sth2();
-  }
-};
-
-M* m; 
-void foo(int x)
-{
-  m = new M;
-  m->P(x);
-}
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C
index 09ed69215320..d6ab4f0b6beb 100644
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C
@@ -1,77 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-/* Multiple initialization paths.  */
-
-typedef long long int64;
-void incr ();
-bool is_valid (int);
-int  get_time ();
-
-class A
-{
-public:
-  A ();
-  ~A () {
-    if (I) delete I;
-  }
-
-private:
-  int* I;
-};
-
-bool get_url (A *);
-bool get_url2 (A *);
-
-class M {
-
- public:
- __attribute__ ((always_inline))
- bool GetC (int *c)  {
-
-    A details_str;
-    /* Intialization path 1  */
-    if (get_url (&details_str))
-      {
-        *c = get_time ();
-        return true;
-      }
-
-    /* insert dtor calls (inlined) into following return paths  */
-    A tmp_str;
-
-    /* Intializtion path 2  */
-    if (get_url2 (&details_str))
-      {
-        *c = get_time ();
-        return true;
-      }
-
-    return false;
-  }
-
-  void do_sth();
-  void do_sth2();
-
-  void P (int64 t)
-    {
-      int cc;
-      if (!GetC (&cc)) /* return flag checked properly */
-        return;
-
-      if (cc <= 0)   /* { dg-bogus "uninitialized" "uninitialized variable warning" } */
-        {
-          this->do_sth();
-          return;
-        }
-
-    do_sth2();
-  }
-};
-
-M* m;
-void test(int x)
-{
-  m = new M;
-  m->P(x);
-}
+#include "uninit-pred-3_a.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_b.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_b.C
deleted file mode 100644
index 8e7b8541725e..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_b.C
+++ /dev/null
@@ -1,87 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-/* Multiple initialization paths.  */
-
-typedef long long int64;
-void incr ();
-bool is_valid (int);
-int  get_time ();
-
-class A
-{
-public:
-  A ();
-  ~A () {
-    if (I) delete I;
-  }
-
-private:
-  int* I;
-};
-
-bool get_url (A *);
-bool get_url2 (A *);
-bool get_url3 (A *);
-
-class M {
-
- public:
- __attribute__ ((always_inline))
- bool GetC (int *c)  {
-
-    A details_str;
-
-    /* Initialization path 1  */
-    if (get_url (&details_str))
-      {
-        *c = get_time ();
-        return true;
-      }
-
-    /* Destructor call before return*/
-    A tmp_str;
-
-    /* Initialization path 2  */
-    if (get_url2 (&details_str))
-      {
-        *c = get_time ();
-        return true;
-      }
-
-    /* Fail to initialize in this path but
-       still returns true  */
-    if (get_url2 (&details_str))
-      {
-        /* Fail to initialize *c  */
-        return true;
-      }
-
-    return false;
-  }
-
-  void do_sth();
-  void do_sth2();
-
-  void P (int64 t)
-    {
-      int cc;
-      if (!GetC (&cc))
-        return;
-
-      if (cc <= 0)   /* { dg-warning "uninitialized" "uninitialized variable warning" } */
-        {
-          this->do_sth();
-          return;
-        }
-
-    do_sth2();
-  }
-};
-
-M* m;
-void test(int x)
-{
-  m = new M;
-  m->P(x);
-}
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C
index c48770ae44dd..4747d283d31c 100644
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C
@@ -1,16 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-Wuninitialized -Og -ftrivial-auto-var-init=zero" } */
-
-int pop ();
-int pop_first_bucket;
-
-int my_pop ()
-{
-  int out;  // { dg-bogus "uninitialized" "uninitialized variable warning" }
-
-  while (pop_first_bucket)
-    if (pop_first_bucket && (out = pop()))
-      return out;
-
-  return 0;
-}
+#include "uninit-pred-4.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_a.cc b/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_a.cc
deleted file mode 100644
index 629677a60259..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_a.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-extern int bar();
-int foo(void)
-{
- for (;;) {
-   int err = ({int _err; /*  { dg-bogus "uninitialized" "false warning" } */
-     for (int i = 0; i < 16; ++i) {
-       _err = 17;
-       _err = bar();
-     }
-     _err; /*  { dg-bogus "uninitialized" "false warning" } */
-   });
-
-   if (err == 0) return 17; 
- }
-
- return 18;
-}
-
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_b.cc b/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_b.cc
deleted file mode 100644
index 04ab364ac83e..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_b.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-extern int bar();
-int foo(int n)
-{
- for (;;) {
-   int err = ({int _err; 
-     for (int i = 0; i < n; ++i) {
-       _err = 17;
-       _err = bar();
-     }
-     _err; 
-   }); /* { dg-warning "uninitialized" "warn on _err" } */
-
-   if (err == 0) return 17; 
- }
-
- return 18;
-}
-
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_c.cc b/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_c.cc
deleted file mode 100644
index 82a1846c6e0b..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop-1_c.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-extern int bar();
-int foo(int n, int m)
-{
- for (;;) {
-   int err = ({int _err; 
-     for (int i = 0; i < 16; ++i) {
-       if (m+i > n)
-          break;
-       _err = 17;
-       _err = bar();
-     }
-     _err; 
-   }); 
-
-   if (err == 0) return 17; }); /* { dg-warning "uninitialized" "warn on _err" } */
- }
-
- return 18;
-}
-
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop_1.cc b/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop_1.cc
deleted file mode 100644
index 629677a60259..000000000000
--- a/gcc/testsuite/g++.dg/auto-init-uninit-pred-loop_1.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
-
-extern int bar();
-int foo(void)
-{
- for (;;) {
-   int err = ({int _err; /*  { dg-bogus "uninitialized" "false warning" } */
-     for (int i = 0; i < 16; ++i) {
-       _err = 17;
-       _err = bar();
-     }
-     _err; /*  { dg-bogus "uninitialized" "false warning" } */
-   });
-
-   if (err == 0) return 17; 
- }
-
- return 18;
-}
-
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-1.c b/gcc/testsuite/gcc.dg/auto-init-uninit-1.c
index cb0e7cc62545..502db591222a 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-1.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-1.c
@@ -2,29 +2,4 @@
    Taken from cppfiles.c (merge_include_chains) */
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-struct list
-{
-  struct list *next;
-  int id;
-};
-
-extern void free (void *);
-
-void remove_dupes (struct list *el)
-{
-  struct list *p, *q, *r;  /* { dg-bogus "r" "uninitialized variable warning" } */
-
-  for (p = el; p; p = p->next)
-  {
-    for (q = el; q != p; q = q->next)
-      if (q->id == p->id)
-      {
-	r->next = p->next;
-	free (p);
-	p = r;
-	break;
-      }
-    r = p;
-  }
-}
+#include "uninit-1.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-11.c b/gcc/testsuite/gcc.dg/auto-init-uninit-11.c
deleted file mode 100644
index 559e2d963376..000000000000
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-11.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Positive test for uninitialized variables.  */
-/* { dg-do compile } */
-/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-int sink;
-
-void f1(int parm)	/* { dg-bogus "uninitialized" "parameter" } */
-{
-  sink = parm;		/* { dg-bogus "uninitialized" "parameter" } */
-}
-
-void f2(void)
-{
-  int x;
-  sink = x;		/* { dg-warning "is used" "unconditional" } */
-}
-
-void f3(int p)
-{
-  int x;		
-  if (p)
-    x = p;
-  sink = x;            /* { dg-warning "may be used" "conditional" } */
-}
-
-void f4(int p)
-{
-  int x;		/* { dg-bogus "uninitialized" "easy if" } */
-  if (p)
-    x = 1;
-  else
-    x = 2;
-  sink = x;
-}
-
-void f5(void)
-{
-  int x, i;		/* { dg-bogus "uninitialized" "easy loop" } */
-  for (i = 0; i < 10; ++i)
-    x = 1;
-  sink = x;
-}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-12.c b/gcc/testsuite/gcc.dg/auto-init-uninit-12.c
index acff725722dc..65da110f5566 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-12.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-12.c
@@ -1,12 +1,4 @@
 /* PR 23497 */
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-typedef _Complex float C;
-C foo()
-{
-  C f;
-  __real__ f = 0;
-  __imag__ f = 0;
-  return f;
-}
+#include "uninit-12.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-14.c b/gcc/testsuite/gcc.dg/auto-init-uninit-14.c
index 592052a9e9d0..9ffe00a67e50 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-14.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-14.c
@@ -1,20 +1,4 @@
 /* PR 24931 */
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-struct p {
-        short x, y;
-};
-
-struct s {
-        int i;
-        struct p p;
-};
-
-struct s f()
-{
-        struct s s;
-        s.p = (struct p){};
-        s.i = (s.p.x || s.p.y);
-        return s;
-}
+#include "uninit-14.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-16.c b/gcc/testsuite/gcc.dg/auto-init-uninit-16.c
index 0e4f336f726f..38e19502a679 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-16.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-16.c
@@ -1,5 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
 
 int foo, bar;
 
@@ -18,6 +20,6 @@ void testfunc()
 
   decode_reloc(foo, &alt_reloc);
 
-  if (alt_reloc) /* { dg-warning "may be used uninitialized" } */
+  if (alt_reloc) /* { dg-warning "may be used uninitialized" "" { xfail *-*-* }  }  */
     bar = 42;
 }
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-18.c b/gcc/testsuite/gcc.dg/auto-init-uninit-18.c
index 4922848f6dc7..1c9afa928c8d 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-18.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-18.c
@@ -1,24 +1,3 @@
 /* { dg-do compile }  */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-char *foo(int bar, char *baz)
-{
-  char *tmp;
-
-  if (bar & 3)
-    tmp = baz;
-
-  switch (bar) {
-  case 1:
-    tmp[5] = 7;    /* { dg-bogus "may be used uninitialized" } */
-    break;
-  case 2:
-    tmp[11] = 15;  /* { dg-bogus "may be used uninitialized" } */
-    break;
-  default:
-    tmp = 0;
-    break;
-  }
-
-  return tmp;      /* { dg-bogus "may be used uninitialized" } */
-}
+#include "uninit-18.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-2.c b/gcc/testsuite/gcc.dg/auto-init-uninit-2.c
index da03bf8f6d98..4c32dc86397e 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-2.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-2.c
@@ -2,51 +2,4 @@
    Taken from cpphash.c (macroexpand) */
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-struct definition
-{
-  int nargs;
-  int rest_args;
-};
-
-struct cpp_reader;
-
-enum cpp_token
-{
-  CPP_EOF, CPP_POP, CPP_COMMA, CPP_RPAREN
-};
-
-extern enum cpp_token macarg (struct cpp_reader *, int);
-
-void
-macroexpand (struct cpp_reader *pfile, struct definition *defn)
-{
-  int nargs = defn->nargs;
-
-  if (nargs >= 0)
-    {
-      enum cpp_token token;  /* { dg-bogus "token" "uninitialized variable warning" } */
-      int i, rest_args;
-      i = 0;
-      rest_args = 0;
-      do
-	{
-	  if (rest_args)
-	    continue;
-	  if (i < nargs || (nargs == 0 && i == 0))
-	    {
-	      /* if we are working on last arg which absorbs rest of args... */
-	      if (i == nargs - 1 && defn->rest_args)
-		rest_args = 1;
-	      token = macarg (pfile, rest_args);
-	    }
-	  else
-	    token = macarg (pfile, 0);
-	  if (token == CPP_EOF || token == CPP_POP)
-	    return;
-
-	  i++;
-	}
-      while (token == CPP_COMMA);
-    }
-}
+#include "uninit-2.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-20.c b/gcc/testsuite/gcc.dg/auto-init-uninit-20.c
index f533ce9c70e7..d81957e5bb94 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-20.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-20.c
@@ -1,18 +1,4 @@
 /* Spurious uninitialized variable warnings, from gdb */
 /* { dg-do compile } */
 /* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
-struct os { struct o *o; };
-struct o { struct o *next; struct os *se; };
-void f(struct o *o){
-  struct os *s;
-  if(o) s = o->se;
-  while(o && s == o->se){
-    s++; // here `o' is non-zero and thus s is initialized
-    s == o->se  // `?' is essential, `if' does not trigger the warning
-      ? (o = o->next, o ? s = o->se : 0)
-      : 0;
-  }
-}
-
-
-
+#include "uninit-20.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-21.c b/gcc/testsuite/gcc.dg/auto-init-uninit-21.c
index 6044eab27870..cc6174607367 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-21.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-21.c
@@ -1,33 +1,4 @@
 /* PR69537, spurious warning because of a missed optimization. */
 /* { dg-do compile } */
 /* { dg-options "-O2 -fno-short-enums -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-enum clnt_stat {
- RPC_SUCCESS=0,
- RPC_CANTENCODEARGS=1,
-};
- 
-int do_ypcall_tr ();
- 
-static int
-yp_master (char **outname)
-{
-  // Replacing enum clnt_stat with int avoids the warning.
-  enum clnt_stat result;
-  result = do_ypcall_tr ();
-  if (result != 0)
-    return result;
-  *outname = __builtin_strdup ("foo");
-  return 0;
-}
- 
-int
-yp_update (void)
-{
-  char *master;
-  int r;
-  if ((r = yp_master (&master)) != 0)
-    return r;
-  __builtin_free (master); /* { dg-bogus "uninitialized" } */
-  return 0;
-}
+#include "uninit-21.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-22.c b/gcc/testsuite/gcc.dg/auto-init-uninit-22.c
index 0200d734a2c3..1e522ce54255 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-22.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-22.c
@@ -1,69 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-O3 -Wuninitialized --param vect-max-version-for-alias-checks=20 -ftrivial-auto-var-init=zero" } */
-
-#include <stdint.h>
-
-#define A1  2896 /* (1/sqrt(2))<<12 */
-#define A2  2217
-#define A3  3784
-#define A4 -5352
-
-#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
-    const int a0 = (src)[s0] + (src)[s4]; \
-    const int a1 = (src)[s0] - (src)[s4]; \
-    const int a2 = (src)[s2] + (src)[s6]; \
-    const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
-    const int a4 = (src)[s5] + (src)[s3]; \
-    const int a5 = (src)[s5] - (src)[s3]; \
-    const int a6 = (src)[s1] + (src)[s7]; \
-    const int a7 = (src)[s1] - (src)[s7]; \
-    const int b0 = a4 + a6; \
-    const int b1 = (A3*(a5 + a7)) >> 11; \
-    const int b2 = ((A4*a5) >> 11) - b0 + b1; \
-    const int b3 = (A1*(a6 - a4) >> 11) - b2; \
-    const int b4 = ((A2*a7) >> 11) + b3 - b1; \
-    (dest)[d0] = munge(a0+a2   +b0); \
-    (dest)[d1] = munge(a1+a3-a2+b2); \
-    (dest)[d2] = munge(a1-a3+a2+b3); \
-    (dest)[d3] = munge(a0-a2   -b4); \
-    (dest)[d4] = munge(a0-a2   +b4); \
-    (dest)[d5] = munge(a1-a3+a2-b3); \
-    (dest)[d6] = munge(a1+a3-a2-b2); \
-    (dest)[d7] = munge(a0+a2   -b0); \
-}
-
-#define MUNGE_NONE(x) (x)
-#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
-
-#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
-#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
-
-static inline void bink_idct_col(int *dest, const int32_t *src)
-{
-    if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
-        dest[0]  =
-        dest[8]  =
-        dest[16] =
-        dest[24] =
-        dest[32] =
-        dest[40] =
-        dest[48] =
-        dest[56] = src[0];
-    } else {
-        IDCT_COL(dest, src);
-    }
-}
-
-int bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block)
-{
-    int i;
-    int temp[64];
-    for (i = 0; i < 8; i++)
-        bink_idct_col(&temp[i], &block[i]);
-    for (i = 0; i < 8; i++) {
-        IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
-    }
-
-    return 0;
-}
-
+#include "uninit-22.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-24.c b/gcc/testsuite/gcc.dg/auto-init-uninit-24.c
index 1f6740c123ad..0f839ba9efa8 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-24.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-24.c
@@ -1,10 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */
-
-int foo (int x)
-{
-  int y;
-  if (x)
-    return *(&y + 1); /* { dg-bogus "may be used uninitialized" } */
-  return 0;
-}
+#include "uninit-24.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-3.c b/gcc/testsuite/gcc.dg/auto-init-uninit-3.c
index 7ff228501f8d..5c109202a5ef 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-3.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-3.c
@@ -2,32 +2,4 @@
    Inspired by cppexp.c (parse_charconst) */
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-extern void error (char *);
-
-int
-parse_charconst (const char *start, const char *end)
-{
-  int c; /* { dg-bogus "c" "uninitialized variable warning" } */
-  int nchars, retval;
-
-  nchars = 0;
-  retval = 0;
-  while (start < end)
-    {
-      c = *start++;
-      if (c == '\'')
-	break;
-      nchars++;
-      retval += c;
-      retval <<= 8;
-    }
-
-  if (nchars == 0)
-    return 0;
-
-  if (c != '\'')
-    error ("malformed character constant");
-
-  return retval;
-}
+#include "uninit-3.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-34.c b/gcc/testsuite/gcc.dg/auto-init-uninit-34.c
index 98fc366c871f..1a687654ebb7 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-34.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-34.c
@@ -4,6 +4,8 @@
    to functions declared with attribute access is diagnosed where expected.
    { dg-do compile }
    { dg-options "-O -Wall -ftrivial-auto-var-init=zero" } */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
 
 #define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
 
@@ -19,10 +21,10 @@ void nowarn_scalar (void)
 
 void warn_scalar_1 (void)
 {
-  int i1;                         // { dg-message "declared here" }
+  int i1;                         // { dg-message "declared here" "" { xfail *-*-* } }
   int i2, i3 = 1, i4;
 
-  f4pi (&i1, &i2, &i3, &i4);      // { dg-warning "'i1' may be used uninitialized" }
+  f4pi (&i1, &i2, &i3, &i4);      // { dg-warning "'i1' may be used uninitialized" "" { xfail *-*-* } }
 }
 
 void warn_scalar_2 (void)
@@ -30,7 +32,7 @@ void warn_scalar_2 (void)
   int j1 = 0, j2, j4;
   int j3;
 
-  f4pi (&j1, &j2, &j3, &j4);      // { dg-warning "'j3' may be used uninitialized" }
+  f4pi (&j1, &j2, &j3, &j4);      // { dg-warning "'j3' may be used uninitialized" "" { xfail *-*-* } }
 }
 
 
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-37.c b/gcc/testsuite/gcc.dg/auto-init-uninit-37.c
index da3c9db1840a..2791b37ca009 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-37.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-37.c
@@ -5,6 +5,8 @@
    arguments of array, VLA, or pointer types.
    { dg-do compile }
    { dg-options "-O2 -Wall -ftrack-macro-expansion=0 -ftrivial-auto-var-init=zero" } */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
 
 #define NONE    /* none */
 #define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
@@ -40,9 +42,9 @@ typedef int IA_[];
 typedef const int CIA_[];
 
 T1 (NONE,   fia_,   IA_);
-T1 (NONE,   fcia_,  CIA_);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
-T1 (RO (1), froia_, IA_);     // { dg-warning "\\\[-Wuninitialized" }
-T1 (RW (1), frwia_, IA_);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (NONE,   fcia_,  CIA_);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froia_, IA_);     // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwia_, IA_);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T1 (WO (1), fwoia_, IA_);
 T1 (X (1),  fxia_,  IA_);
 
@@ -51,9 +53,9 @@ typedef int IA1[1];
 typedef const int CIA1[1];
 
 T1 (NONE,   fia1,   IA1);
-T1 (NONE,   fcia1,  CIA1);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
-T1 (RO (1), froia1, IA1);     // { dg-warning "\\\[-Wuninitialized" }
-T1 (RW (1), frwia1, IA1);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (NONE,   fcia1,  CIA1);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froia1, IA1);     // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwia1, IA1);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T1 (WO (1), fwoia1, IA1);
 T1 (X (1),  fxia1,  IA1);
 
@@ -62,9 +64,9 @@ T1 (X (1),  fxia1,  IA1);
 #define CIARS1 const int[restrict static 1]
 
 T1 (NONE,   fiars1,   IARS1);
-T1 (NONE,   fciars1,  CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" }
-T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" }
-T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (NONE,   fciars1,  CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T1 (WO (1), fwoiars1, IARS1);
 T1 (X (1),  fxiars1,  IARS1);
 
@@ -73,9 +75,9 @@ T1 (X (1),  fxiars1,  IARS1);
 #define CIAS1 const int[static 1]
 
 T1 (NONE,   fias1,   IAS1);
-T1 (NONE,   fcias1,  CIAS1);   // { dg-warning "\\\[-Wmaybe-uninitialized" }
-T1 (RO (1), froias1, IAS1);    // { dg-warning "\\\[-Wuninitialized" }
-T1 (RW (1), frwias1, IAS1);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (NONE,   fcias1,  CIAS1);   // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froias1, IAS1);    // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwias1, IAS1);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T1 (WO (1), fwoias1, IAS1);
 T1 (X (1),  fxias1,  IAS1);
 
@@ -84,9 +86,9 @@ T1 (X (1),  fxias1,  IAS1);
 #define CIAX const int[*]
 
 T1 (NONE,   fiax,   IAX);
-T1 (NONE,   fciax,  CIAX);    // { dg-warning "\\\[-Wmaybe-uninitialized" }
-T1 (RO (1), froiax, IAX);     // { dg-warning "\\\[-Wuninitialized" }
-T1 (RW (1), frwiax, IAX);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (NONE,   fciax,  CIAX);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froiax, IAX);     // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwiax, IAX);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T1 (WO (1), fwoiax, IAX);
 T1 (X (1),  fxiax,  IAX);
 
@@ -95,9 +97,9 @@ T1 (X (1),  fxiax,  IAX);
 #define CIAN int n, const int[n]
 
 T2 (NONE,      fian,   IAN);
-T2 (NONE,      fcian,  CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" }
-T2 (RO (2, 1), froian, IAN);  // { dg-warning "\\\[-Wuninitialized" }
-T2 (RW (2, 1), frwian, IAN);  // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T2 (NONE,      fcian,  CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T2 (RO (2, 1), froian, IAN);  // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T2 (RW (2, 1), frwian, IAN);  // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T2 (WO (2, 1), fwoian, IAN);
 T2 (X (2, 1),  fxian,  IAN);
 
@@ -106,9 +108,9 @@ typedef int* IP;
 typedef const int* CIP;
 
 T1 (NONE,   fip,   IP);
-T1 (NONE,   fcip,  CIP);     // { dg-warning "\\\[-Wmaybe-uninitialized" }
-T1 (RO (1), froip, IP);      // { dg-warning "\\\[-Wuninitialized" }
-T1 (RW (1), frwip, IP);      // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (NONE,   fcip,  CIP);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froip, IP);      // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwip, IP);      // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
 T1 (WO (1), fwoip, IP);
 T1 (X (1),  fxip,  IP);
 
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-38.c b/gcc/testsuite/gcc.dg/auto-init-uninit-38.c
deleted file mode 100644
index 211284b8d9e0..000000000000
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-38.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Positive test for uninitialized variables.  */
-/* { dg-do compile } */
-/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-struct weird {
-       int bit : 1;
-       int val;
-};
-
-int func(int val)
-{
-       struct weird obj = { .val = val }; /* { dg-bogus "is used uninitialized" } */
-       return obj.val;
-}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-4.c b/gcc/testsuite/gcc.dg/auto-init-uninit-4.c
index 482c837cacb2..29ec860f0ed8 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-4.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-4.c
@@ -7,46 +7,4 @@
 
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-extern void abort (void);
-
-struct operation {
-    short op;
-    char rprio;
-    char flags;
-    char unsignedp;
-    long value;
-};
-
-extern struct operation cpp_lex (void);
-
-void
-cpp_parse_expr (void)
-{
-  int rprio; /* { dg-bogus "rprio" "uninitialized variable warning PR19833" } */
-  struct operation op;
-
-  for (;;)
-    {
-      op = cpp_lex ();
-
-      switch (op.op)
-	{
-	case 0:
-	  break;
-	case 1:
-	  return;
-	case 2:
-	  rprio = 1;
-	  break;
-	default:
-	  return;
-	}
-
-      if (op.op == 0)
-	return;
-
-      if (rprio != 1)
-	abort();
-    }
-}
+#include "uninit-4.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-5.c b/gcc/testsuite/gcc.dg/auto-init-uninit-5.c
index ada81c912bdd..65b251a2185f 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-5.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-5.c
@@ -3,37 +3,4 @@
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -fno-tree-dce -fno-tree-vrp -fno-tree-dominator-opts -ftrivial-auto-var-init=zero" } */
 
-extern void use(int);
-extern void foo(void);
-
-void
-func1(int cond)
-{
-    int x;  /* { dg-bogus "x" "uninitialized variable warning" } */
-
-    if(cond)
-	x = 1;
-
-    foo();
-
-    if(cond)
-	use(x);
-}
-
-void
-func2 (int cond)
-{
-    int x;  /* { dg-bogus "x" "uninitialized variable warning" } */
-    int flag = 0;
-
-    if(cond)
-    {
-	x = 1;
-	flag = 1;
-    }
-
-    foo();
-
-    if(flag)
-	use(x);
-}
+#include "uninit-5.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-6.c b/gcc/testsuite/gcc.dg/auto-init-uninit-6.c
index e6cba4ef22c0..7c10dfc5895b 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-6.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-6.c
@@ -4,44 +4,4 @@
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
 
-#include <stddef.h>
-
-struct tree
-{
-    struct tree *car;
-    struct tree *cdr;
-    int type, data;
-};
-
-extern void *malloc(size_t);
-
-#define INTEGER_T 1
-#define PTR_T	  2
-
-#define APPEND(TREE, LAST, TYPE, VALUE)				\
-do {								\
-     struct tree *tmp = malloc (sizeof (struct tree));		\
-     tmp->car = 0; tmp->cdr = 0; tmp->type = TYPE;		\
-     tmp->data = VALUE;						\
-     if (TREE->car)						\
-	 LAST->cdr = tmp;					\
-     else							\
-	 TREE->car = tmp;					\
-     LAST = tmp;						\
-} while(0)
- 
-struct tree *
-make_something(int a, int b, int c)
-{
-    struct tree *rv;
-    struct tree *field;
-
-    rv = malloc (sizeof (struct tree));
-    rv->car = 0;
-
-    APPEND(rv, field, INTEGER_T, a);  /* { dg-bogus "field" "uninitialized variable warning" } */
-    APPEND(rv, field, PTR_T, b);
-    APPEND(rv, field, INTEGER_T, c);
-
-    return rv;
-}
+#include "uninit-6.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-8.c b/gcc/testsuite/gcc.dg/auto-init-uninit-8.c
index 6c298870c679..eaa9c0c9093f 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-8.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-8.c
@@ -5,28 +5,4 @@
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
 
-#include <limits.h>
-
-void
-add_bignums (int *out, int *x, int *y)
-{
-    int p, sum;
-    int carry; /* { dg-bogus "carry" "uninitialized variable warning" } */
-
-    p = 0;
-    for (; *x; x++, y++, out++, p++)
-    {
-	if (p)
-	    sum = *x + *y + carry;
-	else
-	    sum = *x + *y;
-
-	if (sum < 0)
-	{
-	    carry = 1;
-	    sum -= INT_MAX;
-	}
-	else
-	    carry = 0;
-    }
-}
+#include "uninit-8.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-9.c b/gcc/testsuite/gcc.dg/auto-init-uninit-9.c
index 9d65493bde2a..6dccf014fe2b 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-9.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-9.c
@@ -5,38 +5,4 @@
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
 /* { dg-require-effective-target alloca } */
 
-struct foo
-{
-    int type;
-    struct foo *car;
-    struct foo *cdr;
-    char *data;
-    int data2;
-};
-
-extern void use(struct foo *);
-
-#define CLOBBER 6
-#define PARALLEL 3
-
-void
-func(struct foo *list, int count)
-{
-    int n_clobbers = 0;
-    int i;
-    struct foo **clob_list;   /* { dg-bogus "clob_list" "uninitialized variable warning" } */
-
-    if(list[0].type == PARALLEL)
-    {
-	clob_list = __builtin_alloca(count * sizeof(struct foo *));
-	
-	for(i = 1; i < count; i++)
-	{
-	    if(list[i].type == CLOBBER)
-		clob_list[n_clobbers++] = &list[i];
-	}
-    }
-
-    for(i = 0; i < n_clobbers; i++)
-	use(clob_list[i]);
-}
+#include "uninit-9.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-A.c b/gcc/testsuite/gcc.dg/auto-init-uninit-A.c
index 01fcf59f4504..0ef1d92a7473 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-A.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-A.c
@@ -4,114 +4,4 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -Wall -ftrivial-auto-var-init=zero" } */
 
-struct tree
-{
-    struct tree *car, *cdr, *wfl;
-    int code;
-    struct { unsigned int renp:1;
-      unsigned int rtnp:1;
-      unsigned int rpnp:1; } flags;
-};
-typedef struct tree *tree;
-#define NULL_TREE ((tree)0)
-
-/* Codes */
-enum
-{
-    CALL_EXPR, NEW_ARRAY_EXPR, NEW_CLASS_EXPR, CONVERT_EXPR,
-    ARRAY_REF, CONDITIONAL_EXPR, STRING_CST, EXPR_WITH_FILE_LOCATION
-};
-
-/* Flags */
-#define RESOLVE_EXPRESSION_NAME_P(t) ((t)->flags.renp)
-#define RESOLVE_TYPE_NAME_P(t) ((t)->flags.rtnp)
-#define RESOLVE_PACKAGE_NAME_P(t) ((t)->flags.rpnp)
-
-/* Macros */
-#define EXPR_WFL_QUALIFICATION(t) ((t)->wfl)
-#define QUAL_WFL(t) ((t)->wfl)
-#define EXPR_WFL_NODE(t) ((t)->wfl)
-#define TREE_CODE(t) ((t)->code)
-#define TREE_OPERAND(t,x) ((t)->car)
-#define CLASSTYPE_SUPER(t) ((t)->car)
-#define IDENTIFIER_LOCAL_VALUE(t) ((t)->car)
-#define TREE_CHAIN(t) ((t)->cdr)
-#define QUAL_RESOLUTION(t) ((t)->cdr)
-
-extern tree current_class, this_identifier_node;
-extern tree super_identifier_node, length_identifier_node;
-
-tree resolve_and_layout (tree, tree);
-tree lookup_field_wrapper (tree, tree);
-
-void
-qualify_ambiguous_name (id)
-     tree id;
-{
-  tree qual, qual_wfl, decl;
-  tree name;	 /* { dg-bogus "name" "uninitialized variable warning" } */
-  tree ptr_type; /* { dg-bogus "ptr_type" "uninitialized variable warning" } */
-  int again, new_array_found = 0;
-  int super_found = 0, this_found = 0;
-
-  qual = EXPR_WFL_QUALIFICATION (id);
-  do {
-    qual_wfl = QUAL_WFL (qual);
-    switch (TREE_CODE (qual_wfl))
-      {
-      case CALL_EXPR:
-	qual_wfl = TREE_OPERAND (qual_wfl, 0);
-	if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
-	  {
-	    qual = EXPR_WFL_QUALIFICATION (qual_wfl);
-	    qual_wfl = QUAL_WFL (qual);
-	  }
-	break;
-      case NEW_ARRAY_EXPR:
-	qual = TREE_CHAIN (qual);
-	new_array_found = again = 1;
-	continue;
-      case NEW_CLASS_EXPR:
-      case CONVERT_EXPR:
-	qual_wfl = TREE_OPERAND (qual_wfl, 0);
-	break;
-      case ARRAY_REF:
-	while (TREE_CODE (qual_wfl) == ARRAY_REF)
-	  qual_wfl = TREE_OPERAND (qual_wfl, 0);
-	break;
-      default:
-	break;
-      }
-
-    name = EXPR_WFL_NODE (qual_wfl);
-    ptr_type = current_class;
-    again = 0;
-
-  } while (again);
-
-  /* If you put straightforward uses of name and ptr_type here
-     instead of the if-else sequence below, the warnings go away.
-     Therefore I suspect a real bug. */
-  
-  if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
-    {
-      RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
-      QUAL_RESOLUTION (qual) = decl;
-    }
-  else if ((decl = lookup_field_wrapper (ptr_type, name))
-	   || (new_array_found && name == length_identifier_node))
-    {
-      RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
-      QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
-    }
-  else if ((decl = resolve_and_layout (name, NULL_TREE)))
-    {
-      RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
-      QUAL_RESOLUTION (qual) = decl;
-    }
-  else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
-	   || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
-    RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
-  else 
-    RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
-}
+#include "uninit-A.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-B.c b/gcc/testsuite/gcc.dg/auto-init-uninit-B.c
index 0b2837127209..b6d3efdfb880 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-B.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-B.c
@@ -1,5 +1,7 @@
 /* Origin: PR c/179 from Gray Watson <gray@256.com>, adapted as a testcase
    by Joseph Myers <jsm28@cam.ac.uk>.  */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
 /* { dg-do compile } */
 /* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
 extern void foo (int *);
@@ -9,7 +11,7 @@ void
 baz (void)
 {
   int i;
-  if (i) /* { dg-warning "is used uninitialized" "uninit i warning" } */
+  if (i) /* { dg-warning "is used uninitialized" "uninit i warning" { xfail *-*-* } }  */
     bar (i);
   foo (&i);
 }
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-C.c b/gcc/testsuite/gcc.dg/auto-init-uninit-C.c
index a4aa629bf930..be1979626447 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-C.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-C.c
@@ -2,20 +2,4 @@
 /* { dg-do compile } */
 /* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
 
-/* Not all platforms support TImode integers.  */
-#if defined(__LP64__) && !defined(__hppa__)
-typedef int TItype __attribute__ ((mode (TI)));
-#else
-typedef long TItype;
-#endif
-
-
-TItype
-__subvdi3 (TItype a, TItype b)
-{
-  TItype w;
-  
-  w = a - b;
-  
-  return w;
-}
+#include "uninit-C.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-H.c b/gcc/testsuite/gcc.dg/auto-init-uninit-H.c
index 71e2e2d68d7f..e442fab00be6 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-H.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-H.c
@@ -2,32 +2,4 @@
 /* { dg-do compile } */
 /* { dg-options "-O -Wall -Werror -ftrivial-auto-var-init=zero" } */
 
-#if defined __alpha__
-# define ASM __asm__("$30")
-#elif defined __i386__
-# define ASM __asm__("esp")
-#elif defined (__powerpc__) || defined (__PPC__) || defined (__ppc__) || defined (_POWER)
-# define ASM __asm__("r1")
-#elif defined __s390__
-# define ASM __asm__("r15")
-#elif defined __mips
-# define ASM __asm__("$sp")
-#elif defined __sparc__
-# define ASM __asm__("sp")
-#elif defined __ia64__
-# define ASM __asm__("r12")
-#elif defined __hppa__
-# define ASM __asm__("%r30")
-#elif defined __xtensa__
-# define ASM __asm__("sp")
-#else
-/* The register name should be target-dependent so for other targets,
-   we just silence the test.  */
-# define ASM = 0
-#endif
-
-void *load_PCB (void)
-{
-  register void *sp ASM;
-  return sp;			/* { dg-bogus "uninitialized" } */
-}
+#include "uninit-H.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-I.c b/gcc/testsuite/gcc.dg/auto-init-uninit-I.c
index 09680fe9790d..4f9ae6cd98cd 100644
--- a/gcc/testsuite/gcc.dg/auto-init-uninit-I.c
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-I.c
@@ -1,8 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
-
-int sys_msgctl (void)
-{
-  struct { int mode; } setbuf;
-  return setbuf.mode;  /* { dg-warning "'setbuf\.mode' is used" } */
-}
+#include "uninit-H.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-3.c b/gcc/testsuite/gcc.target/aarch64/auto-init-3.c
index 1adc147a3000..7008f76b294c 100644
--- a/gcc/testsuite/gcc.target/aarch64/auto-init-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-3.c
@@ -14,4 +14,6 @@ long double foo()
   return result;
 }
 
-/* { dg-final { scan-rtl-dump-times "const_int 0" 7 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_double\:SF 0\.0" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_double\:DF 0\.0" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_double\:TF 0\.0" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-4.c b/gcc/testsuite/gcc.target/aarch64/auto-init-4.c
index 9ee8335065f1..10197045b4cd 100644
--- a/gcc/testsuite/gcc.target/aarch64/auto-init-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-4.c
@@ -14,6 +14,6 @@ long double foo()
   return result;
 }
 
-/* { dg-final { scan-rtl-dump "fefefefe" "expand" } } */
-/* { dg-final { scan-rtl-dump "fefefefefefefefe" "expand" } } */
-/* { dg-final { scan-rtl-dump "fefefefefefefefefefefefefefefefe" "expand" } } */
+/* { dg-final { scan-rtl-dump "\\-0x0\\.fefefep\\+127" "expand" } } */
+/* { dg-final { scan-rtl-dump "\\-0x0\\.f7f7f7f7f7f7fp\\+1009" "expand" } } */
+/* { dg-final { scan-rtl-dump "\\-0x0\\.ff7f7f7f7f7f7f7f7f7f7f7f7f7fp\\+16128" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-5.c b/gcc/testsuite/gcc.target/aarch64/auto-init-5.c
index 1874d961d5de..ac69ac3df82e 100644
--- a/gcc/testsuite/gcc.target/aarch64/auto-init-5.c
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-5.c
@@ -1,6 +1,6 @@
 /* Verify zero initialization for complex type automatic variables.  */
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
 
 
 _Complex long double result;
@@ -15,5 +15,5 @@ _Complex long double foo()
   return result;
 }
 
-/* { dg-final { scan-rtl-dump-times "const_int 0" 12 "expand" } } */
+/* { dg-final { scan-assembler-times "\.word\t0" 14 } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-3.c b/gcc/testsuite/gcc.target/i386/auto-init-3.c
index 130e55fe2e84..300ddfb34f11 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-3.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-3.c
@@ -1,6 +1,6 @@
 /* Verify zero initialization for floating point type automatic variables.  */
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
 
 long double result;
 
@@ -14,4 +14,4 @@ long double foo()
   return result;
 }
 
-/* { dg-final { scan-rtl-dump-times "const_int 0" 3 "expand" } } */
+/* { dg-final { scan-assembler-times "pxor\t\\\%xmm0, \\\%xmm0" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-4.c b/gcc/testsuite/gcc.target/i386/auto-init-4.c
index 55125b537bbd..abe0b7e46a07 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-4.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-4.c
@@ -16,5 +16,5 @@ long double foo()
 
 /* { dg-final { scan-rtl-dump-times "0xfffffffffefefefe" 1 "expand" } } */
 /* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 1 "expand" } } */
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-5.c b/gcc/testsuite/gcc.target/i386/auto-init-5.c
index 06c15bf935b2..b2e708c52893 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-5.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-5.c
@@ -15,6 +15,6 @@ _Complex long double foo()
   return result;
 }
 
-/* { dg-final { scan-rtl-dump-times "const_int 0" 4 "expand" } } */
+/* { dg-final { scan-assembler-times "\\.long\t0" 14 } } */
 
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-6.c b/gcc/testsuite/gcc.target/i386/auto-init-6.c
index 80bd56bcb9a7..c79c039c2e98 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-6.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-6.c
@@ -16,4 +16,4 @@ _Complex long double foo()
 }
 
 /* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 1 "expand" } } */
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 3 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-7.c b/gcc/testsuite/gcc.target/i386/auto-init-7.c
index e91a024631da..011437965deb 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-7.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-7.c
@@ -29,4 +29,5 @@ double foo()
   return result;
 }
 
-/* { dg-final { scan-rtl-dump-times "const_int 0" 7 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\)\\\)" 3 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-8.c b/gcc/testsuite/gcc.target/i386/auto-init-8.c
index 55e55be3bdd2..28fbeb7eece2 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-8.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-8.c
@@ -30,6 +30,6 @@ double foo()
 }
 
 /* { dg-final { scan-rtl-dump-times "0xfffffffffefefefe" 1 "expand" } } */
-/* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 3 "expand" } } */
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 3 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 2 "expand" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c
index b4069797d939..a238b8b4cf58 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c
@@ -1,7 +1,7 @@
 /* Verify zero initialization for structure type automatic variables with
    padding.  */
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=zero" } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
 
 struct test_aligned {
         int internal1;
@@ -14,6 +14,6 @@ int foo ()
   return var.internal1;
 }
 
-/* { dg-final { scan-assembler-times "movq\t\\\$0," 8 } } */
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 1 "expand" } } */
 
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c
index af7a6028c5ce..3fc6b0729825 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c
@@ -18,4 +18,4 @@ int foo ()
   return var[2].four;
 }
 
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 10 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c
index 31a3ee1fe971..cc982b980f6f 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c
@@ -1,7 +1,7 @@
 /* Verify zero initialization for union type with structure field with
    padding.  */ 
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=zero" } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
 
 struct test_trailing_hole {
         int one;
@@ -23,4 +23,4 @@ int foo ()
   return var.u1.four;
 }
 
-/* { dg-final { scan-assembler-times "movq\t\\\$0," 2 } } */
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c
index bf9ea5d629a3..0fbdb6c046d7 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c
@@ -23,4 +23,4 @@ int foo ()
   return var.u1.four;
 }
 
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c
index 2dc2d035a6c9..5739aa16b114 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c
@@ -14,6 +14,6 @@ int foo ()
   return var.internal1;
 }
 
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 4 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
 
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c
index 1ad60243aa4c..d7be32617e44 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c
@@ -23,6 +23,6 @@ int foo ()
   return var.four.internal1;
 }
 
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 8 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
 
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c
index e18bc3073e18..569b09aef239 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c
@@ -1,7 +1,7 @@
 /* Verify zero initialization for structure type automatic variables with
    tail padding.  */
 /* { dg-do compile } */
-/* { dg-options "-ftrivial-auto-var-init=zero" } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
 
 struct test_trailing_hole {
         char *one;
@@ -17,6 +17,5 @@ int foo ()
   return var.four;
 }
 
-/* { dg-final { scan-assembler-times "movq\t\\\$0," 4 } } */
-
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 1 "expand" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c
index 738a340efb61..4e0b6142134f 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c
@@ -17,6 +17,6 @@ int foo ()
   return var.four;
 }
 
-/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefefefefefefefefefe" 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
 
 
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c
index 40fccadf920d..1ff900f95b98 100644
--- a/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c
@@ -19,5 +19,4 @@ int foo ()
 }
 
 /* { dg-final { scan-assembler "movl\t\\\$0," } } */
-/* { dg-final { scan-assembler "movl\t\\\$20," } } */
 /* { dg-final { scan-assembler "rep stosq" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 330eb7dd89bf..f4fc2b221679 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3452,8 +3452,9 @@ verify_gimple_call (gcall *stmt)
 	}
     }
 
-  /* For a call to .DEFERRED_INIT, we should guarantee that the 1st and the 3rd
-     argument is consistent, i.e.:
+  /* For a call to .DEFERRED_INIT,
+     LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
+     we should guarantee that the 1st and the 3rd arguments are consistent:
      1st argument: SIZE of the DECL;
      3rd argument: IS_VLA, 0 NO, 1 YES;
 
@@ -3467,7 +3468,7 @@ verify_gimple_call (gcall *stmt)
       bool is_vla = (bool) TREE_INT_CST_LOW (is_vla_node);
 
       if (TREE_CODE (lhs) == SSA_NAME)
-       lhs = SSA_NAME_VAR (lhs);
+	lhs = SSA_NAME_VAR (lhs);
 
       poly_uint64 size_from_arg0, size_from_lhs;
       bool is_constant_size_arg0 = poly_int_tree_p (size_of_arg0,
@@ -3497,47 +3498,30 @@ verify_gimple_call (gcall *stmt)
 	}
     }
 
-  /* We will not verify the arguments for the calls to .DEFERRED_INIT.
-     Such call is not a real call, just a placeholder for a later
-     initialization during expand phase.
-     This is mainly to avoid assertion failure for the following
-     case:
-
-     uni_var = .DEFERRED_INIT (var_size, INIT_TYPE, is_vla);
-     foo (&uni_var);
-
-     in the above, the uninitialized auto variable "uni_var" is
-     addressable, therefore should not be in registers, resulting
-     the assertion failure in the following argument verification.  */
-  if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
-    return false;
-
   /* ???  The C frontend passes unpromoted arguments in case it
      didn't see a function declaration before the call.  So for now
      leave the call arguments mostly unverified.  Once we gimplify
      unit-at-a-time we have a chance to fix this.  */
-
-  else
-    for (i = 0; i < gimple_call_num_args (stmt); ++i)
-      {
-	tree arg = gimple_call_arg (stmt, i);
-	if ((is_gimple_reg_type (TREE_TYPE (arg))
-	     && !is_gimple_val (arg))
-	    || (!is_gimple_reg_type (TREE_TYPE (arg))
-		&& !is_gimple_lvalue (arg)))
-	  {
-	    error ("invalid argument to gimple call");
-	    debug_generic_expr (arg);
+  for (i = 0; i < gimple_call_num_args (stmt); ++i)
+    {
+      tree arg = gimple_call_arg (stmt, i);
+      if ((is_gimple_reg_type (TREE_TYPE (arg))
+	   && !is_gimple_val (arg))
+	  || (!is_gimple_reg_type (TREE_TYPE (arg))
+	      && !is_gimple_lvalue (arg)))
+	{
+	  error ("invalid argument to gimple call");
+	  debug_generic_expr (arg);
+	  return true;
+	}
+      if (!is_gimple_reg (arg))
+	{
+	  if (TREE_CODE (arg) == WITH_SIZE_EXPR)
+	    arg = TREE_OPERAND (arg, 0);
+	  if (verify_types_in_gimple_reference (arg, false))
 	    return true;
-	  }
-	if (!is_gimple_reg (arg))
-	  {
-	    if (TREE_CODE (arg) == WITH_SIZE_EXPR)
-	      arg = TREE_OPERAND (arg, 0);
-	    if (verify_types_in_gimple_reference (arg, false))
-	      return true;
-	  }
-      }
+	}
+    }
 
   return false;
 }
diff --git a/gcc/tree.c b/gcc/tree.c
index e923e67b6942..23d7b17774ce 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9508,6 +9508,22 @@ build_common_builtin_nodes (void)
   tree tmp, ftype;
   int ecf_flags;
 
+  /* If user requests automatic variables initialization, the builtin
+     BUILT_IN_CLEAR_PADDING is needed.  */
+  if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
+      && !builtin_decl_explicit_p (BUILT_IN_CLEAR_PADDING))
+    {
+      ftype = build_function_type_list (void_type_node,
+					ptr_type_node,
+					ptr_type_node,
+					integer_type_node,
+					NULL_TREE);
+      local_define_builtin ("__builtin_clear_padding", ftype,
+			    BUILT_IN_CLEAR_PADDING,
+			    "__builtin_clear_padding",
+			      ECF_LEAF | ECF_NOTHROW);
+    }
+
   if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
       || !builtin_decl_explicit_p (BUILT_IN_ABORT))
     {
-- 
2.27.0


[-- Attachment #3: 0001-8th-version-add-ftrivial-auto-var-init-and-variable.patch --]
[-- Type: application/octet-stream, Size: 148056 bytes --]

From 5b55cce07e34241da276d2f110d03583782784ce Mon Sep 17 00:00:00 2001
From: Qing Zhao <qing.zhao@oracle.com>
Date: Sat, 21 Aug 2021 19:43:18 +0000
Subject: [PATCH] 8th version add -ftrivial-auto-var-init and variable 
 attribute  uninitialized to gcc.

---
 gcc/builtins.c                                |   3 +-
 gcc/builtins.h                                |   1 +
 gcc/c-family/c-attribs.c                      |  27 ++
 gcc/common.opt                                |  16 ++
 gcc/doc/extend.texi                           |  16 ++
 gcc/doc/invoke.texi                           |  41 ++-
 gcc/flag-types.h                              |   7 +
 gcc/gimple-fold.c                             |  54 ++--
 gcc/gimplify.c                                | 160 +++++++++++-
 gcc/internal-fn.c                             |  99 ++++++++
 gcc/internal-fn.def                           |   4 +
 gcc/testsuite/c-c++-common/auto-init-1.c      |  39 +++
 gcc/testsuite/c-c++-common/auto-init-10.c     |  22 ++
 gcc/testsuite/c-c++-common/auto-init-11.c     |  14 ++
 gcc/testsuite/c-c++-common/auto-init-12.c     |  14 ++
 gcc/testsuite/c-c++-common/auto-init-13.c     |  23 ++
 gcc/testsuite/c-c++-common/auto-init-14.c     |  23 ++
 gcc/testsuite/c-c++-common/auto-init-15.c     |  13 +
 gcc/testsuite/c-c++-common/auto-init-16.c     |  13 +
 gcc/testsuite/c-c++-common/auto-init-2.c      |  39 +++
 gcc/testsuite/c-c++-common/auto-init-3.c      |  19 ++
 gcc/testsuite/c-c++-common/auto-init-4.c      |  19 ++
 gcc/testsuite/c-c++-common/auto-init-5.c      |  21 ++
 gcc/testsuite/c-c++-common/auto-init-6.c      |  21 ++
 gcc/testsuite/c-c++-common/auto-init-7.c      |  35 +++
 gcc/testsuite/c-c++-common/auto-init-8.c      |  35 +++
 gcc/testsuite/c-c++-common/auto-init-9.c      |  20 ++
 gcc/testsuite/c-c++-common/auto-init-esra.c   |  35 +++
 .../c-c++-common/auto-init-padding-1.c        |  23 ++
 .../c-c++-common/auto-init-padding-2.c        | 114 +++++++++
 .../c-c++-common/auto-init-padding-3.c        | 114 +++++++++
 .../g++.dg/auto-init-uninit-pred-1_a.C        |   3 +
 .../g++.dg/auto-init-uninit-pred-2_a.C        |   3 +
 .../g++.dg/auto-init-uninit-pred-3_a.C        |   3 +
 .../g++.dg/auto-init-uninit-pred-4.C          |   3 +
 gcc/testsuite/gcc.dg/auto-init-sra-1.c        |  24 ++
 gcc/testsuite/gcc.dg/auto-init-sra-2.c        |  24 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-1.c     |   5 +
 gcc/testsuite/gcc.dg/auto-init-uninit-12.c    |   4 +
 gcc/testsuite/gcc.dg/auto-init-uninit-13.c    |  10 +
 gcc/testsuite/gcc.dg/auto-init-uninit-14.c    |   4 +
 gcc/testsuite/gcc.dg/auto-init-uninit-15.c    |  26 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-16.c    |  25 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-17.c    |  15 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-18.c    |   3 +
 gcc/testsuite/gcc.dg/auto-init-uninit-19.c    |  26 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-2.c     |   5 +
 gcc/testsuite/gcc.dg/auto-init-uninit-20.c    |   4 +
 gcc/testsuite/gcc.dg/auto-init-uninit-21.c    |   4 +
 gcc/testsuite/gcc.dg/auto-init-uninit-22.c    |   3 +
 gcc/testsuite/gcc.dg/auto-init-uninit-23.c    |  27 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-24.c    |   3 +
 gcc/testsuite/gcc.dg/auto-init-uninit-25.c    |  23 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-26.c    |  23 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-3.c     |   5 +
 gcc/testsuite/gcc.dg/auto-init-uninit-34.c    |  60 +++++
 gcc/testsuite/gcc.dg/auto-init-uninit-36.c    | 238 ++++++++++++++++++
 gcc/testsuite/gcc.dg/auto-init-uninit-37.c    | 156 ++++++++++++
 gcc/testsuite/gcc.dg/auto-init-uninit-4.c     |  10 +
 gcc/testsuite/gcc.dg/auto-init-uninit-5.c     |   6 +
 gcc/testsuite/gcc.dg/auto-init-uninit-6.c     |   7 +
 gcc/testsuite/gcc.dg/auto-init-uninit-8.c     |   8 +
 gcc/testsuite/gcc.dg/auto-init-uninit-9.c     |   8 +
 gcc/testsuite/gcc.dg/auto-init-uninit-A.c     |   7 +
 gcc/testsuite/gcc.dg/auto-init-uninit-B.c     |  17 ++
 gcc/testsuite/gcc.dg/auto-init-uninit-C.c     |   5 +
 gcc/testsuite/gcc.dg/auto-init-uninit-H.c     |   5 +
 gcc/testsuite/gcc.dg/auto-init-uninit-I.c     |   3 +
 .../gcc.target/aarch64/auto-init-1.c          |  32 +++
 .../gcc.target/aarch64/auto-init-2.c          |  35 +++
 .../gcc.target/aarch64/auto-init-3.c          |  19 ++
 .../gcc.target/aarch64/auto-init-4.c          |  19 ++
 .../gcc.target/aarch64/auto-init-5.c          |  19 ++
 .../gcc.target/aarch64/auto-init-6.c          |  18 ++
 .../gcc.target/aarch64/auto-init-7.c          |  32 +++
 .../gcc.target/aarch64/auto-init-8.c          |  32 +++
 .../gcc.target/aarch64/auto-init-padding-1.c  |  17 ++
 .../gcc.target/aarch64/auto-init-padding-10.c |  22 ++
 .../gcc.target/aarch64/auto-init-padding-11.c |  27 ++
 .../gcc.target/aarch64/auto-init-padding-12.c |  27 ++
 .../gcc.target/aarch64/auto-init-padding-2.c  |  18 ++
 .../gcc.target/aarch64/auto-init-padding-3.c  |  27 ++
 .../gcc.target/aarch64/auto-init-padding-4.c  |  27 ++
 .../gcc.target/aarch64/auto-init-padding-5.c  |  22 ++
 .../gcc.target/aarch64/auto-init-padding-6.c  |  20 ++
 .../gcc.target/aarch64/auto-init-padding-7.c  |  20 ++
 .../gcc.target/aarch64/auto-init-padding-8.c  |  22 ++
 .../gcc.target/aarch64/auto-init-padding-9.c  |  21 ++
 gcc/testsuite/gcc.target/i386/auto-init-1.c   |  32 +++
 gcc/testsuite/gcc.target/i386/auto-init-2.c   |  36 +++
 gcc/testsuite/gcc.target/i386/auto-init-21.c  |  14 ++
 gcc/testsuite/gcc.target/i386/auto-init-22.c  |  14 ++
 gcc/testsuite/gcc.target/i386/auto-init-23.c  |  13 +
 gcc/testsuite/gcc.target/i386/auto-init-24.c  |  13 +
 gcc/testsuite/gcc.target/i386/auto-init-3.c   |  17 ++
 gcc/testsuite/gcc.target/i386/auto-init-4.c   |  20 ++
 gcc/testsuite/gcc.target/i386/auto-init-5.c   |  20 ++
 gcc/testsuite/gcc.target/i386/auto-init-6.c   |  19 ++
 gcc/testsuite/gcc.target/i386/auto-init-7.c   |  33 +++
 gcc/testsuite/gcc.target/i386/auto-init-8.c   |  35 +++
 .../gcc.target/i386/auto-init-padding-1.c     |  19 ++
 .../gcc.target/i386/auto-init-padding-10.c    |  21 ++
 .../gcc.target/i386/auto-init-padding-11.c    |  26 ++
 .../gcc.target/i386/auto-init-padding-12.c    |  26 ++
 .../gcc.target/i386/auto-init-padding-2.c     |  19 ++
 .../gcc.target/i386/auto-init-padding-3.c     |  30 +++
 .../gcc.target/i386/auto-init-padding-4.c     |  28 +++
 .../gcc.target/i386/auto-init-padding-5.c     |  21 ++
 .../gcc.target/i386/auto-init-padding-6.c     |  22 ++
 .../gcc.target/i386/auto-init-padding-7.c     |  22 ++
 .../gcc.target/i386/auto-init-padding-8.c     |  22 ++
 .../gcc.target/i386/auto-init-padding-9.c     |  22 ++
 gcc/tree-cfg.c                                |  47 +++-
 gcc/tree-sra.c                                | 124 ++++++++-
 gcc/tree-ssa-structalias.c                    |   3 +
 gcc/tree-ssa-uninit.c                         |  47 ++++
 gcc/tree-ssa.c                                |  40 +++
 gcc/tree.c                                    |  16 ++
 118 files changed, 3142 insertions(+), 44 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-1.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-10.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-11.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-12.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-13.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-14.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-15.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-16.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-2.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-3.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-4.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-5.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-6.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-7.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-8.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-9.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-esra.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-padding-1.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-padding-2.c
 create mode 100644 gcc/testsuite/c-c++-common/auto-init-padding-3.c
 create mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C
 create mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C
 create mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C
 create mode 100644 gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-sra-1.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-sra-2.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-1.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-12.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-13.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-14.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-15.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-16.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-17.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-18.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-19.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-2.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-20.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-21.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-22.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-23.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-24.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-25.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-26.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-3.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-34.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-36.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-37.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-4.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-5.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-6.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-8.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-9.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-A.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-B.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-C.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-H.c
 create mode 100644 gcc/testsuite/gcc.dg/auto-init-uninit-I.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-3.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-4.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-5.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-6.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-7.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-8.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-10.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-11.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-12.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-3.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-4.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-5.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-6.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-7.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-8.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/auto-init-padding-9.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-21.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-22.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-24.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-8.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-10.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-11.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-12.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-8.c
 create mode 100644 gcc/testsuite/gcc.target/i386/auto-init-padding-9.c

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 995486277612..3e57eb03af03 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -142,7 +142,6 @@ static rtx expand_builtin_strcpy (tree, rtx);
 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx);
 static rtx expand_builtin_stpcpy (tree, rtx, machine_mode);
 static rtx expand_builtin_strncpy (tree, rtx);
-static rtx expand_builtin_memset (tree, rtx, machine_mode);
 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, machine_mode, tree);
 static rtx expand_builtin_bzero (tree);
 static rtx expand_builtin_strlen (tree, rtx, machine_mode);
@@ -3872,7 +3871,7 @@ builtin_memset_gen_str (void *data, void *prev,
    try to get the result in TARGET, if convenient (and in mode MODE if that's
    convenient).  */
 
-static rtx
+rtx
 expand_builtin_memset (tree exp, rtx target, machine_mode mode)
 {
   if (!validate_arglist (exp,
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 16b47ac1a7b3..d330b78e5917 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -114,6 +114,7 @@ extern rtx builtin_strncpy_read_str (void *, void *, HOST_WIDE_INT,
 				     fixed_size_mode);
 extern rtx builtin_memset_read_str (void *, void *, HOST_WIDE_INT,
 				    fixed_size_mode);
+extern rtx expand_builtin_memset (tree, rtx, machine_mode);
 extern rtx expand_builtin_saveregs (void);
 extern tree std_build_builtin_va_list (void);
 extern tree std_fn_abi_va_list (tree);
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index e60fb31d8c8e..96e306fd2c30 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -83,6 +83,7 @@ static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
 static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
 static tree handle_error_attribute (tree *, tree, tree, int, bool *);
 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
+static tree handle_uninitialized_attribute (tree *, tree, tree, int, bool *);
 static tree handle_externally_visible_attribute (tree *, tree, tree, int,
 						 bool *);
 static tree handle_no_reorder_attribute (tree *, tree, tree, int,
@@ -331,6 +332,8 @@ const struct attribute_spec c_common_attribute_table[] =
 			      handle_used_attribute, NULL },
   { "unused",                 0, 0, false, false, false, false,
 			      handle_unused_attribute, NULL },
+  { "uninitialized",	      0, 0, true, false, false, false,
+			      handle_uninitialized_attribute, NULL },
   { "retain",                 0, 0, true,  false, false, false,
 			      handle_retain_attribute, NULL },
   { "externally_visible",     0, 0, true,  false, false, false,
@@ -1613,6 +1616,30 @@ handle_retain_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
   return NULL_TREE;
 }
 
+/* Handle an "uninitialized" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_uninitialized_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+				int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  tree decl = *node;
+  if (!VAR_P (decl))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+	       "is not a variable", name, decl);
+      *no_add_attrs = true;
+    }
+  else if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+	       "is not a local variable", name, decl);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "externally_visible" attribute; arguments as in
    struct attribute_spec.handler.  */
 
diff --git a/gcc/common.opt b/gcc/common.opt
index ed8ab5fbe13d..6c861ee1ae6a 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -3078,6 +3078,22 @@ ftree-scev-cprop
 Common Var(flag_tree_scev_cprop) Init(1) Optimization
 Enable copy propagation of scalar-evolution information.
 
+ftrivial-auto-var-init=
+Common Joined RejectNegative Enum(auto_init_type) Var(flag_auto_var_init) Init(AUTO_INIT_UNINITIALIZED) Optimization
+-ftrivial-auto-var-init=[uninitialized|pattern|zero]	Add initializations to automatic variables.
+
+Enum
+Name(auto_init_type) Type(enum auto_init_type) UnknownError(unrecognized automatic variable initialization type %qs)
+
+EnumValue
+Enum(auto_init_type) String(uninitialized) Value(AUTO_INIT_UNINITIALIZED)
+
+EnumValue
+Enum(auto_init_type) String(pattern) Value(AUTO_INIT_PATTERN)
+
+EnumValue
+Enum(auto_init_type) String(zero) Value(AUTO_INIT_ZERO)
+
 ; -fverbose-asm causes extra commentary information to be produced in
 ; the generated assembly code (to make it more readable).  This option
 ; is generally only of use to those who actually need to read the
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 49df8e6dc38a..ca57e507466c 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7560,6 +7560,22 @@ will be placed in new, unique sections.
 
 This additional functionality requires Binutils version 2.36 or later.
 
+@item uninitialized
+@cindex @code{uninitialized} variable attribute
+This attribute, attached to a variable with automatic storage, means that
+the variable should not be automatically initialized by the compiler when
+the option @code{-ftrivial-auto-var-init} presents.
+
+With the option @code{-ftrivial-auto-var-init}, all the automatic variables
+that do not have explicit initializers will be initialized by the compiler.
+These additional compiler initializations might incur run-time overhead,
+sometimes dramatically.  This attribute can be used to mark some variables
+to be excluded from such automatical initialization in order to reduce runtime
+overhead.
+
+This attribute has no effect when the option @code{-ftrivial-auto-var-init}
+does not present.
+
 @item vector_size (@var{bytes})
 @cindex @code{vector_size} variable attribute
 This attribute specifies the vector size for the type of the declared
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d8a6b0b60c9a..4bc3fed91f1c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -573,9 +573,9 @@ Objective-C and Objective-C++ Dialects}.
 -ftree-parallelize-loops=@var{n}  -ftree-pre  -ftree-partial-pre  -ftree-pta @gol
 -ftree-reassoc  -ftree-scev-cprop  -ftree-sink  -ftree-slsr  -ftree-sra @gol
 -ftree-switch-conversion  -ftree-tail-merge @gol
--ftree-ter  -ftree-vectorize  -ftree-vrp  -funconstrained-commons @gol
--funit-at-a-time  -funroll-all-loops  -funroll-loops @gol
--funsafe-math-optimizations  -funswitch-loops @gol
+-ftree-ter  -ftree-vectorize  -ftree-vrp  -ftrivial-auto-var-init @gol
+-funconstrained-commons -funit-at-a-time  -funroll-all-loops @gol
+-funroll-loops -funsafe-math-optimizations  -funswitch-loops @gol
 -fipa-ra  -fvariable-expansion-in-unroller  -fvect-cost-model  -fvpt @gol
 -fweb  -fwhole-program  -fwpa  -fuse-linker-plugin -fzero-call-used-regs @gol
 --param @var{name}=@var{value}
@@ -11819,6 +11819,41 @@ Perform basic block vectorization on trees. This flag is enabled by default at
 @option{-O3} and by @option{-ftree-vectorize}, @option{-fprofile-use},
 and @option{-fauto-profile}.
 
+@item -ftrivial-auto-var-init=@var{choice}
+@opindex ftrivial-auto-var-init
+Initialize automatic variables with either a pattern or with zeroes to increase
+the security and predictability of a program by preventing uninitialized memory
+disclosure and use.
+GCC still considers an automatic variable that doesn't have an explicit
+initializer as uninitialized, -Wuninitialized will still report warning messages
+on such automatic variables.
+With this option, GCC will also initialize any padding of automatic variables
+that have structure or union types to zeroes.
+
+The three values of @var{choice} are:
+
+@itemize @bullet
+@item
+@samp{uninitialized} doesn't initialize any automatic variables.
+This is C and C++'s default.
+
+@item
+@samp{pattern} Initialize automatic variables with values which will likely
+transform logic bugs into crashes down the line, are easily recognized in a
+crash dump and without being values that programmers can rely on for useful
+program semantics.
+The current value is byte-repeatable pattern with byte "0xFE".
+The values used for pattern initialization might be changed in the future.
+
+@item
+@samp{zero} Initialize automatic variables with zeroes.
+@end itemize
+
+The default is @samp{uninitialized}.
+
+You can control this behavior for a specific variable by using the variable
+attribute @code{uninitialized} (@pxref{Variable Attributes}).
+
 @item -fvect-cost-model=@var{model}
 @opindex fvect-cost-model
 Alter the cost model used for vectorization.  The @var{model} argument
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 4fb1cb4743d6..250c0609a84e 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -276,6 +276,13 @@ enum vect_cost_model {
   VECT_COST_MODEL_DEFAULT = 1
 };
 
+/* Automatic variable initialization type.  */
+enum auto_init_type {
+  AUTO_INIT_UNINITIALIZED = 0,
+  AUTO_INIT_PATTERN = 1,
+  AUTO_INIT_ZERO = 2
+};
+
 /* Different instrumentation modes.  */
 enum sanitize_code {
   /* AddressSanitizer.  */
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 3f2c176cff6d..dd0e6b5daffa 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -4518,12 +4518,14 @@ clear_padding_add_padding (clear_padding_struct *buf,
     }
 }
 
-static void clear_padding_type (clear_padding_struct *, tree, HOST_WIDE_INT);
+static void clear_padding_type (clear_padding_struct *, tree,
+				HOST_WIDE_INT, bool);
 
 /* Clear padding bits of union type TYPE.  */
 
 static void
-clear_padding_union (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
+clear_padding_union (clear_padding_struct *buf, tree type,
+		     HOST_WIDE_INT sz, bool for_auto_init)
 {
   clear_padding_struct *union_buf;
   HOST_WIDE_INT start_off = 0, next_off = 0;
@@ -4568,7 +4570,7 @@ clear_padding_union (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
 	      continue;
 	    gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
 			&& !COMPLETE_TYPE_P (TREE_TYPE (field)));
-	    if (!buf->clear_in_mask)
+	    if (!buf->clear_in_mask && !for_auto_init)
 	      error_at (buf->loc, "flexible array member %qD does not have "
 				  "well defined padding bits for %qs",
 			field, "__builtin_clear_padding");
@@ -4579,7 +4581,7 @@ clear_padding_union (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
 	union_buf->off = start_off;
 	union_buf->size = start_size;
 	memset (union_buf->buf, ~0, start_size);
-	clear_padding_type (union_buf, TREE_TYPE (field), fldsz);
+	clear_padding_type (union_buf, TREE_TYPE (field), fldsz, for_auto_init);
 	clear_padding_add_padding (union_buf, sz - fldsz);
 	clear_padding_flush (union_buf, true);
       }
@@ -4649,7 +4651,8 @@ clear_padding_type_may_have_padding_p (tree type)
      __builtin_clear_padding (buf.base);  */
 
 static void
-clear_padding_emit_loop (clear_padding_struct *buf, tree type, tree end)
+clear_padding_emit_loop (clear_padding_struct *buf, tree type,
+			 tree end, bool for_auto_init)
 {
   tree l1 = create_artificial_label (buf->loc);
   tree l2 = create_artificial_label (buf->loc);
@@ -4660,7 +4663,7 @@ clear_padding_emit_loop (clear_padding_struct *buf, tree type, tree end)
   g = gimple_build_label (l1);
   gimple_set_location (g, buf->loc);
   gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
-  clear_padding_type (buf, type, buf->sz);
+  clear_padding_type (buf, type, buf->sz, for_auto_init);
   clear_padding_flush (buf, true);
   g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR, buf->base,
 			   size_int (buf->sz));
@@ -4678,10 +4681,16 @@ clear_padding_emit_loop (clear_padding_struct *buf, tree type, tree end)
 }
 
 /* Clear padding bits for TYPE.  Called recursively from
-   gimple_fold_builtin_clear_padding.  */
+   gimple_fold_builtin_clear_padding.  If FOR_AUTO_INIT is true,
+   the __builtin_clear_padding is not called by the end user,
+   instead, it's inserted by the compiler to initialize the
+   paddings of automatic variable.  Therefore, we should not
+   emit the error messages for flexible array members to confuse
+   the end user.  */
 
 static void
-clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
+clear_padding_type (clear_padding_struct *buf, tree type,
+		    HOST_WIDE_INT sz, bool for_auto_init)
 {
   switch (TREE_CODE (type))
     {
@@ -4765,7 +4774,7 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
 		  continue;
 		gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE
 			    && !COMPLETE_TYPE_P (ftype));
-		if (!buf->clear_in_mask)
+		if (!buf->clear_in_mask && !for_auto_init)
 		  error_at (buf->loc, "flexible array member %qD does not "
 				      "have well defined padding bits for %qs",
 			    field, "__builtin_clear_padding");
@@ -4781,7 +4790,8 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
 		gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
 		clear_padding_add_padding (buf, pos - cur_pos);
 		cur_pos = pos;
-		clear_padding_type (buf, TREE_TYPE (field), fldsz);
+		clear_padding_type (buf, TREE_TYPE (field),
+				    fldsz, for_auto_init);
 		cur_pos += fldsz;
 	      }
 	  }
@@ -4821,7 +4831,7 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
 	  buf->align = TYPE_ALIGN (elttype);
 	  buf->off = 0;
 	  buf->size = 0;
-	  clear_padding_emit_loop (buf, elttype, end);
+	  clear_padding_emit_loop (buf, elttype, end, for_auto_init);
 	  buf->base = base;
 	  buf->sz = prev_sz;
 	  buf->align = prev_align;
@@ -4831,10 +4841,10 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
 	  break;
 	}
       for (HOST_WIDE_INT i = 0; i < nelts; i++)
-	clear_padding_type (buf, TREE_TYPE (type), fldsz);
+	clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
       break;
     case UNION_TYPE:
-      clear_padding_union (buf, type, sz);
+      clear_padding_union (buf, type, sz, for_auto_init);
       break;
     case REAL_TYPE:
       gcc_assert ((size_t) sz <= clear_padding_unit);
@@ -4858,14 +4868,14 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz)
       break;
     case COMPLEX_TYPE:
       fldsz = int_size_in_bytes (TREE_TYPE (type));
-      clear_padding_type (buf, TREE_TYPE (type), fldsz);
-      clear_padding_type (buf, TREE_TYPE (type), fldsz);
+      clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
+      clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
       break;
     case VECTOR_TYPE:
       nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
       fldsz = int_size_in_bytes (TREE_TYPE (type));
       for (HOST_WIDE_INT i = 0; i < nelts; i++)
-	clear_padding_type (buf, TREE_TYPE (type), fldsz);
+	clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
       break;
     case NULLPTR_TYPE:
       gcc_assert ((size_t) sz <= clear_padding_unit);
@@ -4901,7 +4911,7 @@ clear_type_padding_in_mask (tree type, unsigned char *mask)
   buf.sz = int_size_in_bytes (type);
   buf.size = 0;
   buf.union_ptr = mask;
-  clear_padding_type (&buf, type, buf.sz);
+  clear_padding_type (&buf, type, buf.sz, false);
   clear_padding_flush (&buf, true);
 }
 
@@ -4911,9 +4921,13 @@ static bool
 gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
 {
   gimple *stmt = gsi_stmt (*gsi);
-  gcc_assert (gimple_call_num_args (stmt) == 2);
+  gcc_assert (gimple_call_num_args (stmt) == 3);
   tree ptr = gimple_call_arg (stmt, 0);
   tree typearg = gimple_call_arg (stmt, 1);
+  /* the 3rd argument of __builtin_clear_padding is to distinguish whether
+     this call is made by the user or by the compiler for automatic variable
+     initialization.  */
+  bool for_auto_init = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
   tree type = TREE_TYPE (TREE_TYPE (typearg));
   location_t loc = gimple_location (stmt);
   clear_padding_struct buf;
@@ -4970,7 +4984,7 @@ gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
 	  buf.sz = eltsz;
 	  buf.align = TYPE_ALIGN (elttype);
 	  buf.alias_type = build_pointer_type (elttype);
-	  clear_padding_emit_loop (&buf, elttype, end);
+	  clear_padding_emit_loop (&buf, elttype, end, for_auto_init);
 	}
     }
   else
@@ -4983,7 +4997,7 @@ gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
 	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
 	}
       buf.alias_type = build_pointer_type (type);
-      clear_padding_type (&buf, type, buf.sz);
+      clear_padding_type (&buf, type, buf.sz, for_auto_init);
       clear_padding_flush (&buf, true);
     }
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 070d0e4df45a..48db771d6824 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1743,6 +1743,101 @@ force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
   return NULL_TREE;
 }
 
+/* Generate an initialization to automatic variable DECL based on INIT_TYPE.
+   Build a call to internal const function DEFERRED_INIT:
+   1st argument: SIZE of the DECL;
+   2nd argument: INIT_TYPE;
+   3rd argument: IS_VLA, 0 NO, 1 YES;
+
+   as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
+   if IS_VLA is false, the LHS is the DECL itself,
+   if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
+   to this DECL.  */
+static void
+gimple_add_init_for_auto_var (tree decl,
+			      enum auto_init_type init_type,
+			      bool is_vla,
+			      gimple_seq *seq_p)
+{
+  gcc_assert (auto_var_p (decl));
+  gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
+  location_t loc = EXPR_LOCATION (decl);
+  tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
+
+  tree init_type_node
+    = build_int_cst (integer_type_node, (int) init_type);
+  tree is_vla_node
+    = build_int_cst (integer_type_node, (int) is_vla);
+
+  tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
+		 			    TREE_TYPE (decl), 3,
+					    decl_size, init_type_node,
+					    is_vla_node);
+
+  /* If this DECL is a VLA, a temporary address variable for it has been
+     created, the replacement for DECL is recorded in DECL_VALUE_EXPR (decl),
+     we should use it as the LHS of the call.  */
+
+  tree lhs_call
+    = is_vla ? DECL_VALUE_EXPR (decl) : decl;
+  gimplify_assign (lhs_call, call, seq_p);
+}
+
+/* Generate padding initialization for automatic vairable DECL.
+   C guarantees that brace-init with fewer initializers than members
+   aggregate will initialize the rest of the aggregate as-if it were
+   static initialization.  In turn static initialization guarantees
+   that padding is initialized to zero. So, we always initialize paddings
+   to zeroes regardless INIT_TYPE.
+   To do the padding initialization, we insert a call to
+   __BUILTIN_CLEAR_PADDING (&decl, 0, for_auto_init = true).
+   Note, we add an additional dummy argument for __BUILTIN_CLEAR_PADDING,
+   'for_auto_init' to distinguish whether this call is for automatic
+   variable initialization or not.
+   */
+static void
+gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
+				      gimple_seq *seq_p)
+{
+  tree addr_of_decl = NULL_TREE;
+  bool for_auto_init = true;
+  tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
+
+  if (is_vla)
+    {
+      /* The temporary address variable for this vla should be
+	 created in gimplify_vla_decl.  */
+      gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
+      gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF);
+      addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
+    }
+  else
+    {
+      mark_addressable (decl);
+      addr_of_decl = build_fold_addr_expr (decl);
+    }
+
+  gimple *call = gimple_build_call (fn,
+				    3, addr_of_decl,
+				    build_zero_cst (TREE_TYPE (addr_of_decl)),
+				    build_int_cst (integer_type_node,
+						   (int) for_auto_init));
+  gimplify_seq_add_stmt (seq_p, call);
+}
+
+/* Return true if the DECL need to be automaticly initialized by the
+   compiler.  */
+static bool
+is_var_need_auto_init (tree decl)
+{
+  if (auto_var_p (decl)
+      && (opt_for_fn (current_function_decl, flag_auto_var_init)
+	    > AUTO_INIT_UNINITIALIZED)
+      && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))))
+    return true;
+  return false;
+}
+
 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
    and initialization explicit.  */
 
@@ -1839,6 +1934,28 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
 	       as they may contain a label address.  */
 	    walk_tree (&init, force_labels_r, NULL, NULL);
 	}
+      /* When there is no explicit initializer, if the user requested,
+	 We should insert an artifical initializer for this automatic
+	 variable.  */
+      else if (is_var_need_auto_init (decl))
+	{
+	  gimple_add_init_for_auto_var (decl,
+					opt_for_fn (current_function_decl,
+						    flag_auto_var_init),
+					is_vla,
+					seq_p);
+	  /* The expanding of a call to the above .DEFERRED_INIT will apply
+	     block initialization to the whole space covered by this variable.
+	     As a result, all the paddings will be initialized to zeroes
+	     for zero initialization and 0xFE byte-repeatable patterns for
+	     pattern initialization.
+	     In order to make the paddings as zeroes for pattern init, We
+	     should add a call to __builtin_clear_padding to clear the
+	     paddings to zero in compatiple with CLANG.  */
+	  if (opt_for_fn (current_function_decl, flag_auto_var_init)
+	      == AUTO_INIT_PATTERN)
+	    gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
+	}
     }
 
   return GS_ALL_DONE;
@@ -3410,11 +3527,15 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
 	  {
 	    /* Remember the original type of the argument in an internal
 	       dummy second argument, as in GIMPLE pointer conversions are
-	       useless.  */
+	       useless. also mark this call as not for automatic initialization
+	       in the internal dummy third argument.  */
 	    p = CALL_EXPR_ARG (*expr_p, 0);
+	    bool for_auto_init = false;
 	    *expr_p
-	      = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
-				     build_zero_cst (TREE_TYPE (p)));
+	      = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
+				     build_zero_cst (TREE_TYPE (p)),
+				     build_int_cst (integer_type_node,
+						    (int) for_auto_init));
 	    return GS_OK;
 	  }
 	break;
@@ -4871,6 +4992,9 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   tree object, ctor, type;
   enum gimplify_status ret;
   vec<constructor_elt, va_gc> *elts;
+  bool cleared = false;
+  bool is_empty_ctor = false;
+  bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
 
   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
 
@@ -4913,7 +5037,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	struct gimplify_init_ctor_preeval_data preeval_data;
 	HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
 	HOST_WIDE_INT num_unique_nonzero_elements;
-	bool cleared, complete_p, valid_const_initializer;
+	bool complete_p, valid_const_initializer;
 
 	/* Aggregate types must lower constructors to initialization of
 	   individual elements.  The exception is that a CONSTRUCTOR node
@@ -4922,6 +5046,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  {
 	    if (notify_temp_creation)
 	      return GS_OK;
+	    is_empty_ctor = true;
 	    break;
 	  }
 
@@ -5247,13 +5372,28 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   if (want_value)
     {
       *expr_p = object;
-      return GS_OK;
+      ret = GS_OK;
     }
   else
     {
       *expr_p = NULL;
-      return GS_ALL_DONE;
-    }
+      ret = GS_ALL_DONE;
+    }
+
+  /* If the user requests to initialize automatic variables, we
+     should initialize paddings inside the variable.  Add a call to
+     __BUILTIN_CLEAR_PADDING (&object, 0, for_auto_init = true) to
+     initialize paddings of object always to zero regardless of
+     INIT_TYPE.  Note, we will not insert this call if the aggregate
+     variable has be completely cleared already or it's initialized
+     with an empty constructor.  */
+  if (is_init_expr
+      && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
+	  || !AGGREGATE_TYPE_P (type))
+      && is_var_need_auto_init (object))
+    gimple_add_padding_init_for_auto_var (object, false, pre_p);
+
+  return ret;
 }
 
 /* Given a pointer value OP0, return a simplified version of an
@@ -5394,10 +5534,12 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
 	     crack at this before we break it down.  */
 	  if (ret != GS_UNHANDLED)
 	    break;
+
 	  /* If we're initializing from a CONSTRUCTOR, break this into
 	     individual MODIFY_EXPRs.  */
-	  return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
-					    false);
+	  ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
+					   false);
+	  return ret;
 
 	case COND_EXPR:
 	  /* If we're assigning to a non-register type, push the assignment
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 1360a00f0b93..ada2a820ff15 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -53,6 +53,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl-iter.h"
 #include "gimple-range.h"
 
+/* For lang_hooks.types.type_for_mode.  */
+#include "langhooks.h"
+
 /* The names of each internal function, indexed by function number.  */
 const char *const internal_fn_name_array[] = {
 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
@@ -2977,6 +2980,102 @@ expand_UNIQUE (internal_fn, gcall *stmt)
     emit_insn (pattern);
 }
 
+/* Expand the IFN_DEFERRED_INIT function:
+   LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA);
+
+   if IS_VLA is false, the LHS is the DECL itself,
+   if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
+   to this DECL.
+
+   Initialize the LHS with zero/pattern according to its second argument
+   INIT_TYPE:
+   if INIT_TYPE is AUTO_INIT_ZERO, use zeroes to initialize;
+   if INIT_TYPE is AUTO_INIT_PATTERN, use 0xFE byte-repeatable pattern
+     to initialize;
+   The LHS variable is initialized including paddings.
+   The reasons to choose 0xFE for pattern initialization are:
+     1. It is a non-canonical virtual address on x86_64, and at the
+	high end of the i386 kernel address space.
+     2. It is a very large float value (-1.694739530317379e+38).
+     3. It is also an unusual number for integers.  */
+#define INIT_PATTERN_VALUE  0xFE
+static void
+expand_DEFERRED_INIT (internal_fn, gcall *stmt)
+{
+  tree lhs = gimple_call_lhs (stmt);
+  tree var_size = gimple_call_arg (stmt, 0);
+  enum auto_init_type init_type
+    = (enum auto_init_type) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1));
+  bool is_vla = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
+  bool reg_lhs = true;
+
+  tree var_type = TREE_TYPE (lhs);
+  gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
+
+  if (DECL_P (lhs))
+    {
+      rtx tem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+      reg_lhs = !MEM_P (tem);
+    }
+  else if (TREE_CODE (lhs) == SSA_NAME)
+    reg_lhs = true;
+  else
+    {
+      gcc_assert (is_vla);
+      reg_lhs = false;
+    }
+
+
+  if (!reg_lhs)
+    {
+    /* If this is a VLA or the variable is not in register,
+       expand to a memset to initialize it.  */
+
+      mark_addressable (lhs);
+      tree var_addr = build_fold_addr_expr (lhs);
+
+      tree value = (init_type == AUTO_INIT_PATTERN) ?
+		    build_int_cst (integer_type_node,
+				   INIT_PATTERN_VALUE) :
+		    integer_zero_node;
+      tree m_call = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMSET),
+				     3, var_addr, value, var_size);
+      /* Expand this memset call.  */
+      expand_builtin_memset (m_call, NULL_RTX, TYPE_MODE (var_type));
+    }
+  else
+    {
+    /* If this variable is in a register, use expand_assignment might
+       generate better code.  */
+      tree init = build_zero_cst (var_type);
+      unsigned HOST_WIDE_INT total_bytes
+	= tree_to_uhwi (TYPE_SIZE_UNIT (var_type));
+
+      if (init_type == AUTO_INIT_PATTERN)
+	{
+	  tree alt_type = NULL_TREE;
+	  if (!can_native_interpret_type_p (var_type))
+	    {
+	      alt_type
+		= lang_hooks.types.type_for_mode (TYPE_MODE (var_type),
+						  TYPE_UNSIGNED (var_type));
+	      gcc_assert (can_native_interpret_type_p (alt_type));
+	    }
+
+	  unsigned char *buf = (unsigned char *) xmalloc (total_bytes);
+	  memset (buf, INIT_PATTERN_VALUE, total_bytes);
+	  init = native_interpret_expr (alt_type ? alt_type : var_type,
+					buf, total_bytes);
+	  gcc_assert (init);
+
+	  if (alt_type)
+	    init = build1 (VIEW_CONVERT_EXPR, var_type, init);
+	}
+
+      expand_assignment (lhs, init, false);
+    }
+}
+
 /* The size of an OpenACC compute dimension.  */
 
 static void
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 3ac9ae68b2a6..88169ef4656d 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -360,6 +360,10 @@ DEF_INTERNAL_FN (VEC_CONVERT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (UNIQUE, ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (PHI, 0, NULL)
 
+/* A function to represent an artifical initialization to an uninitialized
+   automatic variable.  */
+DEF_INTERNAL_FN (DEFERRED_INIT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+
 /* DIM_SIZE and DIM_POS return the size of a particular compute
    dimension and the executing thread's position within that
    dimension.  DIM_POS is pure (and not const) so that it isn't
diff --git a/gcc/testsuite/c-c++-common/auto-init-1.c b/gcc/testsuite/c-c++-common/auto-init-1.c
new file mode 100644
index 000000000000..8b8ba3dd7e8d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-1.c
@@ -0,0 +1,39 @@
+/* Verify zero initialization for integer and pointer type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+enum E {
+  N1 = 0,
+  N2,
+  N3
+};
+
+extern void bar (char, short, int, enum E, long, long long, int *, bool);
+
+void foo()
+{
+  char temp1;
+  short temp2;
+  int temp3;
+  enum E temp4;
+  long temp5;
+  long long temp6;
+  int *temp7;
+  bool temp8;
+
+  bar (temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8);
+  return;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(1, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(2, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(4, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(4, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp6 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp8 = .DEFERRED_INIT \\(1, 2, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-10.c b/gcc/testsuite/c-c++-common/auto-init-10.c
new file mode 100644
index 000000000000..f35205f2a300
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-10.c
@@ -0,0 +1,22 @@
+/* Verify the variable attribute "uninitialized".  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+extern void bar (char, long long *) __attribute__ ((uninitialized)); /* { dg-warning "'uninitialized' attribute ignored because" "is not a variable" } */
+extern int __attribute__ ((uninitialized)) boo1; /* { dg-warning "'uninitialized' attribute ignored because 'boo1' is not a local variable" } */
+static int __attribute__ ((uninitialized)) boo2; /* { dg-warning "'uninitialized' attribute ignored because 'boo2' is not a local variable" } */
+
+
+void foo()
+{
+  short temp1;
+  long long __attribute__ ((uninitialized)) temp2[10];
+  static int __attribute__ ((uninitialized)) boo3; /* { dg-warning "'uninitialized' attribute ignored because 'boo3' is not a local variable" } */
+
+
+  bar (temp1, temp2);
+  return;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(2, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump-not "temp2 = .DEFERRED_INIT \\(" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-11.c b/gcc/testsuite/c-c++-common/auto-init-11.c
new file mode 100644
index 000000000000..a2d66908d83e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-11.c
@@ -0,0 +1,14 @@
+/* Verify zero initialization for VLA automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+extern void bar (int);
+
+void foo(int n)
+{
+  int arr[n];
+  bar (arr[2]);
+  return;
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 2, 1\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-12.c b/gcc/testsuite/c-c++-common/auto-init-12.c
new file mode 100644
index 000000000000..f05d743fda02
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-12.c
@@ -0,0 +1,14 @@
+/* Verify zero initialization for VLA automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+extern void bar (int);
+
+void foo(int n)
+{
+  int arr[n];
+  bar (arr[2]);
+  return;
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 1, 1\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-13.c b/gcc/testsuite/c-c++-common/auto-init-13.c
new file mode 100644
index 000000000000..b0c0365b288a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-13.c
@@ -0,0 +1,23 @@
+/* Verify the auto initialization of structure or union with a flexible array
+   member.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+struct a {
+  int b;
+  int array[];
+};
+union tar {
+  struct a bar;
+  char buf;
+};
+
+int foo()
+{
+  struct a d;
+  union tar var;
+  return d.b + var.bar.b;
+}
+
+/* { dg-final { scan-tree-dump "d = .DEFERRED_INIT \\(4, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "var = .DEFERRED_INIT \\(4, 1, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-14.c b/gcc/testsuite/c-c++-common/auto-init-14.c
new file mode 100644
index 000000000000..986bb19faaf0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-14.c
@@ -0,0 +1,23 @@
+/* Verify the auto initialization of structure or union with a flexible array
+   member.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+struct a {
+  int b;
+  int array[];
+};
+union tar {
+  struct a bar;
+  char buf;
+};
+
+int foo()
+{
+  struct a d;
+  union tar var;
+  return d.b + var.bar.b;
+}
+
+/* { dg-final { scan-tree-dump "d = .DEFERRED_INIT \\(4, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "var = .DEFERRED_INIT \\(4, 2, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-15.c b/gcc/testsuite/c-c++-common/auto-init-15.c
new file mode 100644
index 000000000000..aa9d7fab68a6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-15.c
@@ -0,0 +1,13 @@
+/* Verify the auto initialization of nested VLA.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+void g(void *);
+
+void foo(int a)
+{
+  int x[a][a];
+  g(x);
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 2, 1\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-16.c b/gcc/testsuite/c-c++-common/auto-init-16.c
new file mode 100644
index 000000000000..86493eef9e47
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-16.c
@@ -0,0 +1,13 @@
+/* Verify the auto initialization of nested VLA.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+void g(void *);
+
+void foo(int a)
+{
+  int x[a][a];
+  g(x);
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 1, 1\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-2.c b/gcc/testsuite/c-c++-common/auto-init-2.c
new file mode 100644
index 000000000000..71955b54ba03
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-2.c
@@ -0,0 +1,39 @@
+/* Verify pattern initialization for integer and pointer type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+enum E {
+  N1 = 0,
+  N2,
+  N3
+};
+
+extern void bar (char, short, int, enum E, long, long long, int *, bool);
+
+void foo()
+{
+  char temp1;
+  short temp2;
+  int temp3;
+  enum E temp4;
+  long temp5;
+  long long temp6;
+  int *temp7;
+  bool temp8;
+
+  bar (temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8);
+  return;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(1, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(2, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(4, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(4, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(8, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp6 = .DEFERRED_INIT \\(8, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(8, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp8 = .DEFERRED_INIT \\(1, 1, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-3.c b/gcc/testsuite/c-c++-common/auto-init-3.c
new file mode 100644
index 000000000000..312275666381
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-3.c
@@ -0,0 +1,19 @@
+/* Verify zero initialization for floating point type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+long double result;
+
+long double foo()
+{
+  float temp1;
+  double temp2;
+  long double temp3;
+  
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(4, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(16, 2, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-4.c b/gcc/testsuite/c-c++-common/auto-init-4.c
new file mode 100644
index 000000000000..15a431726dcd
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-4.c
@@ -0,0 +1,19 @@
+/* Verify pattern initialization for floating point type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+long double result;
+
+long double foo()
+{
+  float temp1;
+  double temp2;
+  long double temp3;
+  
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(4, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(8, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(16, 1, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-5.c b/gcc/testsuite/c-c++-common/auto-init-5.c
new file mode 100644
index 000000000000..54f90bc890b5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-5.c
@@ -0,0 +1,21 @@
+/* Verify zero initialization for complex type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+
+_Complex long double result;
+
+_Complex long double foo()
+{
+  _Complex float temp1;
+  _Complex double temp2;
+  _Complex long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(16, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(32, 2, 0\\)" "gimple" } } */
+
diff --git a/gcc/testsuite/c-c++-common/auto-init-6.c b/gcc/testsuite/c-c++-common/auto-init-6.c
new file mode 100644
index 000000000000..4124a2b183aa
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-6.c
@@ -0,0 +1,21 @@
+/* Verify pattern initialization for complex type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+
+_Complex long double result;
+
+_Complex long double foo()
+{
+  _Complex float temp1;
+  _Complex double temp2;
+  _Complex long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(8, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(16, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(32, 1, 0\\)" "gimple" } } */
+
diff --git a/gcc/testsuite/c-c++-common/auto-init-7.c b/gcc/testsuite/c-c++-common/auto-init-7.c
new file mode 100644
index 000000000000..19986969a8f7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-7.c
@@ -0,0 +1,35 @@
+/* Verify zero initialization for array, union, and structure type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+struct S
+{
+  int f1;
+  float f2;
+  char f3[20];
+};
+
+union U
+{
+  char u1[5];
+  int u2;
+  float u3; 
+};
+
+double result;
+
+double foo()
+{
+  int temp1[3];
+  double temp2[3];
+  struct S temp3;
+  union U temp4;
+  
+  result = temp1[2] + temp2[1] + temp3.f2 + temp4.u3;
+  return result;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(12, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(24, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(28, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-8.c b/gcc/testsuite/c-c++-common/auto-init-8.c
new file mode 100644
index 000000000000..9778e911e3ad
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-8.c
@@ -0,0 +1,35 @@
+/* Verify pattern initialization for array, union, and structure type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+struct S
+{
+  int f1;
+  float f2;
+  char f3[20];
+};
+
+union U
+{
+  char u1[5];
+  int u2;
+  float u3; 
+};
+
+double result;
+
+double foo()
+{
+  int temp1[3];
+  double temp2[3];
+  struct S temp3;
+  union U temp4;
+  
+  result = temp1[2] + temp2[1] + temp3.f2 + temp4.u3;
+  return result;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(12, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(24, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(28, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(8, 1, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-9.c b/gcc/testsuite/c-c++-common/auto-init-9.c
new file mode 100644
index 000000000000..29acb7f86691
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-9.c
@@ -0,0 +1,20 @@
+/* Verify the variable attribute "uninitialized".  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-tree-gimple" } */
+
+extern void bar (char, long long *) __attribute__ ((uninitialized)); /* { dg-warning "'uninitialized' attribute ignored because" "is not a variable" } */
+extern int __attribute__ ((uninitialized)) boo1; /* { dg-warning "'uninitialized' attribute ignored because 'boo1' is not a local variable" } */
+static int __attribute__ ((uninitialized)) boo2; /* { dg-warning "'uninitialized' attribute ignored because 'boo2' is not a local variable" } */
+
+void foo()
+{
+  short temp1;
+  long long __attribute__ ((uninitialized)) temp2[10];
+  static int __attribute__ ((uninitialized)) boo3; /* { dg-warning "'uninitialized' attribute ignored because 'boo3' is not a local variable" } */
+
+  bar (temp1, temp2);
+  return;
+}
+
+/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(2, 2, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump-not "temp2 = .DEFERRED_INIT \\(8, 2, 0\\)" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-esra.c b/gcc/testsuite/c-c++-common/auto-init-esra.c
new file mode 100644
index 000000000000..77ec02355df4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-esra.c
@@ -0,0 +1,35 @@
+/* Verify the strength reduction adjustment for -ftrivial-auto-var-init.  */ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftrivial-auto-var-init=zero -fdump-tree-gimple -fdump-tree-esra" } */
+
+
+typedef double VECTOR[3];
+
+enum
+{
+ X = 0,
+ Y = 1,
+ Z = 2,
+ T = 3
+};
+
+void Assign_Vector(VECTOR d, VECTOR s)
+{
+ d[X] = s[X];
+ d[Y] = s[Y];
+ d[Z] = s[Z];
+}
+
+void VCross(VECTOR a, const VECTOR b, const VECTOR c)
+{
+ VECTOR tmp;
+
+ tmp[X] = b[Y] * c[Z] - b[Z] * c[Y];
+ tmp[Y] = b[Z] * c[X] - b[X] * c[Z];
+ tmp[Z] = b[X] * c[Y] - b[Y] * c[X];
+
+ Assign_Vector(a, tmp);
+}
+
+/* { dg-final { scan-tree-dump-times "tmp = .DEFERRED_INIT \\(24, 2, 0\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times ".DEFERRED_INIT \\(8, 2, 0\\)" 3 "esra" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-padding-1.c b/gcc/testsuite/c-c++-common/auto-init-padding-1.c
new file mode 100644
index 000000000000..97f78ee7d56a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-padding-1.c
@@ -0,0 +1,23 @@
+/* Verify the padding initialization for pattern initialization, we always emit
+ * a call to __builtin_clear_padding to initialize the paddings to zero.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-tree-gimple" } */
+
+
+struct test_small_hole {
+  int one;
+  char two;
+  /* 3 byte padding hole here. */
+  int three;
+  unsigned long four;
+};
+
+extern void g (struct test_small_hole);
+void foo(int a)
+{
+  struct test_small_hole s; 
+  g(s);
+}
+
+/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(24, 1, 0\\)" "gimple" } } */
+/* { dg-final { scan-tree-dump "__builtin_clear_padding" "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/auto-init-padding-2.c b/gcc/testsuite/c-c++-common/auto-init-padding-2.c
new file mode 100644
index 000000000000..e2b50dc5ae8e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-padding-2.c
@@ -0,0 +1,114 @@
+/* To test that the compiler can fill all the paddings to zeroes for the 
+   structures when the auto variable is partially initialized,  fully 
+   initialized, or not initialized for -ftrivial-auto-var-init=zero.  */
+/* { dg-do run} */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+/* Structure with no padding. */
+struct test_packed {
+  unsigned long one;
+  unsigned long two;
+  unsigned long three;
+  unsigned long four;
+} p1;
+
+/* Simple structure with padding likely to be covered by compiler. */
+struct test_small_hole {
+  unsigned long one;
+  char two;
+  /* 3 byte padding hole here. */
+  int three;
+  unsigned long four;
+} sh1;
+
+/* Try to trigger unhandled padding in a structure. */
+struct test_aligned {
+  unsigned int internal1;
+  unsigned long long internal2;
+} __attribute__((__aligned__(64)));
+
+struct test_aligned a1;
+
+struct test_big_hole {
+  unsigned char one;
+  unsigned char two;
+  unsigned char three;
+  /* 61 byte padding hole here. */
+  struct test_aligned four;
+} __attribute__((__aligned__(64))); 
+
+struct test_big_hole bh1;
+
+struct test_trailing_hole {
+  char *one;
+  char *two;
+  char *three;
+  char four;
+  /* "sizeof(unsigned long) - 1" byte padding hole here. */
+} th1;
+
+__attribute__((noipa)) void
+foo (struct test_packed *p, struct test_small_hole *sh, struct test_aligned *a,
+     struct test_big_hole *bh, struct test_trailing_hole *th)
+{
+  p->one = 1; p->two = 2; p->three = 3; p->four = 4;
+  sh->one = 11; sh->two = 12; sh->three = 13; sh->four = 14;
+  a->internal1 = 21; a->internal2 = 22;
+  bh->one = 31; bh->two = 32; bh->three = 33;
+  bh->four.internal1 = 34; bh->four.internal2 = 35; 
+  th->one = 0; th->two = 0; th->three = 0; th->four = 44;
+}
+
+int main ()
+{
+  struct test_packed p2;
+  struct test_small_hole sh2;
+  struct test_aligned a2;
+  struct test_big_hole bh2;
+  struct test_trailing_hole th2;
+
+  struct test_packed p3 = {.one = 1};
+  struct test_small_hole sh3 = {.two = 12};
+  struct test_aligned a3 = {.internal1 = 21};
+  struct test_big_hole bh3 = {.one = 31};
+  struct test_trailing_hole th3 = {.three = 0};
+
+  struct test_packed p4 = {.one = 1, .two = 2, .three = 3, .four = 4};
+  struct test_small_hole sh4 = {.one = 11, .two = 12, .three = 13, .four = 14};
+  struct test_aligned a4 = {.internal1 = 21, .internal2 = 22};
+  struct test_big_hole bh4 = {.one = 31, .two = 32, .three = 33};
+  struct test_trailing_hole th4 = {.one = 0, .two = 0, .three = 0, .four = 44};
+
+  foo (&p1, &sh1, &a1, &bh1, &th1);
+  foo (&p2, &sh2, &a2, &bh2, &th2);
+  foo (&p3, &sh3, &a3, &bh3, &th3);
+  bh4.four.internal1 = 34; bh4.four.internal2 = 35;
+
+  __builtin_clear_padding (&p1);
+  __builtin_clear_padding (&sh1);
+  __builtin_clear_padding (&a1);
+  __builtin_clear_padding (&bh1);
+  __builtin_clear_padding (&th1);
+
+  if (__builtin_memcmp (&p1, &p2, sizeof (p1))
+      || __builtin_memcmp (&sh1, &sh2, sizeof (sh1))
+      || __builtin_memcmp (&a1, &a2, sizeof (a1))
+      || __builtin_memcmp (&bh1, &bh2, sizeof (bh1))
+      || __builtin_memcmp (&th1, &th2, sizeof (th1)))
+    __builtin_abort ();
+  if (__builtin_memcmp (&p1, &p3, sizeof (p1))
+      || __builtin_memcmp (&sh1, &sh3, sizeof (sh1))
+      || __builtin_memcmp (&a1, &a3, sizeof (a1))
+      || __builtin_memcmp (&bh1, &bh3, sizeof (bh1))
+      || __builtin_memcmp (&th1, &th3, sizeof (th1)))
+    __builtin_abort ();
+  if (__builtin_memcmp (&p1, &p4, sizeof (p1))
+      || __builtin_memcmp (&sh1, &sh4, sizeof (sh1))
+      || __builtin_memcmp (&a1, &a4, sizeof (a1))
+      || __builtin_memcmp (&bh1, &bh4, sizeof (bh1))
+      || __builtin_memcmp (&th1, &th4, sizeof (th1)))
+    __builtin_abort ();
+
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/auto-init-padding-3.c b/gcc/testsuite/c-c++-common/auto-init-padding-3.c
new file mode 100644
index 000000000000..e2c48c002c95
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/auto-init-padding-3.c
@@ -0,0 +1,114 @@
+/* To test that the compiler can fill all the paddings to zeroes for the 
+   structures when the auto variable is partially initialized,  fully 
+   initialized, or not initialized for -ftrivial-auto-var-init=pattern.  */
+/* { dg-do run} */
+/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+
+/* Structure with no padding. */
+struct test_packed {
+  unsigned long one;
+  unsigned long two;
+  unsigned long three;
+  unsigned long four;
+} p1;
+
+/* Simple structure with padding likely to be covered by compiler. */
+struct test_small_hole {
+  unsigned long one;
+  char two;
+  /* 3 byte padding hole here. */
+  int three;
+  unsigned long four;
+} sh1;
+
+/* Try to trigger unhandled padding in a structure. */
+struct test_aligned {
+  unsigned int internal1;
+  unsigned long long internal2;
+} __attribute__((__aligned__(64)));
+
+struct test_aligned a1;
+
+struct test_big_hole {
+  unsigned char one;
+  unsigned char two;
+  unsigned char three;
+  /* 61 byte padding hole here. */
+  struct test_aligned four;
+} __attribute__((__aligned__(64))); 
+
+struct test_big_hole bh1;
+
+struct test_trailing_hole {
+  char *one;
+  char *two;
+  char *three;
+  char four;
+  /* "sizeof(unsigned long) - 1" byte padding hole here. */
+} th1;
+
+__attribute__((noipa)) void
+foo (struct test_packed *p, struct test_small_hole *sh, struct test_aligned *a,
+     struct test_big_hole *bh, struct test_trailing_hole *th)
+{
+  p->one = 1; p->two = 2; p->three = 3; p->four = 4;
+  sh->one = 11; sh->two = 12; sh->three = 13; sh->four = 14;
+  a->internal1 = 21; a->internal2 = 22;
+  bh->one = 31; bh->two = 32; bh->three = 33;
+  bh->four.internal1 = 34; bh->four.internal2 = 35; 
+  th->one = 0; th->two = 0; th->three = 0; th->four = 44;
+}
+
+int main ()
+{
+  struct test_packed p2;
+  struct test_small_hole sh2;
+  struct test_aligned a2;
+  struct test_big_hole bh2;
+  struct test_trailing_hole th2;
+
+  struct test_packed p3 = {.one = 1};
+  struct test_small_hole sh3 = {.two = 12};
+  struct test_aligned a3 = {.internal1 = 21};
+  struct test_big_hole bh3 = {.one = 31};
+  struct test_trailing_hole th3 = {.three = 0};
+
+  struct test_packed p4 = {.one = 1, .two = 2, .three = 3, .four = 4};
+  struct test_small_hole sh4 = {.one = 11, .two = 12, .three = 13, .four = 14};
+  struct test_aligned a4 = {.internal1 = 21, .internal2 = 22};
+  struct test_big_hole bh4 = {.one = 31, .two = 32, .three = 33};
+  struct test_trailing_hole th4 = {.one = 0, .two = 0, .three = 0, .four = 44};
+
+  foo (&p1, &sh1, &a1, &bh1, &th1);
+  foo (&p2, &sh2, &a2, &bh2, &th2);
+  foo (&p3, &sh3, &a3, &bh3, &th3);
+  bh4.four.internal1 = 34; bh4.four.internal2 = 35;
+
+  __builtin_clear_padding (&p1);
+  __builtin_clear_padding (&sh1);
+  __builtin_clear_padding (&a1);
+  __builtin_clear_padding (&bh1);
+  __builtin_clear_padding (&th1);
+
+  if (__builtin_memcmp (&p1, &p2, sizeof (p1))
+      || __builtin_memcmp (&sh1, &sh2, sizeof (sh1))
+      || __builtin_memcmp (&a1, &a2, sizeof (a1))
+      || __builtin_memcmp (&bh1, &bh2, sizeof (bh1))
+      || __builtin_memcmp (&th1, &th2, sizeof (th1)))
+    __builtin_abort ();
+  if (__builtin_memcmp (&p1, &p3, sizeof (p1))
+      || __builtin_memcmp (&sh1, &sh3, sizeof (sh1))
+      || __builtin_memcmp (&a1, &a3, sizeof (a1))
+      || __builtin_memcmp (&bh1, &bh3, sizeof (bh1))
+      || __builtin_memcmp (&th1, &th3, sizeof (th1)))
+    __builtin_abort ();
+  if (__builtin_memcmp (&p1, &p4, sizeof (p1))
+      || __builtin_memcmp (&sh1, &sh4, sizeof (sh1))
+      || __builtin_memcmp (&a1, &a4, sizeof (a1))
+      || __builtin_memcmp (&bh1, &bh4, sizeof (bh1))
+      || __builtin_memcmp (&th1, &th4, sizeof (th1)))
+    __builtin_abort ();
+
+
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C
new file mode 100644
index 000000000000..43002235a53c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-1_a.C
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
+#include "uninit-pred-1_a.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C
new file mode 100644
index 000000000000..5551060b1225
--- /dev/null
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-2_a.C
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
+#include "uninit-pred-2_a.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C
new file mode 100644
index 000000000000..d6ab4f0b6beb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-3_a.C
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-Wuninitialized -O2 -ftrivial-auto-var-init=zero" } */
+#include "uninit-pred-3_a.C"
diff --git a/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C b/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C
new file mode 100644
index 000000000000..4747d283d31c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/auto-init-uninit-pred-4.C
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-Wuninitialized -Og -ftrivial-auto-var-init=zero" } */
+#include "uninit-pred-4.C"
diff --git a/gcc/testsuite/gcc.dg/auto-init-sra-1.c b/gcc/testsuite/gcc.dg/auto-init-sra-1.c
new file mode 100644
index 000000000000..88fd66678f29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-sra-1.c
@@ -0,0 +1,24 @@
+/* Verify that SRA total scalarization will not be confused by padding
+   and also not confused by auto initialization.  */
+/* { dg-do compile } */
+/* { dg-options "-O1 --param sra-max-scalarization-size-Ospeed=16 -fdump-tree-release_ssa -ftrivial-auto-var-init=zero" } */
+
+struct S
+{
+  int i;
+  unsigned short f1;
+  char f2;
+  unsigned short f3, f4;
+};
+
+
+int foo (struct S *p)
+{
+  struct S l;
+
+  l = *p;
+  l.i++;
+  *p = l;
+}
+
+/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa" } } */
diff --git a/gcc/testsuite/gcc.dg/auto-init-sra-2.c b/gcc/testsuite/gcc.dg/auto-init-sra-2.c
new file mode 100644
index 000000000000..d260f5ae934e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-sra-2.c
@@ -0,0 +1,24 @@
+/* Verify that SRA total scalarization will not be confused by padding
+   and also not confused by auto initialization.  */
+/* { dg-do compile } */
+/* { dg-options "-O1 --param sra-max-scalarization-size-Ospeed=16 -fdump-tree-release_ssa -ftrivial-auto-var-init=pattern" } */
+
+struct S
+{
+  int i;
+  unsigned short f1;
+  char f2;
+  unsigned short f3, f4;
+};
+
+
+int foo (struct S *p)
+{
+  struct S l;
+
+  l = *p;
+  l.i++;
+  *p = l;
+}
+
+/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa" } } */
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-1.c b/gcc/testsuite/gcc.dg/auto-init-uninit-1.c
new file mode 100644
index 000000000000..502db591222a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-1.c
@@ -0,0 +1,5 @@
+/* Spurious uninitialized variable warnings, case 1.
+   Taken from cppfiles.c (merge_include_chains) */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-1.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-12.c b/gcc/testsuite/gcc.dg/auto-init-uninit-12.c
new file mode 100644
index 000000000000..65da110f5566
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-12.c
@@ -0,0 +1,4 @@
+/* PR 23497 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-12.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-13.c b/gcc/testsuite/gcc.dg/auto-init-uninit-13.c
new file mode 100644
index 000000000000..87dd8b587e00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-13.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+typedef _Complex float C;
+C foo()
+{
+  C f;
+  __imag__ f = 0;
+  return f;	/* { dg-warning "is used" "unconditional" } */
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-14.c b/gcc/testsuite/gcc.dg/auto-init-uninit-14.c
new file mode 100644
index 000000000000..9ffe00a67e50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-14.c
@@ -0,0 +1,4 @@
+/* PR 24931 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-14.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-15.c b/gcc/testsuite/gcc.dg/auto-init-uninit-15.c
new file mode 100644
index 000000000000..121f0cff274a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-15.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/17506
+   We issue an uninitialized variable warning at a wrong location at
+   line 11, which is very confusing.  Make sure we print out a note to
+   make it less confusing.  (not xfailed alternative)
+   But it is of course ok if we warn in bar about uninitialized use
+   of j.  (not xfailed alternative)  */
+/* { dg-do compile } */
+/* { dg-options "-O1 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+inline int
+foo (int i)
+{
+  if (i) /* { dg-warning "used uninitialized" } */
+    return 1;
+  return 0;
+}
+
+void baz (void);
+
+void
+bar (void)
+{
+  int j; /* { dg-message "note: 'j' was declared here" "" } */
+  for (; foo (j); ++j)  /* { dg-warning "'j' is used uninitialized" "" { xfail *-*-* } } */
+    baz ();
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-16.c b/gcc/testsuite/gcc.dg/auto-init-uninit-16.c
new file mode 100644
index 000000000000..38e19502a679
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-16.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
+
+int foo, bar;
+
+static
+void decode_reloc(int reloc, int *is_alt)
+{
+  if (reloc >= 20)
+      *is_alt = 1;
+  else if (reloc >= 10)
+      *is_alt = 0;
+}
+
+void testfunc()
+{
+  int alt_reloc;
+
+  decode_reloc(foo, &alt_reloc);
+
+  if (alt_reloc) /* { dg-warning "may be used uninitialized" "" { xfail *-*-* }  }  */
+    bar = 42;
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-17.c b/gcc/testsuite/gcc.dg/auto-init-uninit-17.c
new file mode 100644
index 000000000000..9eec9440c75e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-17.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+typedef _Complex float C;
+C foo(int cond)
+{
+  C f;
+  __imag__ f = 0;
+  if (cond)
+    {
+      __real__ f = 1;
+      return f;
+    }
+  return f;	/* { dg-warning "may be used" "unconditional" } */
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-18.c b/gcc/testsuite/gcc.dg/auto-init-uninit-18.c
new file mode 100644
index 000000000000..1c9afa928c8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-18.c
@@ -0,0 +1,3 @@
+/* { dg-do compile }  */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-18.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-19.c b/gcc/testsuite/gcc.dg/auto-init-uninit-19.c
new file mode 100644
index 000000000000..38d27e4f9548
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-19.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+/* { dg-additional-options "-finline-small-functions" { target avr-*-* } } */
+
+int a, l, m;
+float *b;
+float c, d, e, g, h;
+unsigned char i, k;
+void
+fn1 (int p1, float *f1, float *f2, float *f3, unsigned char *c1, float *f4,
+     unsigned char *c2, float *p10)
+{
+  if (p1 & 8)
+    b[3] = p10[a];
+  /* { dg-warning "may be used uninitialized" "" { target { { nonpic || pie_enabled } || { hppa*64*-*-* *-*-darwin* } } } .-1 } */
+}
+
+void
+fn2 ()
+{
+  float *n;
+  if (l & 6)
+    n = &c + m;
+  fn1 (l, &d, &e, &g, &i, &h, &k, n);
+  /* { dg-warning "may be used uninitialized" "" { target { ! { { nonpic || pie_enabled } || { hppa*64*-*-* *-*-darwin* } } } } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-2.c b/gcc/testsuite/gcc.dg/auto-init-uninit-2.c
new file mode 100644
index 000000000000..4c32dc86397e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-2.c
@@ -0,0 +1,5 @@
+/* Spurious uninitialized variable warnings, case 2.
+   Taken from cpphash.c (macroexpand) */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-2.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-20.c b/gcc/testsuite/gcc.dg/auto-init-uninit-20.c
new file mode 100644
index 000000000000..d81957e5bb94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-20.c
@@ -0,0 +1,4 @@
+/* Spurious uninitialized variable warnings, from gdb */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-20.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-21.c b/gcc/testsuite/gcc.dg/auto-init-uninit-21.c
new file mode 100644
index 000000000000..cc6174607367
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-21.c
@@ -0,0 +1,4 @@
+/* PR69537, spurious warning because of a missed optimization. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-short-enums -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-21.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-22.c b/gcc/testsuite/gcc.dg/auto-init-uninit-22.c
new file mode 100644
index 000000000000..1e522ce54255
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-22.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -Wuninitialized --param vect-max-version-for-alias-checks=20 -ftrivial-auto-var-init=zero" } */
+#include "uninit-22.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-23.c b/gcc/testsuite/gcc.dg/auto-init-uninit-23.c
new file mode 100644
index 000000000000..f1f783973ae4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-23.c
@@ -0,0 +1,27 @@
+/* PR tree-optimization/78455 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+int ij;
+
+void
+ql (void)
+{
+  int m5 = 0;
+
+  for (;;)
+  {
+    if (0)
+      for (;;)
+      {
+        int *go;
+        int *t4 = go; /* { dg-warning "is used uninitialized" } */
+
+ l1:
+        *t4 = (*t4 != 0) ? 0 : 2; /* { dg-warning "is used uninitialized" } */
+      }
+
+    if (ij != 0)
+      goto l1;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-24.c b/gcc/testsuite/gcc.dg/auto-init-uninit-24.c
new file mode 100644
index 000000000000..0f839ba9efa8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-24.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-24.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-25.c b/gcc/testsuite/gcc.dg/auto-init-uninit-25.c
new file mode 100644
index 000000000000..f36d95f9d279
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-25.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */
+
+extern unsigned bar (void);
+extern void quux (void);
+
+unsigned foo (unsigned v)
+{
+  unsigned u;
+  if (v != 1)
+    u = bar ();
+
+  // Prevent the "dom" pass from changing the CFG layout based on the inference
+  // 'if (v != 1) is false then (v != 2) is true'.  (Now it would have to
+  // duplicate the loop in order to do so, which is deemed expensive.)
+  for (int i = 0; i < 10; i++)
+    quux ();
+
+  if (v != 2)
+    return u;       /* { dg-warning "may be used uninitialized" } */
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-26.c b/gcc/testsuite/gcc.dg/auto-init-uninit-26.c
new file mode 100644
index 000000000000..ae97ecfa71e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-26.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wmaybe-uninitialized -ftrivial-auto-var-init=zero" } */
+
+extern unsigned bar (void);
+extern void quux (void);
+
+unsigned foo (unsigned v)
+{
+  unsigned u;
+  if (v != 100)
+    u = bar ();
+
+  // Prevent the "dom" pass from changing the CFG layout based on the inference
+  // 'if (v != 100) is false then (v < 105) is true'.  (Now it would have to
+  // duplicate the loop in order to do so, which is deemed expensive.)
+  for (int i = 0; i < 10; i++)
+    quux ();
+
+  if (v < 105) /* v == 100 falls into this range.  */
+    return u;       /* { dg-warning "may be used uninitialized" }  */
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-3.c b/gcc/testsuite/gcc.dg/auto-init-uninit-3.c
new file mode 100644
index 000000000000..5c109202a5ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-3.c
@@ -0,0 +1,5 @@
+/* Spurious uninit variable warnings, case 3.
+   Inspired by cppexp.c (parse_charconst) */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-3.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-34.c b/gcc/testsuite/gcc.dg/auto-init-uninit-34.c
new file mode 100644
index 000000000000..1a687654ebb7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-34.c
@@ -0,0 +1,60 @@
+/* PR middle-end/10138 - warn for uninitialized arrays passed as const*
+   arguments
+   Verify that passing pointers to uninitialized objects to arguments
+   to functions declared with attribute access is diagnosed where expected.
+   { dg-do compile }
+   { dg-options "-O -Wall -ftrivial-auto-var-init=zero" } */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
+
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+
+RW (1) RW (3) void
+f4pi (int*, int*, int*, int*);    // { dg-message "in a call to 'f4pi' declared with attribute 'access \\\(read_write, \[13\]\\\)'" }
+
+
+void nowarn_scalar (void)
+{
+  int i1 = 0, i2, i3 = 1, i4;
+  f4pi (&i1, &i2, &i3, &i4);
+}
+
+void warn_scalar_1 (void)
+{
+  int i1;                         // { dg-message "declared here" "" { xfail *-*-* } }
+  int i2, i3 = 1, i4;
+
+  f4pi (&i1, &i2, &i3, &i4);      // { dg-warning "'i1' may be used uninitialized" "" { xfail *-*-* } }
+}
+
+void warn_scalar_2 (void)
+{
+  int j1 = 0, j2, j4;
+  int j3;
+
+  f4pi (&j1, &j2, &j3, &j4);      // { dg-warning "'j3' may be used uninitialized" "" { xfail *-*-* } }
+}
+
+
+void nowarn_array_init (void)
+{
+  int a1[4] = { 0 }, a2[5], a3[6] = { 0 }, a4[7];
+
+  f4pi (a1, a2, a3, a4);
+}
+
+void warn_array_1 (void)
+{
+  int a1[4];                  // { dg-message "'a1' declared here" }
+  int a2[5], a3[6] = { 0 }, a4[7];
+
+  f4pi (a1, a2, a3, a4);      // { dg-warning "'a1' may be used uninitialized" }
+}
+
+void warn_array_2 (void)
+{
+  int a1[4] = { 0 }, a2[5], a4[7];
+  int a3[6];                  // { dg-message "'a3' declared here" }
+
+  f4pi (a1, a2, a3, a4);      // { dg-warning "'a3' may be used uninitialized" }
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-36.c b/gcc/testsuite/gcc.dg/auto-init-uninit-36.c
new file mode 100644
index 000000000000..64377d380ee9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-36.c
@@ -0,0 +1,238 @@
+/* PR middle-end/10138 - warn for uninitialized arrays passed as const*
+   arguments
+   Verify that passing pointers to uninitialized objects to const
+   arguments to built-ins is diagnosed where expected.
+   { dg-do compile }
+   { dg-options "-O -Wall -ftrivial-auto-var-init=zero" }
+   { dg-require-effective-target alloca } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* alloca (size_t);
+void* malloc (size_t);
+void* realloc (void*, size_t);
+
+void* memcpy (void*, const void*, size_t);
+char* strcpy (char*, const char*);
+size_t strlen (const char*);
+
+void sink (void*);
+
+void nowarn_array_memcpy (void *d, unsigned n)
+{
+  int a[2];
+  /* Diagnose this?  */
+  memcpy (d, a, n /* Non-constant to avoid folding into MEM_REF.  */);
+}
+
+void nowarn_array_plus_cst_memcpy (void *d, unsigned n)
+{
+  int a[3];
+  /* Diagnose this?  */
+  memcpy (d, a + 1, n);
+}
+
+void nowarn_array_plus_var_memcpy (void *d, unsigned n, int i)
+{
+  int a[4];
+  /* Diagnose this?  */
+  memcpy (d, a + i, n);
+}
+
+void nowarn_array_assign_memcpy (char *d, unsigned n)
+{
+  int a[3];
+  a[1] = 3;
+  memcpy (d, a, n);
+}
+
+void nowarn_array_init_memcpy (char *d, unsigned n)
+{
+  int a[4] = { 0 };
+  memcpy (d, a, n);
+}
+
+void nowarn_array_compound_memcpy (void *d, unsigned n)
+{
+  memcpy (d, (int[2]){ 0 }, n);
+}
+
+void nowarn_struct_assign_memcpy (void *d, unsigned n)
+{
+  struct S { int a, b, c, d; } s;
+  s.b = 1;
+  s.d = 2;
+  memcpy (d, &s, n);
+}
+
+
+void nowarn_array_init_strcpy (char *d[], unsigned n)
+{
+  char a[8] = "012";
+
+  strcpy (d[0], a);
+  strcpy (d[1], a + 1);
+  strcpy (d[1], a + 2);
+  strcpy (d[1], a + 3);
+  strcpy (d[1], a + 4);
+  strcpy (d[1], a + 5);
+  strcpy (d[1], a + 6);
+  strcpy (d[1], a + 7);
+}
+
+
+void nowarn_array_assign_strcpy (char *d[], unsigned n)
+{
+  char a[8];
+  a[0] = '0';
+  a[1] = '1';
+  a[2] = '2';
+  a[3] = '\0';
+
+  strcpy (d[0], a);
+  strcpy (d[1], a + 1);
+  strcpy (d[1], a + 2);
+  strcpy (d[1], a + 3);
+}
+
+void warn_array_plus_cst_strcpy (char *d, unsigned n)
+{
+  char a[8];
+  a[0] = '1';
+  a[1] = '2';
+  a[2] = '3';
+  a[3] = '\0';
+
+  strcpy (d, a + 4);          // { dg-warning "\\\[-Wuninitialized" }
+  strcpy (d, a + 5);          // { dg-warning "\\\[-Wuninitialized" }
+  strcpy (d, a + 6);          // { dg-warning "\\\[-Wuninitialized" }
+  strcpy (d, a + 7);          // { dg-warning "\\\[-Wuninitialized" }
+}
+
+void nowarn_array_plus_var_strcpy (char *d, int i)
+{
+  char a[8];
+  a[0] = '1';
+  a[1] = '2';
+  a[2] = '3';
+  a[3] = '\0';
+
+  strcpy (d, a + i);
+}
+
+
+size_t nowarn_array_assign_strlen (const char *s)
+{
+  char a[8];
+  a[0] = s[0];
+  a[1] = s[1];
+  a[2] = s[2];
+  a[3] = s[3];
+
+  size_t n = 0;
+
+  n += strlen (a);
+  n += strlen (a + 1);
+  n += strlen (a + 2);
+  n += strlen (a + 3);
+  return n;
+}
+
+size_t warn_array_plus_cst_strlen (const char *s)
+{
+  char a[8];
+  a[0] = s[0];
+  a[1] = s[1];
+  a[2] = s[2];
+  a[3] = s[3];
+
+  return strlen (a + 4);      // { dg-warning "\\\[-Wuninitialized" }
+}
+
+size_t nowarn_array_plus_var_strlen (const char *s, int i)
+{
+  char a[8];
+  a[0] = s[0];
+  a[1] = s[1];
+  a[2] = s[2];
+  a[3] = s[3];
+
+  return strlen (a + i);
+}
+
+
+size_t nowarn_alloca_assign_strlen (int i)
+{
+  char *p = (char*)alloca (8);
+  p[i] = '\0';
+  return strlen (p);
+}
+
+size_t nowarn_alloca_escape_strlen (int i)
+{
+  char *p = (char*)alloca (8);
+  sink (p);
+  return strlen (p);
+}
+
+size_t warn_alloca_strlen (void)
+{
+  char *p = (char*)alloca (8);
+  return strlen (p);          // { dg-warning "\\\[-Wuninitialized" }
+}
+
+
+size_t nowarn_malloc_assign_strlen (int i)
+{
+  char *p = (char*)malloc (8);
+  p[i] = '\0';
+  return strlen (p);
+}
+
+size_t nowarn_malloc_escape_strlen (int i)
+{
+  char *p = (char*)malloc (8);
+  sink (p);
+  return strlen (p);
+}
+
+size_t warn_malloc_strlen (void)
+{
+  char *p = (char*)malloc (8);
+  return strlen (p);          // { dg-warning "\\\[-Wuninitialized" }
+}
+
+
+size_t nowarn_realloc_strlen (void *p)
+{
+  char *q = (char*)realloc (p, 8);
+  return strlen (q);
+}
+
+
+size_t nowarn_vla_assign_strlen (int n, int i)
+{
+  char vla[n];
+  vla[i] = '\0';
+  return strlen (vla);
+}
+
+size_t nowarn_vla_strcpy_strlen (int n, const char *s, int i)
+{
+  char vla[n];
+  strcpy (vla, s);
+  return strlen (vla + i);
+}
+
+size_t nowarn_vla_escape_strlen (int n, int i)
+{
+  char vla[n];
+  sink (vla);
+  return strlen (vla);
+}
+
+size_t warn_vla_strlen (unsigned n)
+{
+  char vla[n];
+  return strlen (vla);        // { dg-warning "\\\[-Wuninitialized" }
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-37.c b/gcc/testsuite/gcc.dg/auto-init-uninit-37.c
new file mode 100644
index 000000000000..2791b37ca009
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-37.c
@@ -0,0 +1,156 @@
+/* PR middle-end/10138 - warn for uninitialized arrays passed as const arguments
+   Verify that -Wuninitialized and -Wmaybe-uninitialized trigger (or don't)
+   when passing uninitialized variables by reference to functions declared
+   with or without attribute access and with (or without) const qualified
+   arguments of array, VLA, or pointer types.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -ftrack-macro-expansion=0 -ftrivial-auto-var-init=zero" } */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
+
+#define NONE    /* none */
+#define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+#define WO(...) __attribute__ ((access (write_only, __VA_ARGS__)))
+#define X(...)  __attribute__ ((access (none, __VA_ARGS__)))
+
+#define CONCAT(x, y) x ## y
+#define CAT(x, y)    CONCAT (x, y)
+#define UNIQ(pfx)    CAT (pfx, __LINE__)
+
+extern void sink (void*);
+
+
+#define T1(attr, name, type)			\
+  void UNIQ (CAT (test_, name))(void) {		\
+    extern attr void UNIQ (name)(type);		\
+    int x;					\
+    UNIQ (name)(&x);				\
+    sink (&x);					\
+  }
+
+#define T2(attr, name, types)			\
+  void UNIQ (CAT (test_, name))(void) {		\
+    extern attr void UNIQ (name)(types);	\
+    int x;					\
+    UNIQ (name)(1, &x);				\
+    sink (&x);					\
+  }
+
+
+typedef int IA_[];
+typedef const int CIA_[];
+
+T1 (NONE,   fia_,   IA_);
+T1 (NONE,   fcia_,  CIA_);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froia_, IA_);     // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwia_, IA_);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (WO (1), fwoia_, IA_);
+T1 (X (1),  fxia_,  IA_);
+
+
+typedef int IA1[1];
+typedef const int CIA1[1];
+
+T1 (NONE,   fia1,   IA1);
+T1 (NONE,   fcia1,  CIA1);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froia1, IA1);     // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwia1, IA1);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (WO (1), fwoia1, IA1);
+T1 (X (1),  fxia1,  IA1);
+
+
+#define IARS1  int[restrict static 1]
+#define CIARS1 const int[restrict static 1]
+
+T1 (NONE,   fiars1,   IARS1);
+T1 (NONE,   fciars1,  CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (WO (1), fwoiars1, IARS1);
+T1 (X (1),  fxiars1,  IARS1);
+
+
+#define IAS1  int[static 1]
+#define CIAS1 const int[static 1]
+
+T1 (NONE,   fias1,   IAS1);
+T1 (NONE,   fcias1,  CIAS1);   // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froias1, IAS1);    // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwias1, IAS1);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (WO (1), fwoias1, IAS1);
+T1 (X (1),  fxias1,  IAS1);
+
+
+#define IAX  int[*]
+#define CIAX const int[*]
+
+T1 (NONE,   fiax,   IAX);
+T1 (NONE,   fciax,  CIAX);    // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froiax, IAX);     // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwiax, IAX);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (WO (1), fwoiax, IAX);
+T1 (X (1),  fxiax,  IAX);
+
+
+#define IAN  int n, int[n]
+#define CIAN int n, const int[n]
+
+T2 (NONE,      fian,   IAN);
+T2 (NONE,      fcian,  CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T2 (RO (2, 1), froian, IAN);  // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T2 (RW (2, 1), frwian, IAN);  // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T2 (WO (2, 1), fwoian, IAN);
+T2 (X (2, 1),  fxian,  IAN);
+
+
+typedef int* IP;
+typedef const int* CIP;
+
+T1 (NONE,   fip,   IP);
+T1 (NONE,   fcip,  CIP);     // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (RO (1), froip, IP);      // { dg-warning "\\\[-Wuninitialized" "" { xfail *-*-* } }
+T1 (RW (1), frwip, IP);      // { dg-warning "\\\[-Wmaybe-uninitialized" "" { xfail *-*-* } }
+T1 (WO (1), fwoip, IP);
+T1 (X (1),  fxip,  IP);
+
+
+/* Verify that the notes printed after the warning mention attribute
+   access only when the attribute is explicitly used in the declaration
+   and not otherwise.  */
+
+void test_note_cst_restrict (void)
+{
+  extern void
+    fccar (const char[restrict]);   // { dg-message "by argument 1 of type 'const char\\\[restrict]' to 'fccar'" "note" }
+
+  char a[1];                  // { dg-message "'a' declared here" "note" }
+  fccar (a);                  // { dg-warning "'a' may be used uninitialized" }
+}
+
+void test_note_vla (int n)
+{
+  extern void
+    fccvla (const char[n]);   // { dg-message "by argument 1 of type 'const char\\\[n]' to 'fccvla'" "note" }
+
+  char a[2];                  // { dg-message "'a' declared here" "note" }
+  fccvla (a);                 // { dg-warning "'a' may be used uninitialized" }
+}
+
+void test_note_ro (void)
+{
+  extern RO (1) void
+    frocar (char[restrict]);  // { dg-message "in a call to 'frocar' declared with attribute 'access \\\(read_only, 1\\\)'" "note" }
+
+  char a[3];                  // { dg-message "'a' declared here" "note" }
+  frocar (a);                 // { dg-warning "'a' is used uninitialized" }
+}
+
+void test_note_rw (void)
+{
+  extern RW (1) void
+    frwcar (char[restrict]);  // { dg-message "in a call to 'frwcar' declared with attribute 'access \\\(read_write, 1\\\)'" "note" }
+
+  char a[4];                  // { dg-message "'a' declared here" "note" }
+  frwcar (a);                 // { dg-warning "'a' may be used uninitialized" }
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-4.c b/gcc/testsuite/gcc.dg/auto-init-uninit-4.c
new file mode 100644
index 000000000000..29ec860f0ed8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-4.c
@@ -0,0 +1,10 @@
+/* Spurious uninit variable warnings, case 4.
+   Simplified version of cppexp.c (cpp_parse_expr).
+
+   This one is really fragile, it gets it right if you take out case
+   1, or if the structure is replaced by an int, or if the structure
+   has fewer members (!) */
+
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-4.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-5.c b/gcc/testsuite/gcc.dg/auto-init-uninit-5.c
new file mode 100644
index 000000000000..65b251a2185f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-5.c
@@ -0,0 +1,6 @@
+/* Spurious uninitialized-variable warnings.  */
+/* Disable jump threading, etc to test compiler analysis.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -fno-tree-dce -fno-tree-vrp -fno-tree-dominator-opts -ftrivial-auto-var-init=zero" } */
+
+#include "uninit-5.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-6.c b/gcc/testsuite/gcc.dg/auto-init-uninit-6.c
new file mode 100644
index 000000000000..7c10dfc5895b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-6.c
@@ -0,0 +1,7 @@
+/* Spurious uninitialized variable warnings.
+   This one inspired by java/class.c:build_utf8_ref.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+#include "uninit-6.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-8.c b/gcc/testsuite/gcc.dg/auto-init-uninit-8.c
new file mode 100644
index 000000000000..eaa9c0c9093f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-8.c
@@ -0,0 +1,8 @@
+/* Uninitialized variable warning tests...
+   Inspired by part of optabs.c:expand_binop.
+   May be the same as uninit-1.c.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+#include "uninit-8.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-9.c b/gcc/testsuite/gcc.dg/auto-init-uninit-9.c
new file mode 100644
index 000000000000..6dccf014fe2b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-9.c
@@ -0,0 +1,8 @@
+/* Spurious uninitialized variable warnings.  Slight variant on the
+   documented case, inspired by reg-stack.c:record_asm_reg_life.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+/* { dg-require-effective-target alloca } */
+
+#include "uninit-9.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-A.c b/gcc/testsuite/gcc.dg/auto-init-uninit-A.c
new file mode 100644
index 000000000000..0ef1d92a7473
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-A.c
@@ -0,0 +1,7 @@
+/* Inspired by part of java/parse.y.
+   May be a real bug in CSE. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -ftrivial-auto-var-init=zero" } */
+
+#include "uninit-A.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-B.c b/gcc/testsuite/gcc.dg/auto-init-uninit-B.c
new file mode 100644
index 000000000000..b6d3efdfb880
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-B.c
@@ -0,0 +1,17 @@
+/* Origin: PR c/179 from Gray Watson <gray@256.com>, adapted as a testcase
+   by Joseph Myers <jsm28@cam.ac.uk>.  */
+/* -ftrivial-auto-var-init will make the uninitialized warning for address
+   taken auto var going away, FIXME later.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+extern void foo (int *);
+extern void bar (int);
+
+void
+baz (void)
+{
+  int i;
+  if (i) /* { dg-warning "is used uninitialized" "uninit i warning" { xfail *-*-* } }  */
+    bar (i);
+  foo (&i);
+}
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-C.c b/gcc/testsuite/gcc.dg/auto-init-uninit-C.c
new file mode 100644
index 000000000000..be1979626447
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-C.c
@@ -0,0 +1,5 @@
+/* Spurious uninitialized variable warning, inspired by libgcc2.c.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */
+
+#include "uninit-C.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-H.c b/gcc/testsuite/gcc.dg/auto-init-uninit-H.c
new file mode 100644
index 000000000000..e442fab00be6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-H.c
@@ -0,0 +1,5 @@
+/* PR 14204 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wall -Werror -ftrivial-auto-var-init=zero" } */
+
+#include "uninit-H.c"
diff --git a/gcc/testsuite/gcc.dg/auto-init-uninit-I.c b/gcc/testsuite/gcc.dg/auto-init-uninit-I.c
new file mode 100644
index 000000000000..4f9ae6cd98cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/auto-init-uninit-I.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized -ftrivial-auto-var-init=zero" } */
+#include "uninit-H.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-1.c b/gcc/testsuite/gcc.target/aarch64/auto-init-1.c
new file mode 100644
index 000000000000..0fa470880bf5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-1.c
@@ -0,0 +1,32 @@
+/* Verify zero initialization for integer and pointer type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+enum E {
+  N1 = 0,
+  N2,
+  N3
+};
+
+extern void bar (char, short, int, enum E, long, long long, int *, bool);
+
+void foo()
+{
+  char temp1;
+  short temp2;
+  int temp3;
+  enum E temp4;
+  long temp5;
+  long long temp6;
+  int *temp7;
+  bool temp8;
+
+  bar (temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8);
+  return;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0" 11 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-2.c b/gcc/testsuite/gcc.target/aarch64/auto-init-2.c
new file mode 100644
index 000000000000..2c54e6d60382
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-2.c
@@ -0,0 +1,35 @@
+/* Verify pattern initialization for integer and pointer type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-O -ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+enum E {
+  N1 = 0,
+  N2,
+  N3
+};
+
+extern void bar (char, short, int, enum E, long, long long, int *, bool);
+
+void foo()
+{
+  char temp1;
+  short temp2;
+  int temp3;
+  enum E temp4;
+  long temp5;
+  long long temp6;
+  int *temp7;
+  bool temp8;
+
+  bar (temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8);
+  return;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfe\\\]" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffefe" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffefefefe" 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefe" 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-3.c b/gcc/testsuite/gcc.target/aarch64/auto-init-3.c
new file mode 100644
index 000000000000..7008f76b294c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-3.c
@@ -0,0 +1,19 @@
+/* Verify zero initialization for floating point type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+long double result;
+
+long double foo()
+{
+  float temp1;
+  double temp2;
+  long double temp3;
+  
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_double\:SF 0\.0" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_double\:DF 0\.0" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_double\:TF 0\.0" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-4.c b/gcc/testsuite/gcc.target/aarch64/auto-init-4.c
new file mode 100644
index 000000000000..10197045b4cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-4.c
@@ -0,0 +1,19 @@
+/* Verify pattern initialization for floating point type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-O -ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+long double result;
+
+long double foo()
+{
+  float temp1;
+  double temp2;
+  long double temp3;
+  
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump "\\-0x0\\.fefefep\\+127" "expand" } } */
+/* { dg-final { scan-rtl-dump "\\-0x0\\.f7f7f7f7f7f7fp\\+1009" "expand" } } */
+/* { dg-final { scan-rtl-dump "\\-0x0\\.ff7f7f7f7f7f7f7f7f7f7f7f7f7fp\\+16128" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-5.c b/gcc/testsuite/gcc.target/aarch64/auto-init-5.c
new file mode 100644
index 000000000000..ac69ac3df82e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-5.c
@@ -0,0 +1,19 @@
+/* Verify zero initialization for complex type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+
+_Complex long double result;
+
+_Complex long double foo()
+{
+  _Complex float temp1;
+  _Complex double temp2;
+  _Complex long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-assembler-times "\.word\t0" 14 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-6.c b/gcc/testsuite/gcc.target/aarch64/auto-init-6.c
new file mode 100644
index 000000000000..27c16b336789
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-6.c
@@ -0,0 +1,18 @@
+/* Verify pattern initialization for complex type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+
+_Complex long double result;
+
+_Complex long double foo()
+{
+  _Complex float temp1;
+  _Complex double temp2;
+  _Complex long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 3 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-7.c b/gcc/testsuite/gcc.target/aarch64/auto-init-7.c
new file mode 100644
index 000000000000..ac27fbe92f4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-7.c
@@ -0,0 +1,32 @@
+/* Verify zero initialization for array, union, and structure type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+struct S
+{
+  int f1;
+  float f2;
+  char f3[20];
+};
+
+union U
+{
+  char u1[5];
+  int u2;
+  float u3; 
+};
+
+double result;
+
+double foo()
+{
+  int temp1[3];
+  double temp2[3];
+  struct S temp3;
+  union U temp4;
+  
+  result = temp1[2] + temp2[1] + temp3.f2 + temp4.u3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0" 8 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-8.c b/gcc/testsuite/gcc.target/aarch64/auto-init-8.c
new file mode 100644
index 000000000000..3943f5a4d6b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-8.c
@@ -0,0 +1,32 @@
+/* Verify pattern initialization for array, union, and structure type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct S
+{
+  int f1;
+  float f2;
+  char f3[20];
+};
+
+union U
+{
+  char u1[5];
+  int u2;
+  float u3; 
+};
+
+double result;
+
+double foo()
+{
+  int temp1[3];
+  double temp2[3];
+  struct S temp3;
+  union U temp4;
+  
+  result = temp1[2] + temp2[1] + temp3.f2 + temp4.u3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 4 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-1.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-1.c
new file mode 100644
index 000000000000..d3a88c724545
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-1.c
@@ -0,0 +1,17 @@
+/* Verify zero initialization for structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_aligned {
+        int internal1;
+        long long internal2;
+} __attribute__ ((aligned(64)));
+
+int foo ()
+{
+  struct test_aligned var;
+  return var.internal1;
+}
+
+/* { dg-final { scan-assembler-times "stp\tq0, q0," 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-10.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-10.c
new file mode 100644
index 000000000000..b0f3acb2f528
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-10.c
@@ -0,0 +1,22 @@
+/* Verify pattern initialization for array type with structure element with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+
+int foo ()
+{
+  struct test_trailing_hole var[10]; 
+  return var[2].four;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-11.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-11.c
new file mode 100644
index 000000000000..02f7edc51008
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-11.c
@@ -0,0 +1,27 @@
+/* Verify zero initialization for union type with structure field with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+union test_union_padding {
+  struct test_trailing_hole u1;
+  long long u2;
+};
+
+
+int foo ()
+{
+  union test_union_padding var;
+  return var.u1.four;
+}
+
+/* { dg-final { scan-assembler "stp\txzr, xzr," } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-12.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-12.c
new file mode 100644
index 000000000000..555972f1728f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-12.c
@@ -0,0 +1,27 @@
+/* Verify pattern initialization for union type with structure field with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+union test_union_padding {
+  struct test_trailing_hole u1;
+  long long u2;
+};
+
+
+int foo ()
+{
+  union test_union_padding var;
+  return var.u1.four;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-2.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-2.c
new file mode 100644
index 000000000000..aceceb87fbe1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-2.c
@@ -0,0 +1,18 @@
+/* Verify pattern initialization for structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+
+struct test_aligned {
+        int internal1;
+        long long internal2;
+} __attribute__ ((aligned(64)));
+
+int foo ()
+{
+  struct test_aligned var;
+  return var.internal1;
+}
+
+/* { dg-final { scan-assembler-times "stp\tq0, q0," 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-3.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-3.c
new file mode 100644
index 000000000000..085c38629210
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-3.c
@@ -0,0 +1,27 @@
+/* Verify zero initialization for nested structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_aligned {
+        unsigned internal1;
+        unsigned long long internal2;
+} __attribute__ ((aligned(64)));
+
+struct test_big_hole {
+        char one;
+        char two;
+        char three;
+        /* 61 byte padding hole here. */
+        struct test_aligned four;
+} __attribute__ ((aligned(64)));
+
+
+int foo ()
+{
+  struct test_big_hole var;
+  return var.four.internal1;
+}
+
+/* { dg-final { scan-assembler-times "stp\tq0, q0," 4 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-4.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-4.c
new file mode 100644
index 000000000000..7a6ddbc20ee1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-4.c
@@ -0,0 +1,27 @@
+/* Verify pattern initialization for nested structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+
+struct test_aligned {
+        unsigned internal1;
+        unsigned long long internal2;
+} __attribute__ ((aligned(64)));
+
+struct test_big_hole {
+        char one;
+        char two;
+        char three;
+        /* 61 byte padding hole here. */
+        struct test_aligned four;
+} __attribute__ ((aligned(64)));
+
+
+int foo ()
+{
+  struct test_big_hole var;
+  return var.four.internal1;
+}
+
+/* { dg-final { scan-assembler-times "stp\tq0, q0," 5 } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-5.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-5.c
new file mode 100644
index 000000000000..3c45a6c6288d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-5.c
@@ -0,0 +1,22 @@
+/* Verify zero initialization for structure type automatic variables with
+   tail padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_trailing_hole {
+        char *one;
+        char *two;
+        char *three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var;
+  return var.four;
+}
+
+/* { dg-final { scan-assembler-times "stp\txzr, xzr," 2 } } */
+
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-6.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-6.c
new file mode 100644
index 000000000000..bfef23d52a10
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-6.c
@@ -0,0 +1,20 @@
+/* Verify pattern initialization for structure type automatic variables with
+   tail padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        char *one;
+        char *two;
+        char *three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var;
+  return var.four;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-7.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-7.c
new file mode 100644
index 000000000000..cb96c3a1e4b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-7.c
@@ -0,0 +1,20 @@
+/* Verify zero initialization for structure type automatic variables with
+   padding and has explicit initialization.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var = {.one = 1,.two = 2, .four = 'c'};
+  return var.four;
+}
+
+/* { dg-final { scan-assembler "stp\txzr, xzr," } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-8.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-8.c
new file mode 100644
index 000000000000..ce7c7cd31c1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-8.c
@@ -0,0 +1,22 @@
+/* Verify pattern initialization for structure type automatic variables with
+   padding and has explicit initialization.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var = {.one = 1,.two = 2, .four = 'c'};
+  return var.four;
+}
+
+/* { dg-final { scan-assembler "stp\txzr, xzr," } } */
+
+
diff --git a/gcc/testsuite/gcc.target/aarch64/auto-init-padding-9.c b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-9.c
new file mode 100644
index 000000000000..c81e5ff28b0b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/auto-init-padding-9.c
@@ -0,0 +1,21 @@
+/* Verify zero initialization for array type with structure element with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+
+int foo ()
+{
+  struct test_trailing_hole var[10]; 
+  return var[2].four;
+}
+
+/* { dg-final { scan-assembler-times "stp\tq0, q0," 5 } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-1.c b/gcc/testsuite/gcc.target/i386/auto-init-1.c
new file mode 100644
index 000000000000..b7690df24060
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-1.c
@@ -0,0 +1,32 @@
+/* Verify zero initialization for integer and pointer type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+enum E {
+  N1 = 0,
+  N2,
+  N3
+};
+
+extern void bar (char, short, int, enum E, long, long long, int *, bool);
+
+void foo()
+{
+  char temp1;
+  short temp2;
+  int temp3;
+  enum E temp4;
+  long temp5;
+  long long temp6;
+  int *temp7;
+  bool temp8;
+
+  bar (temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8);
+  return;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0" 10 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-2.c b/gcc/testsuite/gcc.target/i386/auto-init-2.c
new file mode 100644
index 000000000000..e76fc2565168
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-2.c
@@ -0,0 +1,36 @@
+/* Verify pattern initialization for integer and pointer type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+enum E {
+  N1 = 0,
+  N2,
+  N3
+};
+
+extern void bar (char, short, int, enum E, long, long long, int *, bool);
+
+void foo()
+{
+  char temp1;
+  short temp2;
+  int temp3;
+  enum E temp4;
+  long temp5;
+  long long temp6;
+  int *temp7;
+  bool temp8;
+
+  bar (temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8);
+  return;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe" 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffefe" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffefefefe" 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfefefefefefefefe" 3 "expand" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-21.c b/gcc/testsuite/gcc.target/i386/auto-init-21.c
new file mode 100644
index 000000000000..1192a908f9df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-21.c
@@ -0,0 +1,14 @@
+/* Verify zero initialization for VLA automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+extern void bar (int);
+
+void foo(int n)
+{
+  int arr[n];
+  bar (arr[2]);
+  return;
+}
+
+/* { dg-final { scan-rtl-dump "__builtin_memset" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-22.c b/gcc/testsuite/gcc.target/i386/auto-init-22.c
new file mode 100644
index 000000000000..431d9664e94f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-22.c
@@ -0,0 +1,14 @@
+/* Verify zero initialization for VLA automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+extern void bar (int);
+
+void foo(int n)
+{
+  int arr[n];
+  bar (arr[2]);
+  return;
+}
+
+/* { dg-final { scan-rtl-dump "__builtin_memset" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-23.c b/gcc/testsuite/gcc.target/i386/auto-init-23.c
new file mode 100644
index 000000000000..72094f6bdb92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-23.c
@@ -0,0 +1,13 @@
+/* Verify the auto initialization of nested VLA.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+void g(void *);
+
+void foo(int a)
+{
+  int x[a][a];
+  g(x);
+}
+
+/* { dg-final { scan-rtl-dump "__builtin_memset" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-24.c b/gcc/testsuite/gcc.target/i386/auto-init-24.c
new file mode 100644
index 000000000000..5cc3a756a1c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-24.c
@@ -0,0 +1,13 @@
+/* Verify the auto initialization of nested VLA.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+void g(void *);
+
+void foo(int a)
+{
+  int x[a][a];
+  g(x);
+}
+
+/* { dg-final { scan-rtl-dump "__builtin_memset" "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-3.c b/gcc/testsuite/gcc.target/i386/auto-init-3.c
new file mode 100644
index 000000000000..300ddfb34f11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-3.c
@@ -0,0 +1,17 @@
+/* Verify zero initialization for floating point type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+long double result;
+
+long double foo()
+{
+  float temp1;
+  double temp2;
+  long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-assembler-times "pxor\t\\\%xmm0, \\\%xmm0" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-4.c b/gcc/testsuite/gcc.target/i386/auto-init-4.c
new file mode 100644
index 000000000000..abe0b7e46a07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-4.c
@@ -0,0 +1,20 @@
+/* Verify pattern initialization for floating point type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+long double result;
+
+long double foo()
+{
+  float temp1;
+  double temp2;
+  long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffefefefe" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-5.c b/gcc/testsuite/gcc.target/i386/auto-init-5.c
new file mode 100644
index 000000000000..b2e708c52893
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-5.c
@@ -0,0 +1,20 @@
+/* Verify zero initialization for complex type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+
+_Complex long double result;
+
+_Complex long double foo()
+{
+  _Complex float temp1;
+  _Complex double temp2;
+  _Complex long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-assembler-times "\\.long\t0" 14 } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-6.c b/gcc/testsuite/gcc.target/i386/auto-init-6.c
new file mode 100644
index 000000000000..c79c039c2e98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-6.c
@@ -0,0 +1,19 @@
+/* Verify pattern initialization for complex type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+
+_Complex long double result;
+
+_Complex long double foo()
+{
+  _Complex float temp1;
+  _Complex double temp2;
+  _Complex long double temp3;
+
+  result = temp1 + temp2 + temp3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-7.c b/gcc/testsuite/gcc.target/i386/auto-init-7.c
new file mode 100644
index 000000000000..011437965deb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-7.c
@@ -0,0 +1,33 @@
+/* Verify zero initialization for array, union, and structure type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+struct S
+{
+  int f1;
+  float f2;
+  char f3[20];
+};
+
+union U
+{
+  char u1[5];
+  int u2;
+  float u3; 
+};
+
+double result;
+
+double foo()
+{
+  int temp1[3];
+  double temp2[3];
+  struct S temp3;
+  union U temp4;
+  
+  result = temp1[2] + temp2[1] + temp3.f2 + temp4.u3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\)\\\)" 3 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-8.c b/gcc/testsuite/gcc.target/i386/auto-init-8.c
new file mode 100644
index 000000000000..28fbeb7eece2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-8.c
@@ -0,0 +1,35 @@
+/* Verify pattern initialization for array, union, and structure type automatic variables.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct S
+{
+  int f1;
+  float f2;
+  char f3[20];
+};
+
+union U
+{
+  char u1[5];
+  int u2;
+  float u3; 
+};
+
+double result;
+
+double foo()
+{
+  int temp1[3];
+  double temp2[3];
+  struct S temp3;
+  union U temp4;
+  
+  result = temp1[2] + temp2[1] + temp3.f2 + temp4.u3;
+  return result;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffefefefe" 1 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "\\\[0xfefefefefefefefe\\\]" 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 2 "expand" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c
new file mode 100644
index 000000000000..a238b8b4cf58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-1.c
@@ -0,0 +1,19 @@
+/* Verify zero initialization for structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+struct test_aligned {
+        int internal1;
+        long long internal2;
+} __attribute__ ((aligned(64)));
+
+int foo ()
+{
+  struct test_aligned var;
+  return var.internal1;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 1 "expand" } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c
new file mode 100644
index 000000000000..3fc6b0729825
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-10.c
@@ -0,0 +1,21 @@
+/* Verify pattern initialization for array type with structure element with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+
+int foo ()
+{
+  struct test_trailing_hole var[10]; 
+  return var[2].four;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c
new file mode 100644
index 000000000000..cc982b980f6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-11.c
@@ -0,0 +1,26 @@
+/* Verify zero initialization for union type with structure field with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+union test_union_padding {
+  struct test_trailing_hole u1;
+  long long u2;
+};
+
+
+int foo ()
+{
+  union test_union_padding var;
+  return var.u1.four;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c
new file mode 100644
index 000000000000..0fbdb6c046d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-12.c
@@ -0,0 +1,26 @@
+/* Verify pattern initialization for union type with structure field with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+union test_union_padding {
+  struct test_trailing_hole u1;
+  long long u2;
+};
+
+
+int foo ()
+{
+  union test_union_padding var;
+  return var.u1.four;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c
new file mode 100644
index 000000000000..5739aa16b114
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-2.c
@@ -0,0 +1,19 @@
+/* Verify pattern initialization for structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_aligned {
+        int internal1;
+        long long internal2;
+} __attribute__ ((aligned(64)));
+
+int foo ()
+{
+  struct test_aligned var;
+  return var.internal1;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c
new file mode 100644
index 000000000000..8a6d764b9fa4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-3.c
@@ -0,0 +1,30 @@
+/* Verify zero initialization for nested structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_aligned {
+        unsigned internal1;
+        unsigned long long internal2;
+} __attribute__ ((aligned(64)));
+
+struct test_big_hole {
+        char one;
+        char two;
+        char three;
+        /* 61 byte padding hole here. */
+        struct test_aligned four;
+} __attribute__ ((aligned(64)));
+
+
+int foo ()
+{
+  struct test_big_hole var;
+  return var.four.internal1;
+}
+
+/* { dg-final { scan-assembler "movl\t\\\$0," } } */
+/* { dg-final { scan-assembler "movl\t\\\$16," } } */
+/* { dg-final { scan-assembler "rep stosq" } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c
new file mode 100644
index 000000000000..d7be32617e44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-4.c
@@ -0,0 +1,28 @@
+/* Verify pattern initialization for nested structure type automatic variables with
+   padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_aligned {
+        unsigned internal1;
+        unsigned long long internal2;
+} __attribute__ ((aligned(64)));
+
+struct test_big_hole {
+        char one;
+        char two;
+        char three;
+        /* 61 byte padding hole here. */
+        struct test_aligned four;
+} __attribute__ ((aligned(64)));
+
+
+int foo ()
+{
+  struct test_big_hole var;
+  return var.four.internal1;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c
new file mode 100644
index 000000000000..569b09aef239
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-5.c
@@ -0,0 +1,21 @@
+/* Verify zero initialization for structure type automatic variables with
+   tail padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        char *one;
+        char *two;
+        char *three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var;
+  return var.four;
+}
+
+/* { dg-final { scan-rtl-dump-times "const_int 0 \\\[0\\\]\\\) repeated x16" 1 "expand" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c
new file mode 100644
index 000000000000..4e0b6142134f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-6.c
@@ -0,0 +1,22 @@
+/* Verify pattern initialization for structure type automatic variables with
+   tail padding.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern -fdump-rtl-expand" } */
+
+struct test_trailing_hole {
+        char *one;
+        char *two;
+        char *three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var;
+  return var.four;
+}
+
+/* { dg-final { scan-rtl-dump-times "0xfffffffffffffffe\\\]\\\) repeated x16" 1 "expand" } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-7.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-7.c
new file mode 100644
index 000000000000..b5abffb0fc66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-7.c
@@ -0,0 +1,22 @@
+/* Verify zero initialization for structure type automatic variables with
+   padding and has explicit initialization.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var = {.one = 1,.two = 2, .four = 'c'};
+  return var.four;
+}
+
+/* { dg-final { scan-assembler-times "movq\t\\\$0," 2 } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-8.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-8.c
new file mode 100644
index 000000000000..66591cff4488
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-8.c
@@ -0,0 +1,22 @@
+/* Verify pattern initialization for structure type automatic variables with
+   padding and has explicit initialization.  */
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=pattern" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+int foo ()
+{
+  struct test_trailing_hole var = {.one = 1,.two = 2, .four = 'c'};
+  return var.four;
+}
+
+/* { dg-final { scan-assembler-times "movq\t\\\$0," 2 } } */
+
+
diff --git a/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c b/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c
new file mode 100644
index 000000000000..1ff900f95b98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/auto-init-padding-9.c
@@ -0,0 +1,22 @@
+/* Verify zero initialization for array type with structure element with
+   padding.  */ 
+/* { dg-do compile } */
+/* { dg-options "-ftrivial-auto-var-init=zero" } */
+
+struct test_trailing_hole {
+        int one;
+        int two;
+        int three;
+        char four;
+        /* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+
+int foo ()
+{
+  struct test_trailing_hole var[10]; 
+  return var[2].four;
+}
+
+/* { dg-final { scan-assembler "movl\t\\\$0," } } */
+/* { dg-final { scan-assembler "rep stosq" } } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 61b53913e0b3..367dcfa20bf8 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3452,11 +3452,56 @@ verify_gimple_call (gcall *stmt)
 	}
     }
 
+  /* For a call to .DEFERRED_INIT,
+     LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
+     we should guarantee that the 1st and the 3rd arguments are consistent:
+     1st argument: SIZE of the DECL;
+     3rd argument: IS_VLA, 0 NO, 1 YES;
+
+     if IS_VLA is false, the 1st argument should be a constant and the same as
+     the size of the LHS.  */
+  if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+    {
+      tree size_of_arg0 = gimple_call_arg (stmt, 0);
+      tree size_of_lhs = TYPE_SIZE_UNIT (TREE_TYPE (lhs));
+      tree is_vla_node = gimple_call_arg (stmt, 2);
+      bool is_vla = (bool) TREE_INT_CST_LOW (is_vla_node);
+
+      if (TREE_CODE (lhs) == SSA_NAME)
+	lhs = SSA_NAME_VAR (lhs);
+
+      poly_uint64 size_from_arg0, size_from_lhs;
+      bool is_constant_size_arg0 = poly_int_tree_p (size_of_arg0,
+						    &size_from_arg0);
+      bool is_constant_size_lhs = poly_int_tree_p (size_of_lhs,
+						   &size_from_lhs);
+      if (!is_vla)
+	{
+	  if (!is_constant_size_arg0)
+	    {
+	      error ("%<DEFFERED_INIT%> calls for non-VLA should have "
+		     "constant size for the first argument");
+	      return true;
+	    }
+	  else if (!is_constant_size_lhs)
+	    {
+	      error ("%<DEFFERED_INIT%> calls for non-VLA should have "
+		     "constant size for the LHS");
+	      return true;
+	    }
+	  else if (maybe_ne (size_from_arg0, size_from_lhs))
+	    {
+	      error ("%<DEFFERED_INIT%> calls for non-VLA should have same "
+		     "constant size for the first argument and LHS");
+	      return true;
+	    }
+	}
+    }
+
   /* ???  The C frontend passes unpromoted arguments in case it
      didn't see a function declaration before the call.  So for now
      leave the call arguments mostly unverified.  Once we gimplify
      unit-at-a-time we have a chance to fix this.  */
-
   for (i = 0; i < gimple_call_num_args (stmt); ++i)
     {
       tree arg = gimple_call_arg (stmt, i);
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 3a9e14f50a08..0363c5efb786 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -384,6 +384,13 @@ static struct
 
   /* Numbber of components created when splitting aggregate parameters.  */
   int param_reductions_created;
+
+  /* Number of deferred_init calls that are modified.  */
+  int deferred_init;
+
+  /* Number of deferred_init calls that are created by
+     generate_subtree_deferred_init.  */
+  int subtree_deferred_init;
 } sra_stats;
 
 static void
@@ -1388,7 +1395,14 @@ scan_function (void)
 
 	      t = gimple_call_lhs (stmt);
 	      if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
-		ret |= build_access_from_expr (t, stmt, true);
+		{
+		  /* If the STMT is a call to DEFERRED_INIT, avoid setting
+		     cannot_scalarize_away_bitmap.  */
+		  if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+		    ret |= !!build_access_from_expr_1 (t, stmt, true);
+		  else
+		    ret |= build_access_from_expr (t, stmt, true);
+		}
 	      break;
 
 	    case GIMPLE_ASM:
@@ -4099,6 +4113,88 @@ get_repl_default_def_ssa_name (struct access *racc, tree reg_type)
   return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
 }
 
+
+/* Generate statements to call .DEFERRED_INIT to initialize scalar replacements
+   of accesses within a subtree ACCESS; all its children, siblings and their
+   children are to be processed.
+   GSI is a statement iterator used to place the new statements.  */
+static void
+generate_subtree_deferred_init (struct access *access,
+				tree init_type,
+				tree is_vla,
+				gimple_stmt_iterator *gsi,
+				location_t loc)
+{
+  do
+    {
+      if (access->grp_to_be_replaced)
+	{
+	  tree repl = get_access_replacement (access);
+	  gimple *call
+	    = gimple_build_call_internal (IFN_DEFERRED_INIT, 3,
+					  TYPE_SIZE_UNIT (TREE_TYPE (repl)),
+					  init_type, is_vla);
+	  gimple_call_set_lhs (call, repl);
+	  gsi_insert_before (gsi, call, GSI_SAME_STMT);
+	  update_stmt (call);
+	  gimple_set_location (call, loc);
+	  sra_stats.subtree_deferred_init++;
+	}
+      if (access->first_child)
+	generate_subtree_deferred_init (access->first_child, init_type,
+					is_vla, gsi, loc);
+
+      access = access ->next_sibling;
+    }
+  while (access);
+}
+
+/* For a call to .DEFERRED_INIT:
+   var = .DEFERRED_INIT (size_of_var, init_type, is_vla);
+   examine the LHS variable VAR and replace it with a scalar replacement if
+   there is one, also replace the RHS call to a call to .DEFERRED_INIT of
+   the corresponding scalar relacement variable.  Examine the subtree and
+   do the scalar replacements in the subtree too.  STMT is the call, GSI is
+   the statment iterator to place newly created statement.  */
+
+static enum assignment_mod_result
+sra_modify_deferred_init (gimple *stmt, gimple_stmt_iterator *gsi)
+{
+  tree lhs = gimple_call_lhs (stmt);
+  tree init_type = gimple_call_arg (stmt, 1);
+  tree is_vla = gimple_call_arg (stmt, 2);
+
+  struct access *lhs_access = get_access_for_expr (lhs);
+  if (!lhs_access)
+    return SRA_AM_NONE;
+
+  location_t loc = gimple_location (stmt);
+
+  if (lhs_access->grp_to_be_replaced)
+    {
+      tree lhs_repl = get_access_replacement (lhs_access);
+      gimple_call_set_lhs (stmt, lhs_repl);
+      tree arg0_repl = TYPE_SIZE_UNIT (TREE_TYPE (lhs_repl));
+      gimple_call_set_arg (stmt, 0, arg0_repl);
+      sra_stats.deferred_init++;
+      gcc_assert (!lhs_access->first_child);
+      return SRA_AM_MODIFIED;
+    }
+
+  if (lhs_access->first_child)
+    generate_subtree_deferred_init (lhs_access->first_child,
+				    init_type, is_vla, gsi, loc);
+  if (lhs_access->grp_covered)
+    {
+      unlink_stmt_vdef (stmt);
+      gsi_remove (gsi, true);
+      release_defs (stmt);
+      return SRA_AM_REMOVED;
+    }
+
+  return SRA_AM_MODIFIED;
+}
+
 /* Examine both sides of the assignment statement pointed to by STMT, replace
    them with a scalare replacement if there is one and generate copying of
    replacements if scalarized aggregates have been used in the assignment.  GSI
@@ -4463,17 +4559,27 @@ sra_modify_function_body (void)
 	      break;
 
 	    case GIMPLE_CALL:
-	      /* Operands must be processed before the lhs.  */
-	      for (i = 0; i < gimple_call_num_args (stmt); i++)
+	      /* Handle calls to .DEFERRED_INIT specially.  */
+	      if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
 		{
-		  t = gimple_call_arg_ptr (stmt, i);
-		  modified |= sra_modify_expr (t, &gsi, false);
+		  assign_result = sra_modify_deferred_init (stmt, &gsi);
+		  modified |= assign_result == SRA_AM_MODIFIED;
+		  deleted = assign_result == SRA_AM_REMOVED;
 		}
-
-	      if (gimple_call_lhs (stmt))
+	      else
 		{
-		  t = gimple_call_lhs_ptr (stmt);
-		  modified |= sra_modify_expr (t, &gsi, true);
+		  /* Operands must be processed before the lhs.  */
+		  for (i = 0; i < gimple_call_num_args (stmt); i++)
+		    {
+		      t = gimple_call_arg_ptr (stmt, i);
+		      modified |= sra_modify_expr (t, &gsi, false);
+		    }
+
+	      	  if (gimple_call_lhs (stmt))
+		    {
+		      t = gimple_call_lhs_ptr (stmt);
+		      modified |= sra_modify_expr (t, &gsi, true);
+		    }
 		}
 	      break;
 
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index fb0e42997032..7da664acc78c 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4916,6 +4916,9 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
       && find_func_aliases_for_builtin_call (fn, t))
     return;
 
+  if (gimple_call_internal_p (t, IFN_DEFERRED_INIT))
+    return;
+
   fi = get_fi_for_callee (t);
   if (!in_ipa_mode
       || (fi->decl && fndecl && !fi->is_fn_info))
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index ad2cf48819b3..3f0912182122 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -152,6 +152,42 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
   if (is_gimple_assign (context)
       && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
     return;
+
+  /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
+     .DEFERRED_INIT.  This is for handling the following case correctly:
+
+  1 typedef _Complex float C;
+  2 C foo (int cond)
+  3 {
+  4   C f;
+  5   __imag__ f = 0;
+  6   if (cond)
+  7     {
+  8       __real__ f = 1;
+  9       return f;
+ 10     }
+ 11   return f;
+ 12 }
+
+    with -ftrivial-auto-var-init, compiler will insert the following
+    artificial initialization at line 4:
+  f = .DEFERRED_INIT (f, 2);
+  _1 = REALPART_EXPR <f>;
+
+    without the following special handling, _1 = REALPART_EXPR <f> will
+    be treated as the uninitialized use point, which is incorrect. (the
+    real uninitialized use point is at line 11).  */
+  if (is_gimple_assign (context)
+      && (gimple_assign_rhs_code (context) == REALPART_EXPR
+	  || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
+    {
+      tree v = gimple_assign_rhs1 (context);
+      if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
+	  && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
+				     IFN_DEFERRED_INIT))
+	return;
+    }
+
   if (!has_undefined_value_p (t))
     return;
 
@@ -349,6 +385,11 @@ check_defs (ao_ref *ref, tree vdef, void *data_)
   check_defs_data *data = (check_defs_data *)data_;
   gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
 
+  /* Ignore the vdef if the definition statement is a call
+     to .DEFERRED_INIT function.  */
+  if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
+    return false;
+
   /* The ASAN_MARK intrinsic doesn't modify the variable.  */
   if (is_gimple_call (def_stmt))
     {
@@ -875,6 +916,12 @@ warn_uninitialized_vars (bool wmaybe_uninit)
 	  ssa_op_iter op_iter;
 	  tree use;
 
+	  /* The call is an artificial use, will not provide meaningful
+	     error message.  If the result of the call is used somewhere
+	     else, we warn there instead.  */
+	  if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+	    continue;
+
 	  if (is_gimple_debug (stmt))
 	    continue;
 
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 4cc400d3c2eb..0fba404babe9 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1325,6 +1325,46 @@ ssa_undefined_value_p (tree t, bool partial)
   if (gimple_nop_p (def_stmt))
     return true;
 
+  /* The value is undefined if the definition statement is a call
+     to .DEFERRED_INIT function.  */
+  if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
+    return true;
+
+  /* The value is partially undefined if the definition statement is
+     a REALPART_EXPR or IMAGPART_EXPR and its operand is defined by
+     the call to .DEFERRED_INIT function.  This is for handling the
+     following case:
+
+  1 typedef _Complex float C;
+  2 C foo (int cond)
+  3 {
+  4   C f;
+  5   __imag__ f = 0;
+  6   if (cond)
+  7     {
+  8       __real__ f = 1;
+  9       return f;
+ 10     }
+ 11   return f;
+ 12 }
+
+    with -ftrivial-auto-var-init, compiler will insert the following
+    artificial initialization:
+  f = .DEFERRED_INIT (f, 2);
+  _1 = REALPART_EXPR <f>;
+
+    we should treat the definition _1 = REALPART_EXPR <f> as undefined.  */
+  if (partial && is_gimple_assign (def_stmt)
+      && (gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
+	  || gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR))
+    {
+      tree real_imag_part = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
+      if (TREE_CODE (real_imag_part) == SSA_NAME
+	 && gimple_call_internal_p (SSA_NAME_DEF_STMT (real_imag_part),
+				    IFN_DEFERRED_INIT))
+	return true;
+    }
+
   /* Check if the complex was not only partially defined.  */
   if (partial && is_gimple_assign (def_stmt)
       && gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
diff --git a/gcc/tree.c b/gcc/tree.c
index cba3bca41b3a..2e44150c0352 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9510,6 +9510,22 @@ build_common_builtin_nodes (void)
   tree tmp, ftype;
   int ecf_flags;
 
+  /* If user requests automatic variables initialization, the builtin
+     BUILT_IN_CLEAR_PADDING is needed.  */
+  if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
+      && !builtin_decl_explicit_p (BUILT_IN_CLEAR_PADDING))
+    {
+      ftype = build_function_type_list (void_type_node,
+					ptr_type_node,
+					ptr_type_node,
+					integer_type_node,
+					NULL_TREE);
+      local_define_builtin ("__builtin_clear_padding", ftype,
+			    BUILT_IN_CLEAR_PADDING,
+			    "__builtin_clear_padding",
+			      ECF_LEAF | ECF_NOTHROW);
+    }
+
   if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
       || !builtin_decl_explicit_p (BUILT_IN_ABORT))
     {
-- 
2.27.0


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2021-09-16 18:55 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-21 20:07 [patch][version 8]add -ftrivial-auto-var-init and variable attribute "uninitialized" to gcc Qing Zhao
2021-09-03 14:47 ` Qing Zhao
2021-09-11  8:03   ` [PATCH] testsuite: Fix c-c++-common/auto-init-* tests Jakub Jelinek
2021-09-11 11:45     ` Richard Biener
2021-09-11 16:58     ` Qing Zhao
2021-09-15 17:59     ` Qing Zhao
2021-09-16  9:19       ` Jakub Jelinek
2021-09-16 14:49         ` Qing Zhao
2021-09-16 14:56           ` Jakub Jelinek
2021-09-16 15:39             ` Qing Zhao
2021-09-16 15:47               ` Jakub Jelinek
2021-09-16 17:11                 ` Qing Zhao
2021-09-16 17:39                   ` Iain Sandoe
2021-09-16 18:55                     ` Qing Zhao
2021-09-06 10:16 ` [patch][version 8]add -ftrivial-auto-var-init and variable attribute "uninitialized" to gcc Richard Biener
2021-09-07 16:57   ` Qing Zhao
2021-09-07 18:33     ` Qing Zhao
2021-09-09 22:49   ` [COMMITTED][patch][version 9]add " Qing Zhao
2021-09-09 23:10     ` Kees Cook
2021-09-10  7:23       ` Richard Biener
2021-09-10 13:46         ` Jose E. Marchesi
2021-09-10 14:36           ` Qing Zhao
2021-09-13  9:32           ` Richard Biener
2021-09-13 14:38             ` Jose E. Marchesi
2021-09-10  8:47     ` Christophe LYON
2021-09-10  9:08       ` Martin Liška
2021-09-10 14:01         ` Jeff Law
2021-09-10  9:40       ` Thomas Schwinge
2021-09-10 14:30         ` Qing Zhao
2021-09-10 14:26       ` Qing Zhao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).