[gcc(refs/users/meissner/heads/work164-bugs)] Add power10 ori/oris and xori/xoris fusion support.

2024-04-09 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:a0937c1e3b69500a19eef7816ccb0dab3f03e80b

commit a0937c1e3b69500a19eef7816ccb0dab3f03e80b
Author: Michael Meissner 
Date:   Tue Apr 9 17:40:58 2024 -0400

Add power10 ori/oris and xori/xoris fusion support.

2024-04-09  Michael Meissner  

gcc/

* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.md (gen_wide_immediate): Add wide 
immediate
fusion patterns.
* config/rs6000/predicates.md (u32bit_cint_2_insns_operand): New 
predicate.
* config/rs6000/rs6000.md (IORXOR_OP): New code attribute.
(ior, xor splitter): Do not split ior/xor patterns that could be 
fused
on power10.

Make sure wide immediate fusion does not generate illegal instructions.

Diff:
---
 gcc/config/rs6000/fusion.md | 15 +++
 gcc/config/rs6000/genfusion.pl  | 22 ++
 gcc/config/rs6000/predicates.md |  9 +
 gcc/config/rs6000/rs6000.md |  5 -
 4 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index 4ed9ae1d69f..5feedf83cad 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -3055,3 +3055,18 @@
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
(set_attr "length" "8")])
+
+;; ori_oris and xori_xoris fusion patterns generated by gen_wide_immediate
+(define_insn "*fuse_i_is"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=")
+(iorxor:DI
+  (match_operand:DI 1 "gpc_reg_operand" "r")
+  (match_operand:DI 2 "u32bit_cint_2_insns_operand" "n")))]
+  "(TARGET_P10_FUSION)"
+{
+  HOST_WIDE_INT value = INTVAL (operands[2]);
+  operands[3] = GEN_INT (value & 0x);
+  operands[4] = GEN_INT ((value >> 16) & 0x);
+  return "i %0,%1,%3\;is %0,%0,%4";
+}
+  [(set_attr "length" "8")])
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 2271be14bfa..b6f1016b830 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -367,6 +367,28 @@ EOF
   }
 }
 
+sub gen_wide_immediate
+{
+print <<"EOF";
+
+;; ori_oris and xori_xoris fusion patterns generated by gen_wide_immediate
+(define_insn "*fuse_i_is"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=")
+(iorxor:DI
+  (match_operand:DI 1 "gpc_reg_operand" "r")
+  (match_operand:DI 2 "u32bit_cint_2_insns_operand" "n")))]
+  "(TARGET_P10_FUSION)"
+{
+  HOST_WIDE_INT value = INTVAL (operands[2]);
+  operands[3] = GEN_INT (value & 0x);
+  operands[4] = GEN_INT ((value >> 16) & 0x);
+  return "i %0,%1,%3\\;is %0,%0,%4";
+}
+  [(set_attr "length" "8")])
+EOF
+}
+
 gen_ld_cmpi_p10();
 gen_logical_addsubf();
 gen_addadd;
+gen_wide_immediate();
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index d23ce9a77a3..83f368b2916 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -282,6 +282,15 @@
   (and (match_code "const_int")
(match_test "(0x8000 + UINTVAL (op)) >> 32 == 0")))
 
+;; Return 1 if op is a 32-bit unsigned constant where the upper 16-bits is
+;; non-zero along with the lower 16-bits that needs two instructions (ORI/ORIS
+;; or XORI/XORIS to do the operation).
+(define_predicate "u32bit_cint_2_insns_operand"
+  (and (match_code "const_int")
+   (match_test "(INTVAL (op) >> 32) == 0")
+   (match_test "(INTVAL (op) & 0x) != 0")
+   (match_test "(INTVAL (op) & 0x) != 0")))
+
 ;; Return 1 if op is a constant 32-bit unsigned
 (define_predicate "c32bit_cint_operand"
   (and (match_code "const_int")
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 1acd34ca0ee..f626b68ebb2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -822,6 +822,9 @@
 (SF "TARGET_P8_VECTOR")
 (DI "TARGET_POWERPC64")])
 
+;; Convert iorxor iterator into or/xor instruction
+(define_code_attr IORXOR_OP [(ior "or") (xor "xor")])
+
 (include "darwin.md")
 
 ;; Start with fixed-point load and store insns.  Here we put only the more
@@ -3933,7 +3936,7 @@
   [(set (match_operand:GPR 0 "gpc_reg_operand")
(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
(match_operand:GPR 2 "non_logical_cint_operand")))]
-  ""
+  "mode != DImode || !TARGET_P10_FUSION"
   [(set (match_dup 3)
(iorxor:GPR (match_dup 1)
(match_dup 4)))


[gcc(refs/users/meissner/heads/work164-bugs)] Add power10 ori/oris and xori/xoris fusion support.

2024-04-08 Thread Michael Meissner via Gcc-cvs
https://gcc.gnu.org/g:9b813c320ee59176e3279391ef7c47ef6ea8ba3a

commit 9b813c320ee59176e3279391ef7c47ef6ea8ba3a
Author: Michael Meissner 
Date:   Tue Apr 9 00:30:46 2024 -0400

Add power10 ori/oris and xori/xoris fusion support.

2024-04-09  Michael Meissner  

gcc/

* config/rs6000/fusion.md: Regenerate.
* config/rs6000/genfusion.md (gen_wide_immediate): Add wide 
immediate
fusion patterns.
* config/rs6000/rs6000.md (IORXOR_OP): New code attribute.
(ior, xor splitter): Do not split ior/xor patterns that could be 
fused
on power10.

Diff:
---
 gcc/config/rs6000/fusion.md| 10 ++
 gcc/config/rs6000/genfusion.pl | 17 +
 gcc/config/rs6000/rs6000.md|  5 -
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index 4ed9ae1d69f..45819627df6 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -3055,3 +3055,13 @@
   [(set_attr "type" "fused_vector")
(set_attr "cost" "6")
(set_attr "length" "8")])
+
+;; ori_oris and xori_xoris fusion patterns generated by gen_wide_immediate
+(define_insn "*fuse_i_is"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=")
+(iorxor:DI
+  (match_operand:DI 1 "gpc_reg_operand" "r")
+  (match_operand:DI 2 "non_logical_cint_operand" "n")))]
+  "(TARGET_P10_FUSION)"
+  "i %0,%1,%w2\;is %0,%0,%v2"
+  [(set_attr "length" "8")])
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index 2271be14bfa..d059de8afc9 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -367,6 +367,23 @@ EOF
   }
 }
 
+sub gen_wide_immediate
+{
+print <<"EOF";
+
+;; ori_oris and xori_xoris fusion patterns generated by gen_wide_immediate
+(define_insn "*fuse_i_is"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=")
+(iorxor:DI
+  (match_operand:DI 1 "gpc_reg_operand" "r")
+  (match_operand:DI 2 "non_logical_cint_operand" "n")))]
+  "(TARGET_P10_FUSION)"
+  "i %0,%1,%w2\\;is %0,%0,%v2"
+  [(set_attr "length" "8")])
+EOF
+}
+
 gen_ld_cmpi_p10();
 gen_logical_addsubf();
 gen_addadd;
+gen_wide_immediate();
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 1acd34ca0ee..f626b68ebb2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -822,6 +822,9 @@
 (SF "TARGET_P8_VECTOR")
 (DI "TARGET_POWERPC64")])
 
+;; Convert iorxor iterator into or/xor instruction
+(define_code_attr IORXOR_OP [(ior "or") (xor "xor")])
+
 (include "darwin.md")
 
 ;; Start with fixed-point load and store insns.  Here we put only the more
@@ -3933,7 +3936,7 @@
   [(set (match_operand:GPR 0 "gpc_reg_operand")
(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
(match_operand:GPR 2 "non_logical_cint_operand")))]
-  ""
+  "mode != DImode || !TARGET_P10_FUSION"
   [(set (match_dup 3)
(iorxor:GPR (match_dup 1)
(match_dup 4)))