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 assemble_variable(struct tree_decl decl)20assemble_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 main()40main () 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 } 49