1 /* { dg-do run { target { bmi2 && { ! ia32 } } } } */
2 /* { dg-options "-mbmi2 -O2" } */
3 
4 #include <x86intrin.h>
5 #include "bmi2-check.h"
6 
7 __attribute__((noinline))
8 unsigned __int128
calc_mul_u64(unsigned long long volatile a,unsigned long long b)9 calc_mul_u64 (unsigned long long volatile a, unsigned long long b)
10 {
11   unsigned __int128 res = 0;
12   int i;
13   for (i = 0; i < b; ++i)
14     res += (unsigned __int128) a;
15 
16   return res;
17 }
18 
19 __attribute__((noinline))
20 unsigned long long
calc_mulx_u64(unsigned long long x,unsigned long long y,unsigned long long * res_h)21 calc_mulx_u64 (unsigned long long x,
22 	       unsigned long long y,
23 	       unsigned long long *res_h)
24 {
25   return _mulx_u64 (x, y, res_h);
26 }
27 
28 
29 static void
bmi2_test()30 bmi2_test ()
31 {
32   unsigned i;
33   unsigned long long a = 0xce7ace0ce7ace0;
34   unsigned long long b = 0xface;
35   unsigned long long res_l, res_h;
36   unsigned __int128 res, res_ref;
37 
38   for (i=0; i<5; ++i) {
39     a = a * (i + 1);
40     b = b / (i + 1);
41 
42     res_ref = calc_mul_u64 (a, b);
43 
44     res_l = calc_mulx_u64 (a, b, &res_h);
45 
46     res = ((unsigned __int128) res_h << 64) | res_l;
47 
48     if (res != res_ref)
49       abort();
50   }
51 }
52