This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: patch to stop GCC from shifting by a negative number
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: geoffk at geoffk dot org, rth at redhat dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 16 Aug 2002 14:08:47 -0700 (PDT)
- Subject: Re: patch to stop GCC from shifting by a negative number
Here is a new patch to stop GCC from shifting by a negative number in
trunc_int_for_mode. It is basically Geoff Keating's patch
(http://gcc.gnu.org/ml/gcc-patches/2002-08/msg00853.html) that ensures
we don't call trunc_int_for_mode with VOIDmode but with a couple of
extra changes in combine.c to stop us from calling it with Vector or
Complex modes either.
With Geoff's original patch I was failing
gcc.c-torture/execute/20020227-1.c and gcc.c-torture/compile/simd-1.c,
with them it passes the test suite with no regressions.
Here is a patch that includes both my changes and Geoff's.
Steve Ellcey
sje@cup.hp.com
2002-08-12 Geoffrey Keating <geoffk@redhat.com>
Steve Ellcey <sje@cup.hp.com>
* explow.c (trunc_int_for_mode): Abort when the mode is not
an integer mode.
* combine.c (expand_compound_operation): Don't expand Vector
or Complex modes into shifts.
(expand_field_assignment): Don't do bitwise arithmatic and
shifts on Vector or Complex modes.
(simplify_comparison): Don't call trunc_int_for_mode
for VOIDmode.
* recog.c (general_operand): Likewise.
(immediate_operand): Likewise.
(nonmemory_operand): Likewise.
*** gcc.orig/gcc/explow.c Fri Aug 16 12:12:13 2002
--- gcc/gcc/explow.c Fri Aug 16 12:12:55 2002
*************** trunc_int_for_mode (c, mode)
*** 49,54 ****
--- 49,59 ----
{
int width = GET_MODE_BITSIZE (mode);
+ /* You want to truncate to a _what_? */
+ if (GET_MODE_CLASS (mode) != MODE_INT
+ && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
+ abort ();
+
/* Canonicalize BImode to 0 and STORE_FLAG_VALUE. */
if (mode == BImode)
return c & 1 ? STORE_FLAG_VALUE : 0;
*** gcc.orig/gcc/combine.c Fri Aug 16 12:12:17 2002
--- gcc/gcc/combine.c Fri Aug 16 12:20:23 2002
*************** expand_compound_operation (x)
*** 5634,5639 ****
--- 5634,5646 ----
if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD)
return x;
+ /* Reject MODEs that aren't MODE_INT or MODE_PARTIAL_INT because
+ turning vector or complex modes into shifts causes problems. */
+
+ if (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_INT
+ && GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_PARTIAL_INT)
+ return x;
+
len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
/* If the inner object has VOIDmode (the only way this can happen
is if it is an ASM_OPERANDS), we can't do anything since we don't
*************** expand_compound_operation (x)
*** 5655,5660 ****
--- 5662,5674 ----
|| GET_MODE (XEXP (x, 0)) == VOIDmode)
return x;
+ /* Reject MODEs that aren't MODE_INT or MODE_PARTIAL_INT because
+ turning vector or complex modes into shifts causes problems. */
+
+ if (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_INT
+ && GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_PARTIAL_INT)
+ return x;
+
len = INTVAL (XEXP (x, 1));
pos = INTVAL (XEXP (x, 2));
*************** expand_field_assignment (x)
*** 5862,5873 ****
compute_mode = GET_MODE (inner);
! /* Don't attempt bitwise arithmetic on non-integral modes. */
! if (! INTEGRAL_MODE_P (compute_mode))
{
enum machine_mode imode;
! /* Something is probably seriously wrong if this matches. */
if (! FLOAT_MODE_P (compute_mode))
break;
--- 5876,5889 ----
compute_mode = GET_MODE (inner);
! /* Don't attempt bitwise arithmetic on non-integer modes. */
! if (GET_MODE_CLASS (compute_mode) != MODE_INT
! && GET_MODE_CLASS (compute_mode) != MODE_PARTIAL_INT)
!
{
enum machine_mode imode;
! /* Don't try doing anything for Vector or Integer complex types. */
if (! FLOAT_MODE_P (compute_mode))
break;
*************** simplify_comparison (code, pop0, pop1)
*** 10177,10183 ****
/* Get the constant we are comparing against and turn off all bits
not on in our mode. */
! const_op = trunc_int_for_mode (INTVAL (op1), mode);
op1 = GEN_INT (const_op);
/* If we are comparing against a constant power of two and the value
--- 10193,10201 ----
/* Get the constant we are comparing against and turn off all bits
not on in our mode. */
! const_op = INTVAL (op1);
! if (mode != VOIDmode)
! const_op = trunc_int_for_mode (const_op, mode);
op1 = GEN_INT (const_op);
/* If we are comparing against a constant power of two and the value
*** gcc.orig/gcc/recog.c Fri Aug 16 12:12:21 2002
--- gcc/gcc/recog.c Fri Aug 16 12:12:55 2002
*************** general_operand (op, mode)
*** 954,959 ****
--- 954,960 ----
return 0;
if (GET_CODE (op) == CONST_INT
+ && mode != VOIDmode
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
return 0;
*************** immediate_operand (op, mode)
*** 1159,1164 ****
--- 1160,1166 ----
return 0;
if (GET_CODE (op) == CONST_INT
+ && mode != VOIDmode
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
return 0;
*************** nonmemory_operand (op, mode)
*** 1241,1246 ****
--- 1243,1249 ----
return 0;
if (GET_CODE (op) == CONST_INT
+ && mode != VOIDmode
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
return 0;