{"id":2223060,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2223060/?format=json","project":{"id":17,"url":"http://patchwork.ozlabs.org/api/1.0/projects/17/?format=json","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},"msgid":"<20260414094856.982C34B3A5@imap1.dmz-prg2.suse.org>","date":"2026-04-14T09:48:56","name":"tree-optimization/124875 - re-instantiate alias-set code in PRE","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"666854477c0f58d6bce8423c40f027dfab287f23","submitter":{"id":4338,"url":"http://patchwork.ozlabs.org/api/1.0/people/4338/?format=json","name":"Richard Biener","email":"rguenther@suse.de"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/gcc/patch/20260414094856.982C34B3A5@imap1.dmz-prg2.suse.org/mbox/","series":[{"id":499808,"url":"http://patchwork.ozlabs.org/api/1.0/series/499808/?format=json","date":"2026-04-14T09:48:56","name":"tree-optimization/124875 - re-instantiate alias-set code in PRE","version":1,"mbox":"http://patchwork.ozlabs.org/series/499808/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2223060/checks/","tags":{},"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\tdkim=pass (1024-bit key;\n unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256\n header.s=susede2_rsa header.b=Okr/klA0;\n\tdkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=88LQutSd;\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.a=rsa-sha256 header.s=susede2_rsa header.b=Okr/klA0;\n\tdkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=88LQutSd;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.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;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256\n header.s=susede2_rsa header.b=Okr/klA0;\n\tdkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=88LQutSd;\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.a=rsa-sha256 header.s=susede2_rsa header.b=Okr/klA0;\n\tdkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=88LQutSd","sourceware.org;\n dmarc=pass (p=none dis=none) header.from=suse.de","sourceware.org; spf=pass smtp.mailfrom=suse.de","server2.sourceware.org;\n arc=none smtp.remote-ip=195.135.223.131","smtp-out2.suse.de;\n dkim=pass header.d=suse.de header.s=susede2_rsa header.b=\"Okr/klA0\";\n dkim=pass header.d=suse.de header.s=susede2_ed25519 header.b=88LQutSd"],"Received":["from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 4fvzyJ300vz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 19:49:28 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 81FAD4BA2E10\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 09:49:26 +0000 (GMT)","from smtp-out2.suse.de (smtp-out2.suse.de [195.135.223.131])\n by sourceware.org (Postfix) with ESMTPS id C29E54BA2E1E\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 09:48:57 +0000 (GMT)","from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org\n [IPv6:2a07:de40:b281:104:10:150:64:97])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-out2.suse.de (Postfix) with ESMTPS id B55D05BD18\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 09:48:56 +0000 (UTC)","from imap1.dmz-prg2.suse.org (localhost [127.0.0.1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 982C34B3A5\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 09:48:56 +0000 (UTC)","from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167])\n by imap1.dmz-prg2.suse.org with ESMTPSA id +nuNI4gN3ml7YwAAD6G6ig\n (envelope-from <rguenther@suse.de>)\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 09:48:56 +0000"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 81FAD4BA2E10","OpenDKIM Filter v2.11.0 sourceware.org C29E54BA2E1E"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org C29E54BA2E1E","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org C29E54BA2E1E","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776160138; cv=none;\n b=kngDyObWxArepxLU+oPp3pFUZbpiHiEuGaWV5u8Az+aerxu9dYv7hUJ46tZ5dRtFg8xAXOPwrNrZfPc1I/bXYjsz4gWSX9ep317Xx8qtxxkXRZDtu7P/tkoN83d8G0VxgUrIY5qnVuf6QBEnwsO1d5ODX2HjCajmYZG5bOdDuQg=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776160138; c=relaxed/simple;\n bh=p52bOufjPiQqYvdvRxRx3Zsb1xl15iSJF/MK/TSExlM=;\n h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:Date:\n From:To:Subject:MIME-Version:Message-Id;\n b=Rmk06atloLUG0W5v4duuu97j6xa63vZxFbBwDBbNS162p72LcyAtDW9+6ZWm5PxpDzOQgAkg0ONrSI3nCgOD13JInasNfeqh2uFETTc2uSVwAwo1CKLETtBbpo7N/dzHHgoxLvUc+eu22R5XQeZLFpTy8V4AkaQQBuC2zvfCkvc=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n t=1776160136; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:\n mime-version:mime-version:content-type:content-type;\n bh=mJbuEQbU57s+Qv7itIPJ5z1kGisgs/eEQ6ib/CZeRwk=;\n b=Okr/klA05W4LnOY8Zb3SCV8y+kmnAk2Fjw4EN9k2FwL9GbyGCfzATOl4gGKTDVfEWqPF+d\n ieJtOdVyjrxd1OaYjKZuv3nXhrOT2KboSeUr9PbHHSjLnVo4YxxK/vD6g8xTpv1oVeHzD/\n VghXE321K8k7Ube2i9WdMjK2vxBwM6A=","v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_ed25519; t=1776160136;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:\n mime-version:mime-version:content-type:content-type;\n bh=mJbuEQbU57s+Qv7itIPJ5z1kGisgs/eEQ6ib/CZeRwk=;\n b=88LQutSd7H/jEGBfv7rWuicnreRszAxUTOkHagP6PG0eXJQ5lmgB459wIZVyHruPpPWLDU\n Ol6QRWlUWKvRnbCA==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n t=1776160136; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:\n mime-version:mime-version:content-type:content-type;\n bh=mJbuEQbU57s+Qv7itIPJ5z1kGisgs/eEQ6ib/CZeRwk=;\n b=Okr/klA05W4LnOY8Zb3SCV8y+kmnAk2Fjw4EN9k2FwL9GbyGCfzATOl4gGKTDVfEWqPF+d\n ieJtOdVyjrxd1OaYjKZuv3nXhrOT2KboSeUr9PbHHSjLnVo4YxxK/vD6g8xTpv1oVeHzD/\n VghXE321K8k7Ube2i9WdMjK2vxBwM6A=","v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_ed25519; t=1776160136;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:\n mime-version:mime-version:content-type:content-type;\n bh=mJbuEQbU57s+Qv7itIPJ5z1kGisgs/eEQ6ib/CZeRwk=;\n b=88LQutSd7H/jEGBfv7rWuicnreRszAxUTOkHagP6PG0eXJQ5lmgB459wIZVyHruPpPWLDU\n Ol6QRWlUWKvRnbCA=="],"Date":"Tue, 14 Apr 2026 11:48:56 +0200 (CEST)","From":"Richard Biener <rguenther@suse.de>","To":"gcc-patches@gcc.gnu.org","Subject":"[PATCH] tree-optimization/124875 - re-instantiate alias-set code in\n PRE","MIME-Version":"1.0","Content-Type":"text/plain; charset=US-ASCII","Message-Id":"<20260414094856.982C34B3A5@imap1.dmz-prg2.suse.org>","X-Rspamd-Action":"no action","X-Rspamd-Server":"rspamd2.dmz-prg2.suse.org","X-Spamd-Result":"default: False [-4.51 / 50.00]; BAYES_HAM(-3.00)[100.00%];\n NEURAL_HAM_LONG(-1.00)[-1.000];\n R_DKIM_ALLOW(-0.20)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519];\n NEURAL_HAM_SHORT(-0.20)[-1.000]; MIME_GOOD(-0.10)[text/plain];\n MX_GOOD(-0.01)[];\n RBL_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[2a07:de40:b281:104:10:150:64:97:from];\n RCVD_VIA_SMTP_AUTH(0.00)[]; RCPT_COUNT_ONE(0.00)[1];\n MISSING_XM_UA(0.00)[]; ARC_NA(0.00)[];\n SPAMHAUS_XBL(0.00)[2a07:de40:b281:104:10:150:64:97:from];\n MIME_TRACE(0.00)[0:+];\n RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[2a07:de40:b281:106:10:150:64:167:received];\n RCVD_TLS_ALL(0.00)[];\n DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519];\n FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[];\n FUZZY_RATELIMITED(0.00)[rspamd.com]; RCVD_COUNT_TWO(0.00)[2];\n TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_NONE(0.00)[];\n PREVIOUSLY_DELIVERED(0.00)[gcc-patches@gcc.gnu.org];\n DKIM_TRACE(0.00)[suse.de:+]","X-Rspamd-Queue-Id":"B55D05BD18","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>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"},"content":"The following re-instantiates the alias-set compatibility check in PRE\nthat I removed based on lack of test coverage.  As with the alignment\nand access size compatibility checks this is now done in prefer\nwhich is used to prune the expression set considered for PRE and\ncode hoisting.  Compared to the previous code this does not alter\nexpressions but instead ceases to do PRE or code hoisting if the\nexpressions representing the value can not be made compatible by\nchosing one.\n\nBootstrapped and tested on x86_64-unknown-linux-gnu, pushed.\n\n\tPR tree-optimization/124875\n\t* tree-ssa-pre.cc (prefer): Also compare TBAA set and base_set.\n\tRefactor computing the final prefered expression, do early outs\n\tand allow same prefered expressions.\n\t(sorted_array_from_bitmap_set): Fix thinko that prevented\n\tthe last expression in the set of being excluded.\n\n\t* g++.dg/torture/pr124875.C: New testcase.\n---\n gcc/testsuite/g++.dg/torture/pr124875.C | 112 ++++++++++++++++++++++++\n gcc/tree-ssa-pre.cc                     |  60 ++++++++++---\n 2 files changed, 160 insertions(+), 12 deletions(-)\n create mode 100644 gcc/testsuite/g++.dg/torture/pr124875.C","diff":"diff --git a/gcc/testsuite/g++.dg/torture/pr124875.C b/gcc/testsuite/g++.dg/torture/pr124875.C\nnew file mode 100644\nindex 00000000000..9dab353d65b\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/torture/pr124875.C\n@@ -0,0 +1,112 @@\n+// { dg-do run }\n+\n+#include <memory>  // unique_ptr\n+#include <utility> // std::move\n+\n+namespace {\n+\n+template <typename T, unsigned N>\n+struct SmallVector {\n+  alignas(T) char InlineElts[sizeof(T) * N];\n+\n+  unsigned Size = 0;\n+  //[[gnu::optimize(0)]]\n+  T* begin() { return (T*)this->InlineElts; }\n+  //[[gnu::optimize(0)]]\n+  T* end() { return begin() + this->Size; }\n+\n+  [[gnu::optimize(0)]]\n+  ~SmallVector() {\n+    this->destroy_range(this->begin(), this->end());\n+  }\n+\n+  [[gnu::optimize(0)]]\n+  static void destroy_range(T *S, T *E) {\n+    while (S != E) {\n+      --E;\n+      E->~T();\n+    }\n+  }\n+\n+  //[[gnu::optimize(0)]]\n+  void push_back(T &&Elt) {\n+    ::new ((void *)this->end()) T(std::move(Elt));\n+    this->Size += 1;\n+  }\n+};\n+\n+////////////////////////\n+\n+template <class T> struct Expected {\n+  using E = std::unique_ptr<int>;\n+\n+  [[gnu::optimize(0)]]\n+  explicit Expected(T &&Val)\n+  {\n+    HasError = false;\n+    new (&t) T(std::forward<T>(Val));\n+  }\n+\n+  [[gnu::optimize(0)]]\n+  explicit Expected(Expected &&Other) {\n+    HasError = Other.HasError;\n+\n+    if (!HasError)\n+      new (&t) T(std::move(Other.t));\n+    else\n+      new (&e) E(std::move(Other.e));\n+  }\n+\n+  Expected &operator=(Expected &&Other) = delete;\n+\n+  //[[gnu::optimize(0)]]\n+  ~Expected() {\n+    if (!HasError)\n+      t.~T();\n+    else\n+      e.~E();\n+  }\n+\n+  [[gnu::optimize(0)]]\n+  T& get() {\n+    return t;\n+  }\n+\n+  union {\n+    T t;\n+    E e;\n+  };\n+  bool HasError;\n+};\n+\n+struct EA {\n+  bool destroyed;\n+\n+  [[gnu::optimize(0)]]\n+  EA() : destroyed(false) {}\n+  [[gnu::optimize(0)]]\n+  // catch double desruction\n+  ~EA() { if (destroyed) __builtin_abort();  destroyed = true; }\n+};\n+\n+[[gnu::optimize(0)]]\n+static std::unique_ptr<EA> mkEA() {\n+  return std::make_unique<EA>();\n+}\n+\n+//__attribute__((optimize(0)))\n+[[gnu::noinline]]\n+static void parseCallExpr_() {\n+  SmallVector<std::unique_ptr<EA>, 4> Args;\n+  Expected<std::unique_ptr<EA>> Arg =\n+      Expected<std::unique_ptr<EA>>(mkEA());\n+\n+  Args.push_back(std::move(Arg.get()));\n+}\n+\n+}\n+\n+[[gnu::optimize(0)]]\n+int main() {\n+  parseCallExpr_();\n+}\ndiff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc\nindex a665ef6ebe2..0e5eaf86bc7 100644\n--- a/gcc/tree-ssa-pre.cc\n+++ b/gcc/tree-ssa-pre.cc\n@@ -836,25 +836,57 @@ prefer (pre_expr a, pre_expr b)\n {\n   if (a->kind == REFERENCE && b->kind == REFERENCE)\n     {\n-      auto &oprsa = PRE_EXPR_REFERENCE (a)->operands;\n-      auto &oprsb = PRE_EXPR_REFERENCE (b)->operands;\n+      auto refa = PRE_EXPR_REFERENCE (a);\n+      auto refb = PRE_EXPR_REFERENCE (b);\n+      auto &oprsa = refa->operands;\n+      auto &oprsb = refb->operands;\n+      pre_expr palias = NULL;\n+      if (refa->set == refb->set\n+\t  && refa->base_set == refb->base_set)\n+\t;\n+      else if ((refb->set == refa->set\n+\t\t|| alias_set_subset_of (refb->set, refa->set))\n+\t       && (refb->base_set == refa->base_set\n+\t\t   || alias_set_subset_of (refb->base_set, refa->base_set)))\n+\tpalias = a;\n+      else if ((refa->set == refb->set\n+\t\t|| alias_set_subset_of (refa->set, refb->set))\n+\t       && (refa->base_set == refb->base_set\n+\t\t   || alias_set_subset_of (refa->base_set, refb->base_set)))\n+\tpalias = b;\n+      else\n+\t/* We have to chose an expression representation that can stand\n+\t   in for all others - there can be none, in which case we have\n+\t   to drop this PRE/hoisting opportunity.\n+\t   ???  Previously we've arranged for alias-set zero being used\n+\t   as fallback, but we do not really want to allocate a new expression\n+\t   here unless it proves to be absolutely necessary.  */\n+\treturn NULL;\n+      pre_expr p = palias;\n       if (oprsa.length () > 1 && oprsb.length () > 1)\n \t{\n \t  vn_reference_op_t vroa = &oprsa[oprsa.length () - 2];\n \t  vn_reference_op_t vrob = &oprsb[oprsb.length () - 2];\n \t  if (vroa->opcode == MEM_REF && vrob->opcode == MEM_REF)\n \t    {\n-\t      pre_expr palign = NULL, psize = NULL;\n \t      /* We have to canonicalize to the more conservative alignment.\n \t\t gcc.dg/torture/pr65270-?.c.*/\n+\t      pre_expr palign = NULL;\n \t      if (TYPE_ALIGN (vroa->type) < TYPE_ALIGN (vrob->type))\n \t\tpalign = a;\n \t      else if (TYPE_ALIGN (vroa->type) > TYPE_ALIGN (vrob->type))\n \t\tpalign = b;\n+\t      if (palign)\n+\t\t{\n+\t\t  if (p && p != palign)\n+\t\t    return NULL;\n+\t\t  p = palign;\n+\t\t}\n \t      /* We have to canonicalize to the more conservative (smaller)\n \t\t innermost object access size.  gcc.dg/torture/pr110799.c.  */\n \t      if (TYPE_SIZE (vroa->type) != TYPE_SIZE (vrob->type))\n \t\t{\n+\t\t  pre_expr psize = NULL;\n \t\t  if (!TYPE_SIZE (vroa->type))\n \t\t    psize = a;\n \t\t  else if (!TYPE_SIZE (vrob->type))\n@@ -870,15 +902,19 @@ prefer (pre_expr a, pre_expr b)\n \t\t\tpsize = b;\n \t\t    }\n \t\t  /* ???  What about non-constant sizes?  */\n+\t\t  if (psize)\n+\t\t    {\n+\t\t      if (p && p != psize)\n+\t\t\treturn NULL;\n+\t\t      p = psize;\n+\t\t    }\n \t\t}\n-\t      if (palign && psize)\n-\t\treturn NULL;\n-\t      /* Note we cannot leave it undecided because when having\n-\t\t more than two expressions we have to keep doing\n-\t\t pariwise reduction.  */\n-\t      return palign ? palign : (psize ? psize : b);\n \t    }\n \t}\n+      /* Note we cannot leave it undecided because when having\n+\t more than two expressions we have to keep doing\n+\t pariwise reduction.  */\n+      return p ? p : b;\n     }\n   /* Always prefer an non-REFERENCE, avoiding the above mess.  */\n   else if (a->kind == REFERENCE)\n@@ -1028,12 +1064,12 @@ sorted_array_from_bitmap_set (bitmap_set_t set, bool for_insertion)\n \t\t    break;\n \t\tfor (k = j;; ++k)\n \t\t  {\n-\t\t    if (k == result.length () - 1\n-\t\t\t|| result[k + 1]->value_id != result[i]->value_id)\n-\t\t      break;\n \t\t    if (result[k]->kind == REFERENCE)\n \t\t      bitmap_set_bit (exclusions,\n \t\t\t\t      get_expression_id (result[k]));\n+\t\t    if (k == result.length () - 1\n+\t\t\t|| result[k + 1]->value_id != result[i]->value_id)\n+\t\t      break;\n \t\t  }\n \t\ti = k;\n \t      }\n","prefixes":[]}