1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
/* PR tree-optimization/100864 */
/* { dg-do run } */
/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
#define op_ne !=
#define op_eq ==
#define op_lt <
#define op_le <=
#define op_gt >
#define op_ge >=
#define operators(t) \
t(ne) \
t(eq) \
t(lt) \
t(le) \
t(gt) \
t(ge)
#define cmpfunc(v, op) \
__attribute__((noipa)) \
_Bool func_##op##_##v(v int a, v int b, v _Bool e) \
{ \
v _Bool c = (a op_##op b); \
v _Bool d = !c; \
return (e & d) | c; \
}
#define cmp_funcs(op) \
cmpfunc(, op) \
cmpfunc(volatile , op)
operators(cmp_funcs)
#define test(op) \
if (func_##op##_ (a, b, e) != func_##op##_volatile (a, b, e)) \
__builtin_abort();
int main()
{
for(int a = -3; a <= 3; a++)
for(int b = -3; b <= 3; b++)
{
_Bool e = 0;
operators(test)
e = 1;
operators(test)
}
return 0;
}
/* Check to make sure we optimize `(a&!b) | b` -> `a | b`. */
/* There are 6 different comparison operators testing here. */
/* bit_not_expr and bit_and_expr should show up for each one (volatile). */
/* Each operator should show up twice
(except for `!=` which shows up 2*6 (each tester) + 2 (the 2 loops) extra = 16). */
/* bit_ior_expr will show up for each operator twice (non-volatile and volatile). */
/* { dg-final { scan-tree-dump-times "ne_expr," 16 "optimized"} } */
/* { dg-final { scan-tree-dump-times "eq_expr," 2 "optimized"} } */
/* { dg-final { scan-tree-dump-times "lt_expr," 2 "optimized"} } */
/* { dg-final { scan-tree-dump-times "le_expr," 2 "optimized"} } */
/* { dg-final { scan-tree-dump-times "gt_expr," 2 "optimized"} } */
/* { dg-final { scan-tree-dump-times "ge_expr," 2 "optimized"} } */
/* { dg-final { scan-tree-dump-times "bit_not_expr," 6 "optimized"} } */
/* { dg-final { scan-tree-dump-times "bit_and_expr," 6 "optimized"} } */
/* { dg-final { scan-tree-dump-times "bit_ior_expr," 12 "optimized"} } */
|