Fix -- Wide int sign extension in combine.c

Donn Terry donn@interix.com
Thu Feb 11 09:54:00 GMT 1999


Change to gcc.  When HOST_WIDE_INT is 64 bits.
Failure from testcase gcc.c-torture/930506-2.c.

Short form: bit masking did not take signed arithemetic into full
account
in some cases of force_to_mode() (specifically when optimizing
arithmetic
on force-aligned quantities).


Gory details:
Discussing the patch from the bottom change upward (as that makes
the most sense):


The last change:

The code just prior to here computes smask, which is the sign-extended
(to HWI bits) version of the mask of 'interesting' bits, if a signed
number is involved.

However, in computing the value argument to plus_constant, mask,
not smask, is used.  If XEXP(x,1) is negative, this masks off the
sign extension (from 32 to 64 bits, e.g.).  (Negative values occur,
for example, in INITIALIZE_TRAMPOLINE for the i386.)  (The generated
assembly is incorrect, containing a nonsense number instead of a
small one.)


The prior changes outside the ifdef/endif:
It turns out that just the fix above causes an infinite recursion
in compiling gcc/tree.c (in this case, dealing with QI type).  Using
smask in these locations seems intuitively reasonable, fixes the
recursion, and improves the regression results.  (Note; the situation
is rare; tree.c is the first file compiled during a build that appears
to
hit the problem.)


The changes inside the ifdef/endif: arguing from analogy, only,
as STACK_BIAS doesn't apply in my case.


N.B.  This actually exhibited itself as an assembler error (using my
current gas) where it complained that it was unable to relocate a
symbol that wasn't even really there, in turn because it was being
passed a constant > 32 bits.  Don't know if that info will help anyone
else, but it might.

ChangeLog entry:
        * combine.c:force_to_mode(): handle wide negative numbers
correctly.

--- ../../egcs.source.old/gcc/combine.c Fri Feb  5 12:18:43 1999
+++ combine.c   Wed Feb 10 20:07:47 1999
@@ -6413,20 +6413,20 @@
                 unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);

                sp_mask &= ~ (sp_alignment - 1);
-               if ((sp_mask & ~ mask) == 0
-                   && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ mask) !=
0)
+               if ((sp_mask & ~ smask) == 0
+                   && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ smask)
!= 0)
                  return force_to_mode (plus_constant (XEXP (x, 0),
                                                       ((INTVAL (XEXP
(x, 1)) -
-                                                        STACK_BIAS) &
mask)
+                                                        STACK_BIAS) &
smask)
                                                       + STACK_BIAS),
-                                       mode, mask, reg, next_select);
+                                       mode, smask, reg, next_select);
               }
 #endif
-           if ((nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0
-               && (INTVAL (XEXP (x, 1)) & ~ mask) != 0)
+           if ((nonzero_bits (XEXP (x, 0), mode) & ~ smask) == 0
+               && (INTVAL (XEXP (x, 1)) & ~ smask) != 0)
              return force_to_mode (plus_constant (XEXP (x, 0),
-                                                  INTVAL (XEXP (x, 1))
& mask),

-                                   mode, mask, reg, next_select);
+                                                  INTVAL (XEXP (x, 1))
& smask)
,
+                                   mode, smask, reg, next_select);
          }
       }
-- 

===================================================
Donn Terry                  mailto:donn@interix.com
Softway Systems, Inc.        http://www.interix.com
2850 McClelland Dr, Ste. 1800   Ft.Collins CO 80525
Tel: +1-970-204-9900           Fax: +1-970-204-9951
===================================================


More information about the Gcc-patches mailing list