1  /* PR tree-optimization/95852 */
       2  /* { dg-do compile } */
       3  /* { dg-options "-O2 -fdump-tree-optimized -masm=att" } */
       4  /* { dg-final { scan-tree-dump-times " = \.MUL_OVERFLOW " 32 "optimized" } } */
       5  /* { dg-final { scan-assembler-times "\timull\t" 32 } } */
       6  /* In functions that return 0 on non-overflow (f2, f10, f18, f26), the overflow
       7     flag is propagated to the return value's PHI node in the non-call path; on
       8     ia32 PIC, sibcalls are not viable, so the known value of the flag can't be
       9     propagated to the return block, that is only duplicated in bbro, too late
      10     for fwprop2 or even cprop_hardreg.  */
      11  /* { dg-final { scan-assembler-times "\tseto\t" 12 { target { ia32 && { ! nonpic } } } } } */
      12  /* { dg-final { scan-assembler-times "\tseto\t" 8 { target { nonpic || { ! ia32 } } } } } */
      13  /* { dg-final { scan-assembler-times "\tsetno\t" 8 } } */
      14  /* { dg-final { scan-assembler-times "\tjn\?o\t" 16 } } */
      15  
      16  unsigned fn (void);
      17  
      18  int
      19  f1 (unsigned x, unsigned y)
      20  {
      21    unsigned int r = x * y;
      22    return x && ((int) r / (int) x) != (int) y;
      23  }
      24  
      25  unsigned
      26  f2 (unsigned x, unsigned y)
      27  {
      28    unsigned int r = x * y;
      29    if (x && ((int) r / (int) x) != (int) y)
      30      return fn ();
      31    return 0;
      32  }
      33  
      34  int
      35  f3 (unsigned x, unsigned y)
      36  {
      37    unsigned int r = x * y;
      38    return !x || ((int) r / (int) x) == (int) y;
      39  }
      40  
      41  unsigned
      42  f4 (unsigned x, unsigned y)
      43  {
      44    unsigned int r = x * y;
      45    if (!x || ((int) r / (int) x) == (int) y)
      46      return fn ();
      47    return 0;
      48  }
      49  
      50  int
      51  f5 (int x, int y)
      52  {
      53    int r = (unsigned) x * y;
      54    return x && (r / x) != y;
      55  }
      56  
      57  int
      58  f6 (int x, int y)
      59  {
      60    int r = (unsigned) x * y;
      61    if (x && (r / x) != y)
      62      return fn ();
      63    return 0;
      64  }
      65  
      66  int
      67  f7 (int x, int y)
      68  {
      69    int r = (unsigned) x * y;
      70    return !x || (r / x) == y;
      71  }
      72  
      73  int
      74  f8 (int x, int y)
      75  {
      76    int r = (unsigned) x * y;
      77    if (!x || (r / x) == y)
      78      return fn ();
      79    return 0;
      80  }
      81  
      82  int
      83  f9 (unsigned x, unsigned y)
      84  {
      85    unsigned r = x * y;
      86    return y && ((int) r / (int) y) != (int) x;
      87  }
      88  
      89  unsigned
      90  f10 (unsigned x, unsigned y)
      91  {
      92    unsigned int r = x * y;
      93    if (y && ((int) r / (int) y) != (int) x)
      94      return fn ();
      95    return 0;
      96  }
      97  
      98  int
      99  f11 (unsigned x, unsigned y)
     100  {
     101    unsigned r = x * y;
     102    return !y || ((int) r / (int) y) == (int) x;
     103  }
     104  
     105  unsigned
     106  f12 (unsigned x, unsigned y)
     107  {
     108    unsigned int r = x * y;
     109    if (!y || ((int) r / (int) y) == (int) x)
     110      return fn ();
     111    return 0;
     112  }
     113  
     114  int
     115  f13 (int x, int y)
     116  {
     117    int r = (unsigned) x * y;
     118    return y && (r / y) != x;
     119  }
     120  
     121  int
     122  f14 (int x, int y)
     123  {
     124    int r = (unsigned) x * y;
     125    if (y && (r / y) != x)
     126      return fn ();
     127    return 0;
     128  }
     129  
     130  int
     131  f15 (int x, int y)
     132  {
     133    int r = (unsigned) x * y;
     134    return !y || (r / y) == x;
     135  }
     136  
     137  int
     138  f16 (int x, int y)
     139  {
     140    int r = (unsigned) x * y;
     141    if (!y || (r / y) == x)
     142      return fn ();
     143    return 0;
     144  }
     145  
     146  int
     147  f17 (unsigned x)
     148  {
     149    unsigned r = x * 35U;
     150    return x && ((int) r / (int) x) != 35;
     151  }
     152  
     153  unsigned
     154  f18 (unsigned x)
     155  {
     156    unsigned int r = x * 35U;
     157    if (x && ((int) r / (int) x) != 35)
     158      return fn ();
     159    return 0;
     160  }
     161  
     162  int
     163  f19 (unsigned x)
     164  {
     165    unsigned r = x * 35U;
     166    return !x || ((int) r / (int) x) == 35;
     167  }
     168  
     169  unsigned
     170  f20 (unsigned x)
     171  {
     172    unsigned int r = x * 35U;
     173    if (!x || ((int) r / (int) x) == 35)
     174      return fn ();
     175    return 0;
     176  }
     177  
     178  int
     179  f21 (int x)
     180  {
     181    int r = (unsigned) x * 35;
     182    return x && (r / x) != 35;
     183  }
     184  
     185  int
     186  f22 (int x)
     187  {
     188    int r = (unsigned) x * 35;
     189    if (x && (r / x) != 35)
     190      return fn ();
     191    return 0;
     192  }
     193  
     194  int
     195  f23 (int x)
     196  {
     197    int r = (unsigned) x * 35;
     198    return !x || (r / x) == 35;
     199  }
     200  
     201  int
     202  f24 (int x)
     203  {
     204    int r = (unsigned) x * 35;
     205    if (!x || (r / x) == 35)
     206      return fn ();
     207    return 0;
     208  }
     209  
     210  int
     211  f25 (unsigned x)
     212  {
     213    unsigned r = x * 35U;
     214    return ((int) r / 35) != (int) x;
     215  }
     216  
     217  unsigned
     218  f26 (unsigned x)
     219  {
     220    unsigned int r = x * 35U;
     221    if (((int) r / 35) != (int) x)
     222      return fn ();
     223    return 0;
     224  }
     225  
     226  int
     227  f27 (unsigned x)
     228  {
     229    unsigned r = x * 35U;
     230    return !35 || ((int) r / 35) == (int) x;
     231  }
     232  
     233  unsigned
     234  f28 (unsigned x)
     235  {
     236    unsigned int r = x * 35U;
     237    if (((int) r / 35) == (int) x)
     238      return fn ();
     239    return 0;
     240  }
     241  
     242  int
     243  f29 (int x)
     244  {
     245    int r = (unsigned) x * 35;
     246    return 35 && (r / 35) != x;
     247  }
     248  
     249  int
     250  f30 (int x)
     251  {
     252    int r = (unsigned) x * 35;
     253    if ((r / 35) != x)
     254      return fn ();
     255    return 0;
     256  }
     257  
     258  int
     259  f31 (int x)
     260  {
     261    int r = (unsigned) x * 35;
     262    return (r / 35) == x;
     263  }
     264  
     265  int
     266  f32 (int x)
     267  {
     268    int r = (unsigned) x * 35;
     269    if ((r / 35) == x)
     270      return fn ();
     271    return 0;
     272  }