summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@multimania.com>2002-09-04 22:24:12 +0000
committerRichard Henderson <rth@gcc.gnu.org>2002-09-04 15:24:12 -0700
commit29984e05aed74b14a9bd3e5c53cbdb34663db9be (patch)
tree554d4fcbbefd729d8d802a888bfc3a6e99fe9406
parent8d46398edf4ebc906649a4d1a3658e5d6166129c (diff)
downloadgcc-29984e05aed74b14a9bd3e5c53cbdb34663db9be.tar.gz
re PR c/7102 (unsigned char divisision results in floating exception)
PR c/7102 * optabs.c (expand_binop): Convert CONST_INTs in all cases. From-SVN: r56815
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/optabs.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20020904-1.c19
3 files changed, 31 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7b8e319ab6f..ae3918f66d6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2002-09-04 Eric Botcazou <ebotcazou@multimania.com>
+
+ PR c/7102
+ * optabs.c (expand_binop): Convert CONST_INTs in all cases.
+
2002-09-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
* pa.md (setccfp0, setccfp1): New patterns.
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 3f17034f0d5..a7dae46dbcb 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -779,23 +779,18 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
}
/* In case the insn wants input operands in modes different from
- the result, convert the operands. It would seem that we
- don't need to convert CONST_INTs, but we do, so that they're
- a properly sign-extended for their modes; we choose the
- widest mode between mode and mode[01], so that, in a widening
- operation, we call convert_modes with different FROM and TO
- modes, which ensures the value is sign-extended. Shift
- operations are an exception, because the second operand needs
- not be extended to the mode of the result. */
+ those of the actual operands, convert the operands. It would
+ seem that we don't need to convert CONST_INTs, but we do, so
+ that they're properly zero-extended or sign-extended for their
+ modes; shift operations are an exception, because the second
+ operand needs not be extended to the mode of the result. */
if (GET_MODE (op0) != mode0
&& mode0 != VOIDmode)
xop0 = convert_modes (mode0,
GET_MODE (op0) != VOIDmode
? GET_MODE (op0)
- : GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode0)
- ? mode
- : mode0,
+ : mode,
xop0, unsignedp);
if (GET_MODE (xop1) != mode1
@@ -803,8 +798,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
xop1 = convert_modes (mode1,
GET_MODE (op1) != VOIDmode
? GET_MODE (op1)
- : (GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode1)
- && ! shift_op)
+ : ! shift_op
? mode
: mode1,
xop1, unsignedp);
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020904-1.c b/gcc/testsuite/gcc.c-torture/execute/20020904-1.c
new file mode 100644
index 00000000000..24eeb0cb0a0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20020904-1.c
@@ -0,0 +1,19 @@
+/* PR c/7102 */
+
+/* Verify that GCC zero-extends integer constants
+ in unsigned binary operations. */
+
+typedef unsigned char u8;
+
+u8 fun(u8 y)
+{
+ u8 x=((u8)255)/y;
+ return x;
+}
+
+int main(void)
+{
+ if (fun((u8)2) != 127)
+ abort ();
+ return 0;
+}