1 /* { dg-do assemble } */
2 /* { dg-timeout-factor 2.0 } */
3 /* { dg-options "-O1 -fno-reorder-blocks -fno-tree-cselim --save-temps" } */
4 
5 
6 __attribute__((noinline, noclone)) int
restore(int a,int b)7 restore (int a, int b)
8 {
9   return a * b;
10 }
11 
12 __attribute__((noinline, noclone)) void
do_nothing(int * input)13 do_nothing (int *input)
14 {
15   *input = restore (*input, 1);
16   return;
17 }
18 #define ENTRY_SUM(n, x) \
19     sum = sum / ((n) + (x)); \
20     sum = restore (sum, (n) + (x));
21 
22 #define ENTRY_SUM2(n, x) ENTRY_SUM ((n), (x)) ENTRY_SUM ((n), (x)+1)
23 #define ENTRY_SUM4(n, x) ENTRY_SUM2 ((n), (x)) ENTRY_SUM2 ((n), (x)+2)
24 #define ENTRY_SUM8(n, x) ENTRY_SUM4 ((n), (x)) ENTRY_SUM4 ((n), (x)+4)
25 #define ENTRY_SUM16(n, x) ENTRY_SUM8 ((n), (x)) ENTRY_SUM8 ((n), (x)+8)
26 #define ENTRY_SUM32(n, x) ENTRY_SUM16 ((n), (x)) ENTRY_SUM16 ((n), (x)+16)
27 #define ENTRY_SUM64(n, x) ENTRY_SUM32 ((n), (x)) ENTRY_SUM32 ((n), (x)+32)
28 #define ENTRY_SUM128(n, x) ENTRY_SUM64 ((n), (x)) ENTRY_SUM64 ((n), (x)+64)
29 
30 #define CASE_ENTRY(n) \
31   case n: \
32     sum = sum / (n + 1); \
33     sum = restore (sum, n + 1); \
34     if (sum == (n + addend)) \
35       break;\
36     ENTRY_SUM128 ((n), 2) \
37     ENTRY_SUM16 ((n), 130) \
38     break;
39 
40 #define CASE_ENTRY2(n) CASE_ENTRY ((n)) CASE_ENTRY ((n)+1)
41 #define CASE_ENTRY4(n) CASE_ENTRY2 ((n)) CASE_ENTRY2 ((n)+2)
42 #define CASE_ENTRY8(n) CASE_ENTRY4 ((n)) CASE_ENTRY4 ((n)+4)
43 #define CASE_ENTRY16(n) CASE_ENTRY8 ((n)) CASE_ENTRY8 ((n)+8)
44 #define CASE_ENTRY32(n) CASE_ENTRY16 ((n)) CASE_ENTRY16 ((n)+16)
45 #define CASE_ENTRY64(n) CASE_ENTRY32 ((n)) CASE_ENTRY32 ((n)+32)
46 #define CASE_ENTRY128(n) CASE_ENTRY64 ((n)) CASE_ENTRY64 ((n)+64)
47 
48 __attribute__((noinline, noclone)) long long
test_and_branch(int selector,int addend,int cond)49 test_and_branch (int selector, int addend, int cond)
50 {
51   long long sum = selector + 1;
52 
53   if (selector > 200)
54     {
55 start0:
56       return sum - 1;
57 start3:
58       return sum - 2;
59     }
60   else
61     {
62       switch (selector)
63 	{
64 start1:
65 start2:
66 	  CASE_ENTRY128 (1)
67 	  CASE_ENTRY64 (129)
68 	  CASE_ENTRY16 (193)
69 	}
70 
71       do_nothing ((int *)&sum);
72 
73       if (cond == 0)
74 	goto start0;
75       else if (cond < 0)
76 	goto start1;
77       else if ((cond & 0x010) != 0)
78 	goto start2;
79       else if (cond >= 14)
80 	goto start3;
81 
82     }
83 
84   return -1;
85 }
86 
87 /* { dg-final { scan-assembler "Lbcond" } } */
88 /* { dg-final { scan-assembler "Lcb" } } */
89 /* { dg-final { scan-assembler "Ltb" } } */
90