This is the mail archive of the gcc-bugs@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]

[Bug rtl-optimization/55278] [4.8/4.9 Regression] Botan performance regressions apparently due to LRA


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55278

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-05-08 06:58:37 UTC ---
unsigned int
f1 (unsigned int x, unsigned int y)
{
  return (x << y) | (x >> (32 - y));
}

unsigned int
f2 (unsigned int x, unsigned long y)
{
  return (x << y) | (x >> (32 - y));
}

unsigned int
f3 (unsigned int x)
{
  return (x << 1) | (x >> (32 - 1));
}

unsigned int
f4 (unsigned int x)
{
  return (x << (32 - 1)) | (x >> 1);
}

unsigned short int
f5 (unsigned short int x, unsigned int y)
{
  return (x << y) | (x >> (16 - y));
}

unsigned short int
f6 (unsigned short int x, unsigned long y)
{
  return (x << y) | (x >> (16 - y));
}

unsigned char
f7 (unsigned char x, unsigned int y)
{
  return (x << y) | (x >> (8 - y));
}

unsigned char
f8 (unsigned char x, unsigned long y)
{
  return (x << y) | (x >> (8 - y));
}

unsigned int
f9 (unsigned int x, unsigned int y)
{
  return (x << y) | (x >> (sizeof (unsigned int) - y));
}

unsigned int
f10 (unsigned int x, unsigned long y)
{
  return (x << y) | (x >> (sizeof (unsigned int) - y));
}

unsigned int
f11 (unsigned int x)
{
  return (x << 1) | (x >> (sizeof (unsigned int) - 1));
}

unsigned int
f12 (unsigned int x)
{
  return (x << (sizeof (unsigned int) - 1)) | (x >> 1);
}

unsigned short int
f13 (unsigned short int x, unsigned int y)
{
  return (x << y) | (x >> (sizeof (unsigned short) - y));
}

unsigned short int
f14 (unsigned short int x, unsigned long y)
{
  return (x << y) | (x >> (sizeof (unsigned short) - y));
}

unsigned char
f15 (unsigned char x, unsigned int y)
{
  return (x << y) | (x >> (sizeof (unsigned char) - y));
}

unsigned char
f16 (unsigned char x, unsigned long y)
{
  return (x << y) | (x >> (sizeof (unsigned char) - y));
}

shows lots of various issues with rotates:
1) if the shift count isn't int expression, we don't detect that (there is
extra
   cast that bit_rotate: doesn't handle) - example f2
2) for f3 we emit rorl $31, %eax while we should special case it and emit
   roll %eax instead (shorter insn; backend issue)
3) the casts added for promoted types aren't handled - example f5
   - I guess even that is fine to handle, because say for y 17, while << 17
   is defined behavior, >> (16 - 17) or >> (16U - 17) should be undefined
   behavior and thus really y should be [1, 15].
4) the deferred SIZEOF_EXPR folding in C++ plays a role here
5) as mentioned in another PR, these rotate idioms assume non-zero rotation
   count, for 0 they have undefined behavior, so we should recognize also
   another form

So, IMHO bit_rotate: should be extended to handle these (except that it can't
do anything about SIZEOF_EXPR, being a FE tree (unless we add some langhook for
it
or handle it again in C++ lang folder), and perhaps some later pass (bswap pass
or gimple-fold?) should be taught to recognize it too.  And the vectorizer
pattern detection needs to be taught to undo that if there is no vector
rotation optab.


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