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.

Reply via email to