Commit cb3b8d33 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/45216 (Rotate expressions not recognized at tree level)

	PR tree-optimization/45216
	PR tree-optimization/57157
	* tree-ssa-forwprop.c (simplify_rotate): New function.
	(ssa_forward_propagate_and_combine): Call it.

	* c-c++-common/rotate-1.c: New test.
	* c-c++-common/rotate-1a.c: New test.
	* c-c++-common/rotate-2.c: New test.
	* c-c++-common/rotate-2a.c: New test.
	* c-c++-common/rotate-3.c: New test.
	* c-c++-common/rotate-3a.c: New test.
	* c-c++-common/rotate-4.c: New test.
	* c-c++-common/rotate-4a.c: New test.

From-SVN: r198769
parent fb7f649d
2013-05-10 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/45216
PR tree-optimization/57157
* tree-ssa-forwprop.c (simplify_rotate): New function.
(ssa_forward_propagate_and_combine): Call it.
2013-05-10 Richard Biener <rguenther@suse.de>
* tree-vect-data-refs.c (vect_enhance_data_refs_alignment): Do not
......
2013-05-10 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/45216
PR tree-optimization/57157
* c-c++-common/rotate-1.c: New test.
* c-c++-common/rotate-1a.c: New test.
* c-c++-common/rotate-2.c: New test.
* c-c++-common/rotate-2a.c: New test.
* c-c++-common/rotate-3.c: New test.
* c-c++-common/rotate-3a.c: New test.
* c-c++-common/rotate-4.c: New test.
* c-c++-common/rotate-4a.c: New test.
2013-05-10 Richard Biener <rguenther@suse.de>
* gcc.target/i386/avx256-unaligned-load-2.c: Make well-defined.
......
/* Check rotate pattern detection. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
unsigned int
f1 (unsigned int x, unsigned int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f2 (unsigned int x, unsigned long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f3 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned int
f4 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x >> 1);
}
unsigned short int
f5 (unsigned short int x, unsigned int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned short int
f6 (unsigned short int x, unsigned long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned char
f7 (unsigned char x, unsigned int y)
{
return (x << y) | (x >> (__CHAR_BIT__ - y));
}
unsigned char
f8 (unsigned char x, unsigned long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ - y));
}
unsigned int
f9 (unsigned int x, unsigned int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f10 (unsigned int x, unsigned long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f11 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned int
f12 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x >> 1);
}
unsigned short int
f13 (unsigned short int x, unsigned int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned short int
f14 (unsigned short int x, unsigned long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned char
f15 (unsigned char x, unsigned int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned char
f16 (unsigned char x, unsigned long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned int
f17 (unsigned int x, unsigned int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
}
unsigned int
f18 (unsigned int x, unsigned long int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
}
unsigned int
f19 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x << 1);
}
unsigned int
f20 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned short int
f21 (unsigned short int x, unsigned int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
}
unsigned short int
f22 (unsigned short int x, unsigned long int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
}
unsigned char
f23 (unsigned char x, unsigned int y)
{
return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
}
unsigned char
f24 (unsigned char x, unsigned long int y)
{
return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
}
unsigned int
f25 (unsigned int x, unsigned int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
}
unsigned int
f26 (unsigned int x, unsigned long int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
}
unsigned int
f27 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x << 1);
}
unsigned int
f28 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned short int
f29 (unsigned short int x, unsigned int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
}
unsigned short int
f30 (unsigned short int x, unsigned long int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
}
unsigned char
f31 (unsigned char x, unsigned int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
}
unsigned char
f32 (unsigned char x, unsigned long int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
}
unsigned int
f33 (unsigned int x, unsigned int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f34 (unsigned int x, unsigned long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f35 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned int
f36 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x << 1);
}
unsigned short int
f37 (unsigned short int x, unsigned int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned short int
f38 (unsigned short int x, unsigned long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned char
f39 (unsigned char x, unsigned int y)
{
return (x >> y) | (x << (__CHAR_BIT__ - y));
}
unsigned char
f40 (unsigned char x, unsigned long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ - y));
}
unsigned int
f41 (unsigned int x, unsigned int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f42 (unsigned int x, unsigned long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f43 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned int
f44 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x << 1);
}
unsigned short int
f45 (unsigned short int x, unsigned int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned short int
f46 (unsigned short int x, unsigned long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned char
f47 (unsigned char x, unsigned int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned char
f48 (unsigned char x, unsigned long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned int
f49 (unsigned int x, unsigned int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
}
unsigned int
f50 (unsigned int x, unsigned long int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
}
unsigned int
f51 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x >> 1);
}
unsigned int
f52 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned short int
f53 (unsigned short int x, unsigned int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
}
unsigned short int
f54 (unsigned short int x, unsigned long int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
}
unsigned char
f55 (unsigned char x, unsigned int y)
{
return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
}
unsigned char
f56 (unsigned char x, unsigned long int y)
{
return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
}
unsigned int
f57 (unsigned int x, unsigned int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
}
unsigned int
f58 (unsigned int x, unsigned long int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
}
unsigned int
f59 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x >> 1);
}
unsigned int
f60 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned short int
f61 (unsigned short int x, unsigned int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
}
unsigned short int
f62 (unsigned short int x, unsigned long int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
}
unsigned char
f63 (unsigned char x, unsigned int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
}
unsigned char
f64 (unsigned char x, unsigned long int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
}
/* { dg-do run } */
/* { dg-options "-O2 -Wno-overflow" } */
extern
#ifdef __cplusplus
"C"
#endif
void abort (void);
#ifndef ROTATE_N
#define ROTATE_N "rotate-1.c"
#endif
#include ROTATE_N
unsigned int expected[] = {
0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf,
0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf,
0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf,
0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf };
#define F(n) __typeof (f##n) f##n __attribute__((noinline, noclone));
#define D(n) F(n##0) F(n##1) F(n##2) F(n##3) F(n##4) F(n##5) F(n##6) F(n##7) F(n##8) F(n##9)
#define ALL \
F(1) F(2) F(3) F(4) F(5) F(6) F(7) F(8) F(9) \
D(1) D(2) D(3) D(4) D(5) F(60) F(61) F(62) F(63) F(64)
ALL
int
main ()
{
#if __CHAR_BIT__ != 8 || __SIZEOF_SHORT__ != 2 || __SIZEOF_INT__ != 4
return 0;
#else
#undef F
#define F(n) if ((unsigned int) f##n (0x12345678U, 3) != expected[n - 1]) abort ();
ALL
return 0;
#endif
}
/* Check rotate pattern detection. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
unsigned int
f1 (unsigned int x, unsigned int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f2 (unsigned int x, unsigned long int y)
{
return (x << y) | (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) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f6 (unsigned short int x, unsigned long int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f7 (unsigned char x, unsigned int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f8 (unsigned char x, unsigned long int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f9 (unsigned int x, unsigned int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f10 (unsigned int x, unsigned long int y)
{
return (x << y) | (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) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f14 (unsigned short int x, unsigned long int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f15 (unsigned char x, unsigned int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f16 (unsigned char x, unsigned long int y)
{
return (x << y) | (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);
}
unsigned int
f18 (unsigned int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << y);
}
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);
}
unsigned short int
f22 (unsigned short int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << y);
}
unsigned char
f23 (unsigned char x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
}
unsigned char
f24 (unsigned char x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
}
unsigned int
f25 (unsigned int x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << y);
}
unsigned int
f26 (unsigned int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << y);
}
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);
}
unsigned short int
f30 (unsigned short int x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x << y);
}
unsigned char
f31 (unsigned char x, unsigned int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << y);
}
unsigned char
f32 (unsigned char x, unsigned long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << y);
}
unsigned int
f33 (unsigned int x, unsigned int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f34 (unsigned int x, unsigned long int y)
{
return (x >> y) | (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) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f38 (unsigned short int x, unsigned long int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f39 (unsigned char x, unsigned int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f40 (unsigned char x, unsigned long int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f41 (unsigned int x, unsigned int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f42 (unsigned int x, unsigned long int y)
{
return (x >> y) | (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) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f46 (unsigned short int x, unsigned long int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f47 (unsigned char x, unsigned int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f48 (unsigned char x, unsigned long int y)
{
return (x >> y) | (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);
}
unsigned int
f50 (unsigned int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> y);
}
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);
}
unsigned short int
f54 (unsigned short int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> y);
}
unsigned char
f55 (unsigned char x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
}
unsigned char
f56 (unsigned char x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
}
unsigned int
f57 (unsigned int x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> y);
}
unsigned int
f58 (unsigned int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> y);
}
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);
}
unsigned short int
f62 (unsigned short int x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x >> y);
}
unsigned char
f63 (unsigned char x, unsigned int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> y);
}
unsigned char
f64 (unsigned char x, unsigned long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> y);
}
/* { dg-do run } */
/* { dg-options "-O2 -Wno-overflow" } */
#define ROTATE_N "rotate-2.c"
#include "rotate-1a.c"
/* Check rotate pattern detection. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
unsigned int
f1 (unsigned int x, int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f2 (unsigned int x, long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f3 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned int
f4 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x >> 1);
}
unsigned short int
f5 (unsigned short int x, int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned short int
f6 (unsigned short int x, long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned char
f7 (unsigned char x, int y)
{
return (x << y) | (x >> (__CHAR_BIT__ - y));
}
unsigned char
f8 (unsigned char x, long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ - y));
}
unsigned int
f9 (unsigned int x, int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f10 (unsigned int x, long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f11 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned int
f12 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x >> 1);
}
unsigned short int
f13 (unsigned short int x, int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned short int
f14 (unsigned short int x, long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned char
f15 (unsigned char x, int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned char
f16 (unsigned char x, long int y)
{
return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned int
f17 (unsigned int x, int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
}
unsigned int
f18 (unsigned int x, long int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
}
unsigned int
f19 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x << 1);
}
unsigned int
f20 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned short int
f21 (unsigned short int x, int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
}
unsigned short int
f22 (unsigned short int x, long int y)
{
return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
}
unsigned char
f23 (unsigned char x, int y)
{
return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
}
unsigned char
f24 (unsigned char x, long int y)
{
return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
}
unsigned int
f25 (unsigned int x, int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
}
unsigned int
f26 (unsigned int x, long int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
}
unsigned int
f27 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x << 1);
}
unsigned int
f28 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) ^ (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned short int
f29 (unsigned short int x, int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
}
unsigned short int
f30 (unsigned short int x, long int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
}
unsigned char
f31 (unsigned char x, int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
}
unsigned char
f32 (unsigned char x, long int y)
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
}
unsigned int
f33 (unsigned int x, int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f34 (unsigned int x, long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
}
unsigned int
f35 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned int
f36 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x << 1);
}
unsigned short int
f37 (unsigned short int x, int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned short int
f38 (unsigned short int x, long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
}
unsigned char
f39 (unsigned char x, int y)
{
return (x >> y) | (x << (__CHAR_BIT__ - y));
}
unsigned char
f40 (unsigned char x, long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ - y));
}
unsigned int
f41 (unsigned int x, int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f42 (unsigned int x, long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
}
unsigned int
f43 (unsigned int x, int y __attribute__((unused)))
{
return (x >> 1) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned int
f44 (unsigned int x, int y __attribute__((unused)))
{
return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x << 1);
}
unsigned short int
f45 (unsigned short int x, int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned short int
f46 (unsigned short int x, long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
}
unsigned char
f47 (unsigned char x, int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned char
f48 (unsigned char x, long int y)
{
return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
}
unsigned int
f49 (unsigned int x, int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
}
unsigned int
f50 (unsigned int x, long int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
}
unsigned int
f51 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x >> 1);
}
unsigned int
f52 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
}
unsigned short int
f53 (unsigned short int x, int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
}
unsigned short int
f54 (unsigned short int x, long int y)
{
return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
}
unsigned char
f55 (unsigned char x, int y)
{
return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
}
unsigned char
f56 (unsigned char x, long int y)
{
return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
}
unsigned int
f57 (unsigned int x, int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
}
unsigned int
f58 (unsigned int x, long int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
}
unsigned int
f59 (unsigned int x, int y __attribute__((unused)))
{
return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x >> 1);
}
unsigned int
f60 (unsigned int x, int y __attribute__((unused)))
{
return (x << 1) ^ (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
}
unsigned short int
f61 (unsigned short int x, int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
}
unsigned short int
f62 (unsigned short int x, long int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
}
unsigned char
f63 (unsigned char x, int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
}
unsigned char
f64 (unsigned char x, long int y)
{
return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
}
/* { dg-do run } */
/* { dg-options "-O2 -Wno-overflow" } */
#define ROTATE_N "rotate-4.c"
#include "rotate-1a.c"
/* Check rotate pattern detection. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
unsigned int
f1 (unsigned int x, int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f2 (unsigned int x, long int y)
{
return (x << y) | (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) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f6 (unsigned short int x, long int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f7 (unsigned char x, int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f8 (unsigned char x, long int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f9 (unsigned int x, int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f10 (unsigned int x, long int y)
{
return (x << y) | (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) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f14 (unsigned short int x, long int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f15 (unsigned char x, int y)
{
return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f16 (unsigned char x, long int y)
{
return (x << y) | (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);
}
unsigned int
f18 (unsigned int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << y);
}
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);
}
unsigned short int
f22 (unsigned short int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << y);
}
unsigned char
f23 (unsigned char x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
}
unsigned char
f24 (unsigned char x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
}
unsigned int
f25 (unsigned int x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << y);
}
unsigned int
f26 (unsigned int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << y);
}
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);
}
unsigned short int
f30 (unsigned short int x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x << y);
}
unsigned char
f31 (unsigned char x, int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << y);
}
unsigned char
f32 (unsigned char x, long int y)
{
return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << y);
}
unsigned int
f33 (unsigned int x, int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
}
unsigned int
f34 (unsigned int x, long int y)
{
return (x >> y) | (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) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned short int
f38 (unsigned short int x, long int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
}
unsigned char
f39 (unsigned char x, int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned char
f40 (unsigned char x, long int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
}
unsigned int
f41 (unsigned int x, int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1)));
}
unsigned int
f42 (unsigned int x, long int y)
{
return (x >> y) | (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) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned short int
f46 (unsigned short int x, long int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1)));
}
unsigned char
f47 (unsigned char x, int y)
{
return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1)));
}
unsigned char
f48 (unsigned char x, long int y)
{
return (x >> y) | (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);
}
unsigned int
f50 (unsigned int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> y);
}
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);
}
unsigned short int
f54 (unsigned short int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> y);
}
unsigned char
f55 (unsigned char x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
}
unsigned char
f56 (unsigned char x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
}
unsigned int
f57 (unsigned int x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> y);
}
unsigned int
f58 (unsigned int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> y);
}
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);
}
unsigned short int
f62 (unsigned short int x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x >> y);
}
unsigned char
f63 (unsigned char x, int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> y);
}
unsigned char
f64 (unsigned char x, long int y)
{
return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> y);
}
/* { dg-do run } */
/* { dg-options "-O2 -Wno-overflow" } */
#define ROTATE_N "rotate-4.c"
#include "rotate-1a.c"
......@@ -2124,6 +2124,242 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
}
/* Recognize rotation patterns. Return true if a transformation
applied, otherwise return false.
We are looking for X with unsigned type T with bitsize B, OP being
+, | or ^, some type T2 wider than T and
(X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B
((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B
(X << Y) OP (X >> (B - Y))
(X << (int) Y) OP (X >> (int) (B - Y))
((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y)))
(X << Y) OP (X >> ((-Y) & (B - 1)))
(X << (int) Y) OP (X >> (int) ((-Y) & (B - 1)))
((T) ((T2) X << Y)) OP ((T) ((T2) X >> ((-Y) & (B - 1))))
((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
and transform these into:
X r<< CNT1
X r<< Y
Note, in the patterns with T2 type, the type of OP operands
might be even a signed type, but should have precision B. */
static bool
simplify_rotate (gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
tree arg[2], rtype, rotcnt = NULL_TREE;
tree def_arg1[2], def_arg2[2];
enum tree_code def_code[2];
tree lhs;
int i;
bool swapped_p = false;
gimple g;
arg[0] = gimple_assign_rhs1 (stmt);
arg[1] = gimple_assign_rhs2 (stmt);
rtype = TREE_TYPE (arg[0]);
/* Only create rotates in complete modes. Other cases are not
expanded properly. */
if (!INTEGRAL_TYPE_P (rtype)
|| TYPE_PRECISION (rtype) != GET_MODE_PRECISION (TYPE_MODE (rtype)))
return false;
for (i = 0; i < 2; i++)
defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
/* Look through narrowing conversions. */
if (CONVERT_EXPR_CODE_P (def_code[0])
&& CONVERT_EXPR_CODE_P (def_code[1])
&& INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[0]))
&& INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[1]))
&& TYPE_PRECISION (TREE_TYPE (def_arg1[0]))
== TYPE_PRECISION (TREE_TYPE (def_arg1[1]))
&& TYPE_PRECISION (TREE_TYPE (def_arg1[0])) > TYPE_PRECISION (rtype)
&& has_single_use (arg[0])
&& has_single_use (arg[1]))
{
for (i = 0; i < 2; i++)
{
arg[i] = def_arg1[i];
defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
}
}
/* One operand has to be LSHIFT_EXPR and one RSHIFT_EXPR. */
for (i = 0; i < 2; i++)
if (def_code[i] != LSHIFT_EXPR && def_code[i] != RSHIFT_EXPR)
return false;
else if (!has_single_use (arg[i]))
return false;
if (def_code[0] == def_code[1])
return false;
/* If we've looked through narrowing conversions before, look through
widening conversions from unsigned type with the same precision
as rtype here. */
if (TYPE_PRECISION (TREE_TYPE (def_arg1[0])) != TYPE_PRECISION (rtype))
for (i = 0; i < 2; i++)
{
tree tem;
enum tree_code code;
defcodefor_name (def_arg1[i], &code, &tem, NULL);
if (!CONVERT_EXPR_CODE_P (code)
|| !INTEGRAL_TYPE_P (TREE_TYPE (tem))
|| TYPE_PRECISION (TREE_TYPE (tem)) != TYPE_PRECISION (rtype))
return false;
def_arg1[i] = tem;
}
/* Both shifts have to use the same first operand. */
if (TREE_CODE (def_arg1[0]) != SSA_NAME || def_arg1[0] != def_arg1[1])
return false;
if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0])))
return false;
/* CNT1 + CNT2 == B case above. */
if (host_integerp (def_arg2[0], 1)
&& host_integerp (def_arg2[1], 1)
&& (unsigned HOST_WIDE_INT) tree_low_cst (def_arg2[0], 1)
+ tree_low_cst (def_arg2[1], 1) == TYPE_PRECISION (rtype))
rotcnt = def_arg2[0];
else if (TREE_CODE (def_arg2[0]) != SSA_NAME
|| TREE_CODE (def_arg2[1]) != SSA_NAME)
return false;
else
{
tree cdef_arg1[2], cdef_arg2[2], def_arg2_alt[2];
enum tree_code cdef_code[2];
/* Look through conversion of the shift count argument.
The C/C++ FE cast any shift count argument to integer_type_node.
The only problem might be if the shift count type maximum value
is equal or smaller than number of bits in rtype. */
for (i = 0; i < 2; i++)
{
def_arg2_alt[i] = def_arg2[i];
defcodefor_name (def_arg2[i], &cdef_code[i],
&cdef_arg1[i], &cdef_arg2[i]);
if (CONVERT_EXPR_CODE_P (cdef_code[i])
&& INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
&& TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
> floor_log2 (TYPE_PRECISION (rtype))
&& TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
== GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (cdef_arg1[i]))))
{
def_arg2_alt[i] = cdef_arg1[i];
defcodefor_name (def_arg2_alt[i], &cdef_code[i],
&cdef_arg1[i], &cdef_arg2[i]);
}
}
for (i = 0; i < 2; i++)
/* Check for one shift count being Y and the other B - Y,
with optional casts. */
if (cdef_code[i] == MINUS_EXPR
&& host_integerp (cdef_arg1[i], 0)
&& tree_low_cst (cdef_arg1[i], 0) == TYPE_PRECISION (rtype)
&& TREE_CODE (cdef_arg2[i]) == SSA_NAME)
{
tree tem;
enum tree_code code;
if (cdef_arg2[i] == def_arg2[1 - i]
|| cdef_arg2[i] == def_arg2_alt[1 - i])
{
rotcnt = cdef_arg2[i];
break;
}
defcodefor_name (cdef_arg2[i], &code, &tem, NULL);
if (CONVERT_EXPR_CODE_P (code)
&& INTEGRAL_TYPE_P (TREE_TYPE (tem))
&& TYPE_PRECISION (TREE_TYPE (tem))
> floor_log2 (TYPE_PRECISION (rtype))
&& TYPE_PRECISION (TREE_TYPE (tem))
== GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
&& (tem == def_arg2[1 - i]
|| tem == def_arg2_alt[1 - i]))
{
rotcnt = tem;
break;
}
}
/* The above sequence isn't safe for Y being 0,
because then one of the shifts triggers undefined behavior.
This alternative is safe even for rotation count of 0.
One shift count is Y and the other (-Y) & (B - 1). */
else if (cdef_code[i] == BIT_AND_EXPR
&& host_integerp (cdef_arg2[i], 0)
&& tree_low_cst (cdef_arg2[i], 0)
== TYPE_PRECISION (rtype) - 1
&& TREE_CODE (cdef_arg1[i]) == SSA_NAME)
{
tree tem;
enum tree_code code;
defcodefor_name (cdef_arg1[i], &code, &tem, NULL);
if (CONVERT_EXPR_CODE_P (code)
&& INTEGRAL_TYPE_P (TREE_TYPE (tem))
&& TYPE_PRECISION (TREE_TYPE (tem))
> floor_log2 (TYPE_PRECISION (rtype))
&& TYPE_PRECISION (TREE_TYPE (tem))
== GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem))))
defcodefor_name (tem, &code, &tem, NULL);
if (code == NEGATE_EXPR)
{
if (tem == def_arg2[1 - i] || tem == def_arg2_alt[1 - i])
{
rotcnt = tem;
break;
}
defcodefor_name (tem, &code, &tem, NULL);
if (CONVERT_EXPR_CODE_P (code)
&& INTEGRAL_TYPE_P (TREE_TYPE (tem))
&& TYPE_PRECISION (TREE_TYPE (tem))
> floor_log2 (TYPE_PRECISION (rtype))
&& TYPE_PRECISION (TREE_TYPE (tem))
== GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
&& (tem == def_arg2[1 - i]
|| tem == def_arg2_alt[1 - i]))
{
rotcnt = tem;
break;
}
}
}
if (rotcnt == NULL_TREE)
return false;
swapped_p = i != 1;
}
if (!useless_type_conversion_p (TREE_TYPE (def_arg2[0]),
TREE_TYPE (rotcnt)))
{
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (TREE_TYPE (def_arg2[0]),
NULL),
rotcnt, NULL_TREE);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
rotcnt = gimple_assign_lhs (g);
}
lhs = gimple_assign_lhs (stmt);
if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
lhs = make_ssa_name (TREE_TYPE (def_arg1[0]), NULL);
g = gimple_build_assign_with_ops (((def_code[0] == LSHIFT_EXPR) ^ swapped_p)
? LROTATE_EXPR : RROTATE_EXPR,
lhs, def_arg1[0], rotcnt);
if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
{
gsi_insert_before (gsi, g, GSI_SAME_STMT);
g = gimple_build_assign_with_ops (NOP_EXPR, gimple_assign_lhs (stmt),
lhs, NULL_TREE);
}
gsi_replace (gsi, g, false);
return true;
}
/* Perform re-associations of the plus or minus statement STMT that are
always permitted. Returns true if the CFG was changed. */
......@@ -3114,6 +3350,11 @@ ssa_forward_propagate_and_combine (void)
cfg_changed = true;
changed = did_something != 0;
}
else if ((code == PLUS_EXPR
|| code == BIT_IOR_EXPR
|| code == BIT_XOR_EXPR)
&& simplify_rotate (&gsi))
changed = true;
else if (code == BIT_AND_EXPR
|| code == BIT_IOR_EXPR
|| code == BIT_XOR_EXPR)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment