[Bug target/27006] New: Invalid altivec constant loading code
uweigand at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Mon Apr 3 18:52:00 GMT 2006
When compiling the following code with -O0 -maltivec:
typedef union
{
int i[4];
__attribute__((altivec(vector__))) int v;
} vec_int4;
int main (void)
{
vec_int4 i1;
i1.v = (__attribute__((altivec(vector__))) int){31, 31, 31, 31};
printf ("%d\n", i1.i[0]);
return 0;
}
the output printed is 30, not 31.
The load of the vector constant is done by the following pair
of instructions:
vspltisw 0,15
vadduwm 0,0,0
which are generated by this splitter in altivec.md:
(define_split
[(set (match_operand:VI 0 "altivec_register_operand" "")
(match_operand:VI 1 "easy_vector_constant_add_self" ""))]
"TARGET_ALTIVEC && reload_completed"
[(set (match_dup 0) (match_dup 3))
(set (match_dup 0) (plus:VI (match_dup 0)
(match_dup 0)))]
{
rtx dup = gen_easy_altivec_constant (operands[1]);
rtx const_vec;
/* Divide the operand of the resulting VEC_DUPLICATE, and use
simplify_rtx to make a CONST_VECTOR. */
XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
XEXP (dup, 0), const1_rtx);
const_vec = simplify_rtx (dup);
if (GET_MODE (const_vec) == <MODE>mode)
operands[3] = const_vec;
else
operands[3] = gen_lowpart (<MODE>mode, const_vec);
})
Now, easy_vector_constand_add_self accepts all constants between
16 and 31, where I think it should really only be accepting *even*
constants.
The test is really implemented in rs6000.h:
#define EASY_VECTOR_15_ADD_SELF(n) (!EASY_VECTOR_15((n)) \
&& EASY_VECTOR_15((n) >> 1))
and adding a condition ((n) & 1) == 0 here fixes the problem.
Is this the proper solution?
--
Summary: Invalid altivec constant loading code
Product: gcc
Version: 4.2.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: uweigand at gcc dot gnu dot org
GCC target triplet: powerpc-*-linux*
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27006
More information about the Gcc-bugs
mailing list