1 /* { dg-do run } */
2 /* { dg-require-effective-target int32plus } */
3 /* { dg-options "-O -fdump-tree-fre1 -fdump-tree-dse1" } */
4 
5 extern void abort (void);
6 
7 union U { int i; char c[4]; short s[2]; };
8 
foo(int i)9 char __attribute__((noinline,noclone)) foo(int i)
10 {
11   union U u;
12   u.i = i;
13   /* This should be equivalent to (char) i.  */
14 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
15   return u.c[0];
16 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
17   return u.c[3];
18 #else
19   return 0x04;
20 #endif
21 }
22 
baz(int i)23 short __attribute__((noinline,noclone)) baz(int i)
24 {
25   union U u;
26   u.i = i;
27   /* This should be equivalent to (char) i.  */
28 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
29   return u.s[0];
30 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
31   return u.s[1];
32 #else
33   return 0x0304;
34 #endif
35 }
36 
bar(int j)37 char __attribute__((noinline,noclone)) bar(int j)
38 {
39   union U u;
40   u.i = j;
41   /* This gets simplified to a BIT_FIELD_REF.  */
42   return u.c[2];
43 }
44 
main()45 int main()
46 {
47   if (foo (0x01020304) != 0x04)
48     abort ();
49   if (baz (0x01020304) != 0x0304)
50     abort ();
51   return 0;
52 }
53 
54 /* { dg-final { scan-tree-dump "\\(char\\) i_" "fre1" } } */
55 /* { dg-final { scan-tree-dump "\\(short int\\) i_" "fre1" } } */
56 /* { dg-final { scan-tree-dump-not "u.i =" "dse1" } } */
57