1  /* Inspired by 'libgomp.oacc-c-c++-common/nvptx-sese-1.c'.  */
       2  
       3  /* { dg-additional-options -O1 } */
       4  /* { dg-additional-options -fdump-tree-dom3-raw } */
       5  
       6  
       7  extern int
       8  __attribute__((const))
       9  foo1 (int);
      10  
      11  int f1 (int r)
      12  {
      13    if (foo1 (r)) /* If this first 'if' holds...  */
      14      r *= 2; /* ..., 'r' now has a zero-value lower-most bit...  */
      15  
      16    if (r & 1) /* ..., so this second 'if' can never hold...  */
      17      { /* ..., so this is unreachable.  */
      18        /* In constrast, if the first 'if' does not hold ('foo1 (r) == 0'), the
      19  	 second 'if' may hold, but we know ('foo1' being 'const') that
      20  	 'foo1 (r) == 0', so don't have to re-evaluate it here: */
      21        r += foo1 (r);
      22      }
      23  
      24    return r;
      25  }
      26  /* Thus, if optimizing, we only ever expect one call of 'foo1'.
      27     { dg-final { scan-tree-dump-times {gimple_call <foo1,} 1 dom3 } } */
      28  
      29  
      30  extern int
      31  __attribute__((const))
      32  foo2 (int);
      33  
      34  int f2 (int r)
      35  {
      36    if (foo2 (r))
      37      r *= 8;
      38  
      39    if (r & 7)
      40      r += foo2 (r);
      41  
      42    return r;
      43  }
      44  /* { dg-final { scan-tree-dump-times {gimple_call <foo2,} 1 dom3 } } */
      45  
      46  
      47  extern int
      48  __attribute__((const))
      49  foo3 (int);
      50  
      51  int f3 (int r)
      52  {
      53    if (foo3 (r))
      54      r <<= 4;
      55  
      56    if ((r & 64) && ((r & 8) || (r & 4) || (r & 2) || (r & 1)))
      57      r += foo3 (r);
      58  
      59    return r;
      60  }
      61  /* { dg-final { scan-tree-dump-times {gimple_call <foo3,} 1 dom3 } } */
      62  
      63  
      64  extern int
      65  __attribute__((const))
      66  foo4 (int);
      67  
      68  int f4 (int r)
      69  {
      70    if (foo4 (r))
      71      r *= 8;
      72  
      73    if ((r >> 1) & 2)
      74      r += foo4 (r);
      75  
      76    return r;
      77  }
      78  /* { dg-final { scan-tree-dump-times {gimple_call <foo4,} 1 dom3 } } */
      79  
      80  
      81  extern int
      82  __attribute__((const))
      83  foo5 (int);
      84  
      85  int f5 (int r) /* Works for both 'signed' and 'unsigned'.  */
      86  {
      87    if (foo5 (r))
      88      r *= 2;
      89  
      90    if ((r % 2) != 0)
      91      r += foo5 (r);
      92  
      93    return r;
      94  }
      95  /* { dg-final { scan-tree-dump-times {gimple_call <foo5,} 1 dom3 } } */
      96  
      97  
      98  extern int
      99  __attribute__((const))
     100  foo6 (int);
     101  
     102  int f6 (unsigned int r) /* 'unsigned' is important here.  */
     103  {
     104    if (foo6 (r))
     105      r *= 2;
     106  
     107    if ((r % 2) == 1)
     108      r += foo6 (r);
     109  
     110    return r;
     111  }
     112  /* { dg-final { scan-tree-dump-times {gimple_call <foo6,} 1 dom3 } } */