On Sat, Apr 14, 2007 at 02:49:47PM -0400, Daniel Jacobowitz wrote:
> On Sat, Apr 14, 2007 at 11:28:59AM -0700, H. J. Lu wrote:
> > __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")))]
> 
> That's irrelevant.  You have a function, __builtin_ia32_vec_set_v2di,
> which you didn't show the type of - but there's probably nothing in
> the C builtin decl that says it modifies its arguments.  If the RTL
> says that it clobbers its first input, then the RTL register allocator
> is responsible for handling that.

__builtin_ia32_vec_set_v2di is

v2di __builtin_ia32_vec_set_v2di (v2di, long long, const int)

It is similar to

v8hi __builtin_ia32_vec_set_v2di (v4hi, short, const int)

(define_insn "*sse2_pinsrw"
  [(set (match_operand:V8HI 0 "register_operand" "=x")
        (vec_merge:V8HI
          (vec_duplicate:V8HI
            (match_operand:HI 2 "nonimmediate_operand" "rm"))
          (match_operand:V8HI 1 "register_operand" "0")
          (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]

Both are expanded by ix86_expand_vector_set with

      tmp = gen_rtx_VEC_DUPLICATE (mode, val);
      tmp = gen_rtx_VEC_MERGE (mode, tmp, target, GEN_INT (1 << elt));
      emit_insn (gen_rtx_SET (VOIDmode, target, tmp));

For 

typedef long long __m128i __attribute__ ((__vector_size__ (16),
__may_alias__));
typedef short __v8hi __attribute__ ((__vector_size__ (16)));

extern __m128i res[2];

void
foo(int x, __m128i val)
{
  res[0] = ((__m128i) __builtin_ia32_vec_set_v8hi ((__v8hi)(val), (x),
(0x0)));
  res[1] = ((__m128i) __builtin_ia32_vec_set_v8hi ((__v8hi)(val), (x),
(0x1)));
}

I got

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


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

and gimple dump is

foo (x, val)
{
  short int D.2078;
  int D.2079;
  vector short int D.2080;
  vector short int D.2081;
  vector short int D.2082;
  vector long long int D.2083;
  vector short int D.2084;
  vector short int D.2085;
  vector short int D.2086;
  vector long long int D.2087;

  D.2078 = (short int) x;
  D.2079 = (int) D.2078;
  D.2080 = VIEW_CONVERT_EXPR<vector short int>(val);
  D.2082 = __builtin_ia32_vec_set_v8hi (D.2080, D.2079, 0);
  D.2081 = D.2082;
  D.2083 = VIEW_CONVERT_EXPR<vector long long int>(D.2081);
  res[0] = D.2083;
  D.2078 = (short int) x;
  D.2079 = (int) D.2078;
  D.2084 = VIEW_CONVERT_EXPR<vector short int>(val);
  D.2086 = __builtin_ia32_vec_set_v8hi (D.2084, D.2079, 1);
  D.2085 = D.2086;
  D.2087 = VIEW_CONVERT_EXPR<vector long long int>(D.2085);
  res[1] = D.2087;
}

Why is there a difference?


H.J.

Reply via email to