[PATCH-2,rs6000] Put constant into pseudo at expand when it needs two insns [PR86106]
Checks
Commit Message
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
@@ -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:
@@ -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")
new file mode 100644
@@ -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} } } */