Fix PR c/7102

Eric Botcazou ebotcazou@libertysurf.fr
Sat Jul 6 09:40:00 GMT 2002


Hello,

The testcase gives a SIGFPE on i386 at runtime because the unsigned division
overflows. The pattern for udivqi3 is given below:

(define_insn "udivqi3"
  [(set (match_operand:QI 0 "register_operand" "=a")
 (udiv:QI (match_operand:HI 1 "register_operand" "0")
   (match_operand:QI 2 "nonimmediate_operand" "qm")))
   (clobber (reg:CC 17))]
  "TARGET_QIMODE_MATH"
  "div{b}\t%2")

Note the HImode of the dividend: divb is a 16/8-bit unsigned division.

255 is expanded as (const_int -1) by the RTL expander because of the QImode
of the underlying tree node. The problem is that (const_int -1) is not
modified in the QImode -> HImode transition for the dividend. Therefore the
HImode dividend ends up being loaded with (const_int -1), i.e 65535, and
65535/2 overflows the 8-bit register.

The proposed fix is to let (const_int -1) be zero-extended in this case to
(const_int 255) because of the unsigned-ness of the division. See:
http://gcc.gnu.org/ml/gcc/2002-07/msg00201.html

Bootstrapped/regtested (C/C++) on k6-pc-linux-gnu (gcc-3_1-branch).


2002-07-06  Eric Botcazou  <ebotcazou@multimania.com>

 PR c/7102
 * optabs.c (expand_binop): Convert CONST_INTs in all cases.


/* PR c/7102 */

/* Verify that GCC zero-extends integer constants
   in unsigned binary operations. */

typedef unsigned char u8;

void fun(u8 y)
{
  u8 x=((u8)255)/y;
}

int main(void)
{
  fun((u8)2);
  return 0;
}

--
Eric Botcazou
ebotcazou@multimania.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr7102.diff
Type: application/octet-stream
Size: 2188 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20020706/d62e031b/attachment.obj>


More information about the Gcc-patches mailing list