From: Aaron Sawdey <acsaw...@linux.ibm.com> PR99070 is caused by a fusion pattern matching that the individual instructions do not match when it is split later. In this case the ld+cmpi patterns were allowing a d-form load address, which the split condition would rightly split, however that left us with something that could not be matched by a ds-form ld instruction, hence the ICE. This only happened if the target cpu was not power10 -- if we were targeting power10 then a prefixed pld instruction would get generated because that can handle d-form. However this is not optimal code either.
So the solution is a new predicate (ds_form_mem_operand) that only accepts what we can take as for a ds-form load. Then a small modification of the genfusion.pl script changes the relevant ld+cmpi patterns to use the new predicate. OK for trunk if bootstrap/regtest passes? gcc/ChangeLog PR target/99070 * config/rs6000/predicates.md (ds_form_mem_operand) New predicate. * config/rs6000/genfusion.pl (gen_ld_cmpi_p10) Use ds_form_mem_operand in ld/lwa patterns. * config/rs6000/fusion.md: Regenerate file. --- gcc/config/rs6000/fusion.md | 177 ++++++++++++++++---------------- gcc/config/rs6000/genfusion.pl | 7 +- gcc/config/rs6000/predicates.md | 20 ++++ 3 files changed, 113 insertions(+), 91 deletions(-) diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md index 737a6da385f..56478fcae1d 100644 --- a/gcc/config/rs6000/fusion.md +++ b/gcc/config/rs6000/fusion.md @@ -1,7 +1,6 @@ -;; -*- buffer-read-only: t -*- ;; Generated automatically by genfusion.pl -;; Copyright (C) 2020 Free Software Foundation, Inc. +;; Copyright (C) 2020,2021 Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; @@ -23,18 +22,18 @@ ;; 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 "non_update_memory_operand" "m") - (match_operand:DI 3 "const_m1_to_1_operand" "n"))) + (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m") + (match_operand:DI 3 "const_m1_to_1_operand" "n"))) (clobber (match_scratch:DI 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "ld%X1 %0,%1\;cmpdi 0,%0,%3" + "ld%X1 %0,%1\;cmpdi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), DImode, NON_PREFIXED_DS))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) - (compare:CC (match_dup 0) - (match_dup 3)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -44,18 +43,18 @@ (define_insn_and_split "*ld_cmpdi_cr0_DI_clobber_CC_none" ;; 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 "non_update_memory_operand" "m") - (match_operand:DI 3 "const_0_to_1_operand" "n"))) + (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m") + (match_operand:DI 3 "const_0_to_1_operand" "n"))) (clobber (match_scratch:DI 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "ld%X1 %0,%1\;cmpldi 0,%0,%3" + "ld%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), DImode, NON_PREFIXED_DS))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -65,18 +64,18 @@ (define_insn_and_split "*ld_cmpldi_cr0_DI_clobber_CCUNS_none" ;; 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 "non_update_memory_operand" "m") - (match_operand:DI 3 "const_m1_to_1_operand" "n"))) + (compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m") + (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 && TARGET_P10_FUSION_LD_CMPI)" - "ld%X1 %0,%1\;cmpdi 0,%0,%3" + "ld%X1 %0,%1\;cmpdi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), DImode, NON_PREFIXED_DS))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) - (compare:CC (match_dup 0) - (match_dup 3)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -86,18 +85,18 @@ (define_insn_and_split "*ld_cmpdi_cr0_DI_DI_CC_none" ;; 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 "non_update_memory_operand" "m") - (match_operand:DI 3 "const_0_to_1_operand" "n"))) + (compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m") + (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 && TARGET_P10_FUSION_LD_CMPI)" - "ld%X1 %0,%1\;cmpldi 0,%0,%3" + "ld%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), DImode, NON_PREFIXED_DS))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + DImode, NON_PREFIXED_DS))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -107,18 +106,18 @@ (define_insn_and_split "*ld_cmpldi_cr0_DI_DI_CCUNS_none" ;; 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 "non_update_memory_operand" "m") - (match_operand:SI 3 "const_m1_to_1_operand" "n"))) + (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m") + (match_operand:SI 3 "const_m1_to_1_operand" "n"))) (clobber (match_scratch:SI 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lwa%X1 %0,%1\;cmpdi 0,%0,%3" + "lwa%X1 %0,%1\;cmpdi %2,%0,%3" "&& 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))" + || !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 2) - (compare:CC (match_dup 0) - (match_dup 3)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -129,17 +128,17 @@ (define_insn_and_split "*lwa_cmpdi_cr0_SI_clobber_CC_none" (define_insn_and_split "*lwz_cmpldi_cr0_SI_clobber_CCUNS_none" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:SI 1 "non_update_memory_operand" "m") - (match_operand:SI 3 "const_0_to_1_operand" "n"))) + (match_operand:SI 3 "const_0_to_1_operand" "n"))) (clobber (match_scratch:SI 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lwz%X1 %0,%1\;cmpldi 0,%0,%3" + "lwz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), SImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + SImode, NON_PREFIXED_D))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -149,18 +148,18 @@ (define_insn_and_split "*lwz_cmpldi_cr0_SI_clobber_CCUNS_none" ;; 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 "non_update_memory_operand" "m") - (match_operand:SI 3 "const_m1_to_1_operand" "n"))) + (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m") + (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 && TARGET_P10_FUSION_LD_CMPI)" - "lwa%X1 %0,%1\;cmpdi 0,%0,%3" + "lwa%X1 %0,%1\;cmpdi %2,%0,%3" "&& 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))" + || !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 2) - (compare:CC (match_dup 0) - (match_dup 3)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -171,17 +170,17 @@ (define_insn_and_split "*lwa_cmpdi_cr0_SI_SI_CC_none" (define_insn_and_split "*lwz_cmpldi_cr0_SI_SI_CCUNS_none" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:SI 1 "non_update_memory_operand" "m") - (match_operand:SI 3 "const_0_to_1_operand" "n"))) + (match_operand:SI 3 "const_0_to_1_operand" "n"))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lwz%X1 %0,%1\;cmpldi 0,%0,%3" + "lwz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), SImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + SImode, NON_PREFIXED_D))" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -191,18 +190,18 @@ (define_insn_and_split "*lwz_cmpldi_cr0_SI_SI_CCUNS_none" ;; 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 "non_update_memory_operand" "m") - (match_operand:SI 3 "const_m1_to_1_operand" "n"))) + (compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m") + (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 && TARGET_P10_FUSION_LD_CMPI)" - "lwa%X1 %0,%1\;cmpdi 0,%0,%3" + "lwa%X1 %0,%1\;cmpdi %2,%0,%3" "&& 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))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + SImode, 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)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -213,17 +212,17 @@ (define_insn_and_split "*lwa_cmpdi_cr0_SI_EXTSI_CC_sign" (define_insn_and_split "*lwz_cmpldi_cr0_SI_EXTSI_CCUNS_zero" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:SI 1 "non_update_memory_operand" "m") - (match_operand:SI 3 "const_0_to_1_operand" "n"))) + (match_operand:SI 3 "const_0_to_1_operand" "n"))) (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") (zero_extend:EXTSI (match_dup 1)))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lwz%X1 %0,%1\;cmpldi 0,%0,%3" + "lwz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), SImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + SImode, NON_PREFIXED_D))" [(set (match_dup 0) (zero_extend:EXTSI (match_dup 1))) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -234,17 +233,17 @@ (define_insn_and_split "*lwz_cmpldi_cr0_SI_EXTSI_CCUNS_zero" (define_insn_and_split "*lha_cmpdi_cr0_HI_clobber_CC_sign" [(set (match_operand:CC 2 "cc_reg_operand" "=x") (compare:CC (match_operand:HI 1 "non_update_memory_operand" "m") - (match_operand:HI 3 "const_m1_to_1_operand" "n"))) + (match_operand:HI 3 "const_m1_to_1_operand" "n"))) (clobber (match_scratch:GPR 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lha%X1 %0,%1\;cmpdi 0,%0,%3" + "lha%X1 %0,%1\;cmpdi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), HImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + HImode, NON_PREFIXED_D))" [(set (match_dup 0) (sign_extend:GPR (match_dup 1))) (set (match_dup 2) - (compare:CC (match_dup 0) - (match_dup 3)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -255,17 +254,17 @@ (define_insn_and_split "*lha_cmpdi_cr0_HI_clobber_CC_sign" (define_insn_and_split "*lhz_cmpldi_cr0_HI_clobber_CCUNS_zero" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:HI 1 "non_update_memory_operand" "m") - (match_operand:HI 3 "const_0_to_1_operand" "n"))) + (match_operand:HI 3 "const_0_to_1_operand" "n"))) (clobber (match_scratch:GPR 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lhz%X1 %0,%1\;cmpldi 0,%0,%3" + "lhz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), HImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + HImode, NON_PREFIXED_D))" [(set (match_dup 0) (zero_extend:GPR (match_dup 1))) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -276,17 +275,17 @@ (define_insn_and_split "*lhz_cmpldi_cr0_HI_clobber_CCUNS_zero" (define_insn_and_split "*lha_cmpdi_cr0_HI_EXTHI_CC_sign" [(set (match_operand:CC 2 "cc_reg_operand" "=x") (compare:CC (match_operand:HI 1 "non_update_memory_operand" "m") - (match_operand:HI 3 "const_m1_to_1_operand" "n"))) + (match_operand:HI 3 "const_m1_to_1_operand" "n"))) (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r") (sign_extend:EXTHI (match_dup 1)))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lha%X1 %0,%1\;cmpdi 0,%0,%3" + "lha%X1 %0,%1\;cmpdi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), HImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + HImode, NON_PREFIXED_D))" [(set (match_dup 0) (sign_extend:EXTHI (match_dup 1))) (set (match_dup 2) - (compare:CC (match_dup 0) - (match_dup 3)))] + (compare:CC (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -297,17 +296,17 @@ (define_insn_and_split "*lha_cmpdi_cr0_HI_EXTHI_CC_sign" (define_insn_and_split "*lhz_cmpldi_cr0_HI_EXTHI_CCUNS_zero" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:HI 1 "non_update_memory_operand" "m") - (match_operand:HI 3 "const_0_to_1_operand" "n"))) + (match_operand:HI 3 "const_0_to_1_operand" "n"))) (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r") (zero_extend:EXTHI (match_dup 1)))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lhz%X1 %0,%1\;cmpldi 0,%0,%3" + "lhz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), HImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + HImode, NON_PREFIXED_D))" [(set (match_dup 0) (zero_extend:EXTHI (match_dup 1))) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -318,17 +317,17 @@ (define_insn_and_split "*lhz_cmpldi_cr0_HI_EXTHI_CCUNS_zero" (define_insn_and_split "*lbz_cmpldi_cr0_QI_clobber_CCUNS_zero" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:QI 1 "non_update_memory_operand" "m") - (match_operand:QI 3 "const_0_to_1_operand" "n"))) + (match_operand:QI 3 "const_0_to_1_operand" "n"))) (clobber (match_scratch:GPR 0 "=r"))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lbz%X1 %0,%1\;cmpldi 0,%0,%3" + "lbz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), QImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + QImode, NON_PREFIXED_D))" [(set (match_dup 0) (zero_extend:GPR (match_dup 1))) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") @@ -339,17 +338,17 @@ (define_insn_and_split "*lbz_cmpldi_cr0_QI_clobber_CCUNS_zero" (define_insn_and_split "*lbz_cmpldi_cr0_QI_GPR_CCUNS_zero" [(set (match_operand:CCUNS 2 "cc_reg_operand" "=x") (compare:CCUNS (match_operand:QI 1 "non_update_memory_operand" "m") - (match_operand:QI 3 "const_0_to_1_operand" "n"))) + (match_operand:QI 3 "const_0_to_1_operand" "n"))) (set (match_operand:GPR 0 "gpc_reg_operand" "=r") (zero_extend:GPR (match_dup 1)))] "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)" - "lbz%X1 %0,%1\;cmpldi 0,%0,%3" + "lbz%X1 %0,%1\;cmpldi %2,%0,%3" "&& reload_completed && (cc_reg_not_cr0_operand (operands[2], CCmode) - || !address_is_non_pfx_d_or_x (XEXP (operands[1],0), QImode, NON_PREFIXED_D))" + || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0), + QImode, NON_PREFIXED_D))" [(set (match_dup 0) (zero_extend:GPR (match_dup 1))) (set (match_dup 2) - (compare:CCUNS (match_dup 0) - (match_dup 3)))] + (compare:CCUNS (match_dup 0) (match_dup 3)))] "" [(set_attr "type" "load") (set_attr "cost" "8") diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl index e1c45f57065..c86c7436a62 100755 --- a/gcc/config/rs6000/genfusion.pl +++ b/gcc/config/rs6000/genfusion.pl @@ -56,7 +56,7 @@ sub mode_to_ldst_char sub gen_ld_cmpi_p10 { my ($lmode, $ldst, $clobbermode, $result, $cmpl, $echr, $constpred, - $ccmode, $np, $extend, $resultmode); + $mempred, $ccmode, $np, $extend, $resultmode); LMODE: foreach $lmode ('DI','SI','HI','QI') { $ldst = mode_to_ldst_char($lmode); $clobbermode = $lmode; @@ -70,11 +70,13 @@ sub gen_ld_cmpi_p10 $result = "GPR" if $result eq "EXTQI"; CCMODE: foreach $ccmode ('CC','CCUNS') { $np = "NON_PREFIXED_D"; + $mempred = "non_update_memory_operand"; if ( $ccmode eq 'CC' ) { next CCMODE if $lmode eq 'QI'; if ( $lmode eq 'DI' || $lmode eq 'SI' ) { # ld and lwa are both DS-FORM. $np = "NON_PREFIXED_DS"; + $mempred = "ds_form_mem_operand"; } $cmpl = ""; $echr = "a"; @@ -83,6 +85,7 @@ sub gen_ld_cmpi_p10 if ( $lmode eq 'DI' ) { # ld is DS-form, but lwz is not. $np = "NON_PREFIXED_DS"; + $mempred = "ds_form_mem_operand"; } $cmpl = "l"; $echr = "z"; @@ -105,7 +108,7 @@ sub gen_ld_cmpi_p10 print "(define_insn_and_split \"*l${ldst}${echr}_cmp${cmpl}di_cr0_${lmode}_${result}_${ccmode}_${extend}\"\n"; print " [(set (match_operand:${ccmode} 2 \"cc_reg_operand\" \"=x\")\n"; - print " (compare:${ccmode} (match_operand:${lmode} 1 \"non_update_memory_operand\" \"m\")\n"; + print " (compare:${ccmode} (match_operand:${lmode} 1 \"${mempred}\" \"m\")\n"; if ($ccmode eq 'CCUNS') { print " "; } print " (match_operand:${lmode} 3 \"${constpred}\" \"n\")))\n"; if ($result eq 'clobber') { diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index bd6ef1e56a5..1556514263a 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -992,6 +992,26 @@ (define_predicate "lwa_operand" return INTVAL (offset) % 4 == 0; }) +;; Return 1 if the operand is a memory operand that has a valid address for +;; a DS-form instruction. I.e. the address has to be either just a register, +;; or register + const where the two low order bits of const are zero. +(define_predicate "ds_form_mem_operand" + (match_code "subreg,mem") +{ + rtx inner, addr, offset; + + inner = op; + if (reload_completed && SUBREG_P (inner)) + inner = SUBREG_REG (inner); + + if (!any_memory_operand (inner, mode)) + return false; + + addr = XEXP (inner, 0); + + return address_to_insn_form (addr, mode, NON_PREFIXED_DS) == INSN_FORM_DS; +}) + ;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. (define_predicate "symbol_ref_operand" (and (match_code "symbol_ref") -- 2.27.0