From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id 9CF783858C20; Fri, 9 Jun 2023 01:32:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9CF783858C20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686274340; bh=X15ZMtRAfhnR5+numx6WPvx5YkI6zeDlGJejdz1W50Q=; h=From:To:Subject:Date:From; b=r78GwcER1Aq1DAOwUrNwDyCNgs67Cu2NZxrqlcJcikkmAPZK4aTvWL6fBhiCk3Be/ Hu6aPyvSFxdlHW2McAuBrxpwV1t/tcLMMao6fA3YbcQ1UADOpymRgNYq6TFttrdLkf aUArHZkBcxQLoBo1DsDrBSkcNbdtzU7t5Lb/Tmro= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Michael Meissner To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work122)] Fix power10 fusion and -fstack-protector, PR target/105325 X-Act-Checkin: gcc X-Git-Author: Michael Meissner X-Git-Refname: refs/users/meissner/heads/work122 X-Git-Oldrev: e4476bf79a8ae731bb98a6bb2c1d208048289bf1 X-Git-Newrev: 58463f8c025a5473e187cb1d9149cd27f71fb4eb Message-Id: <20230609013220.9CF783858C20@sourceware.org> Date: Fri, 9 Jun 2023 01:32:20 +0000 (GMT) List-Id: https://gcc.gnu.org/g:58463f8c025a5473e187cb1d9149cd27f71fb4eb commit 58463f8c025a5473e187cb1d9149cd27f71fb4eb Author: Michael Meissner Date: Thu Jun 8 21:32:01 2023 -0400 Fix power10 fusion and -fstack-protector, PR target/105325 This patch fixes an issue where if you use the -fstack-protector and -mcpu=power10 options and you have a large stack frame, the GCC compiler will generate a LWA instruction with a large offset. There are several problems with the current GCC: 1) The prefixed attribute was not checking insns with the type fused_load_cmpi for being load insns. This meant if the load + compare fusion was not split, the insn size might be off, and the wrong instruction might be generated. 2) The code in prefixed_load_p looks at the "sign_extend" attribute and whether the register mode was different than the memory for SImode loads to detect LWA instructions. 3) The constraints in fusion.md (generated by genfusion.pl) use "m" for LWA and LD, when they should use "YZ". 4) The code to determine whether to split the insn if it has a prefixed address was passing in SImode. For LWA, we need to pass in DImode and not SImode to properly determine if the address is prefixed. The fix is to modify genfusion.pl that it sets the "YZ" constraint instead of "m" for the ld and lwa instructions. I also set the signed attribute on the HI/SImode loads that do sign extension. I modified the predicate for lwa to use lwa_operand instead of the predicate ds_form_mem_operand. This predicate has direct checks to prevent a prefixed lwa from being generated. I also modified the condition for the insn splitter so that it passes DImode for the lwa instructions and not SImode. I modified the "prefixed" attribute so that it also checks fused_load_cmpi. 2023-06-07 Michael Meissner gcc/ * config/rs6000/genfusion.pl (gen_ld_cmpi_p10_one): Fix problems that allowed prefixed lwa to be generated. * config/rs6000/fusion.md: Regenerate. * config/rs6000/rs6000.md (prefixed attribute): Treat fused_load_cmpi insns as being load insns. gcc/testsuite/ * g++.target/powerpc/pr105325.C: New test. Diff: --- gcc/config/rs6000/fusion.md | 25 +++++++++++++++---------- gcc/config/rs6000/genfusion.pl | 27 ++++++++++++++++++++++----- gcc/config/rs6000/rs6000.md | 2 +- gcc/testsuite/g++.target/powerpc/pr105325.C | 26 ++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md index d45fb138a70..b7c9035e882 100644 --- a/gcc/config/rs6000/fusion.md +++ b/gcc/config/rs6000/fusion.md @@ -22,7 +22,7 @@ ;; load mode is DI result mode is clobber compare mode is CC extend is none (define_insn_and_split "*ld_cmpdi_cr0_DI_clobber_CC_none" [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m") + (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "YZ") (match_operand:DI 3 "const_m1_to_1_operand" "n"))) (clobber (match_scratch:DI 0 "=r"))] "(TARGET_P10_FUSION)" @@ -43,7 +43,7 @@ ;; load mode is DI result mode is clobber compare mode is CCUNS extend is none (define_insn_and_split "*ld_cmpldi_cr0_DI_clobber_CCUNS_none" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") - (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m") + (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "YZ") (match_operand:DI 3 "const_0_to_1_operand" "n"))) (clobber (match_scratch:DI 0 "=r"))] "(TARGET_P10_FUSION)" @@ -64,7 +64,7 @@ ;; load mode is DI result mode is DI compare mode is CC extend is none (define_insn_and_split "*ld_cmpdi_cr0_DI_DI_CC_none" [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m") + (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "YZ") (match_operand:DI 3 "const_m1_to_1_operand" "n"))) (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))] "(TARGET_P10_FUSION)" @@ -85,7 +85,7 @@ ;; load mode is DI result mode is DI compare mode is CCUNS extend is none (define_insn_and_split "*ld_cmpldi_cr0_DI_DI_CCUNS_none" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") - (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m") + (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "YZ") (match_operand:DI 3 "const_0_to_1_operand" "n"))) (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))] "(TARGET_P10_FUSION)" @@ -106,7 +106,7 @@ ;; load mode is SI result mode is clobber compare mode is CC extend is none (define_insn_and_split "*lwa_cmpdi_cr0_SI_clobber_CC_none" [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m") + (compare:CC (match_operand:SI 1 "lwa_operand" "YZ") (match_operand:SI 3 "const_m1_to_1_operand" "n"))) (clobber (match_scratch:SI 0 "=r"))] "(TARGET_P10_FUSION)" @@ -114,13 +114,14 @@ "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), - SImode, NON_PREFIXED_DS))" + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "fused_load_cmpi") (set_attr "cost" "8") + (set_attr "sign_extend" "yes") (set_attr "length" "8")]) ;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10 @@ -148,7 +149,7 @@ ;; load mode is SI result mode is SI compare mode is CC extend is none (define_insn_and_split "*lwa_cmpdi_cr0_SI_SI_CC_none" [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m") + (compare:CC (match_operand:SI 1 "lwa_operand" "YZ") (match_operand:SI 3 "const_m1_to_1_operand" "n"))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))] "(TARGET_P10_FUSION)" @@ -156,13 +157,14 @@ "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), - SImode, NON_PREFIXED_DS))" + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "fused_load_cmpi") (set_attr "cost" "8") + (set_attr "sign_extend" "yes") (set_attr "length" "8")]) ;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10 @@ -190,7 +192,7 @@ ;; load mode is SI result mode is EXTSI compare mode is CC extend is sign (define_insn_and_split "*lwa_cmpdi_cr0_SI_EXTSI_CC_sign" [(set (match_operand:CC 2 "cc_reg_operand" "=x") - (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m") + (compare:CC (match_operand:SI 1 "lwa_operand" "YZ") (match_operand:SI 3 "const_m1_to_1_operand" "n"))) (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") (sign_extend:EXTSI (match_dup 1)))] "(TARGET_P10_FUSION)" @@ -198,13 +200,14 @@ "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), - SImode, NON_PREFIXED_DS))" + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (sign_extend:EXTSI (match_dup 1))) (set (match_dup 2) (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "fused_load_cmpi") (set_attr "cost" "8") + (set_attr "sign_extend" "yes") (set_attr "length" "8")]) ;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10 @@ -247,6 +250,7 @@ "" [(set_attr "type" "fused_load_cmpi") (set_attr "cost" "8") + (set_attr "sign_extend" "yes") (set_attr "length" "8")]) ;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10 @@ -289,6 +293,7 @@ "" [(set_attr "type" "fused_load_cmpi") (set_attr "cost" "8") + (set_attr "sign_extend" "yes") (set_attr "length" "8")]) ;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10 diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl index 82e8f863b02..599bd3ad19b 100755 --- a/gcc/config/rs6000/genfusion.pl +++ b/gcc/config/rs6000/genfusion.pl @@ -57,14 +57,23 @@ sub gen_ld_cmpi_p10_one { my ($lmode, $result, $ccmode) = @_; + my $lmode_prefix_call = $lmode; my $np = "NON_PREFIXED_D"; my $mempred = "non_update_memory_operand"; my $extend; if ($ccmode eq "CC") { - # ld and lwa are both DS-FORM. - ($lmode =~ /^[SD]I$/) and $np = "NON_PREFIXED_DS"; - ($lmode =~ /^[SD]I$/) and $mempred = "ds_form_mem_operand"; + # ld and lwa are both DS-FORM. lwa needs to use lwa_operand and also + # call address_is_non_pfx_d_or_x with DImode, not SImode to properly + # handle recognizing whether the address is prefixed. + if ($lmode eq "DI") { + $np = "NON_PREFIXED_DS"; + $mempred = "ds_form_mem_operand"; + } elsif ($lmode eq "SI") { + $np = "NON_PREFIXED_DS"; + $mempred = "lwa_operand"; + $lmode_prefix_call = "DI"; + } } else { if ($lmode eq "DI") { # ld is DS-form, but lwz is not. @@ -91,12 +100,13 @@ sub gen_ld_cmpi_p10_one } my $ldst = mode_to_ldst_char($lmode); + my $constraint = ($np eq "NON_PREFIXED_DS") ? "YZ" : "m"; print <