This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Overflow clue request. MMIX: ieee/rbug.c needs fixuns_truncdfdi2to use (unsigned_fix:DI (unsigned_fix:DF op1))
- From: Hans-Peter Nilsson <hp at bitrange dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 17 Mar 2002 20:45:05 -0500 (EST)
- Subject: Overflow clue request. MMIX: ieee/rbug.c needs fixuns_truncdfdi2to use (unsigned_fix:DI (unsigned_fix:DF op1))
Apparently the inner fix of (unsigned_fix:N (fix:M op1), can
overflow in constant folding for valid operands, while
(unsigned_fix:N (unsigned_fix:M op1)) doesn't. The former rtl,
with M=df N=di, is the input operand of fixuns_truncdfdi2 of
i960.md and pa.md and AFAICS should be a correct way to express
it. Nevertherless, overflow happens in
gcc.c-torture/execute/ieee/rbug.c at -O3 and friends.
(FIXUNS_TRUNC_LIKE_FIX_TRUNC is properly not defined here as
well asl i960.md and pa.md.) rtl.texi says "how rounding is
done is not specified" and doesn't mention overflow at all, so
the only definition I see is how simplify-rtx.c and real.c
simplify constant expressions.
That actual definition is that for op1 =
(const_double:DF 4891140605170656321 [0x43e0d2774dafa441] 0
[0x0] [9.697299402072394e+18]) it overflows (fix:DF op1) to
(const_double:DF 4890909195324358656 [0x43e0000000000000] 0
[0x0] [9.223372036854776e+18]) but (unsigned_fix:DF op1) returns
op1. Apparently the "fix" and "unsigned_fix" operations can
overflow for DFmode. See real.c:etruncui. For targets where
rbug.c fails, this is likely the problem.
Strange. I would have thought that overflows for integers
representable in DF but not in DI wouldn't happen until the
conversion to DI. That's might be a bug, but can pass as a
strange definition. (It also doesn't match MMIX insns.) Given
the apparent general target confusion over fix_truncMN2
mentioned earlier, it wouldn't be surprising if it *is* a bug.
Anybody with clues? If real.c has it wrong, I'll try and fix it
and the docs, but to start with, I'd like some clues about TRT
for overflow behavior here. Please.
As mentioned, most major targets have just a (unsigned_fix:DI
op1) for the input operand for fixuns_truncdfdi2. That's does
not match the documentation, though simplify-rtx.c takes care of
it: the fixuns_truncdfdi2 pattern is supposed to handle
non-integer values but (unsigned_fix:DI op1) is just supposed to
handle an integer-valued operand in a float mode.
The following fixes gcc.c-torture/execute/ieee/rbug.c execution,
-O3 and friends by appeasing real.c:etruncui, though the docs
don't mention unsigned_fix with a float mode. Committed to
trunk; will commit to 3.1 too.
* config/mmix/mmix.md ("fixuns_truncdfdi2"): Use (unsigned_fix:DI
(unsigned_fix:DF op1)), not (unsigned_fix:DI (fix:DF op1)).
Index: mmix.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mmix/mmix.md,v
retrieving revision 1.9
diff -p -c -r1.9 mmix.md
*** mmix.md 2002/03/17 13:07:29 1.9
--- mmix.md 2002/03/17 19:33:08
*************** DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\
*** 569,575 ****
(define_insn "fixuns_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unsigned_fix:DI
! (fix:DF (match_operand:DF 1 "register_operand" "r"))))]
""
;; ROUND_OFF
"FIXU %0,1,%1")
--- 569,575 ----
(define_insn "fixuns_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unsigned_fix:DI
! (unsigned_fix:DF (match_operand:DF 1 "register_operand" "r"))))]
""
;; ROUND_OFF
"FIXU %0,1,%1")
brgds, H-P