🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #1417

truncation SImode -> HImode wrong if word_mode == QImode

#1417
From: Andreas Luik
Date: Tue, 22 Dec 1992 19:47
98 lines
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!luik

Show 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