[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