Message ID | Z8/xaV0bfNxKtGJ1@tucnak |
---|---|
State | New |
Headers |
Return-Path: <gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 110113858294 for <patchwork@sourceware.org>; Tue, 11 Mar 2025 08:19:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 110113858294 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=JQkypsKN X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id BB310385840C for <gcc-patches@gcc.gnu.org>; Tue, 11 Mar 2025 08:16:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BB310385840C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BB310385840C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741681023; cv=none; b=IKZq3tj5xz6XW6W9B8EEXPjAzfw9NC0fsq87ejqRrPFRLLjSM9XWnLLWsIAmguQaW/KVMoriWe3dySjyjyIA/pBZLzDBDrTwbFzPNFK2RKgZ36sa5NhXBxl0b/wyqAwg0zB7vPifVX6f9Wq8TGThVi9p5HMEygQdhut21eZEn60= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741681023; c=relaxed/simple; bh=S8+KI7tS0C9BOSEl8BX7cvNdVrgXJOuMroTmM65jpRI=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=wboibyG8m/aKqWCtUq2HFUAcSQO6jxu+5YN79vf41KNefrwxB/e5KRfD6rTO00rAodIm7wWf8uRH9eAwIl/hL3Lx+SPzLSZVAXz9r04DsVr+Ds0bqExivQ5DcuI6It5gI2BrzvIr1sRVrfPYO0iiOuqVjjKCvGrxdrRNl0vRXVA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BB310385840C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741681018; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=4Ieq1xDh30P9EpKq5d6NXEO+XzF1RirNhtdrO2GqsYs=; b=JQkypsKNtdq+f4eAsg6MLxjv9Hq8QHchUMGOCBuNiV5UGvLh/v651xsBa2svAK6tCDk9jv 2capYCnX5ySynyump5NEVUwcaDXIUP+lAy4bDGvZwOb/IxWiXw1O4WAFOtuDDPneNSEUDy s7DpkgDC5ka4vuazgcauIhf8zWSU6YU= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-501-MFzB-6zPPrSB7EkPllBuig-1; Tue, 11 Mar 2025 04:16:53 -0400 X-MC-Unique: MFzB-6zPPrSB7EkPllBuig-1 X-Mimecast-MFC-AGG-ID: MFzB-6zPPrSB7EkPllBuig_1741681012 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B213419560B0; Tue, 11 Mar 2025 08:16:51 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.22.89.222]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3D5FD19560AB; Tue, 11 Mar 2025 08:16:51 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 52B8GlST1927558 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 11 Mar 2025 09:16:47 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 52B8Gfsr1927553; Tue, 11 Mar 2025 09:16:41 +0100 Date: Tue, 11 Mar 2025 09:16:41 +0100 From: Jakub Jelinek <jakub@redhat.com> To: Richard Biener <rguenther@suse.de> Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] cfgexpand: Special case expansion of dead COMPLEX_EXPRs at -O0 [PR119120] Message-ID: <Z8/xaV0bfNxKtGJ1@tucnak> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: EndWZd12daslN4CGrpoHQo_Nf6Knro1u43Fn9hgdHYs_1741681012 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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>, <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>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> Reply-To: Jakub Jelinek <jakub@redhat.com> Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org |
Series |
cfgexpand: Special case expansion of dead COMPLEX_EXPRs at -O0 [PR119120]
|
|
Commit Message
Jakub Jelinek
March 11, 2025, 8:16 a.m. UTC
Hi! The PR119190 patch I've posted regresses the PR119120 testcase (not adding to testsuite, as it is fairly hard to scan for that problem). The issue is that for the partial setting of _Complex floating vars through __real__ on it first and __imag__ later (or vice versa) and since we forced all complex vars into SSA form we often have undefined (D) arguments of those COMPLEX_EXPRs. When we don't DCE them (for -O0 debug info reasons), their expansion will copy both the real and imag parts using the floating mode and on some targets like 387 that copying alone can unfortunately trigger exceptions on sNaNs or other problematic bit patterns and for uninitialized memory it can be triggered randomly based on whatever is on the stack before. The following patch deals just with the unused COMPLEX_EXPRs at -O0, if it is used, either complex lowering should have replaced its parts or it represents a user store somewhere, or passing to function argument etc., all that should be really avoided for partially uninitialized complex. And the patch attempts to find the uninitialized arguments (unfortunately at -O0 we don't forward propagate the (D) SSA_NAMEs) and only copy the initialized parts. Another option would be to arrange for the copying to be done in integral mode rather than floating, kind of VCE and back. Though, not sure how to handle then XFmode or on 32-bit targets TFmode when there is no corresponding intergral mode or it isn't usable. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Or shall I go the VCE route instead? 2025-03-11 Jakub Jelinek <jakub@redhat.com> PR target/119120 * cfgexpand.cc (expand_gimple_stmt_1): At -O0 expand a COMPLEX_EXPR with zero uses of lhs if it has complex floating point mode as stores of just the parts which aren't known to be uninitialized. Jakub
Comments
On Tue, 11 Mar 2025, Jakub Jelinek wrote: > Hi! > > The PR119190 patch I've posted regresses the PR119120 testcase (not adding > to testsuite, as it is fairly hard to scan for that problem). > The issue is that for the partial setting of _Complex floating vars > through __real__ on it first and __imag__ later (or vice versa) and since > we forced all complex vars into SSA form we often have undefined (D) > arguments of those COMPLEX_EXPRs. When we don't DCE them (for -O0 debug > info reasons), their expansion will copy both the real and imag parts > using the floating mode and on some targets like 387 that copying alone can > unfortunately trigger exceptions on sNaNs or other problematic bit patterns > and for uninitialized memory it can be triggered randomly based on whatever > is on the stack before. > > The following patch deals just with the unused COMPLEX_EXPRs at -O0, > if it is used, either complex lowering should have replaced its parts or > it represents a user store somewhere, or passing to function argument etc., > all that should be really avoided for partially uninitialized complex. > And the patch attempts to find the uninitialized arguments (unfortunately > at -O0 we don't forward propagate the (D) SSA_NAMEs) and only copy the > initialized parts. Another option would be to arrange for the copying > to be done in integral mode rather than floating, kind of VCE and back. > Though, not sure how to handle then XFmode or on 32-bit targets TFmode > when there is no corresponding intergral mode or it isn't usable. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > Or shall I go the VCE route instead? I think the patch as-is is more robust, but still - ugh ... I wonder whether we can instead avoid introducing the COMPLEX_EXPR at all at -O0? > 2025-03-11 Jakub Jelinek <jakub@redhat.com> > > PR target/119120 > * cfgexpand.cc (expand_gimple_stmt_1): At -O0 expand a COMPLEX_EXPR > with zero uses of lhs if it has complex floating point mode as > stores of just the parts which aren't known to be uninitialized. > > --- gcc/cfgexpand.cc.jj 2025-01-07 20:11:04.632662813 +0100 > +++ gcc/cfgexpand.cc 2025-03-10 21:28:01.071078448 +0100 > @@ -4294,6 +4294,70 @@ expand_gimple_stmt_1 (gimple *stmt) > if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target)) > promoted = true; > > + /* At -O0 an unused COMPLEX_EXPR might be kept in the IL by > + cplxlower0 pass to ensure correct debug info. If one or both > + arguments of COMPLEX_EXPR is unitialized and it is a complex > + floating-point mode, don't actually copy the uninitialized > + part(s) using floating-point mode, as that could cause extra > + exceptions. */ > + if (!optimize > + && gimple_assign_rhs_code (assign_stmt) == COMPLEX_EXPR > + && TREE_CODE (lhs) == SSA_NAME > + && has_zero_uses (lhs) > + && MEM_P (target) > + && SCALAR_FLOAT_MODE_P (GET_MODE_INNER (GET_MODE (target)))) > + { > + op0 = gimple_assign_rhs1 (assign_stmt); > + tree op1 = gimple_assign_rhs2 (assign_stmt); > + gimple *g; > + bool ignore_op0 = (TREE_CODE (op0) == SSA_NAME > + && SSA_NAME_IS_DEFAULT_DEF (op0) > + && (!SSA_NAME_VAR (op0) > + || VAR_P (SSA_NAME_VAR (op0)))); > + bool ignore_op1 = (TREE_CODE (op1) == SSA_NAME > + && SSA_NAME_IS_DEFAULT_DEF (op1) > + && (!SSA_NAME_VAR (op1) > + || VAR_P (SSA_NAME_VAR (op1)))); > + tree tem = op0; > + while (!ignore_op0 > + && TREE_CODE (tem) == SSA_NAME > + && (g = SSA_NAME_DEF_STMT (tem)) > + && is_gimple_assign (g) > + && gimple_assign_rhs_code (g) == SSA_NAME) > + { > + tem = gimple_assign_rhs1 (g); > + if (SSA_NAME_IS_DEFAULT_DEF (tem) > + && (!SSA_NAME_VAR (tem) || VAR_P (SSA_NAME_VAR (tem)))) > + ignore_op0 = true; > + } > + tem = op1; > + while (!ignore_op1 > + && TREE_CODE (tem) == SSA_NAME > + && (g = SSA_NAME_DEF_STMT (tem)) > + && is_gimple_assign (g) > + && gimple_assign_rhs_code (g) == SSA_NAME) > + { > + tem = gimple_assign_rhs1 (g); > + if (SSA_NAME_IS_DEFAULT_DEF (tem) > + && (!SSA_NAME_VAR (tem) || VAR_P (SSA_NAME_VAR (tem)))) > + ignore_op1 = true; > + } > + if (ignore_op0 || ignore_op1) > + { > + if (!ignore_op0) > + { > + rtx rop0 = expand_normal (op0); > + write_complex_part (target, rop0, 0, true); > + } > + else if (!ignore_op1) > + { > + rtx rop1 = expand_normal (op1); > + write_complex_part (target, rop1, 1, true); > + } > + break; > + } > + } > + > /* If we store into a promoted register, don't directly > expand to target. */ > temp = promoted ? NULL_RTX : target; > > Jakub > >
On Tue, Mar 11, 2025 at 10:18:18AM +0100, Richard Biener wrote: > I think the patch as-is is more robust, but still - ugh ... I wonder > whether we can instead avoid introducing the COMPLEX_EXPR at all > at -O0? Can we set DECL_NOT_GIMPLE_REG_P at -O0 during gimplification (where we've already handled some uses/setters of it), at least when gimplify_modify_expr_complex_part sees {REAL,IMAG}PART_EXPR on {VAR,PARM,RESULT}_DECL? Or would we need to basically revert to the old way (for -O0 only) where we assumed all complex vars aren't gimple regs unless proven otherwise (not assume it for getting initialized internal vars of course)? Jakub
On Tue, 11 Mar 2025, Jakub Jelinek wrote: > On Tue, Mar 11, 2025 at 10:18:18AM +0100, Richard Biener wrote: > > I think the patch as-is is more robust, but still - ugh ... I wonder > > whether we can instead avoid introducing the COMPLEX_EXPR at all > > at -O0? > > Can we set DECL_NOT_GIMPLE_REG_P at -O0 during gimplification (where > we've already handled some uses/setters of it), at least when > gimplify_modify_expr_complex_part sees {REAL,IMAG}PART_EXPR on > {VAR,PARM,RESULT}_DECL? Yes, that should work for LHS __real / __imag. > Or would we need to basically revert to the old way (for -O0 only) where > we assumed all complex vars aren't gimple regs unless proven otherwise > (not assume it for getting initialized internal vars of course)? No, I wouldn't go this far at this point. Richard.
On Tue, Mar 11, 2025 at 12:13:13PM +0100, Richard Biener wrote: > On Tue, 11 Mar 2025, Jakub Jelinek wrote: > > > On Tue, Mar 11, 2025 at 10:18:18AM +0100, Richard Biener wrote: > > > I think the patch as-is is more robust, but still - ugh ... I wonder > > > whether we can instead avoid introducing the COMPLEX_EXPR at all > > > at -O0? > > > > Can we set DECL_NOT_GIMPLE_REG_P at -O0 during gimplification (where > > we've already handled some uses/setters of it), at least when > > gimplify_modify_expr_complex_part sees {REAL,IMAG}PART_EXPR on > > {VAR,PARM,RESULT}_DECL? > > Yes, that should work for LHS __real / __imag. Unfortunately it doesn't. Although successfully bootstrapped on x86_64-linux and i686-linux, it caused g++.dg/cpp1z/decomp2.C, g++.dg/torture/pr109262.C and g++.dg/torture/pr88149.C regressions. Minimal testcase is -O0: void foo (float x, float y) { __complex__ float z = x + y * 1.0fi; __real__ z = 1.0f; } which ICEs with pr88149.c: In function ‘foo’: pr88149.c:2:1: error: non-register as LHS of binary operation 2 | foo (float x, float y) | ^~~ z = COMPLEX_EXPR <_2, y.0>; pr88149.c:2:1: internal compiler error: ‘verify_gimple’ failed When the initialization is being gimplified, z is still not DECL_NOT_GIMPLE_REG_P and so is_gimple_reg is true for it and so it gimplifies it as z = COMPLEX_EXPR <_2, y.0>; later, instead of building _3 = IMAGPART_EXPR <z>; z = COMPLEX_EXPR <1.0e+0, _3>; like before, the patch forces z to be not a gimple reg and uses REALPART_EXPR <z> = 1.0e+0; but it is too late, nothing fixes up the gimplification of the COMPLEX_EXPR anymore. So, I think we'd really need to do it the old way with adjusted naming of the flag, so assume for all non-addressable VAR_DECLs/PARM_DECLs/RESULT_DECLs with COMPLEX_TYPE if (!optimize) they are DECL_NOT_GIMPLE_REG_P (perhaps with the exception of get_internal_tmp_var), and at some point (what) if at all optimize that away if the partial accesses aren't done. Thoughts on this? 2025-03-11 Jakub Jelinek <jakub@redhat.com> PR target/119120 * gimplify.cc (gimplify_modify_expr): Don't call gimplify_modify_expr_complex_part for -O0, instead set DECL_NOT_GIMPLE_REG_P on the {REAL,IMAG}PART_EXPR operand. --- gcc/gimplify.cc.jj 2025-03-10 09:31:20.579772627 +0100 +++ gcc/gimplify.cc 2025-03-11 15:03:27.633636148 +0100 @@ -7237,7 +7237,15 @@ gimplify_modify_expr (tree *expr_p, gimp if ((TREE_CODE (*to_p) == REALPART_EXPR || TREE_CODE (*to_p) == IMAGPART_EXPR) && is_gimple_reg (TREE_OPERAND (*to_p, 0))) - return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); + { + if (optimize) + return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); + /* When not optimizing, instead set DECL_NOT_GIMPLE_REG_P on it and + keep using {REAL,IMAG}PART_EXPR on the partial initializations + in order to avoid copying around uninitialized parts. See + PR119120. */ + DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (*to_p, 0)) = 1; + } /* Try to alleviate the effects of the gimplification creating artificial temporaries (see for example is_gimple_reg_rhs) on the debug info, but Jakub
On Wed, 12 Mar 2025, Jakub Jelinek wrote: > On Tue, Mar 11, 2025 at 12:13:13PM +0100, Richard Biener wrote: > > On Tue, 11 Mar 2025, Jakub Jelinek wrote: > > > > > On Tue, Mar 11, 2025 at 10:18:18AM +0100, Richard Biener wrote: > > > > I think the patch as-is is more robust, but still - ugh ... I wonder > > > > whether we can instead avoid introducing the COMPLEX_EXPR at all > > > > at -O0? > > > > > > Can we set DECL_NOT_GIMPLE_REG_P at -O0 during gimplification (where > > > we've already handled some uses/setters of it), at least when > > > gimplify_modify_expr_complex_part sees {REAL,IMAG}PART_EXPR on > > > {VAR,PARM,RESULT}_DECL? > > > > Yes, that should work for LHS __real / __imag. > > Unfortunately it doesn't. > > Although successfully bootstrapped on x86_64-linux and i686-linux, > it caused g++.dg/cpp1z/decomp2.C, g++.dg/torture/pr109262.C and > g++.dg/torture/pr88149.C regressions. > > Minimal testcase is -O0: > void > foo (float x, float y) > { > __complex__ float z = x + y * 1.0fi; > __real__ z = 1.0f; > } > which ICEs with > pr88149.c: In function ‘foo’: > pr88149.c:2:1: error: non-register as LHS of binary operation > 2 | foo (float x, float y) > | ^~~ > z = COMPLEX_EXPR <_2, y.0>; > pr88149.c:2:1: internal compiler error: ‘verify_gimple’ failed > When the initialization is being gimplified, z is still > not DECL_NOT_GIMPLE_REG_P and so is_gimple_reg is true for it and > so it gimplifies it as > z = COMPLEX_EXPR <_2, y.0>; > later, instead of building > _3 = IMAGPART_EXPR <z>; > z = COMPLEX_EXPR <1.0e+0, _3>; > like before, the patch forces z to be not a gimple reg and uses > REALPART_EXPR <z> = 1.0e+0; > but it is too late, nothing fixes up the gimplification of the COMPLEX_EXPR > anymore. Ah, yeah - setting DECL_NOT_GIMPLE_REG_P "after the fact" doesn't work. > So, I think we'd really need to do it the old way with adjusted naming > of the flag, so assume for all non-addressable > VAR_DECLs/PARM_DECLs/RESULT_DECLs with COMPLEX_TYPE if (!optimize) they > are DECL_NOT_GIMPLE_REG_P (perhaps with the exception of > get_internal_tmp_var), and at some point (what) if at all optimize that > away if the partial accesses aren't done. We could of course do that in is_gimple_reg (), but I'm not sure if all places that would need to check do so. Alternatively gimplify __real x = .. into tem[DECL_NOT_GIMPLE_REG_P] = x; __real tem = ...; x = tem; when 'x' is a is_gimple_reg? Of course for -O0 this would be quite bad. Likewise for your idea - where would we do this optimization when not optimizing? So it would need to be the frontend(s) setting DECL_NOT_GIMPLE_REG_P when producing lvalue __real/__imag accesses? Richard. > Thoughts on this? > > 2025-03-11 Jakub Jelinek <jakub@redhat.com> > > PR target/119120 > * gimplify.cc (gimplify_modify_expr): Don't call > gimplify_modify_expr_complex_part for -O0, instead set > DECL_NOT_GIMPLE_REG_P on the {REAL,IMAG}PART_EXPR operand. > > --- gcc/gimplify.cc.jj 2025-03-10 09:31:20.579772627 +0100 > +++ gcc/gimplify.cc 2025-03-11 15:03:27.633636148 +0100 > @@ -7237,7 +7237,15 @@ gimplify_modify_expr (tree *expr_p, gimp > if ((TREE_CODE (*to_p) == REALPART_EXPR > || TREE_CODE (*to_p) == IMAGPART_EXPR) > && is_gimple_reg (TREE_OPERAND (*to_p, 0))) > - return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); > + { > + if (optimize) > + return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value); > + /* When not optimizing, instead set DECL_NOT_GIMPLE_REG_P on it and > + keep using {REAL,IMAG}PART_EXPR on the partial initializations > + in order to avoid copying around uninitialized parts. See > + PR119120. */ > + DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (*to_p, 0)) = 1; > + } > > /* Try to alleviate the effects of the gimplification creating artificial > temporaries (see for example is_gimple_reg_rhs) on the debug info, but > > > Jakub > >
--- gcc/cfgexpand.cc.jj 2025-01-07 20:11:04.632662813 +0100 +++ gcc/cfgexpand.cc 2025-03-10 21:28:01.071078448 +0100 @@ -4294,6 +4294,70 @@ expand_gimple_stmt_1 (gimple *stmt) if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target)) promoted = true; + /* At -O0 an unused COMPLEX_EXPR might be kept in the IL by + cplxlower0 pass to ensure correct debug info. If one or both + arguments of COMPLEX_EXPR is unitialized and it is a complex + floating-point mode, don't actually copy the uninitialized + part(s) using floating-point mode, as that could cause extra + exceptions. */ + if (!optimize + && gimple_assign_rhs_code (assign_stmt) == COMPLEX_EXPR + && TREE_CODE (lhs) == SSA_NAME + && has_zero_uses (lhs) + && MEM_P (target) + && SCALAR_FLOAT_MODE_P (GET_MODE_INNER (GET_MODE (target)))) + { + op0 = gimple_assign_rhs1 (assign_stmt); + tree op1 = gimple_assign_rhs2 (assign_stmt); + gimple *g; + bool ignore_op0 = (TREE_CODE (op0) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (op0) + && (!SSA_NAME_VAR (op0) + || VAR_P (SSA_NAME_VAR (op0)))); + bool ignore_op1 = (TREE_CODE (op1) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (op1) + && (!SSA_NAME_VAR (op1) + || VAR_P (SSA_NAME_VAR (op1)))); + tree tem = op0; + while (!ignore_op0 + && TREE_CODE (tem) == SSA_NAME + && (g = SSA_NAME_DEF_STMT (tem)) + && is_gimple_assign (g) + && gimple_assign_rhs_code (g) == SSA_NAME) + { + tem = gimple_assign_rhs1 (g); + if (SSA_NAME_IS_DEFAULT_DEF (tem) + && (!SSA_NAME_VAR (tem) || VAR_P (SSA_NAME_VAR (tem)))) + ignore_op0 = true; + } + tem = op1; + while (!ignore_op1 + && TREE_CODE (tem) == SSA_NAME + && (g = SSA_NAME_DEF_STMT (tem)) + && is_gimple_assign (g) + && gimple_assign_rhs_code (g) == SSA_NAME) + { + tem = gimple_assign_rhs1 (g); + if (SSA_NAME_IS_DEFAULT_DEF (tem) + && (!SSA_NAME_VAR (tem) || VAR_P (SSA_NAME_VAR (tem)))) + ignore_op1 = true; + } + if (ignore_op0 || ignore_op1) + { + if (!ignore_op0) + { + rtx rop0 = expand_normal (op0); + write_complex_part (target, rop0, 0, true); + } + else if (!ignore_op1) + { + rtx rop1 = expand_normal (op1); + write_complex_part (target, rop1, 1, true); + } + break; + } + } + /* If we store into a promoted register, don't directly expand to target. */ temp = promoted ? NULL_RTX : target;