[gcc r11-7570] Tighten predicates for p10 ld/cmpi fusion
Aaron Sawdey
acsawdey@gcc.gnu.org
Tue Mar 9 02:50:18 GMT 2021
https://gcc.gnu.org/g:9433c844c8bcf0166567943b45576ceeeee0b131
commit r11-7570-g9433c844c8bcf0166567943b45576ceeeee0b131
Author: Aaron Sawdey <acsawdey@linux.ibm.com>
Date: Sun Mar 7 14:47:31 2021 -0600
Tighten predicates for p10 ld/cmpi fusion
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.
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.
Diff:
---
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 @@
;; 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 @@
;; 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 @@
;; 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 @@
;; 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 "*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 @@
;; 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 "*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 @@
;; 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 "*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 "*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 "*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 "*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 "*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 "*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_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 @@
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")
More information about the Gcc-cvs
mailing list