PR tree-optimization/83369 - Missing diagnostics during inlining
[official-gcc.git] / gcc / testsuite / gcc.dg / builtin-arith-overflow-2.c
blob1a9e66637a589adb8e232d79fc7271b7bf842d1d
1 /* { dg-do run } */
2 /* { dg-options "-O2 -fdump-tree-optimized" } */
4 /* MUL_OVERFLOW should not be folded into unsigned multiplication,
5 because it sometimes overflows and sometimes does not. */
6 __attribute__((noinline, noclone)) long int
7 fn1 (long int x, long int y, int *ovf)
9 long int res;
10 x &= 65535;
11 y = (y & 65535) - (__LONG_MAX__ / 65535 + 32768);
12 *ovf = __builtin_mul_overflow (x, y, &res);
13 return res;
16 /* MUL_OVERFLOW should not be folded into unsigned multiplication,
17 because it sometimes overflows and sometimes does not. */
18 __attribute__((noinline, noclone)) signed char
19 fn2 (long int x, long int y, int *ovf)
21 signed char res;
22 x = (x & 63) + (__SCHAR_MAX__ / 4);
23 y = (y & 3) + 4;
24 *ovf = __builtin_mul_overflow (x, y, &res);
25 return res;
28 /* ADD_OVERFLOW should be folded into unsigned additrion,
29 because it sometimes overflows and sometimes does not. */
30 __attribute__((noinline, noclone)) unsigned char
31 fn3 (unsigned char x, unsigned char y, int *ovf)
33 unsigned char res;
34 x = (x & 63) + ((unsigned char) ~0 - 65);
35 y = (y & 3);
36 *ovf = __builtin_add_overflow (x, y, &res);
37 return res;
40 /* ADD_OVERFLOW should be folded into unsigned additrion,
41 because it sometimes overflows and sometimes does not. */
42 __attribute__((noinline, noclone)) unsigned char
43 fn4 (unsigned char x, unsigned char y, int *ovf)
45 unsigned char res;
46 x = (x & 15) + ((unsigned char) ~0 - 16);
47 y = (y & 3) + 16;
48 *ovf = __builtin_add_overflow (x, y, &res);
49 return res;
52 /* MUL_OVERFLOW should not be folded into unsigned multiplication,
53 because it sometimes overflows and sometimes does not. */
54 __attribute__((noinline, noclone)) long int
55 fn5 (long int x, unsigned long int y, int *ovf)
57 long int res;
58 y = -65536UL + (y & 65535);
59 *ovf = __builtin_mul_overflow (x, y, &res);
60 return res;
63 int
64 main ()
66 int ovf;
67 if (fn1 (0, 0, &ovf) != 0
68 || ovf
69 || fn1 (65535, 0, &ovf) != (long int) ((__LONG_MAX__ / 65535 + 32768UL) * -65535UL)
70 || !ovf)
71 __builtin_abort ();
72 if (fn2 (0, 0, &ovf) != (signed char) (__SCHAR_MAX__ / 4 * 4U)
73 || ovf
74 || fn2 (0, 1, &ovf) != (signed char) (__SCHAR_MAX__ / 4 * 5U)
75 || !ovf)
76 __builtin_abort ();
77 if (fn3 (0, 0, &ovf) != (unsigned char) ~0 - 65
78 || ovf
79 || fn3 (63, 2, &ovf) != (unsigned char) ~0
80 || ovf
81 || fn3 (62, 3, &ovf) != (unsigned char) ~0
82 || ovf
83 || fn3 (63, 3, &ovf) != 0
84 || !ovf)
85 __builtin_abort ();
86 if (fn4 (0, 0, &ovf) != (unsigned char) ~0
87 || ovf
88 || fn4 (1, 0, &ovf) != 0
89 || !ovf
90 || fn4 (0, 1, &ovf) != 0
91 || !ovf
92 || fn4 (63, 3, &ovf) != 17
93 || !ovf)
94 __builtin_abort ();
95 if (fn5 (0, 0, &ovf) != 0
96 || ovf
97 || fn5 (1, 0, &ovf) != -65536L
98 || !ovf
99 || fn5 (2, 32768, &ovf) != -65536L
100 || !ovf
101 || fn5 (4, 32768 + 16384 + 8192, &ovf) != -32768L
102 || !ovf)
103 __builtin_abort ();
104 return 0;
107 /* { dg-final { scan-tree-dump-times "ADD_OVERFLOW" 2 "optimized" } } */
108 /* { dg-final { scan-tree-dump-times "SUB_OVERFLOW" 0 "optimized" } } */
109 /* { dg-final { scan-tree-dump-times "MUL_OVERFLOW" 3 "optimized" } } */