I am working on SSE4.1 intrinsic. For code:

typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
typedef long long __v2di __attribute__ ((__vector_size__ (16)));
extern __m128i res[2];

void
foo(long long x, __m128i val)
{
  res[0] = ((__m128i) __builtin_ia32_vec_set_v2di ((__v2di)(val), (x), (0x0)));
  res[1] = ((__m128i) __builtin_ia32_vec_set_v2di ((__v2di)(val), (x), (0x1)));
}

The original tree dump is

;; Function foo (foo)
;; enabled by -tree-original


{
  res[0] = VIEW_CONVERT_EXPR<vector long long int>(__builtin_ia32_vec_set_v2di 
(VIEW_CONVERT_EXPR<vector long long int>(val), (long int) x, 0));
  res[1] = VIEW_CONVERT_EXPR<vector long long int>(__builtin_ia32_vec_set_v2di 
(VIEW_CONVERT_EXPR<vector long long int>(val), (long int) x, 1));
}

__builtin_ia32_vec_set_v2di will be expanded to

  [(set (match_operand:V2DI 0 "register_operand" "=x")
        (vec_merge:V2DI
          (vec_duplicate:V2DI
            (match_operand:DI 2 "nonimmediate_operand" "rm"))
          (match_operand:V2DI 1 "register_operand" "0")
          (match_operand:SI 3 "const_pow2_1_to_2_operand" "n")))]


The gimple tree dump becomes

foo (x, val)
{
  vector long long int D.2078;
  vector long long int D.2079;

  D.2078 = __builtin_ia32_vec_set_v2di (val, x, 0);
  res[0] = D.2078;
  D.2079 = __builtin_ia32_vec_set_v2di (val, x, 1);
  res[1] = D.2079;
}

It isn't right since val will be changed in
__builtin_ia32_vec_set_v2di. I was expecting something like

  tmp = val
  D.2078 = __builtin_ia32_vec_set_v2di (tmp, x, 0);
  res[0] = D.2078;
  tmp = val
  D.2079 = __builtin_ia32_vec_set_v2di (tmp, x, 1);
  res[1] = D.2079;


Does anyone what I did wrong?

Thanks.


H.J.

Reply via email to