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))
8unsigned __int128
9calc_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))
20unsigned long long
21calc_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
29static void
30bmi2_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