1 /* { dg-do run } */
2 /* { dg-options "-O2 -funroll-loops -march=z9-109" } */
3 /* { dg-require-effective-target stdint_types } */
4 
5 /* Folding of the FLOGR caused a wrong value to be returned by
6    __builtin_clz becuase of a problem in the RTX we emit for FLOGR.
7    The problematic folding can only be triggered with constants inputs
8    introduced on RTL level.  In this case it happens with loop
9    unrolling.  */
10 
11 #include <stdint.h>
12 #include <assert.h>
13 
pow2_ceil_u32(uint32_t x)14 static inline uint32_t pow2_ceil_u32(uint32_t x) {
15   if (x <= 1) {
16     return x;
17   }
18   int msb_on_index;
19   msb_on_index = (31 ^ __builtin_clz(x - 1));
20   assert(msb_on_index < 31);
21   return 1U << (msb_on_index + 1);
22 }
23 
24 void __attribute__((noinline,noclone))
die(int a)25 die (int a)
26 {
27   if (a)
28     __builtin_abort ();
29 }
30 
test_pow2_ceil_u32(void)31 void test_pow2_ceil_u32(void) {
32   unsigned i;
33 
34   for (i = 0; i < 18; i++) {
35       uint32_t a_ = (pow2_ceil_u32(((uint32_t)1) << i));
36       if (!(a_ == (((uint32_t)1) << i))) {
37 	die(1);
38       }
39   }
40 }
41 
42 int
main(void)43 main(void) {
44   test_pow2_ceil_u32();
45 
46   return 0;
47 }
48