This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Combine] Unusual behaviour in combine


Hi Segher,

> I'll need some compilable source code to investigate this.  That means
> compilable for*me*, so with some target that is in trunk.

I'm not sure I can trigger this on trunk. I've attached a minimal patch, which
adds a pattern which can trigger the behaviour, and 2 c files: foo.c matches a
similar pattern which *can* be combined, bar.c should match the added pattern,
but does not. I believe it is due to some register equivalence problem.

> What you want isn't the kind of optimisation combine does at all.  You 
> probably want to look at something like cprop; or look at how this 
> code is generated, that doesn't seem optimal.

foo.c is a very similar case handled by combine, and bar.c can be handled if
the predicate checking that it is a const_vector is removed, which makes me
think it is a register equivalence issue.

from foo.c.263r.combine:
	Trying 11 -> 12:
	   11: r97:V4SF=r96:V4SF*const_vector
	      REG_DEAD r96:V4SF
	      REG_EQUAL r96:V4SF*const_vector
	   12: r99:V4SI=fix(unspec[r97:V4SF] 25)
	      REG_DEAD r97:V4SF
	Successfully matched this instruction:
	(set (reg:V4SI 99 [ D.3424 ])
	    (fix:V4SI (unspec:V4SI [
			(mult:V4SF (reg:V4SF 96 [ D.3422 ])
			    (const_vector:V4SF [
				    (const_double:SF 4.0e+0 [0x0.8p+3]) repeated x4
				]))
		    ] UNSPEC_FRINTZ)))


from bar.c.263r.combine:
	Trying 10 -> 12:
	   10: r97:V4SF=float(r96:V4SI)
	      REG_DEAD r96:V4SI
	   12: r98:V4SF=r97:V4SF*r99:V4SF
	      REG_DEAD r97:V4SF
	      REG_EQUAL r97:V4SF*const_vector
	Failed to match this instruction:
	(set (reg:V4SF 98 [ D.3424 ])
	    (mult:V4SF (float:V4SF (reg:V4SI 96 [ D.3422 ]))
		(reg:V4SF 99)))
I would expect combine to try this pattern:
	(set (reg:V4SF 98 [ D.3424 ])
	    (mult:V4SF (float:V4SF (reg:V4SI 96 [ D.3422 ]))
		(const_vector:V4SF [
                 	(const_double:SF 2.5e-1 [0x0.8p-1]) repeated x4
				])))

but it does not.

In both cases the constant vector is set outside the basic block, but in the
'foo' case, combine successfully matches the pattern using register
equivalence, while in the 'bar' case in does not.

testcases compiled with:
  aarch64-none-elf-gcc -S -mcpu=cortex-a53 -O2 -ftree-vectorize -fno-inline -fdump-rtl-all -fno-vect-cost-model -dp -fdump-rtl-combine-all -fdump-tree-optimized -o - [foo.c/bar.c]

$gcc -v
COLLECT_GCC=$INSTALL/bin/aarch64-none-elf-gcc
COLLECT_LTO_WRAPPER=$INSTALL/libexec/gcc/aarch64-none-elf/10.0.0/lto-wrapper
Target: aarch64-none-elf
Configured with: src/gcc/configure --target=aarch64-none-elf --prefix=$INSTALL/ --with-gmp=$BUILD/host-tools --with-mpfr=$BUILD/host-tools --with-mpc=$BUILD/host-tools --with-isl=$BUILD/host-tools --disable-shared --disable-nls --disable-threads --disable-tls --enable-checking=yes --enable-languages=c,c++,fortran --with-newlib --with-pkgversion=unknown
Thread model: single
gcc version 10.0.0 20190612 (experimental) (unknown)

From 7e744509575030ca5b3fa6042d02d27171fbfbfd Mon Sep 17 00:00:00 2001
From: Joel Hutton <Joel.Hutton@arm.com>
Date: Tue, 11 Jun 2019 10:10:07 +0100
Subject: [PATCH] Minimal pattern to demonstrate combine behaviour

---
 gcc/config/aarch64/aarch64-protos.h |  1 +
 gcc/config/aarch64/aarch64-simd.md  | 13 +++++++++++++
 gcc/config/aarch64/aarch64.c        |  6 ++++++
 gcc/config/aarch64/predicates.md    |  3 +++
 4 files changed, 23 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a0723266f22..ff1787c37ed 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -483,6 +483,7 @@ enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
 enum reg_class aarch64_regno_regclass (unsigned);
 int aarch64_asm_preferred_eh_data_format (int, int);
 int aarch64_fpconst_pow_of_2 (rtx);
+int aarch64_fp_const_vec (rtx);
 machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned,
 						       machine_mode);
 int aarch64_uxt_size (int, HOST_WIDE_INT);
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index d4c48d2aa61..698b49c006f 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -2133,6 +2133,19 @@
   "TARGET_SIMD"
   {})
 
+(define_insn "*aarch64_combine_scvtf"
+  [(set (match_operand 0 "register_operand" "=w")
+	(mult
+	 (float
+	  (match_operand 1 "" "w"))
+	 (match_operand 2 "aarch64_fp_const_vec" ""))
+	)]
+  ""
+  {
+    return "test_match";
+  }
+)
+
 (define_insn "<optab><fcvt_target><VHSDF:mode>2"
   [(set (match_operand:VHSDF 0 "register_operand" "=w")
 	(FLOATUORS:VHSDF
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 83453d03095..f836246e184 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -18327,6 +18327,12 @@ aarch64_fpconst_pow_of_2 (rtx x)
   return exact_log2 (real_to_integer (r));
 }
 
+int
+aarch64_fp_const_vec (rtx x)
+{
+  return GET_CODE (x) == CONST_VECTOR;
+}
+
 /* If X is a vector of equal CONST_DOUBLE values and that value is
    Y, return the aarch64_fpconst_pow_of_2 of Y.  Otherwise return -1.  */
 
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 10100ca830a..8fece3811b9 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -101,6 +101,9 @@
 (define_predicate "aarch64_fp_vec_pow2"
   (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
 
+(define_predicate "aarch64_fp_const_vec"
+  (match_test "aarch64_fp_const_vec (op)"))
+
 (define_predicate "aarch64_sve_cnt_immediate"
   (and (match_code "const_poly_int")
        (match_test "aarch64_sve_cnt_immediate_p (op)")))
-- 
2.17.1

void
bar (float *a, int *b)
{
  int i;
  for (i = 0; i < 1024; i++)
    a[i] = (((float)b[i])/ 4.0f);
}
void
foo (float *a, int *b)
{
  int i;
  for (i = 0; i < 1024; i++)
    b[i] = a[i] * 4.0f;
}

Attachment: bar.c.262r.ud_dce
Description: bar.c.262r.ud_dce

Attachment: bar.c.263r.combine
Description: bar.c.263r.combine

Attachment: foo.c.262r.ud_dce
Description: foo.c.262r.ud_dce

Attachment: foo.c.263r.combine
Description: foo.c.263r.combine


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]