On Sat, Apr 14, 2007 at 01:40:29PM -0700, H. J. Lu wrote:
> On Sat, Apr 14, 2007 at 01:16:58PM -0700, H. J. Lu wrote:
> > On Sat, Apr 14, 2007 at 12:32:28PM -0700, H. J. Lu wrote:
> > > On Sat, Apr 14, 2007 at 12:23:24PM -0700, Andrew Pinski wrote:
> > > > On 4/14/07, H. J. Lu <hjl@lucon.org> wrote:
> > > > >
> > > > >__builtin_ia32_vec_set_v2di is
> > > > >
> > > > >v2di __builtin_ia32_vec_set_v2di (v2di, long long, const int)
> > > >
> > > > v2di and m128i are the same type except for may_alias which only
> > > > matters when taking its address.
> > >
> > > It sounds right. I guess we get lucky that ix86_expand_vector_set
> > > never has to deal with the input type is the same as __m128i before.
> > > I will see what I can do.
> > >
> >
> > The problem is in ix86_expand_vector_set. In V2DI mode, target is
> > used as source directly without conversion:
> >
> > D.2078 = __builtin_ia32_vec_set_v2di (val, x, 0);
> >
> > where val will be modified, instead of
> >
> > 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;
> >
> > where val won't be modified. This patch works for me. Should we
> > create a new target for all modes, not just V2DI. We may run into
> > the same problem for V2SI and __m64 if such a pattern is ever
> > generated.
> >
> >
The problem is in ix86_expand_vec_set_builtin. It modifies the
source operand while it shouldn't. I open a bug report:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31582
Here is the patch. Tested on Linux/x86 and Linux/x86-64.
H.J.
----
2007-04-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/31582
* config/i386/i386.c (ix86_expand_vec_set_builtin): Make a
copy of source, pass it to ix86_expand_vector_set and return
it as target.
--- gcc/config/i386/i386.c.vec 2007-04-15 09:17:08.000000000 -0700
+++ gcc/config/i386/i386.c 2007-04-15 09:24:07.000000000 -0700
@@ -18399,7 +18399,7 @@ ix86_expand_vec_set_builtin (tree exp)
enum machine_mode tmode, mode1;
tree arg0, arg1, arg2;
int elt;
- rtx op0, op1;
+ rtx op0, op1, target;
arg0 = CALL_EXPR_ARG (exp, 0);
arg1 = CALL_EXPR_ARG (exp, 1);
@@ -18419,9 +18419,13 @@ ix86_expand_vec_set_builtin (tree exp)
op0 = force_reg (tmode, op0);
op1 = force_reg (mode1, op1);
- ix86_expand_vector_set (true, op0, op1, elt);
+ /* OP0 is the source of these builtin functions and shouldn't be
+ modifified. Create a copy, use it and return it as target. */
+ target = gen_reg_rtx (tmode);
+ emit_move_insn (target, op0);
+ ix86_expand_vector_set (true, target, op1, elt);
- return op0;
+ return target;
}
/* Expand an expression EXP that calls a built-in function,