From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id 5E3813858D33; Tue, 13 Jun 2023 02:57:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5E3813858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686625035; bh=4HWIF/sxgiiNbQ5xnEplqTuTREv/hiQ+LEpRnaAU8A8=; h=From:To:Subject:Date:From; b=djHNbpK8Ep5w0skgb3KD2Iwsz6qGlhJ8O+gq5l4h67UbCmGb4UNio+8VdaLO1zWzv usXoXezLvTblbqucEYtb6rH61jUeDsmhqhZngRO+a4K5/XEozCFWj4BWIp+FhkDSbD g1uwH9Rmfq88FwqIdboakWNOSVFsAeV16Wv4jFNk= 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: c65e758acd515db117a7bc53f14588d4c8df5a2d X-Git-Newrev: 1e79bbf02e6321874f28e84fdcaa8a2cf94c514d Message-Id: <20230613025715.5E3813858D33@sourceware.org> Date: Tue, 13 Jun 2023 02:57:15 +0000 (GMT) List-Id: https://gcc.gnu.org/g:1e79bbf02e6321874f28e84fdcaa8a2cf94c514d commit 1e79bbf02e6321874f28e84fdcaa8a2cf94c514d Author: Michael Meissner Date: Mon Jun 12 22:56:55 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 constraints in fusion.md (generated by genfusion.pl) use "m" for LWA and LD, when they should use "YZ". 2) The rules for automatically setting the prefixed attribute were not checking that these fused load and compare immediate fusion operations might have prefixed addresses. The fix is to modify genfusion.pl that it sets the "YZ" constraint instead of "m" for the ld and lwa instructions. This patch also modifies the prefixed and maybe_prefixed attributes so that they check load + compare immediate instructions for be a load instruction. The patch also modifies genfusion.pl so that the lwa_cmp* insns also sets things up so that the prefixed_load_p function declares the address to be prefixed. These modifications include using a DImode scratch register instead of SImode, and setting the "sign_extend" attribute. I also added a test case for this condition. 2023-06-12 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): Add support for load plus compare immediate fused insns. (maybe_prefixed): Likewise. gcc/testsuite/ * g++.target/powerpc/pr105325.C: New test. Diff: --- gcc/config/rs6000/fusion.md | 21 ++++++++++++--------- gcc/config/rs6000/genfusion.pl | 29 +++++++++++++++++++++++++++-- gcc/config/rs6000/rs6000.md | 4 ++-- gcc/testsuite/g++.target/powerpc/pr105325.C | 26 ++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md index d45fb138a70..fdf710bdfc7 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 "ds_form_mem_operand" "YZ") (match_operand:SI 3 "const_m1_to_1_operand" "n"))) (clobber (match_scratch:SI 0 "=r"))] "(TARGET_P10_FUSION)" @@ -115,12 +115,13 @@ && (cc_reg_not_cr0_operand (operands[2], CCmode) || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), SImode, NON_PREFIXED_DS))" - [(set (match_dup 0) (match_dup 1)) + [(set (match_dup 0) (sign_extend:SI (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 "ds_form_mem_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)" @@ -157,12 +158,13 @@ && (cc_reg_not_cr0_operand (operands[2], CCmode) || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), SImode, NON_PREFIXED_DS))" - [(set (match_dup 0) (match_dup 1)) + [(set (match_dup 0) (sign_extend:SI (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 "ds_form_mem_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)" @@ -205,6 +207,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..1a8419d41ef 100755 --- a/gcc/config/rs6000/genfusion.pl +++ b/gcc/config/rs6000/genfusion.pl @@ -61,6 +61,14 @@ sub gen_ld_cmpi_p10_one my $mempred = "non_update_memory_operand"; my $extend; + # We need to special case lwa. The prefixed_load_p function in rs6000.cc + # (which determines if a load instruction is prefixed) uses the fact that the + # register mode is different from the memory mode, and that the sign_extend + # attribute is set to use DS-form rules for the address instead of D-form. + # If the register size is the same, prefixed_load_p assumes we are doing a + # lwz. + my $lwa_insn = ($lmode eq "SI" && $ccmode eq "CC"); + if ($ccmode eq "CC") { # ld and lwa are both DS-FORM. ($lmode =~ /^[SD]I$/) and $np = "NON_PREFIXED_DS"; @@ -91,12 +99,15 @@ sub gen_ld_cmpi_p10_one } my $ldst = mode_to_ldst_char($lmode); + + # DS-form addresses need YZ, and not m. + my $constraint = ($mempred eq "ds_form_mem_operand") ? "YZ" : "m"; print <