[Bug target/98647] Failure to optimize out convertion from float to vector type

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Jan 13 07:01:07 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98647

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org,
                   |                            |matz at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
If the psABI doesn't say those upper parts of the register have to be cleared
(explicitly), then it means their content is undefined in the register passing.
I believe even LLVM doesn't assume it has to be zeros, otherwise it wouldn't
compile:
typedef float V __attribute__((vector_size (16), may_alias));
float foo (V x) { return x[0]; }
into just retq - if the psABI mandated clearing of the upper bits, then we'd
need to clear in that case.

Anyway, as only the low float is extracted from it in the end, it might be best
to just change the mask into 0x7fffffff, 0, 0, 0 and then ignore any code that
would only ensure those upper floats are initialized properly.

Testcase with generic vectors so that intrinsics don't interfere with this:
typedef float V __attribute__((vector_size (16), may_alias));
typedef int W __attribute__((vector_size (16), may_alias));

float
foo (float x)
{
  V a = (V) { x, 0.0, 0.0, 0.0 };
  W b = *(W *)&a;
  b &= (W) { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff };
  V c = *(V *)&b;
  return c[0];
}

V
bar (float x)
{
  V a = (V) { x, 0.0, 0.0, 0.0 };
  W b = *(W *)&a;
  b &= (W) { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff };
  V c = *(V *)&b;
  return c;
}


More information about the Gcc-bugs mailing list