get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2226709/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2226709,
    "url": "http://patchwork.ozlabs.org/api/patches/2226709/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhuom29jc4.gcc.gcc-TEST.pinskia.61.1.2@forge-stage.sourceware.org/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<bmm.hhuom29jc4.gcc.gcc-TEST.pinskia.61.1.2@forge-stage.sourceware.org>",
    "list_archive_url": null,
    "date": "2026-04-22T18:30:27",
    "name": "[v1,2/6] forwprop: Change proping memset into memcpy into a forwprop rather than a backwalk",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "2288a791a345466abfce85979c6c7dacb3519bd9",
    "submitter": {
        "id": 93219,
        "url": "http://patchwork.ozlabs.org/api/people/93219/?format=api",
        "name": "Andrew Pinski via Sourceware Forge",
        "email": "forge-bot+pinskia@forge-stage.sourceware.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhuom29jc4.gcc.gcc-TEST.pinskia.61.1.2@forge-stage.sourceware.org/mbox/",
    "series": [
        {
            "id": 501080,
            "url": "http://patchwork.ozlabs.org/api/series/501080/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501080",
            "date": "2026-04-22T18:30:28",
            "name": "copy-propv3",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501080/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2226709/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2226709/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org",
            "sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g17Sr1jSzz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 04:45:16 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 4356040A1E97\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 18:45:14 +0000 (GMT)",
            "from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id 2155A4B3589B\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:32:05 +0000 (GMT)",
            "from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id ED49F434CE\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:32:04 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 4356040A1E97",
            "OpenDKIM Filter v2.11.0 sourceware.org 2155A4B3589B"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 2155A4B3589B",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 2155A4B3589B",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776882725; cv=none;\n b=HIOzyLmFsXbCzp8er9R2xWwwpbPXP6bs4TsmK04RxdDxHDC/ZokpIvLAoQxUbz0p/w00iVQZcbifs7AMkJ323J5k1+URwQ7z51AtpJuvG6pGFfXfhu7AWCG0YiQbVPmIHXAYK1KpFYQxr0fAto0zKc5q0gPzvIXC3oYiy4tQoOo=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776882725; c=relaxed/simple;\n bh=8eLaGQIyRw6V6d60RvvEyi5PKkZvFCMZqhQgrWF0b+k=;\n h=From:Date:Subject:To:Message-ID;\n b=JC7JMvD70ydNLbzOSoX8Dj86jYkhUDT5wR6+hiEZ1ygzci5vsfl6Q408f6E86KhprhQCStPMGf2FEDJ6Efp0RKK5l8ZgZPMEcQ6XmPol0ZA0doWf0W+GtLkRTtKZGUNmJXuDJYDJp6vGfAB8G+Mkys1SlMcradjKDxhnBK4hQnU=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "Andrew Pinski via Sourceware Forge\n <forge-bot+pinskia@forge-stage.sourceware.org>",
        "Date": "Wed, 22 Apr 2026 18:30:27 +0000",
        "Subject": "[PATCH v1 2/6] forwprop: Change proping memset into memcpy into a\n forwprop rather than a backwalk",
        "To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>",
        "Message-ID": "\n <bmm.hhuom29jc4.gcc.gcc-TEST.pinskia.61.1.2@forge-stage.sourceware.org>",
        "X-Mailer": "batrachomyomachia",
        "X-Pull-Request-Organization": "gcc",
        "X-Pull-Request-Repository": "gcc-TEST",
        "X-Pull-Request": "https://forge.sourceware.org/gcc/gcc-TEST/pulls/61",
        "References": "\n <bmm.hhuom29jc4.gcc.gcc-TEST.pinskia.61.1.0@forge-stage.sourceware.org>",
        "In-Reply-To": "\n <bmm.hhuom29jc4.gcc.gcc-TEST.pinskia.61.1.0@forge-stage.sourceware.org>",
        "X-Patch-URL": "\n https://forge.sourceware.org/pinskia/gcc-TEST/commit/a7a40284ac7eb9650b33fa6005d27a85ed8c0441",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Reply-To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>,\n pinskia@gcc.gnu.org",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "From: Andrew Pinski <quic_apinski@quicinc.com>\n\nOne thing I noticed while working on copy prop for aggregates is that we start with\na memcpy like statement and then walk backwards. This means we could have a few walks\nbackwards to see there was no statement for zeroing. Instead this changes the walk\nbackwards into a true forwprop. In the future we can expand to forwprop the zeroing\ninto say an function argument or something more than memcpy like statement.\n\nThis should speed up slightly the compile time performance since there will be less\nmemsets like statements than memcpy and there is only one walk forwards for memset like\nstaments instead of multiple walk backwards to find the memset.\n\nNote this does add one extra improvement, the memcpy now does not need to have an address\nas its dest argument; this could have been done before too but it was even more noticable\nnow because of the variable became only set so it was removed and the check was removed\nas well.\n\n\tPR tree-optimization/118946\n\ngcc/ChangeLog:\n\n\t* tree-ssa-forwprop.cc (optimize_memcpy_to_memset): Remove.\n\t(optimize_aggr_zeroprop_1): New function.\n\t(optimize_aggr_zeroprop): New function.\n\t(simplify_builtin_call): Don't call optimize_memcpy_to_memset\n\tfor memcpy but call optimize_aggr_zeroprop for memset.\n\t(pass_forwprop::execute): Don't call optimize_memcpy_to_memset\n\tfor aggregate copies but rather call optimize_aggr_zeroprop\n\tfor aggregate stores.\n\ngcc/testsuite/ChangeLog:\n\n\t* gcc.dg/pr118946-1.c: New test.\n\nSigned-off-by: Andrew Pinski <quic_apinski@quicinc.com>\n---\n gcc/testsuite/gcc.dg/pr118946-1.c |  15 ++\n gcc/tree-ssa-forwprop.cc          | 283 +++++++++++++++++-------------\n 2 files changed, 172 insertions(+), 126 deletions(-)\n create mode 100644 gcc/testsuite/gcc.dg/pr118946-1.c",
    "diff": "diff --git a/gcc/testsuite/gcc.dg/pr118946-1.c b/gcc/testsuite/gcc.dg/pr118946-1.c\nnew file mode 100644\nindex 000000000000..6cf2661f2864\n--- /dev/null\n+++ b/gcc/testsuite/gcc.dg/pr118946-1.c\n@@ -0,0 +1,15 @@\n+/* { dg-do compile } */\n+/* { dg-options \"-O2 -fdump-tree-optimized -fdump-tree-forwprop1-details\" } */\n+\n+/* PR tree-optimization/118946 */\n+\n+void f(char *a)\n+{\n+  char t[1024] = {};\n+  __builtin_memcpy(a, t, 10);\n+}\n+\n+/* We should be able to optimize the memcpy into a memset here. */\n+/* { dg-final { scan-tree-dump-times \"after previous\" 1 \"forwprop1\"} } */\n+/* { dg-final { scan-tree-dump-times \"memset \" 1 \"optimized\" } } */\n+/* { dg-final { scan-tree-dump-not \"memcpy \" \"optimized\" } } */\ndiff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc\nindex 2dc77ccba1d7..ca8578cb72a3 100644\n--- a/gcc/tree-ssa-forwprop.cc\n+++ b/gcc/tree-ssa-forwprop.cc\n@@ -1190,117 +1190,56 @@ constant_pointer_difference (tree p1, tree p2)\n   return NULL_TREE;\n }\n \n-\n-/* Optimize\n-   a = {};\n-   b = a;\n-   into\n-   a = {};\n-   b = {};\n-   Similarly for memset (&a, ..., sizeof (a)); instead of a = {};\n-   and/or memcpy (&b, &a, sizeof (a)); instead of b = a;  */\n-\n+/* Helper function for optimize_aggr_zeroprop.\n+   Props the zeroing (memset, VAL) that was done in DEST:LEN\n+   (DEFSTMT) into the STMT.  Returns true if the STMT was updated.  */\n static bool\n-optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree len)\n+optimize_aggr_zeroprop_1 (gimple *defstmt, gimple *stmt,\n+\t\t\t  tree dest, tree val, tree len)\n {\n-  ao_ref read;\n-  gimple *stmt = gsi_stmt (*gsip);\n-  if (gimple_has_volatile_ops (stmt))\n-    return false;\n-\n-  tree src2 = NULL_TREE, len2 = NULL_TREE;\n+  tree src2;\n+  tree len2 = NULL_TREE;\n   poly_int64 offset, offset2;\n-  tree val = integer_zero_node;\n-  bool len_was_null = len == NULL_TREE;\n-  if (len == NULL_TREE)\n-    len = (TREE_CODE (src) == COMPONENT_REF\n-\t   ? DECL_SIZE_UNIT (TREE_OPERAND (src, 1))\n-\t   : TYPE_SIZE_UNIT (TREE_TYPE (src)));\n-  if (len == NULL_TREE\n-      || !poly_int_tree_p (len))\n-    return false;\n-\n-  ao_ref_init (&read, src);\n-  tree vuse = gimple_vuse (stmt);\n-  gimple *defstmt;\n-  unsigned limit = param_sccvn_max_alias_queries_per_access;\n-  do {\n-    /* If the vuse is the default definition, then there is no stores beforhand. */\n-    if (SSA_NAME_IS_DEFAULT_DEF (vuse))\n-      return false;\n-    defstmt = SSA_NAME_DEF_STMT (vuse);\n-    if (is_a <gphi*>(defstmt))\n-      return false;\n-    if (limit-- == 0)\n-      return false;\n-    /* If the len was null, then we can use TBBA. */\n-    if (stmt_may_clobber_ref_p_1 (defstmt, &read,\n-\t\t\t\t  /* tbaa_p = */ len_was_null))\n-      break;\n-    vuse = gimple_vuse (defstmt);\n-  } while (true);\n \n-  if (gimple_store_p (defstmt)\n-      && gimple_assign_single_p (defstmt)\n-      && TREE_CODE (gimple_assign_rhs1 (defstmt)) == STRING_CST\n-      && !gimple_clobber_p (defstmt))\n+  if (gimple_call_builtin_p (stmt, BUILT_IN_MEMCPY)\n+      && TREE_CODE (gimple_call_arg (stmt, 1)) == ADDR_EXPR\n+      && poly_int_tree_p (gimple_call_arg (stmt, 2)))\n     {\n-      tree str = gimple_assign_rhs1 (defstmt);\n-      src2 = gimple_assign_lhs (defstmt);\n-      /* The string must contain all null char's for now.  */\n-      for (int i = 0; i < TREE_STRING_LENGTH (str); i++)\n-\t{\n-\t  if (TREE_STRING_POINTER (str)[i] != 0)\n-\t    {\n-\t      src2 = NULL_TREE;\n-\t      break;\n-\t    }\n-\t}\n+      src2 = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);\n+      len2 = gimple_call_arg (stmt, 2);\n     }\n-  else if (gimple_store_p (defstmt)\n-      && gimple_assign_single_p (defstmt)\n-      && TREE_CODE (gimple_assign_rhs1 (defstmt)) == CONSTRUCTOR\n-      && !gimple_clobber_p (defstmt))\n-    src2 = gimple_assign_lhs (defstmt);\n-  else if (gimple_call_builtin_p (defstmt, BUILT_IN_MEMSET)\n-\t   && TREE_CODE (gimple_call_arg (defstmt, 0)) == ADDR_EXPR\n-\t   && TREE_CODE (gimple_call_arg (defstmt, 1)) == INTEGER_CST)\n-    {\n-      src2 = TREE_OPERAND (gimple_call_arg (defstmt, 0), 0);\n-      len2 = gimple_call_arg (defstmt, 2);\n-      val = gimple_call_arg (defstmt, 1);\n-      /* For non-0 val, we'd have to transform stmt from assignment\n-\t into memset (only if dest is addressable).  */\n-      if (!integer_zerop (val) && is_gimple_assign (stmt))\n-\tsrc2 = NULL_TREE;\n-    }\n-\n-  if (src2 == NULL_TREE)\n-    return false;\n+   else if (gimple_assign_load_p (stmt) && gimple_store_p (stmt))\n+     {\n+\tsrc2 = gimple_assign_rhs1 (stmt);\n+\tlen2 = (TREE_CODE (src2) == COMPONENT_REF\n+\t\t? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1))\n+\t\t: TYPE_SIZE_UNIT (TREE_TYPE (src2)));\n+\t/* Can only handle zero memsets. */\n+\tif (!integer_zerop (val))\n+\t  return false;\n+     }\n+   else\n+     return false;\n \n-  if (len2 == NULL_TREE)\n-    len2 = (TREE_CODE (src2) == COMPONENT_REF\n-\t    ? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1))\n-\t    : TYPE_SIZE_UNIT (TREE_TYPE (src2)));\n   if (len2 == NULL_TREE\n       || !poly_int_tree_p (len2))\n     return false;\n \n-  src = get_addr_base_and_unit_offset (src, &offset);\n+  dest = get_addr_base_and_unit_offset (dest, &offset);\n   src2 = get_addr_base_and_unit_offset (src2, &offset2);\n-  if (src == NULL_TREE\n+  if (dest == NULL_TREE\n       || src2 == NULL_TREE\n-      || maybe_lt (offset, offset2))\n+      || maybe_lt (offset2, offset))\n     return false;\n \n-  if (!operand_equal_p (src, src2, 0))\n+  if (!operand_equal_p (dest, src2, 0))\n     return false;\n \n-  /* [ src + offset2, src + offset2 + len2 - 1 ] is set to val.\n+  /* [ dest + offset, dest + offset + len - 1 ] is set to val.\n      Make sure that\n-     [ src + offset, src + offset + len - 1 ] is a subset of that.  */\n-  if (maybe_gt (wi::to_poly_offset (len) + (offset - offset2),\n-\t\twi::to_poly_offset (len2)))\n+     [ dest + offset2, dest + offset2 + len2 - 1 ] is a subset of that.  */\n+  if (maybe_gt (wi::to_poly_offset (len2) + (offset2 - offset),\n+\t\twi::to_poly_offset (len)))\n     return false;\n \n   if (dump_file && (dump_flags & TDF_DETAILS))\n@@ -1310,7 +1249,7 @@ optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree\n       fprintf (dump_file, \"after previous\\n  \");\n       print_gimple_stmt (dump_file, defstmt, 0, dump_flags);\n     }\n-\n+  gimple *orig_stmt = stmt;\n   /* For simplicity, don't change the kind of the stmt,\n      turn dest = src; into dest = {}; and memcpy (&dest, &src, len);\n      into memset (&dest, val, len);\n@@ -1320,8 +1259,10 @@ optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree\n      of dest, dest isn't volatile.  */\n   if (is_gimple_assign (stmt))\n     {\n-      tree ctor = build_constructor (TREE_TYPE (dest), NULL);\n-      gimple_assign_set_rhs_from_tree (gsip, ctor);\n+      tree ctor_type = TREE_TYPE (gimple_assign_lhs (stmt));\n+      tree ctor = build_constructor (ctor_type, NULL);\n+      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);\n+      gimple_assign_set_rhs_from_tree (&gsi, ctor);\n       update_stmt (stmt);\n       statistics_counter_event (cfun, \"copy zeroing propagation of aggregate\", 1);\n     }\n@@ -1341,8 +1282,112 @@ optimize_memcpy_to_memset (gimple_stmt_iterator *gsip, tree dest, tree src, tree\n       fprintf (dump_file, \"into\\n  \");\n       print_gimple_stmt (dump_file, stmt, 0, dump_flags);\n     }\n+\n+  /* Mark the bb for eh cleanup if needed.  */\n+  if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))\n+    bitmap_set_bit (to_purge, gimple_bb (stmt)->index);\n+\n   return true;\n }\n+\n+/* Optimize\n+   a = {}; // DEST = value ;; LEN(nullptr)\n+   b = a;\n+   into\n+   a = {};\n+   b = {};\n+   Similarly for memset (&a, ..., sizeof (a)); instead of a = {};\n+   and/or memcpy (&b, &a, sizeof (a)); instead of b = a;  */\n+\n+static bool\n+optimize_aggr_zeroprop (gimple_stmt_iterator *gsip)\n+{\n+  ao_ref read;\n+  gimple *stmt = gsi_stmt (*gsip);\n+  if (gimple_has_volatile_ops (stmt))\n+    return false;\n+\n+  tree dest = NULL_TREE;\n+  tree val = integer_zero_node;\n+  tree len = NULL_TREE;\n+  bool can_use_tbba = true;\n+  bool changed = false;\n+\n+  if (gimple_call_builtin_p (stmt, BUILT_IN_MEMSET)\n+      && TREE_CODE (gimple_call_arg (stmt, 0)) == ADDR_EXPR\n+      && TREE_CODE (gimple_call_arg (stmt, 1)) == INTEGER_CST\n+      && poly_int_tree_p (gimple_call_arg (stmt, 2)))\n+    {\n+      dest = TREE_OPERAND (gimple_call_arg (stmt, 0), 0);\n+      len = gimple_call_arg (stmt, 2);\n+      val = gimple_call_arg (stmt, 1);\n+      can_use_tbba = false;\n+    }\n+  else if (gimple_store_p (stmt)\n+      && gimple_assign_single_p (stmt)\n+      && TREE_CODE (gimple_assign_rhs1 (stmt)) == STRING_CST\n+      && !gimple_clobber_p (stmt))\n+    {\n+      tree str = gimple_assign_rhs1 (stmt);\n+      dest = gimple_assign_lhs (stmt);\n+      /* The string must contain all null char's for now.  */\n+      for (int i = 0; i < TREE_STRING_LENGTH (str); i++)\n+\t{\n+\t  if (TREE_STRING_POINTER (str)[i] != 0)\n+\t    {\n+\t      dest = NULL_TREE;\n+\t      break;\n+\t    }\n+\t}\n+    }\n+  else if (gimple_store_p (stmt)\n+\t   && gimple_assign_single_p (stmt)\n+\t   && TREE_CODE (gimple_assign_rhs1 (stmt)) == CONSTRUCTOR\n+\t   && !gimple_clobber_p (stmt))\n+    dest = gimple_assign_lhs (stmt);\n+\n+  if (dest == NULL_TREE)\n+    return false;\n+\n+  if (len == NULL_TREE)\n+    len = (TREE_CODE (dest) == COMPONENT_REF\n+\t   ? DECL_SIZE_UNIT (TREE_OPERAND (dest, 1))\n+\t   : TYPE_SIZE_UNIT (TREE_TYPE (dest)));\n+  if (len == NULL_TREE\n+      || !poly_int_tree_p (len))\n+    return false;\n+\n+  auto_vec<std::pair<tree, unsigned>> worklist;\n+  ao_ref_init (&read, dest);\n+  unsigned limit = param_sccvn_max_alias_queries_per_access;\n+  worklist.safe_push (std::make_pair (gimple_vdef (stmt), limit));\n+\n+  while (!worklist.is_empty ())\n+    {\n+      std::pair<tree, unsigned> top = worklist.pop ();\n+      tree vdef = top.first;\n+      limit = top.second;\n+      gimple *use_stmt;\n+      imm_use_iterator iter;\n+      FOR_EACH_IMM_USE_STMT (use_stmt, iter, vdef)\n+\t{\n+\t  if (is_a <gphi*> (use_stmt))\n+\t    continue;\n+\t  if (gimple_vdef (use_stmt)\n+\t      && !stmt_may_clobber_ref_p_1 (use_stmt, &read,\n+\t\t\t\t\t   /* tbaa_p = */ can_use_tbba)\n+\t      && limit != 0)\n+\t    worklist.safe_push (std::make_pair (gimple_vdef (use_stmt),\n+\t\t\t\t\t\tlimit - 1));\n+\t  if (gimple_call_builtin_p (use_stmt, BUILT_IN_MEMCPY)\n+\t      || (gimple_assign_load_p (use_stmt) && gimple_store_p (use_stmt)))\n+\t    if (optimize_aggr_zeroprop_1 (stmt, use_stmt, dest, val, len))\n+\t     changed = true;\n+\t}\n+    }\n+\n+  return changed;\n+}\n /* Optimizes\n    DEST = SRC;\n    DEST2 = DEST; # DEST2 = SRC2;\n@@ -1462,22 +1507,6 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)\n \n   switch (DECL_FUNCTION_CODE (callee2))\n     {\n-    case BUILT_IN_MEMCPY:\n-      if (gimple_call_num_args (stmt2) == 3)\n-\t{\n-\t  tree dest = gimple_call_arg (stmt2, 0);\n-\t  tree src = gimple_call_arg (stmt2, 1);\n-\t  tree len = gimple_call_arg (stmt2, 2);\n-\t  /* Try to optimize the memcpy to memset if src\n-\t     and dest are addresses. */\n-\t  if (TREE_CODE (dest) == ADDR_EXPR\n-\t      && TREE_CODE (src) == ADDR_EXPR\n-\t      && TREE_CODE (len) == INTEGER_CST\n-\t      && optimize_memcpy_to_memset (gsi_p, TREE_OPERAND (dest, 0),\n-\t\t\t\t\t    TREE_OPERAND (src, 0), len))\n-\t    return true;\n-\t}\n-    break;\n     case BUILT_IN_MEMCHR:\n       if (gimple_call_num_args (stmt2) == 3\n \t  && (res = gimple_call_lhs (stmt2)) != nullptr\n@@ -1539,6 +1568,13 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)\n       break;\n \n     case BUILT_IN_MEMSET:\n+      if (gimple_call_num_args (stmt2) == 3)\n+\t{\n+\t  /* Try to prop the zeroing/value of the memset to memcpy\n+\t     if the dest is an address and the value is a constant. */\n+\t  if (optimize_aggr_zeroprop (gsi_p))\n+\t    return true;\n+\t}\n       if (gimple_call_num_args (stmt2) != 3\n \t  || gimple_call_lhs (stmt2)\n \t  || CHAR_BIT != 8\n@@ -4857,21 +4893,16 @@ pass_forwprop::execute (function *fun)\n \t\t  {\n \t\t    tree rhs1 = gimple_assign_rhs1 (stmt);\n \t\t    enum tree_code code = gimple_assign_rhs_code (stmt);\n-\t\t    if (gimple_assign_load_p (stmt) && gimple_store_p (stmt))\n+\t\t    if (gimple_store_p (stmt) && optimize_aggr_zeroprop (&gsi))\n \t\t      {\n-\t\t\tif (optimize_memcpy_to_memset (&gsi,\n-\t\t\t\t\t\t       gimple_assign_lhs (stmt),\n-\t\t\t\t\t\t       gimple_assign_rhs1 (stmt),\n-\t\t\t\t\t\t       /* len = */NULL_TREE))\n-\t\t\t  {\n-\t\t\t    changed = true;\n-\t\t\t    break;\n-\t\t\t  }\n-\t\t\tif (optimize_agr_copyprop (&gsi))\n-\t\t\t  {\n-\t\t\t    changed = true;\n-\t\t\t    break;\n-\t\t\t  }\n+\t\t\tchanged = true;\n+\t\t\tbreak;\n+\t\t      }\n+\t\t    if (gimple_assign_load_p (stmt) && gimple_store_p (stmt)\n+\t\t\t&& optimize_agr_copyprop (&gsi))\n+\t\t      {\n+\t\t\tchanged = true;\n+\t\t\tbreak;\n \t\t      }\n \n \t\t    if (TREE_CODE_CLASS (code) == tcc_comparison)\n",
    "prefixes": [
        "v1",
        "2/6"
    ]
}