From patchwork Fri Dec 5 17:01:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantinos Eleftheriou X-Patchwork-Id: 126001 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1D82C4CD201D for ; Fri, 5 Dec 2025 16:54:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1D82C4CD201D Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=vrull.eu header.i=@vrull.eu header.a=rsa-sha256 header.s=google header.b=VE2ABcJw X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) by sourceware.org (Postfix) with ESMTPS id DCBC24C900C2 for ; Fri, 5 Dec 2025 16:53:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DCBC24C900C2 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DCBC24C900C2 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764953625; cv=none; b=GQktZJxdM/KF+LsmhsAvX5h5hozJJ/oMyi2Pvc3BtDfaQzOJR6LalaBQ1ddahS0yfH6N76NYG/ZUaiHO2SJiPaDnTKcQwDHgnwx7//AzOgf7dbtxPKw5gORODObsiSDEqc+0o80qCVJQPaalsA9YTScCXT7SGUdGB5+YLWhJevw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764953625; c=relaxed/simple; bh=toDazKvUw673x6zBwsJ6JBqH90LTR6EEiaGzi9k3bWI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=mspUD/2b655Wu5OdFc8kUxSu3ZkvhYTxiBuGkngCV8VQNzha2a2O1i5tffRw/MdpkJ4gbqErq7e750RX1GG2iGCxWYSkU4NtoKCp0zKOPDxMwCIpCWKZjQ/20ed0dEf7+y6xFmNvs3q5JQqo/lfD7DCpz3PTkU2652PgeZ2xF3s= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DCBC24C900C2 Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-b734fcbf1e3so510712666b.3 for ; Fri, 05 Dec 2025 08:53:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1764953623; x=1765558423; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qcrz81Z1P1dVCWGKskklINBOIhTrrNwnJI7jU1WcEVM=; b=VE2ABcJwySQRF48VgtuIaKS9Cdq9GJo4hwONeAqddXbyr9yqLKdOHNxnkc16S00UdV yzariJQBlXz/OvFOu66lNFasLI7qOElgDcQkVGBVZYOoUU7GrPfCDZ8NNSYTm44vLPBo 3H4aXL/AJGQgDUJf01nKwp/hVcLAkLT/oRZaoxnPPfDkp+LEe8fSo9UESymyZAr/oV7w d2XKktV2Xl15l6a06ZyUkl8UpsDeRl2yAnfCNKjMFNKwEQiDFhOlEr+uYX7LXE8B/XbN XptsV91iTiFQgAt6goQ0f32c6wrrmatvw/oqqYEsp1KhsgsHWh8VAlCvFi4HioWxIMqV oN1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764953623; x=1765558423; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qcrz81Z1P1dVCWGKskklINBOIhTrrNwnJI7jU1WcEVM=; b=GKUILh/jzxhIOKeysu1Rn+3WIJtmLua+sEHpy3Yn203O0NtuT8sCBzyjxQuAo6jv29 ghWCv8s9twumO8aDx6rQiBM7ZIJOgxulbObck8NvpIUQr9UgKlhfL4VvilUqtadUkr5T Z+fokphc/jJaHk4Od+quxdtST+D97dfzfF+NsI01q5HPvOpjy852oqsNOOLKy06Vo2pB qwDLLvP2PhVRpC+hq9PweACboAnYEHERJGnxwS0/fUwIyP4Qzm3ZvI4P0/mVewotU7Vg FEKvT1Gdp1SCD7VqJQXfQd9TXHMrZvmVBQlQOyL6XPYsDmLqidBy3HIWAL5nhJbI+pIJ w09g== X-Gm-Message-State: AOJu0YzF92TQ3+dbFy9s1jLJdffZgmcHvSY/QOj8OaHtaAB/xMmarc25 KH6QCdUyMoMzNRVTfvsuGY7nIzoglpEgbOfpwcFejE6ZfQXoQSwodrKTkP7fYOLNvoEOWjCQNmp BW/xOH58= X-Gm-Gg: ASbGncsQDS/Et6PjIoKPIdoPmoii6Z/a47hrhJ/1wXkkkbqgLMgh902M68kdWMWENRa mb9jqLTYoGoBBjjUc4brMVlKrkUfbN3axRqv4V6iAk7TQDqWNG53gSJyVHh5oISa7AGORfKFDQf Z9I5pHbhX8a0axSnLSW1uJPOSrw6mqdOX14i25rYUzfCr65vHeomkRCPKU1fdLVOfb6iaP4p3iB R8ayaR526Ghr9ecgL/5JVGQnnLpgHntHI4EIHw0ESw4ZLKxfd3QBv6n2fe50ST17CzMI4fvwlVi j3yO1Ezb60+atkmOBgoBLaok00yJaOLg472l/Z/sM6b5mfld9OG/xrkgoSKmOsEVGXauyokfAu7 liyJkYKMVloxM07TVHBEqBmmaGRYctF/lfDvaFvygwWZBFnYAlKx32LE8T8esfnAZk+I8JS06qz ildoe7Al1DtXlUijFwlKeGxGkTXR4szh6rUf1dCvvuLWuUuojpTtz8Hvc/JtY06ykXthEt3dclR DnMoFY= X-Google-Smtp-Source: AGHT+IHKt0Ai8OJw0v5FUkoWya343wzjl4TzZ4wSUMhfunq2DZVzIv3Rb2MbCcVqUTdp1YrVgG2aDw== X-Received: by 2002:a17:907:6e8f:b0:b7a:1be3:a584 with SMTP id a640c23a62f3a-b7a1be3a9e9mr76291666b.65.1764953623559; Fri, 05 Dec 2025 08:53:43 -0800 (PST) Received: from ampereone1.sec.univie.ac.at (ampereone1.sec.univie.ac.at. [131.130.126.106]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b79f4a558b3sm418097266b.69.2025.12.05.08.53.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Dec 2025 08:53:43 -0800 (PST) From: Konstantinos Eleftheriou To: gcc-patches@gcc.gnu.org, Philipp Tomsich Cc: Richard Biener , Andrew Pinski , Konstantinos Eleftheriou Subject: [PATCH 1/2] ifcombine: Add tree-ssa-ifcombine.h and update function signatures Date: Fri, 5 Dec 2025 18:01:46 +0100 Message-ID: <20251205170158.1742149-2-konstantinos.eleftheriou@vrull.eu> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251205170158.1742149-1-konstantinos.eleftheriou@vrull.eu> References: <20251205170158.1742149-1-konstantinos.eleftheriou@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org This patch adds the tree-ssa-ifcombine.h header file, with the function declarations for `recognize_if_then_else` and `same_phi_args_p` and removes 'static' from the definitions in tree-ssa-ifcombine.cc, so that they can be used in other passes. gcc/ChangeLog: * tree-ssa-ifcombine.cc (recognize_if_then_else): Removed 'static' and default value for 'succs_any'. (same_phi_args_p): Removed 'static'. * tree-ssa-ifcombine.h: New file. Signed-off-by: Konstantinos Eleftheriou --- gcc/tree-ssa-ifcombine.cc | 7 ++++--- gcc/tree-ssa-ifcombine.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 gcc/tree-ssa-ifcombine.h diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc index 1fff92341982..9dd2119ed87a 100644 --- a/gcc/tree-ssa-ifcombine.cc +++ b/gcc/tree-ssa-ifcombine.cc @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "ssa.h" #include "tree-pretty-print.h" +#include "tree-ssa-ifcombine.h" /* rtl is needed only because arm back-end requires it for BRANCH_COST. */ #include "fold-const.h" @@ -94,10 +95,10 @@ known_succ_p (basic_block cond_bb) basic-blocks to make the pattern match. If SUCCS_ANY, *THEN_BB and *ELSE_BB will not be filled in, and they will be found to match even if reversed. */ -static bool +bool recognize_if_then_else (basic_block cond_bb, basic_block *then_bb, basic_block *else_bb, - bool succs_any = false) + bool succs_any) { edge t, e; @@ -202,7 +203,7 @@ forwarder_block_to (basic_block bb, basic_block to_bb) BB2 to DEST are the same. This makes the CFG merge point free from side-effects. Return true in this case, else false. */ -static bool +bool same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest) { edge e1 = find_edge (bb1, dest); diff --git a/gcc/tree-ssa-ifcombine.h b/gcc/tree-ssa-ifcombine.h new file mode 100644 index 000000000000..251039fe77ab --- /dev/null +++ b/gcc/tree-ssa-ifcombine.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2016-2025 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +GCC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_TREE_SSA_IFCOMBINE_H +#define GCC_TREE_SSA_IFCOMBINE_H + +bool same_phi_args_p (basic_block, basic_block, basic_block); + +bool recognize_if_then_else (basic_block, basic_block *, basic_block *, + bool succs_any = false); + +#endif + From patchwork Fri Dec 5 17:01:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantinos Eleftheriou X-Patchwork-Id: 126002 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DF8FA4CCCA11 for ; Fri, 5 Dec 2025 16:56:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DF8FA4CCCA11 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=vrull.eu header.i=@vrull.eu header.a=rsa-sha256 header.s=google header.b=E+acQRs0 X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) by sourceware.org (Postfix) with ESMTPS id D23E54CCCA02 for ; Fri, 5 Dec 2025 16:53:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D23E54CCCA02 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=vrull.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=vrull.eu ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D23E54CCCA02 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764953626; cv=none; b=VKu3YmLyKmnE3kmlAoGZgAdNL+4dTRxDZRLf4Bg3OQrGghh3bCQ5QVYoZDCCMyNir16BrGeNCM9pz8UHLiGy+RivHxarP89Dt5oZKXouTXw8kxkAH4nKc8d30hCRU35Ju7UPfMaxLUkqupbmvAl9i1SHxdcBt+EesI2I10otHgg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764953626; c=relaxed/simple; bh=BF53rrxjb4AIAnG9pUK+c5/4wbIO4+HbFBLnAGiSnE4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=HPC90mlheeZ6oLv1DsiVskZ+NHXB/k+Tm2XAR7Mv9iAfW5LhaAWSvJlFAom0TOLooiKR/g8tJAGuNXo45+vJXeARnf7ny1VnGH92cbi6/vlxQVA5XZHOVSbyxu1tq6C4tTgbEXDapdAuydMTOAlaJsDM2KXtpykyX3a/8Nwhf4k= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D23E54CCCA02 Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-b79f8f7ea43so349553666b.2 for ; Fri, 05 Dec 2025 08:53:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vrull.eu; s=google; t=1764953624; x=1765558424; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hpNrQLnhtIJqkyEkx4LkIEWEIE+Id324D8q8CzyIA5o=; b=E+acQRs0KXL0JViKH/93DhgMGCzpP5MgN0bKJ6U4sytjbemvNRZ3JaFLD+B6ixsPuQ JIuIwHJUjFRtEfwTiMAt64wSfCl7dzwHpgJppGT1s+UXuNpvGsW6OraYtACLn/IPX9d/ At0OPTUVPcfctBtve2D2T2O+rMsB8F0oYpTKFG4nZLbgcJd92sl02oOvHaNOo0GzYdml ipQg6zWA6rp8D0Y+ItC1z5HNyqvBPP+0yTdejbayhMhj0GG8j5pwiyk0CY73T18FqDlc RDt/mp7JnNQz9Z2T1zZnbTPes+wcPruMXasrsYgc95oH4Ezqo8umSMyVs09USArUOoO2 M/Gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764953624; x=1765558424; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hpNrQLnhtIJqkyEkx4LkIEWEIE+Id324D8q8CzyIA5o=; b=JXurf7qMYW04n4nDB1/t/GrYtR9CnwTLM034TQcguvkIT7uYvbmphSxV6+37K6q2hM cf+C7mxgRg0O1rmdC3ODSRUa0+riDtqfCPhcKNHK8kmcbyn0Cct22+pwInKLRqUczwI9 gXn0FW8c600c2KC240Rd7EMkzQQ+OgACuPLFAeByUiaIzMp41tSdQ4mQA0idRMdqCoqk hEMJcAXm4gII8vRlOfDJbPx60YUQv9klCtz+UczoZP/5rHIIWNRU5S8mipsrVNCpBnhe 39jPWGrM2OuQ1boZywVTvFArvLy89B5u9A+6d/3oTP9FgqR5LWaWPgWxvjG3+bdCJXvm 6jPg== X-Gm-Message-State: AOJu0YyQK3IycsEJLsWxx5Cn28I41u1QdWfatKlgd+lcBGSV/89cLTmy dKFUIOKxXHmllmB4dTQeFiG8y057bBtzXY8LrQSa4jMtc78BlKlI6IugVWHflW0fGhx3V4hJsWT WaCxj+XY= X-Gm-Gg: ASbGncuqCs89y8axr3mHoq7UHJoSyqZJKduyij8VHtUPPeRYqTqtAxGHy+phaz1E9tg 0Iwb365Vk+rNZetktl8oISWnYHydv+2PB9VPyTcYuPIjXNM684SgEOAoSXerylreNnOzQUsA6XS /mV/KDRegWNTubD+zuWv4alaja1SjCrlTs9J7S2fQmnXQDiSiPxd6g6pw8np6Fcbid2KPkjGNRm DNMMwx1ewssRRQJ7EeiyvnKyAWKU4gC9knD61cbReBt9fKEOietlsuC39Fw9dJ7TYcOvg0xDKNe JSZezO0xBWJWobVruCSScKBDQ6R3PF0g5niW8UuHNzgovyhNg0NuPpJ0SyGvbU2AVsb0yqu5zcC ZCh6YCzXGsVg6EBKNDk9kL1sog8Mwq+iWixkVCFdC9BqSAhoxuJ8eBuE7cds7weYncdFcIIVkHx ErYFyzMpEzPKDz7QhE01eeEfvMO9lmkdQTDRDCttfSeRIc3Eln5coaeImgEBf4vpMbdNogpMWup 2/3+L4= X-Google-Smtp-Source: AGHT+IGmp8u18t2NHb7uz5yJp/xkPQm5e8qFVho0IokNolMD4InS4mBGHz1bp4gp3welOkVRzz36kA== X-Received: by 2002:a17:906:f591:b0:b76:277b:9a58 with SMTP id a640c23a62f3a-b79ec3ed62fmr682016966b.9.1764953624440; Fri, 05 Dec 2025 08:53:44 -0800 (PST) Received: from ampereone1.sec.univie.ac.at (ampereone1.sec.univie.ac.at. [131.130.126.106]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b79f4a558b3sm418097266b.69.2025.12.05.08.53.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Dec 2025 08:53:44 -0800 (PST) From: Konstantinos Eleftheriou To: gcc-patches@gcc.gnu.org, Philipp Tomsich Cc: Richard Biener , Andrew Pinski , Konstantinos Eleftheriou Subject: [PATCH 2/2] tail-merge: Combine sequential comparisons leading to the merged block Date: Fri, 5 Dec 2025 18:01:47 +0100 Message-ID: <20251205170158.1742149-3-konstantinos.eleftheriou@vrull.eu> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251205170158.1742149-1-konstantinos.eleftheriou@vrull.eu> References: <20251205170158.1742149-1-konstantinos.eleftheriou@vrull.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org If we consider code like: if (bar1 == x) return foo(); if (bar2 != y) return foo(); return 0; We would like the ifcombine pass to convert this to: if (bar1 == x || bar2 != y) return foo(); return 0; The ifcombine pass can handle this transformation but it is ran very early and it misses the opportunity because there are two seperate blocks for foo(). This patch updates the tail-merging pass so that, after the block merge, it attempts to combine conditions in the predecessors of the merged block in its immediate dominator. The optimization is restricted to targets with support for conditional comparisons. An XFAIL in gcc.dg/guality/pr54693-2.c now triggers only when `-flto` w/o `-fno-use-linker-plugin` is used. The generated code and debug info seems correct, so we have adjusted the clause. PR tree-optimization/102793 gcc/ChangeLog: * tree-ssa-tail-merge.cc (INCLUDE_MEMORY): Added definition. (struct cond_combine_info): New struct. (phi_args_def_p): New function. (maybe_combine_conditions): New function. (apply_clusters): Added call to `maybe_combine_conditions`. (tail_merge_optimize): Added call to `mark_ssa_maybe_undefs`. gcc/testsuite/ChangeLog: * gcc.dg/guality/pr54693-2.c: Update 'x-fail' clause. * gcc.dg/tree-ssa/pr102793-1.c: New test. * gcc.dg/tree-ssa/pr102793-2.c: New test. Signed-off-by: Konstantinos Eleftheriou --- gcc/testsuite/gcc.dg/guality/pr54693-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr102793-1.c | 50 ++++ gcc/testsuite/gcc.dg/tree-ssa/pr102793-2.c | 51 ++++ gcc/tree-ssa-tail-merge.cc | 258 +++++++++++++++++++++ 4 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102793-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102793-2.c diff --git a/gcc/testsuite/gcc.dg/guality/pr54693-2.c b/gcc/testsuite/gcc.dg/guality/pr54693-2.c index 229ef0efbea0..9d0080782410 100644 --- a/gcc/testsuite/gcc.dg/guality/pr54693-2.c +++ b/gcc/testsuite/gcc.dg/guality/pr54693-2.c @@ -18,7 +18,7 @@ foo (int x, int y, int z) while (x > 3 && y > 3 && z > 3) { /* { dg-final { gdb-test .+2 "i" "v + 1" } } */ /* { dg-final { gdb-test .+1 "x" "10 - i" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" } } } } } */ - bar (i); /* { dg-final { gdb-test . "y" "20 - 2 * i" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-Os" } } } } } */ + bar (i); /* { dg-final { gdb-test . "y" "20 - 2 * i" { xfail { aarch64*-*-* && { { any-opts "-flto" } && { no-opts "-fno-use-linker-plugin" } } } } } } */ /* { dg-final { gdb-test .-1 "z" "30 - 3 * i" { xfail { aarch64*-*-* && { any-opts "-fno-fat-lto-objects" "-Os" } } } } } */ i++, x--, y -= 2, z -= 3; } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102793-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr102793-1.c new file mode 100644 index 000000000000..fc02c92059ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102793-1.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ +/* { dg-skip-if "requires ccmp support" { ! { aarch64*-*-* || apxf } } } */ +/* { dg-options "-O3 -fdump-tree-pre" } */ + +typedef unsigned long uint64_t; + +int foo(void); + +int ccmp(uint64_t* s1, uint64_t* s2) +{ + uint64_t d1, d2, bar; + d1 = *s1++; + d2 = *s2++; + bar = (d1 ^ d2) & 0xabcd; + if (bar == 0 || d1 != d2) + return foo(); + return 0; +} + +int noccmp0(uint64_t* s1, uint64_t* s2) +{ + uint64_t d1, d2, bar; + + d1 = *s1++; + d2 = *s2++; + bar = (d1 ^ d2) & 0xabcd; + if (bar == 0) + return foo(); + if (d1 != d2) + return foo(); + return 0; +} + +int noccmp1(uint64_t* s1, uint64_t* s2) +{ + uint64_t d1, d2, d3, d4, bar; + d1 = *s1++; + d2 = *s2++; + d3 = *s1++; + d4 = *s2++; + bar = (d1 ^ d2) & 0xabcd; + if (bar == 0) + return foo(); + if (d3 != d4) + return foo(); + return 0; +} + +/* Check for condition assignments for noccmp0 and noccmp1. */ +/* { dg-final { scan-tree-dump-times {_\d+ = bar_\d+ == 0;\n _\d+ = d\d+_\d+ != d\d+_\d+;} 2 "pre" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102793-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr102793-2.c new file mode 100644 index 000000000000..6e8674781563 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102793-2.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-skip-if "requires ccmp support" { ! { aarch64*-*-* || apxf } } } */ +/* { dg-options "-O3 -fdump-tree-pre" } */ + +typedef unsigned long uint64_t; + +int foo(void); + +uint64_t noccmp0(uint64_t* s1, uint64_t* s2) +{ + uint64_t d1, d2, d3, d4, bar; + d1 = *s1++; + d2 = *s2++; + d3 = *s1++; + d4 = *s2++; + bar = (d1 ^ d2) & 0xabcd; + if (bar == 0) + return foo(); + if (d3 != d4) + d3++; + else + return foo(); + return d3; +} + +uint64_t noccmp1(uint64_t* s1, uint64_t* s2) +{ + uint64_t d1, d2, d3, d4, bar; + d1 = *s1++; + d2 = *s2++; + d3 = *s1++; + d4 = *s2++; + bar = (d1 ^ d2) & 0xabcd; + if (bar == 0) + d3++; + else + return foo(); + if (d3 > d4) + d3++; + else if (d1 != d2) + return foo (); + d3 = d3 + d4 + 1; + return d3; +} + +/* Check for condition assignments in the case that the transformation + is applied. + The transformation should not be applied on noccmp1, where the foo call is + on the false branch of the first condition. */ +/* { dg-final { scan-tree-dump-times {_\d+ = bar_\d+ == 0;\n _\d+ = d\d+_\d+ == d\d+_\d+;} 1 "pre" } } */ +/* { dg-final { scan-tree-dump-times {if \(bar_\d+ == 0\)} 1 "pre" } } */ \ No newline at end of file diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc index 857e91c206b3..f1f81646a3a4 100644 --- a/gcc/tree-ssa-tail-merge.cc +++ b/gcc/tree-ssa-tail-merge.cc @@ -189,6 +189,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "backend.h" +#include "target.h" #include "tree.h" #include "gimple.h" #include "cfghooks.h" @@ -202,10 +203,17 @@ along with GCC; see the file COPYING3. If not see #include "tree-cfg.h" #include "tree-into-ssa.h" #include "tree-ssa-sccvn.h" +#include "tree-ssa-ifcombine.h" #include "cfgloop.h" #include "tree-eh.h" #include "tree-cfgcleanup.h" +#define INCLUDE_MEMORY +#include +#include "gimple-pretty-print.h" +#include "tree-ssa.h" +#include "algorithm" + const int ignore_edge_flags = EDGE_DFS_BACK | EDGE_EXECUTABLE; /* Describes a group of bbs with the same successors. The successor bbs are @@ -277,6 +285,18 @@ struct aux_bb_info basic_block dep_bb; }; +/* Info for maybe_combine_conditions. */ + +struct cond_combine_info +{ + /* Conditional expression that leads to the merged block. */ + gcond *bb_cond_stmt; + /* Block that contains the conditional expression. */ + basic_block cond_bb; + /* True if the merged block resides in the condition's else branch. */ + bool in_else_branch; +}; + /* Macros to access the fields of struct aux_bb_info. */ #define BB_SIZE(bb) (((struct aux_bb_info *)bb->aux)->size) @@ -1707,6 +1727,238 @@ replace_block_by (basic_block bb1, basic_block bb2) static bitmap update_bbs; +static bool phi_args_def_p (basic_block bb, sbitmap visited) +{ + if (bitmap_bit_p (visited, bb->index)) + return true; + + bitmap_set_bit (visited, bb->index); + + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, bb->succs) + { + basic_block succ = e->dest; + gphi_iterator gpi; + + for (gpi = gsi_start_phis (succ); !gsi_end_p (gpi); gsi_next (&gpi)) + { + gphi *phi = gpi.phi (); + use_operand_p use; + ssa_op_iter iter; + + FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE) + { + tree var = USE_FROM_PTR (use); + + if (TREE_CODE (var) != SSA_NAME) + continue; + + if (ssa_name_maybe_undef_p (var)) + return false; + } + } + + if (!phi_args_def_p (succ, visited)) + return false; + } + + return true; +} + +/* Try to combine conditions with edges that lead to BB in its immediate + dominator. Nothing is done for targets that don't support conditional + comparisons. */ + +static void +maybe_combine_conditions (basic_block bb) +{ + if (!targetm.have_ccmp ()) + return; + + basic_block imm_dominator = get_immediate_dominator (CDI_DOMINATORS, bb); + + edge e; + edge_iterator ei; + bool bb_in_else_branch = false; + auto_vec comb_conds (2); + + /* Check that the immediate dominator is found and has two successors and + the merged block has two predecessors. */ + if (!imm_dominator || imm_dominator->succs->length () != 2 + || bb->preds->length () != 2) + return; + + /* Find conditions in if-statements that lead to bb. */ + int index = 0; + int imm_dom_index = -1; + unsigned int non_imm_dom_index; + FOR_EACH_EDGE (e, ei, bb->preds) + { + basic_block then_tmp = NULL; + basic_block else_tmp = NULL; + bb_in_else_branch = recognize_if_then_else (e->src, &then_tmp, &bb); + if (recognize_if_then_else (e->src, &bb, &else_tmp) + || bb_in_else_branch) + { + gcond *cond = safe_dyn_cast (*gsi_last_bb (e->src)); + if (TREE_CODE_CLASS (gimple_cond_code (cond)) != tcc_comparison + || index == 2) + return; + + struct cond_combine_info cci; + cci.bb_cond_stmt = cond; + cci.cond_bb = e->src; + cci.in_else_branch = bb_in_else_branch; + comb_conds.quick_push (cci); + + if (cci.cond_bb == imm_dominator) + imm_dom_index = index; + else + non_imm_dom_index = index; + index++; + } + } + + /* Abort if the immediate dominator is not found in the blocks containing + the conditions or if only one block with a condition is found. */ + if (imm_dom_index == -1 || comb_conds.length () == 1) + return; + + /* Check if the non-immediate dominator block contains other non-debug + statements than the condition and abort in that case. */ + unsigned int stmt_count = 0; + gimple_stmt_iterator gsi + = gsi_start_bb (comb_conds[non_imm_dom_index].cond_bb); + for (; !gsi_end_p (gsi) && stmt_count < 2; gsi_next (&gsi)) + { + if (!is_gimple_debug (gsi_stmt (gsi))) + stmt_count++; + } + + bool other_bb_has_only_cond = stmt_count < 2; + if (!other_bb_has_only_cond) + return; + + basic_block imm_dom_block = comb_conds[imm_dom_index].cond_bb; + basic_block non_imm_dom_block = comb_conds[non_imm_dom_index].cond_bb; + + /* Ensure that the other block is a successor of the immediate dominator, + that phi arguments from both condition blocks to bb are + the same and that phi arguments found starting from the other block + are defined on all paths. */ + auto_sbitmap visited (last_basic_block_for_fn (cfun)); + bitmap_clear (visited); + if ((!find_edge (imm_dom_block, non_imm_dom_block)) + || !same_phi_args_p (imm_dom_block, non_imm_dom_block, bb) + || !phi_args_def_p (non_imm_dom_block, visited)) + return; + + /* Convert condition statements to tree nodes. */ + gcond *imm_dom_cond = comb_conds[imm_dom_index].bb_cond_stmt; + gcond *non_imm_dom_cond = comb_conds[non_imm_dom_index].bb_cond_stmt; + tree bb_cond1_lhs = gimple_cond_lhs (imm_dom_cond); + tree bb_cond1_rhs = gimple_cond_rhs (imm_dom_cond); + tree bb_cond2_lhs = gimple_cond_lhs (non_imm_dom_cond); + tree bb_cond2_rhs = gimple_cond_rhs (non_imm_dom_cond); + + tree cond1_expr = build2 (gimple_cond_code (imm_dom_cond), + TREE_TYPE (bb_cond1_lhs), + bb_cond1_lhs, bb_cond1_rhs); + + tree cond2_expr = build2 (gimple_cond_code (non_imm_dom_cond), + TREE_TYPE (bb_cond2_lhs), + bb_cond2_lhs, bb_cond2_rhs); + + /* Fix the conditional expressions, so that the combined expression is + correct when the remaining block is reached through the else branch. */ + tree_code bool_op = BIT_IOR_EXPR; + bool non_imm_dom_in_else_branch + = comb_conds[non_imm_dom_index].in_else_branch; + if (comb_conds[imm_dom_index].in_else_branch) + bool_op = BIT_AND_EXPR; + + if ((!non_imm_dom_in_else_branch && bool_op == BIT_AND_EXPR) + || (non_imm_dom_in_else_branch && bool_op == BIT_IOR_EXPR)) + { + cond2_expr = invert_truthvalue (cond2_expr); + if (FLOAT_TYPE_P (TREE_TYPE (cond2_expr))) + return; + } + + gsi = gsi_last_bb (imm_dominator); + gimple *last_stmt = *gsi; + + /* Create combined condition. */ + gimple_seq seq = NULL; + tree first_cond_lhs = make_ssa_name (boolean_type_node); + gimple_seq_add_stmt (&seq, gimple_build_assign (first_cond_lhs, cond1_expr)); + tree sec_cond_lhs = make_ssa_name (boolean_type_node); + gassign *sec_cond_assign = gimple_build_assign (sec_cond_lhs, cond2_expr); + gimple_seq_add_stmt (&seq, sec_cond_assign); + tree comb_cond_lhs = make_ssa_name (boolean_type_node); + gimple_seq_add_stmt (&seq, gimple_build_assign (comb_cond_lhs, + bool_op, + first_cond_lhs, + sec_cond_lhs)); + + /* Update immediate dominator's condition with the combined one. */ + gimple_set_location (sec_cond_assign, gimple_location (non_imm_dom_cond)); + gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT); + gcond *last_stmt_cond = safe_dyn_cast (last_stmt); + + gimple_cond_set_condition (last_stmt_cond, EQ_EXPR, comb_cond_lhs, + build_int_cst (TREE_TYPE (comb_cond_lhs), 1)); + update_stmt (last_stmt_cond); + + /* Get the edges from the immediate dominator. */ + edge e_succ_non_imm = nullptr; + edge e_succ_other = nullptr; + FOR_EACH_EDGE (e, ei, imm_dominator->succs) + { + if (e->dest == non_imm_dom_block) + e_succ_non_imm = e; + else + e_succ_other = e; + } + + /* We're going to remove the block that contained the condition that is + now merged in the immediate dominator, so redirect the edge that was + pointing to this block. */ + edge e_red = nullptr; + FOR_EACH_EDGE (e, ei, e_succ_non_imm->dest->succs) + { + if (e->dest == bb) + continue; + e_red = redirect_edge_and_branch (e_succ_non_imm, e->dest); + } + + /* Update edge probabilities. */ + profile_probability new_prob; + profile_count src_count = e_succ_other->src->count; + profile_count dest_count = e_succ_other->dest->count; + if (src_count.nonzero_p () + && dest_count.nonzero_p ()) + new_prob = dest_count.probability_in (src_count); + else + new_prob = profile_probability::always ().apply_scale (1, 2); + + e_succ_other->probability = new_prob; + e_red->probability = new_prob.invert (); + + /* Remove the block. */ + mark_basic_block_deleted (non_imm_dom_block); + same_succ_flush_bb (non_imm_dom_block); + delete_basic_block (non_imm_dom_block); + + if (dump_file) + fprintf (dump_file, "Conditional statements %s and %s combined in BB %d\n", + print_generic_expr_to_str (cond1_expr), + print_generic_expr_to_str (cond2_expr), + imm_dominator->index); + +} + /* For each cluster in all_clusters, merge all cluster->bbs. Returns number of bbs removed. */ @@ -1735,6 +1987,9 @@ apply_clusters (void) bitmap_clear_bit (update_bbs, bb1->index); replace_block_by (bb1, bb2); + + maybe_combine_conditions (bb2); + nr_bbs_removed++; } } @@ -1826,6 +2081,9 @@ tail_merge_optimize (bool need_crit_edge_split) } init_worklist (); + /* This is needed by maybe_combine_conditions. */ + mark_ssa_maybe_undefs (); + while (!worklist.is_empty ()) { if (!loop_entered)