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  }