re PR middle-end/62263 (Good codegen for bitwise rotate requires code that is technically undefined behavior)

PR middle-end/62263
	PR middle-end/82498
	* tree-ssa-forwprop.c (simplify_rotate): Allow def_arg1[N]
	to be any operand_equal_p operands.  For & (B - 1) require
	B to be power of 2.  Recognize
	(X << (Y & (B - 1))) | (X >> ((-Y) & (B - 1))) and similar patterns.

	* c-c++-common/rotate-5.c (f2): New function.  Move old
	function to ...
	(f4): ... this.  Use 127 instead of 128.
	(f3, f5, f6): New functions.
	(main): Test all f[1-6] functions, with both 0 and 1 as
	second arguments.
	* c-c++-common/rotate-6.c: New test.
	* c-c++-common/rotate-6a.c: New test.
	* c-c++-common/rotate-7.c: New test.
	* c-c++-common/rotate-7a.c: New test.
	* c-c++-common/rotate-8.c: New test.

From-SVN: r253760
This commit is contained in:
Jakub Jelinek 2017-10-14 20:47:14 +02:00 committed by Jakub Jelinek
parent 6af90df0e4
commit cc453086d2
9 changed files with 1502 additions and 17 deletions

View File

@ -1,3 +1,12 @@
2017-10-14 Jakub Jelinek <jakub@redhat.com>
PR middle-end/62263
PR middle-end/82498
* tree-ssa-forwprop.c (simplify_rotate): Allow def_arg1[N]
to be any operand_equal_p operands. For & (B - 1) require
B to be power of 2. Recognize
(X << (Y & (B - 1))) | (X >> ((-Y) & (B - 1))) and similar patterns.
2017-10-14 Uros Bizjak <ubizjak@gmail.com> 2017-10-14 Uros Bizjak <ubizjak@gmail.com>
PR bootstrap/82553 PR bootstrap/82553

View File

@ -1,3 +1,19 @@
2017-10-14 Jakub Jelinek <jakub@redhat.com>
PR middle-end/62263
PR middle-end/82498
* c-c++-common/rotate-5.c (f2): New function. Move old
function to ...
(f4): ... this. Use 127 instead of 128.
(f3, f5, f6): New functions.
(main): Test all f[1-6] functions, with both 0 and 1 as
second arguments.
* c-c++-common/rotate-6.c: New test.
* c-c++-common/rotate-6a.c: New test.
* c-c++-common/rotate-7.c: New test.
* c-c++-common/rotate-7a.c: New test.
* c-c++-common/rotate-8.c: New test.
2017-10-14 Hristian Kirtchev <kirtchev@adacore.com> 2017-10-14 Hristian Kirtchev <kirtchev@adacore.com>
* gnat.dg/remote_call_iface.ads, gnat.dg/remote_call_iface.adb: New * gnat.dg/remote_call_iface.ads, gnat.dg/remote_call_iface.adb: New

View File

@ -15,12 +15,40 @@ f1 (unsigned long long x, unsigned int y)
return (x << y) | (x >> ((-y) & 63)); return (x << y) | (x >> ((-y) & 63));
} }
__attribute__((noinline, noclone))
unsigned long long
f2 (unsigned long long x, unsigned int y)
{
return (x << y) + (x >> ((-y) & 63));
}
__attribute__((noinline, noclone))
unsigned long long
f3 (unsigned long long x, unsigned int y)
{
return (x << y) ^ (x >> ((-y) & 63));
}
#if __CHAR_BIT__ * __SIZEOF_INT128__ == 128 #if __CHAR_BIT__ * __SIZEOF_INT128__ == 128
__attribute__((noinline, noclone)) __attribute__((noinline, noclone))
unsigned __int128 unsigned __int128
f2 (unsigned __int128 x, unsigned int y) f4 (unsigned __int128 x, unsigned int y)
{ {
return (x << y) | (x >> ((-y) & 128)); return (x << y) | (x >> ((-y) & 127));
}
__attribute__((noinline, noclone))
unsigned __int128
f5 (unsigned __int128 x, unsigned int y)
{
return (x << y) + (x >> ((-y) & 127));
}
__attribute__((noinline, noclone))
unsigned __int128
f6 (unsigned __int128 x, unsigned int y)
{
return (x << y) ^ (x >> ((-y) & 127));
} }
#endif #endif
#endif #endif
@ -31,12 +59,45 @@ main ()
#if __CHAR_BIT__ * __SIZEOF_LONG_LONG__ == 64 #if __CHAR_BIT__ * __SIZEOF_LONG_LONG__ == 64
if (f1 (0x123456789abcdef0ULL, 0) != 0x123456789abcdef0ULL) if (f1 (0x123456789abcdef0ULL, 0) != 0x123456789abcdef0ULL)
abort (); abort ();
if (f2 (0x123456789abcdef0ULL, 0) != 0x2468acf13579bde0ULL)
abort ();
if (f3 (0x123456789abcdef0ULL, 0) != 0)
abort ();
if (f1 (0x123456789abcdef0ULL, 1) != 0x2468acf13579bde0ULL)
abort ();
if (f2 (0x123456789abcdef0ULL, 1) != 0x2468acf13579bde0ULL)
abort ();
if (f3 (0x123456789abcdef0ULL, 1) != 0x2468acf13579bde0ULL)
abort ();
#if __CHAR_BIT__ * __SIZEOF_INT128__ == 128 #if __CHAR_BIT__ * __SIZEOF_INT128__ == 128
if (f2 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64) if (f4 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL, 0) | 0x0fedcba987654321ULL, 0)
!= ((((unsigned __int128) 0x123456789abcdef0ULL) << 64) != ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL)) | 0x0fedcba987654321ULL))
abort (); abort ();
if (f5 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL, 0)
!= ((((unsigned __int128) 0x2468acf13579bde0ULL) << 64)
| 0x1fdb97530eca8642ULL))
abort ();
if (f6 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL, 0) != 0)
abort ();
if (f4 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL, 1)
!= ((((unsigned __int128) 0x2468acf13579bde0ULL) << 64)
| 0x1fdb97530eca8642ULL))
abort ();
if (f5 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL, 1)
!= ((((unsigned __int128) 0x2468acf13579bde0ULL) << 64)
| 0x1fdb97530eca8642ULL))
abort ();
if (f6 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
| 0x0fedcba987654321ULL, 1)
!= ((((unsigned __int128) 0x2468acf13579bde0ULL) << 64)
| 0x1fdb97530eca8642ULL))
abort ();
#endif #endif
#endif #endif
return 0; return 0;

View File

@ -0,0 +1,582 @@
/* Check rotate pattern detection. */
/* { dg-do compile } */
/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
/* Rotates should be recognized only in functions with | instead of + or ^,
or in functions that have constant shift counts (unused attribute on y). */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 48 "optimized" } } */
unsigned int
f1 (unsigned int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f2 (unsigned int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f3 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f4 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> 1);
}
unsigned short int
f5 (unsigned short int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f6 (unsigned short int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f7 (unsigned char x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f8 (unsigned char x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f9 (unsigned int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f10 (unsigned int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f11 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f12 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> 1);
}
unsigned short int
f13 (unsigned short int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f14 (unsigned short int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f15 (unsigned char x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f16 (unsigned char x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f17 (unsigned int x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f18 (unsigned int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f19 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << 1);
}
unsigned int
f20 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned short int
f21 (unsigned short int x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f22 (unsigned short int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f23 (unsigned char x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << (y & (__CHAR_BIT__ - 1)));
}
unsigned char
f24 (unsigned char x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << (y & (__CHAR_BIT__ - 1)));
}
unsigned int
f25 (unsigned int x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f26 (unsigned int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f27 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 1);
}
unsigned int
f28 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned short int
f29 (unsigned short int x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f30 (unsigned short int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f31 (unsigned char x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f32 (unsigned char x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f33 (unsigned int x, unsigned int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f34 (unsigned int x, unsigned long int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f35 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f36 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << 1);
}
unsigned short int
f37 (unsigned short int x, unsigned int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f38 (unsigned short int x, unsigned long int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f39 (unsigned char x, unsigned int y)
{
return (x >> (y & (__CHAR_BIT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f40 (unsigned char x, unsigned long int y)
{
return (x >> (y & (__CHAR_BIT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f41 (unsigned int x, unsigned int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f42 (unsigned int x, unsigned long int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f43 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f44 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << 1);
}
unsigned short int
f45 (unsigned short int x, unsigned int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f46 (unsigned short int x, unsigned long int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f47 (unsigned char x, unsigned int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f48 (unsigned char x, unsigned long int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f49 (unsigned int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f50 (unsigned int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f51 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> 1);
}
unsigned int
f52 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned short int
f53 (unsigned short int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f54 (unsigned short int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f55 (unsigned char x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned char
f56 (unsigned char x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned int
f57 (unsigned int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f58 (unsigned int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f59 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 1);
}
unsigned int
f60 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned short int
f61 (unsigned short int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f62 (unsigned short int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f63 (unsigned char x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f64 (unsigned char x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f65 (unsigned int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f66 (unsigned int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f67 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f68 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> 1);
}
unsigned short int
f69 (unsigned short int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f70 (unsigned short int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f71 (unsigned char x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f72 (unsigned char x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f73 (unsigned int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f74 (unsigned int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f75 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f76 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> 1);
}
unsigned short int
f77 (unsigned short int x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f78 (unsigned short int x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f79 (unsigned char x, unsigned int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f80 (unsigned char x, unsigned long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f81 (unsigned int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f82 (unsigned int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f83 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> 1);
}
unsigned int
f84 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned short int
f85 (unsigned short int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f86 (unsigned short int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f87 (unsigned char x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) + (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned char
f88 (unsigned char x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) + (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned int
f89 (unsigned int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f90 (unsigned int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f91 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> 1);
}
unsigned int
f92 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned short int
f93 (unsigned short int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f94 (unsigned short int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f95 (unsigned char x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f96 (unsigned char x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}

View File

@ -0,0 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -Wno-overflow" } */
#define ROTATE_N "rotate-6.c"
#include "rotate-1a.c"

View File

@ -0,0 +1,582 @@
/* Check rotate pattern detection. */
/* { dg-do compile } */
/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
/* Rotates should be recognized only in functions with | instead of + or ^,
or in functions that have constant shift counts (unused attribute on y). */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 48 "optimized" } } */
unsigned int
f1 (unsigned int x, int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f2 (unsigned int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f3 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f4 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> 1);
}
unsigned short int
f5 (unsigned short int x, int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f6 (unsigned short int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f7 (unsigned char x, int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f8 (unsigned char x, long int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f9 (unsigned int x, int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f10 (unsigned int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f11 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f12 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> 1);
}
unsigned short int
f13 (unsigned short int x, int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f14 (unsigned short int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f15 (unsigned char x, int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f16 (unsigned char x, long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f17 (unsigned int x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f18 (unsigned int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f19 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << 1);
}
unsigned int
f20 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned short int
f21 (unsigned short int x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f22 (unsigned short int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f23 (unsigned char x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << (y & (__CHAR_BIT__ - 1)));
}
unsigned char
f24 (unsigned char x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << (y & (__CHAR_BIT__ - 1)));
}
unsigned int
f25 (unsigned int x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f26 (unsigned int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f27 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 1);
}
unsigned int
f28 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned short int
f29 (unsigned short int x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f30 (unsigned short int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f31 (unsigned char x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f32 (unsigned char x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f33 (unsigned int x, int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f34 (unsigned int x, long int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f35 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f36 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << 1);
}
unsigned short int
f37 (unsigned short int x, int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f38 (unsigned short int x, long int y)
{
return (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f39 (unsigned char x, int y)
{
return (x >> (y & (__CHAR_BIT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f40 (unsigned char x, long int y)
{
return (x >> (y & (__CHAR_BIT__ - 1))) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f41 (unsigned int x, int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f42 (unsigned int x, long int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f43 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f44 (unsigned int x, int y __attribute__((unused)))
{
return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << 1);
}
unsigned short int
f45 (unsigned short int x, int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f46 (unsigned short int x, long int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f47 (unsigned char x, int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f48 (unsigned char x, long int y)
{
return (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f49 (unsigned int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f50 (unsigned int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f51 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> 1);
}
unsigned int
f52 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned short int
f53 (unsigned short int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f54 (unsigned short int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f55 (unsigned char x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned char
f56 (unsigned char x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned int
f57 (unsigned int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f58 (unsigned int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f59 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 1);
}
unsigned int
f60 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned short int
f61 (unsigned short int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f62 (unsigned short int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f63 (unsigned char x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f64 (unsigned char x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f65 (unsigned int x, int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f66 (unsigned int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f67 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f68 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> 1);
}
unsigned short int
f69 (unsigned short int x, int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f70 (unsigned short int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f71 (unsigned char x, int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f72 (unsigned char x, long int y)
{
return (x << (y & (__CHAR_BIT__ - 1))) + (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f73 (unsigned int x, int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f74 (unsigned int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f75 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f76 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> 1);
}
unsigned short int
f77 (unsigned short int x, int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f78 (unsigned short int x, long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f79 (unsigned char x, int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f80 (unsigned char x, long int y)
{
return (x << (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned int
f81 (unsigned int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f82 (unsigned int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f83 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) + (x >> 1);
}
unsigned int
f84 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned short int
f85 (unsigned short int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f86 (unsigned short int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) + (x >> (y & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f87 (unsigned char x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) + (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned char
f88 (unsigned char x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) + (x >> (y & (__CHAR_BIT__ - 1)));
}
unsigned int
f89 (unsigned int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f90 (unsigned int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f91 (unsigned int x, int y __attribute__((unused)))
{
return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) + (x >> 1);
}
unsigned int
f92 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) + (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned short int
f93 (unsigned short int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f94 (unsigned short int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f95 (unsigned char x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f96 (unsigned char x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) + (x >> (y & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}

View File

@ -0,0 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -Wno-overflow" } */
#define ROTATE_N "rotate-7.c"
#include "rotate-1a.c"

View File

@ -0,0 +1,170 @@
/* PR middle-end/62263 */
/* PR middle-end/82498 */
/* { dg-do compile } */
/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 23 "optimized" } } */
unsigned int
f1 (unsigned int x, unsigned char y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f2 (unsigned int x, signed char y)
{
y &= __CHAR_BIT__ * __SIZEOF_INT__ - 1;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f3 (unsigned int x, unsigned char y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))));
}
unsigned int
f4 (unsigned int x, unsigned char y)
{
y = y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1);
return y ? (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) : x;
}
unsigned int
f5 (unsigned int x, unsigned char y)
{
y = y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1);
return (x << y) | (x >> ((__CHAR_BIT__ * __SIZEOF_INT__ - y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f6 (unsigned int x, unsigned char y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((__CHAR_BIT__ * __SIZEOF_INT__ - (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f7 (unsigned int x, unsigned char y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((__CHAR_BIT__ * __SIZEOF_INT__ - y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f8 (unsigned int x, unsigned char y)
{
return (x << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f9 (unsigned int x, int y)
{
return (0x12345678U << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (0x12345678U >> (-y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f10 (unsigned int x, int y)
{
return (0x12345678U >> (-y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (0x12345678U << (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f11 (unsigned int x, int y)
{
return (0x12345678U >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (0x12345678U << (-y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f12 (unsigned int x, int y)
{
return (0x12345678U << (-y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (0x12345678U >> (y & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned
f13 (unsigned x, unsigned char y)
{
if (y == 0)
return x;
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned
f14 (unsigned x, unsigned y)
{
if (y == 0)
return x;
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned
f15 (unsigned x, unsigned short y)
{
if (y == 0)
return x;
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned
f16 (unsigned x, unsigned char y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
if (y == 0)
return x;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned
f17 (unsigned x, unsigned y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
if (y == 0)
return x;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned
f18 (unsigned x, unsigned short y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
if (y == 0)
return x;
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned
f19 (unsigned x, unsigned char y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (((unsigned char) -y) % (__CHAR_BIT__ * __SIZEOF_INT__)));
}
unsigned
f20 (unsigned x, unsigned int y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (-y % (__CHAR_BIT__ * __SIZEOF_INT__)));
}
unsigned
f21 (unsigned x, unsigned short y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (((unsigned short) -y) % (__CHAR_BIT__ * __SIZEOF_INT__)));
}
unsigned
f22 (unsigned x, unsigned char y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (-y & ((__CHAR_BIT__ * __SIZEOF_INT__) - 1)));
}
unsigned
f23 (unsigned x, unsigned short y)
{
y %= __CHAR_BIT__ * __SIZEOF_INT__;
return (x << y) | (x >> (-y & ((__CHAR_BIT__ * __SIZEOF_INT__) - 1)));
}

View File

@ -1491,9 +1491,14 @@ defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
applied, otherwise return false. applied, otherwise return false.
We are looking for X with unsigned type T with bitsize B, OP being We are looking for X with unsigned type T with bitsize B, OP being
+, | or ^, some type T2 wider than T and +, | or ^, some type T2 wider than T. For:
(X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B (X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B
((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B ((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B
transform these into:
X r<< CNT1
Or for:
(X << Y) OP (X >> (B - Y)) (X << Y) OP (X >> (B - Y))
(X << (int) Y) OP (X >> (int) (B - Y)) (X << (int) Y) OP (X >> (int) (B - Y))
((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y))) ((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
@ -1503,12 +1508,23 @@ defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1)))) ((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1))))
((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1)))) ((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
and transform these into: transform these into:
X r<< CNT1
X r<< Y X r<< Y
Or for:
(X << (Y & (B - 1))) | (X >> ((-Y) & (B - 1)))
(X << (int) (Y & (B - 1))) | (X >> (int) ((-Y) & (B - 1)))
((T) ((T2) X << (Y & (B - 1)))) | ((T) ((T2) X >> ((-Y) & (B - 1))))
((T) ((T2) X << (int) (Y & (B - 1)))) \
| ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
transform these into:
X r<< (Y & (B - 1))
Note, in the patterns with T2 type, the type of OP operands Note, in the patterns with T2 type, the type of OP operands
might be even a signed type, but should have precision B. */ might be even a signed type, but should have precision B.
Expressions with & (B - 1) should be recognized only if B is
a power of 2. */
static bool static bool
simplify_rotate (gimple_stmt_iterator *gsi) simplify_rotate (gimple_stmt_iterator *gsi)
@ -1578,7 +1594,9 @@ simplify_rotate (gimple_stmt_iterator *gsi)
def_arg1[i] = tem; def_arg1[i] = tem;
} }
/* Both shifts have to use the same first operand. */ /* Both shifts have to use the same first operand. */
if (TREE_CODE (def_arg1[0]) != SSA_NAME || def_arg1[0] != def_arg1[1]) if (!operand_equal_for_phi_arg_p (def_arg1[0], def_arg1[1])
|| !types_compatible_p (TREE_TYPE (def_arg1[0]),
TREE_TYPE (def_arg1[1])))
return false; return false;
if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0]))) if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0])))
return false; return false;
@ -1649,8 +1667,10 @@ simplify_rotate (gimple_stmt_iterator *gsi)
/* The above sequence isn't safe for Y being 0, /* The above sequence isn't safe for Y being 0,
because then one of the shifts triggers undefined behavior. because then one of the shifts triggers undefined behavior.
This alternative is safe even for rotation count of 0. This alternative is safe even for rotation count of 0.
One shift count is Y and the other (-Y) & (B - 1). */ One shift count is Y and the other (-Y) & (B - 1).
Or one shift count is Y & (B - 1) and the other (-Y) & (B - 1). */
else if (cdef_code[i] == BIT_AND_EXPR else if (cdef_code[i] == BIT_AND_EXPR
&& pow2p_hwi (TYPE_PRECISION (rtype))
&& tree_fits_shwi_p (cdef_arg2[i]) && tree_fits_shwi_p (cdef_arg2[i])
&& tree_to_shwi (cdef_arg2[i]) && tree_to_shwi (cdef_arg2[i])
== TYPE_PRECISION (rtype) - 1 == TYPE_PRECISION (rtype) - 1
@ -1675,17 +1695,50 @@ simplify_rotate (gimple_stmt_iterator *gsi)
rotcnt = tem; rotcnt = tem;
break; break;
} }
defcodefor_name (tem, &code, &tem, NULL); tree tem2;
defcodefor_name (tem, &code, &tem2, NULL);
if (CONVERT_EXPR_CODE_P (code) if (CONVERT_EXPR_CODE_P (code)
&& INTEGRAL_TYPE_P (TREE_TYPE (tem)) && INTEGRAL_TYPE_P (TREE_TYPE (tem2))
&& TYPE_PRECISION (TREE_TYPE (tem)) && TYPE_PRECISION (TREE_TYPE (tem2))
> floor_log2 (TYPE_PRECISION (rtype)) > floor_log2 (TYPE_PRECISION (rtype))
&& type_has_mode_precision_p (TREE_TYPE (tem)) && type_has_mode_precision_p (TREE_TYPE (tem2)))
&& (tem == def_arg2[1 - i]
|| tem == def_arg2_alt[1 - i]))
{ {
rotcnt = tem; if (tem2 == def_arg2[1 - i]
break; || tem2 == def_arg2_alt[1 - i])
{
rotcnt = tem2;
break;
}
}
else
tem2 = NULL_TREE;
if (cdef_code[1 - i] == BIT_AND_EXPR
&& tree_fits_shwi_p (cdef_arg2[1 - i])
&& tree_to_shwi (cdef_arg2[1 - i])
== TYPE_PRECISION (rtype) - 1
&& TREE_CODE (cdef_arg1[1 - i]) == SSA_NAME)
{
if (tem == cdef_arg1[1 - i]
|| tem2 == cdef_arg1[1 - i])
{
rotcnt = def_arg2[1 - i];
break;
}
tree tem3;
defcodefor_name (cdef_arg1[1 - i], &code, &tem3, NULL);
if (CONVERT_EXPR_CODE_P (code)
&& INTEGRAL_TYPE_P (TREE_TYPE (tem3))
&& TYPE_PRECISION (TREE_TYPE (tem3))
> floor_log2 (TYPE_PRECISION (rtype))
&& type_has_mode_precision_p (TREE_TYPE (tem3)))
{
if (tem == tem3 || tem2 == tem3)
{
rotcnt = def_arg2[1 - i];
break;
}
}
} }
} }
} }