1  /* { dg-do compile } */
       2  /* { dg-options "-O2 -fdump-tree-phiopt -fdump-tree-evrp" } */
       3  
       4  int foo_add (const unsigned char *tmp, int i, int val)
       5  {
       6    return (unsigned char)(((tmp[i] + val)>0xFF)?0xFF:(((tmp[i] + val)<0)?0:(tmp[i] + val)));
       7  }
       8  
       9  int foo_sub (const unsigned char *tmp, int i, int val)
      10  {
      11    return (unsigned char)(((tmp[i] - val)>0xFF)?0xFF:(((tmp[i] - val)<0)?0:(tmp[i] - val)));
      12  }
      13  
      14  int foo_mul (const unsigned char *tmp, int i, int val)
      15  {
      16    return (unsigned char)(((tmp[i] * val)>0xFF)?0xFF:(((tmp[i] * val)<0)?0:(tmp[i] * val)));
      17  }
      18  
      19  /* All cases should end up using min/max for the saturated operations and
      20     have no control flow.  */
      21  /* EVRP leaves copies in the IL which confuses phiopt1 so we have
      22     to rely on phiopt2 instead.  */
      23  /* { dg-final { scan-tree-dump-not " & 255;" "evrp" } } */
      24  /* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt1" { xfail *-*-* } } } */
      25  /* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt1" { xfail *-*-* } } } */
      26  /* { dg-final { scan-tree-dump-not "if " "phiopt1" { xfail *-*-* } } } */
      27  /* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "phiopt2" } } */
      28  /* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "phiopt2" } } */
      29  /* { dg-final { scan-tree-dump-not "if " "phiopt2" } } */