Article View: gnu.gcc.bug
Article #1417truncation SImode -> HImode wrong if word_mode == QImode
From: Andreas Luik
Date: Tue, 22 Dec 1992 19:47
Date: Tue, 22 Dec 1992 19:47
98 lines
3398 bytes
3398 bytes
Program: gcc
Version: 2.3.2
Host: sparc-sun-sunos4.1.3
Target: own
Area: cc1
Input file: trunc.c
static void discardl (long l) {}
void trunc ()
{
long l;
long long ll = (long long) 0x300040005;
l = ll; discardl (l);
}
gcc command: gcc -S trunc.c
Synopsis: truncation SImode -> HImode wrong if word_mode == QImode
Description:
Assume a 16-bit word addressable target machine. Then the machine
modes are:
BITS_PER_UNIT 16
BITS_PER_WORD 16
UNITS_PER_WORD 1
QImode = 16 Bits (C-Types char, short & int)
HImode = 32 Bits (C-Type long)
SImode = 64 Bits (C-Type long long)
word_mode = QImode
The assignment "(long) l = (long long) ll" must truncate the 64-Bit SImode
value to the 32-Bit HImode value. This should be done by
convert_move() [expr.c]. to_mode is HImode, from_mode is SImode.
convert_move() does nothing until it reaches the following statements:
if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD)
{
convert_move (to, gen_lowpart (word_mode, from), 0);
return;
}
As the condition is true, convert_mode() is recursively called with a
source rtx with mode word_mode, i.e. QImode! This is wrong of course.
(Usually this works because the conditions are as follows: from_mode
must be DImode (> BITS_PER_WORD), to_mode must be != from_mode
(otherwise convert_move will simply call emit_move_insn()), i.e.
SImode. From (DImode) will be converted to lowpart(SImode, from) which
will then work because to has a mode <= SImode. Note that this will
fail in traditional architectures if integer arithmetic on TImode
(16 byte ints) will be supported.)
I don't understand the purpose of the above condition. The code that
follows in convert_move() will handle all cases. Especially the code
that handles from_mode DImode using CODE_FOR_truncdixx2 following the
above condition will never get executed.
Would you please check whether this condition (which should serve any
optimization purpose I suppose) should not be eliminated.
Reproduce with:
Difficult without appropriate target description. Please check the
code. Maybe you may add a "truncdisi2" insn to a 32-bit target description
(e.g. sparc.md) and see it ignored (if TRULY_NOOP_TRUNCATION is 0).
Fix:
*** expr.c.ORIG Thu Dec 3 02:10:13 1992
--- expr.c Thu Dec 17 18:55:10 1992
***************
*** 704,714 ****
--- 704,716 ----
return;
}
+ #if 0
if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD)
{
convert_move (to, gen_lowpart (word_mode, from), 0);
return;
}
+ #endif
/* Handle pointer conversion */ /* SPEE 900220 */
if (to_mode == PSImode)
--
Andreas Luik E-Mail: luik@isa.de
(postmaster@isa.de) UUCP: ...!{uunet!unido,pyramid}!isaak!luik
Technical Details
Message-ID:
<9212221747.AA11904@einstein.isa.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!isa.DE!luikShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!isa.DE!luik From: luik@isa.DE (Andreas Luik) Subject: truncation SImode -> HImode wrong if word_mode == QImode Message-ID: <9212221747.AA11904@einstein.isa.de> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Tue, 22 Dec 1992 19:47:00 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 99