aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2022-01-24 18:17:47 +0800
committerliuhongt <hongtao.liu@intel.com>2022-02-08 12:39:31 +0800
commit0103c2e4082c5a342a6834d31ea52bc7e5498016 (patch)
tree36b29e21841b7dc2285079e3b35b5b50f4329871
parentcc2430c122a49130b2b0a8a67455db30bbb8fd00 (diff)
downloadgcc-0103c2e4082c5a342a6834d31ea52bc7e5498016.zip
gcc-0103c2e4082c5a342a6834d31ea52bc7e5498016.tar.gz
gcc-0103c2e4082c5a342a6834d31ea52bc7e5498016.tar.bz2
Don't propagate for a more expensive reg-reg move.
For i386, it enables optimization like: vmovd %xmm0, %edx - vmovd %xmm0, %eax + movl %edx, %eax gcc/ChangeLog: PR rtl-optimization/104059 * regcprop.cc (copyprop_hardreg_forward_1): Don't propagate for a more expensive reg-reg move. gcc/testsuite/ChangeLog: * gcc.target/i386/pr104059.c: New test.
-rw-r--r--gcc/regcprop.cc17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr104059.c22
2 files changed, 38 insertions, 1 deletions
diff --git a/gcc/regcprop.cc b/gcc/regcprop.cc
index 8e966f2..1fdc367 100644
--- a/gcc/regcprop.cc
+++ b/gcc/regcprop.cc
@@ -892,6 +892,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
if (set && REG_P (SET_SRC (set)))
{
rtx src = SET_SRC (set);
+ rtx dest = SET_DEST (set);
unsigned int regno = REGNO (src);
machine_mode mode = GET_MODE (src);
unsigned int i;
@@ -915,7 +916,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
/* If the destination is also a register, try to find a source
register in the same class. */
- if (REG_P (SET_DEST (set)))
+ if (REG_P (dest))
{
new_rtx = find_oldest_value_reg (REGNO_REG_CLASS (regno),
src, vd);
@@ -943,6 +944,20 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
mode, i, regno);
if (new_rtx != NULL_RTX)
{
+ /* Don't propagate for a more expensive reg-reg move. */
+ if (REG_P (dest))
+ {
+ enum reg_class from = REGNO_REG_CLASS (regno);
+ enum reg_class to = REGNO_REG_CLASS (REGNO (dest));
+ enum reg_class new_from = REGNO_REG_CLASS (i);
+ unsigned int original_cost
+ = targetm.register_move_cost (mode, from, to);
+ unsigned int after_cost
+ = targetm.register_move_cost (mode, new_from, to);
+ if (after_cost > original_cost)
+ continue;
+ }
+
if (validate_change (insn, &SET_SRC (set), new_rtx, 0))
{
ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (src);
diff --git a/gcc/testsuite/gcc.target/i386/pr104059.c b/gcc/testsuite/gcc.target/i386/pr104059.c
new file mode 100644
index 0000000..4815fa3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104059.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx2 -O2 -fdump-rtl-cprop_hardreg-details" } */
+/* { dg-final { scan-rtl-dump-not {replaced reg [0-9]* with [0-9]*} "cprop_hardreg" } } */
+
+#include<stdint.h>
+int test (uint8_t *p, uint32_t t[1][1], int n) {
+
+ int sum = 0;
+ uint32_t a0;
+ for (int i = 0; i < 4; i++, p++)
+ t[i][0] = p[0];
+
+ for (int i = 0; i < 4; i++) {
+ {
+ int t0 = t[0][i] + t[0][i];
+ a0 = t0;
+ };
+ sum += a0;
+ }
+ return (((uint16_t)sum) + ((uint32_t)sum >> 16)) >> 1;
+}
+