Bug 16719

Summary: [ColdFire] Illegal move of byte itno address register causes compiler to ICE
Product: gcc Reporter: Peter Barada <peter>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, joel, peter, ralf.corsepius
Priority: P2    
Version: 4.0.0   
Target Milestone: 3.4.5   
Host: Target: m68k-elf
Build: Known to work: 3.4.5 4.0.2 4.1.0
Known to fail: 4.0.0 3.4.4 Last reconfirmed: 2005-01-24 00:55:41
Attachments: Testcase to reproduce the bug

Description Peter Barada 2004-07-26 17:25:18 UTC
I've stumbled across yet another problem with trying to move a byte into an
address registe ron ColdFire.  This problem was pointed out to me by Brett
Swimley, and was reproducedd using today's version of uberbaum.

[peter@baradas peter]$ /tmp/uberbaum/bin/m68k-elf-gcc -I./ -Wall -Wsign-compare
-W -Wno-unused -Wshadow -m5206e -O3 -fomit-frame-pointer -funroll-loops   -S -o
/tmp/safer.s ~/tmp/safer.c
/home/peter/tmp/safer.c: In function `safer_ecb_encrypt':
/home/peter/tmp/safer.c:2494: error: insn does not satisfy its constraints:
(insn 319 318 320 10 (set (reg:QI 14 %a6)
        (mem/s:QI (plus:SI (reg:SI 14 %a6)
                (reg:SI 0 %d0 [104])) [0 safer_ebox S1 A8])) 34 {*m68k.md:752} (nil)
    (nil))
/home/peter/tmp/safer.c:2494: internal compiler error: in
reload_cse_simplify_operands, at postreload.c:378
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


Source code the reproduces the bug:



typedef unsigned char safer_key_t[(1 + 8 * (1 + 2 * 13))];
struct safer_key { safer_key_t key; };


typedef union Symmetric_key {

   struct safer_key safer;

} symmetric_key;

extern void crypt_argchk(char *v, char *s, int d);
extern const unsigned char safer_ebox[], safer_lbox[];

void safer_ecb_encrypt(const unsigned char *block_in,
                             unsigned char *block_out,
                             symmetric_key *skey)

{

    unsigned char a, b, c, d, e, f, g, h, t;
    unsigned int round;
    unsigned char *key;

    if (!(block_in != ((void *)0))) { crypt_argchk("block_in != NULL",
"safer.c", 248); };
    if (!(block_out != ((void *)0))) { crypt_argchk("block_out != NULL",
"safer.c", 249); };
    if (!(skey != ((void *)0))) { crypt_argchk("skey != NULL", "safer.c", 250); };

    key = skey->safer.key;
    a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
    e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
    if (13 < (round = *key)) round = 13;
    while(round-- > 0)
    {
        a ^= *++key; b += *++key; c += *++key; d ^= *++key;
        e ^= *++key; f += *++key; g += *++key; h ^= *++key;
        a = safer_ebox[(a) & 0xFF] + *++key; b = safer_lbox[(b) & 0xFF] ^ *++key;
        c = safer_lbox[(c) & 0xFF] ^ *++key; d = safer_ebox[(d) & 0xFF] + *++key;
        e = safer_ebox[(e) & 0xFF] + *++key; f = safer_lbox[(f) & 0xFF] ^ *++key;
        g = safer_lbox[(g) & 0xFF] ^ *++key; h = safer_ebox[(h) & 0xFF] + *++key;
        { b += a; a += b; }; { d += c; c += d; }; { f += e; e += f; }; { h += g;
g += h; };
        { c += a; a += c; }; { g += e; e += g; }; { d += b; b += d; }; { h += f;
f += h; };
        { e += a; a += e; }; { f += b; b += f; }; { g += c; c += g; }; { h += d;
d += h; };
        t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
    }
    a ^= *++key; b += *++key; c += *++key; d ^= *++key;
    e ^= *++key; f += *++key; g += *++key; h ^= *++key;
    block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
    block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
    block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
    block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
}
Comment 1 Peter Barada 2004-07-26 17:26:39 UTC
Created attachment 6828 [details]
Testcase to reproduce the bug
Comment 2 Andrew Pinski 2004-10-25 00:59:01 UTC
Confirmed, here is a reduced testcase:
unsigned char a, b, c, d, e, f, g;
void safer_ecb_encrypt(unsigned char *block_out, unsigned char *key, unsigned int round)
{
    while(round-- > 0)
    {
        a ^= *++key; b += *++key; c += *++key; d ^= *++key;
        e ^= *++key; f += *++key; g += *++key; 
    }
    block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
    block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
    block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
    block_out[6] = g & 0xFF;
}
Comment 3 Ralf Corsepius 2005-01-27 17:31:32 UTC
(In reply to comment #2)
> Confirmed, here is a reduced testcase:
I can't confirm this ICE with your reduced testcase and m68k-rtems-gcc.
But I can confirm m68k-rtems-gcc to be ICEing with the original example (safer.c).

# m68k-rtems4.7-gcc --version
m68k-rtems4.7-gcc (GCC) 4.0.0 20050126 (experimental)

/tmp/safer.c: In function 'safer_ecb_encrypt':
/tmp/safer.c:2494: error: insn does not satisfy its constraints:
(insn 301 300 302 10 (set (reg:QI 9 %a1)
        (mem/s/u:QI (plus:SI (reg:SI 9 %a1)
                (reg:SI 0 %d0 [91])) [0 safer_ebox S1 A8])) 34 {*m68k.md:752} (nil)
    (nil))
/tmp/safer.c:2494: internal compiler error: in reload_cse_simplify_operands, at
postreload.c:391
Comment 4 Peter Barada 2005-01-27 18:15:57 UTC
See the following for a patch waiting for approval...

http://gcc.gnu.org/ml/gcc-patches/2004-12/msg00405.html
Comment 5 Ralf Corsepius 2005-01-28 14:11:22 UTC
The patch contained in
http://gcc.gnu.org/ml/gcc-patches/2004-12/msg00405.html
doesn't seem to work for me, rsp. triggers another ICE, at least the error
message seems to have changed:

With today's gcc/cvs-trunk + your patch applied:

# m68k-rtems4.7-gcc -W -Wno-unused -Wshadow -m5206e -O3 -fomit-frame-pointer
-funroll-loops -S -o tmp.s /tmp/safer.c
/tmp/safer.c: In function 'safer_ecb_encrypt':
/tmp/safer.c:2494: error: unable to find a register to spill in class 'ADDR_REGS'
/tmp/safer.c:2494: error: this is the insn:
(insn 95 94 97 10 (set (reg:SI 8 %a0 [95])
        (plus:SI (subreg:SI (mem/s/u:QI (plus:SI (reg/f:SI 13 %a5 [189])
                        (reg:SI 0 %d0 [91])) [0 safer_ebox S1 A8]) 0)
            (subreg:SI (mem:QI (plus:SI (reg/v/f:SI 10 %a2 [orig:39 key.78 ] [39])
                        (const_int 9 [0x9])) [0 S1 A8]) 0))) 96 {*addsi3_5200}
(insn_list:REG_DEP_TRUE 91 (nil))
    (expr_list:REG_DEAD (reg:SI 0 %d0 [91])
        (nil)))
/tmp/safer.c:2494: internal compiler error: in spill_failure, at reload1.c:1872

Also I am seeing a new ICE during building RTEMS, but I am not sure if this is
related to your patch.
Comment 6 Bernardo Innocenti 2005-07-11 23:25:50 UTC
Patch attached to Bug #18421 (Attachment #9246 [details]).
Comment 7 GCC Commits 2005-07-11 23:32:10 UTC
Subject: Bug 16719

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	bernie@gcc.gnu.org	2005-07-11 23:32:01

Modified files:
	gcc            : ChangeLog 
	gcc/config/m68k: m68k.md m68k.c m68k.h m68k-protos.h 

Log message:
	PR middle-end/16719
	PR middle-end/18421
	* config/m68k/m68k.h (HARD_REGNO_MODE_OK): Disallow bytes
	in address registers.
	* config/m68k/m68k.c (hard_regno_mode_ok): Likewise.
	* config/m68k/m68k.md: Replace 's' with 'i' in 4th
	alternative of addsi3_5200.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.9411&r2=2.9412
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k.md.diff?cvsroot=gcc&r1=1.84&r2=1.85
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k.c.diff?cvsroot=gcc&r1=1.152&r2=1.153
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k.h.diff?cvsroot=gcc&r1=1.128&r2=1.129
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k-protos.h.diff?cvsroot=gcc&r1=1.20&r2=1.21

Comment 8 Bernardo Innocenti 2005-07-11 23:34:32 UTC
Fixed on mainline.  Pending for 4.0 and 3.4.
Comment 9 GCC Commits 2005-07-26 04:40:52 UTC
Subject: Bug 16719

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	bernie@gcc.gnu.org	2005-07-26 04:40:44

Modified files:
	gcc            : ChangeLog 
	gcc/config/m68k: m68k.md m68k.h m68k.c m68k-protos.h 

Log message:
	Backport from mainline:
	2005-07-12  Peter Barada  <peter@the-baradas.com>
	PR middle-end/16719
	PR middle-end/18421
	* config/m68k/m68k.h (HARD_REGNO_MODE_OK): Disallow bytes
	in address registers.
	* config/m68k/m68k.c (hard_regno_mode_ok): Likewise.
	* config/m68k/m68k.md: Replace 's' with 'i' in 4th
	alternative of addsi3_5200.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.7592.2.331&r2=2.7592.2.332
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k.md.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.80&r2=1.80.34.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k.h.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.123&r2=1.123.10.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.144&r2=1.144.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/m68k/m68k-protos.h.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.17&r2=1.17.18.1

Comment 11 Andrew Pinski 2005-07-26 20:34:02 UTC
Fixed.