1 /* { dg-do run } */
2 using size_t = decltype (sizeof (0));
3 using uint64_t = unsigned long long;
4 
5 namespace HPHP {
6 
bitvec_set(uint64_t * bits,size_t index)7 inline void bitvec_set(uint64_t* bits, size_t index) {
8   bits[index / 64] |= 1ull << (index % 64);
9 }
10 
11 namespace jit {
12 ///////////////////////////////////////////////////////////////////////////////
13 
14 struct VregSet {
15   struct Block;
16 
VregSetVregSet17   VregSet() : blocks{} { blocks.data[1] = 1LL << 0x30; };
18 
VregSetVregSet19   VregSet(const VregSet& o)
20     : blocks{o.blocks}
21   {
22   }
23 
anyVregSet24   bool any() const {
25     if (!isExtended()) return blocks.any();
26     return true;
27   }
removePhysVregSet28   void removePhys() {
29     auto const b = !isExtended() ? &blocks : extended.blocks;
30     b->data[0] = 0;
31     b->data[1] = 0;
32   }
33   static constexpr size_t kBitsPerBlock = 256;
isExtendedVregSet34   bool isExtended() const {
35     return extended.data[1] & (1ULL << (kExtendedBit % 64));
36   }
37 
38   static constexpr size_t kExtendedBit = 127;
39 
40   struct Block {
anyVregSet::Block41     bool any() const {
42       return data[0] | data[1];
43     }
44     uint64_t data[2];
45   };
46   struct Extended {
47     uint64_t data[2];
48     Block* blocks;
49   };
50 
51   union {
52     Block blocks{};
53     Extended extended;
54   };
55 };
56 
57 //////////////////////////////////////////////////////////////////////
58 
59 
60 __attribute__((noinline))
test(VregSet && c)61 bool test(VregSet&& c) {
62   auto copy = c;
63   copy.removePhys();
64   return copy.any();
65 }
66 ///////////////////////////////////////////////////////////////////////////////
67 }}
68 ///////////////////////////////////////////////////////////////////////////////
69 
main()70 int main() {
71   if (HPHP::jit::test(HPHP::jit::VregSet{}))
72     __builtin_abort ();
73   return 0;
74 }
75