[Bug middle-end/54201] XMM constant duplicated
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Aug 31 17:20:31 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54201
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The .rodata duplication should now be gone with the above commit.
I've tried
--- gcc/varasm.c.jj 2020-08-31 10:26:56.978179325 +0200
+++ gcc/varasm.c 2020-08-31 19:15:34.563274307 +0200
@@ -3818,6 +3818,38 @@ force_const_mem (machine_mode in_mode, r
if (!is_a <fixed_size_mode> (in_mode, &mode))
return NULL_RTX;
+ /* Try to canonicalize CONST_VECTORs. See PR54201. */
+ if (GET_CODE (x) == CONST_VECTOR)
+ {
+ machine_mode cmode = MIN_MODE_VECTOR_INT;
+ machine_mode altmode = VOIDmode;
+
+ /* Choose a MODE_VECTOR_INT mode with the same size as in_mode
+ and as large as possible element, as long as the element is
+ at most HWI sized (so that CONST_INTs can be used rather
+ than CONST_DOUBLEs or CONST_WIDE_INTs. */
+ FOR_EACH_MODE_FROM (cmode, cmode)
+ if (known_eq (GET_MODE_SIZE (cmode), GET_MODE_SIZE (in_mode))
+ && known_le (GET_MODE_SIZE (GET_MODE_INNER (cmode)),
+ HOST_BITS_PER_WIDE_INT)
+ && (altmode == VOIDmode
+ || (GET_MODE_SIZE (GET_MODE_INNER (cmode))
+ > GET_MODE_SIZE (GET_MODE_INNER (altmode)))))
+ altmode = cmode;
+ if (altmode != VOIDmode && altmode != in_mode)
+ {
+ rtx altx = simplify_subreg (altmode, x, in_mode, 0);
+ if (altx && GET_CODE (altx) == CONST_VECTOR)
+ {
+ rtx altret = force_const_mem (altmode, altx);
+ if (altret)
+ {
+ PUT_MODE (altret, in_mode);
+ return altret;
+ }
+ }
+ }
+ }
/* If we're not allowed to drop X into the constant pool, don't. */
if (targetm.cannot_force_const_mem (mode, x))
return NULL_RTX;
as a variant of Richi's patch, but e.g. on
typedef int V __attribute__((vector_size (16)));
typedef long long int W __attribute__((vector_size (16)));
typedef float X __attribute__((vector_size (16)));
void
foo (V *v, W *w, X *x)
{
*v += (V) (X) { 2.0f, 2.0f, 2.0f, 2.0f };
*w += (W) (X) { 2.0f, 2.0f, 2.0f, 2.0f };
*x += (X) { 2.0f, 2.0f, 2.0f, 2.0f };
}
nothing will really try to share the loads, so the question is if it would gain
us anything.
More information about the Gcc-bugs
mailing list