111
|
1 /* { dg-do run } */
|
|
2 /* { dg-options "-O2" } */
|
|
3 /* { dg-require-effective-target int32plus } */
|
|
4
|
|
5 struct tree_decl
|
|
6 {
|
|
7 union tree_decl_u1 {
|
|
8 int f;
|
|
9 long i;
|
|
10 struct tree_decl_u1_a {
|
|
11 unsigned int align : 24;
|
|
12 unsigned int off_align : 8;
|
|
13 } a;
|
|
14 } u1;
|
|
15 };
|
|
16
|
|
17 extern void abort (void);
|
|
18
|
|
19 unsigned int
|
|
20 assemble_variable (struct tree_decl decl)
|
|
21 {
|
|
22 unsigned int align;
|
|
23
|
|
24 align = decl.u1.a.align;
|
|
25
|
|
26 if (align > (1 << ((8 * 4) < 64 ? (8 * 4) - 2 : 62)))
|
|
27 align = (1 << ((8 * 4) < 64 ? (8 * 4) - 2 : 62));
|
|
28
|
|
29 /* VRP should not be propagating 0 to the RHS of this assignment.
|
|
30 But it was erroneously applying a cast operation between types of
|
|
31 different precision. align is an unsigned int with range [0,
|
|
32 0x4000000] but the .align field holds only 24 bits. So the cast
|
|
33 was returning a [0, 0] range. */
|
|
34 decl.u1.a.align = align;
|
|
35
|
|
36 return decl.u1.a.align;
|
|
37 }
|
|
38
|
|
39 int
|
|
40 main ()
|
|
41 {
|
|
42 struct tree_decl decl;
|
|
43 decl.u1.a.align = 13;
|
|
44 unsigned int x = assemble_variable (decl);
|
|
45 if (x == 0)
|
|
46 abort ();
|
|
47 return 0;
|
|
48 }
|