diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 36d45caec21..95b81ebfa93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,8 @@ -Tue Jul 23 20:56:03 2002 J"orn Rennecke +Tue Jul 23 21:02:16 2002 J"orn Rennecke + + * reload.c (find_reloads_toplev): Use simplify_gen_subreg. + * simplify-rtx.c (simplify_subreg): When converting to a non-int + mode, try to convert to an integer mode of matching size first. * simplify-rtx.x (simplify_subreg): When constructing a CONST_VECTOR from individual subregs, check that each subreg has been generated diff --git a/gcc/reload.c b/gcc/reload.c index 72e1674008f..7f3568c7ce4 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -4404,51 +4404,16 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn, if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 - && reg_equiv_constant[regno] != 0 - && (tem = operand_subword (reg_equiv_constant[regno], - SUBREG_BYTE (x) / UNITS_PER_WORD, 0, - GET_MODE (SUBREG_REG (x)))) != 0) + && reg_equiv_constant[regno] != 0) { - /* TEM is now a word sized constant for the bits from X that - we wanted. However, TEM may be the wrong representation. - - Use gen_lowpart_common to convert a CONST_INT into a - CONST_DOUBLE and vice versa as needed according to by the mode - of the SUBREG. */ - tem = gen_lowpart_common (GET_MODE (x), tem); + tem = + simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno], + GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); if (!tem) abort (); return tem; } - /* If the SUBREG is wider than a word, the above test will fail. - For example, we might have a SImode SUBREG of a DImode SUBREG_REG - for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for - a 32 bit target. We still can - and have to - handle this - for non-paradoxical subregs of CONST_INTs. */ - if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 - && reg_equiv_constant[regno] != 0 - && GET_CODE (reg_equiv_constant[regno]) == CONST_INT - && (GET_MODE_SIZE (GET_MODE (x)) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) - { - int shift = SUBREG_BYTE (x) * BITS_PER_UNIT; - if (WORDS_BIG_ENDIAN) - shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))) - - GET_MODE_BITSIZE (GET_MODE (x)) - - shift); - /* Here we use the knowledge that CONST_INTs have a - HOST_WIDE_INT field. */ - if (shift >= HOST_BITS_PER_WIDE_INT) - shift = HOST_BITS_PER_WIDE_INT - 1; - return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift); - } - - if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 - && reg_equiv_constant[regno] != 0 - && GET_MODE (reg_equiv_constant[regno]) == VOIDmode) - abort (); - /* If the subreg contains a reg that will be converted to a mem, convert the subreg to a narrower memref now. Otherwise, we would get (subreg (mem ...) ...), diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index d07de68d223..1791f2e4d79 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2347,8 +2347,7 @@ simplify_subreg (outermode, op, innermode, byte) return NULL_RTX; return simplify_subreg (outermode, op, new_mode, subbyte); } - else if (GET_MODE_CLASS (outermode) != MODE_VECTOR_INT - && GET_MODE_CLASS (outermode) != MODE_VECTOR_FLOAT) + else if (GET_MODE_CLASS (outermode) == MODE_INT) /* This shouldn't happen, but let's not do anything stupid. */ return NULL_RTX; } @@ -2387,7 +2386,8 @@ simplify_subreg (outermode, op, innermode, byte) Later it we should move all simplification code here and rewrite GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends using SIMPLIFY_SUBREG. */ - if (subreg_lowpart_offset (outermode, innermode) == byte) + if (subreg_lowpart_offset (outermode, innermode) == byte + && GET_CODE (op) != CONST_VECTOR) { rtx new = gen_lowpart_if_possible (outermode, op); if (new) @@ -2406,6 +2406,19 @@ simplify_subreg (outermode, op, innermode, byte) return new; } + if (GET_MODE_CLASS (outermode) != MODE_INT) + { + enum machine_mode new_mode = int_mode_for_mode (outermode); + + if (new_mode != innermode || byte != 0) + { + op = simplify_subreg (new_mode, op, innermode, byte); + if (! op) + return NULL_RTX; + return simplify_subreg (outermode, op, new_mode, 0); + } + } + offset = byte * BITS_PER_UNIT; switch (GET_CODE (op)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 41b879c854c..2d5649dcbb4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +Tue Jul 23 21:02:43 2002 J"orn Rennecke + + * gcc.c-torture/compile/simd-4.c: New test. + 2002-07-22 Kriang Lerdsuwanakij PR c++/7347, c++/7348 diff --git a/gcc/testsuite/gcc.c-torture/compile/simd-4.c b/gcc/testsuite/gcc.c-torture/compile/simd-4.c new file mode 100644 index 00000000000..6ede943c47d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/simd-4.c @@ -0,0 +1,15 @@ +typedef float floatvect2 __attribute__((mode(V4SF))); + +typedef union +{ + floatvect2 vector; + float f[2]; +}resfloatvect2; + +void tempf(floatvect2 *x, floatvect2 *y) +{ + floatvect2 temp= *x; + floatvect2 temp1=*y; + resfloatvect2 temp2; + *x=temp+temp1; +}