[PATCH-2,rs6000] Put constant into pseudo at expand when it needs two insns [PR86106]

Message ID b1dec3a1-1e7b-28ba-ec9b-ca56e6c15c72@linux.ibm.com
State New
Headers
Series [PATCH-2,rs6000] Put constant into pseudo at expand when it needs two insns [PR86106] |

Commit Message

HAO CHEN GUI March 16, 2023, 5:34 a.m. UTC
  Hi,
  The background and motivation of the patch are listed in the note of
PATCH-1.

  This patch changes the expander of ior/xor and force constant to a pseudo
when it needs 2 insn. Also a combine and split pattern for ior/xor is defined.
rtx_cost of ior insn is adjusted as now it may have 2 insns for certain
constants. We need to check the cost of each operand.

  Bootstrapped and tested on powerpc64-linux BE and LE with no regressions.

Thanks
Gui Haochen

ChangeLog
2023-03-14  Haochen Gui <guihaoc@linux.ibm.com>

gcc/
	* gcc/config/rs6000/rs6000.cc (rs6000_rtx_costs): Check the cost of
	each operand for IOR as it may have 2 insn for certain constants.
	* config/rs6000/rs6000.md (<code><mode>3): Put the second operand into
	register when it's a constant and need 2 ior/xor insns.
	(split for ior/xor): Remove.
	(*<code><mode>_2insn): New insn_and split pattern for 2-insn ior/xor.

gcc/testsuite/
	* gcc.target/powerpc/pr86106.c: New.


patch.diff
  

Patch

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index b3a609f3aa3..f53daff547f 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -22081,10 +22081,6 @@  rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
       return false;

     case IOR:
-      /* FIXME */
-      *total = COSTS_N_INSNS (1);
-      return true;
-
     case CLZ:
     case XOR:
     case ZERO_EXTRACT:
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dba41e3df90..0541f48c42a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3892,7 +3892,8 @@  (define_expand "<code><mode>3"
       DONE;
     }

-  if (non_logical_cint_operand (operands[2], <MODE>mode))
+  if (non_logical_cint_operand (operands[2], <MODE>mode)
+      && !can_create_pseudo_p ())
     {
       rtx tmp = ((!can_create_pseudo_p ()
 		  || rtx_equal_p (operands[0], operands[1]))
@@ -3907,15 +3908,17 @@  (define_expand "<code><mode>3"
       DONE;
     }

-  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
+  if (!logical_operand (operands[2], <MODE>mode))
     operands[2] = force_reg (<MODE>mode, operands[2]);
 })

-(define_split
-  [(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")))]
+(define_insn_and_split "*<code><mode>_2insn"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+		    (match_operand:GPR 2 "non_logical_cint_operand" "n")))]
   ""
+  "#"
+  "&& (!reload_completed || rtx_equal_p (operands[0], operands[1]))"
   [(set (match_dup 3)
 	(iorxor:GPR (match_dup 1)
 		    (match_dup 4)))
@@ -3933,7 +3936,8 @@  (define_split

   operands[4] = GEN_INT (hi);
   operands[5] = GEN_INT (lo);
-})
+}
+  [(set_attr "length" "8")])

 (define_insn "*bool<mode>3_imm"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
diff --git a/gcc/testsuite/gcc.target/powerpc/pr86106.c b/gcc/testsuite/gcc.target/powerpc/pr86106.c
new file mode 100644
index 00000000000..71501476800
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr86106.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-prefixed" } */
+
+unsigned int
+foo (unsigned int val)
+{
+  unsigned int mask = 0x7f7f7f7f;
+
+  return ~(((val & mask) + mask) | val | mask);
+}
+
+/* { dg-final { scan-assembler-not {\maddis\M} } } */
+/* { dg-final { scan-assembler-not {\maddi\M} } } */
+/* { dg-final { scan-assembler-not {\moris\M} } } */