re PR rtl-optimization/13862 (ICE while optimizing asm)

PR opt/13862
        * cselib.c (cselib_record_sets): Don't record multiple sets in
        asm insns.

From-SVN: r78845
This commit is contained in:
Richard Henderson 2004-03-03 10:31:36 -08:00 committed by Richard Henderson
parent 039e3c5c45
commit b7048ab7b2
3 changed files with 90 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2003-03-03 Richard Henderson <rth@redhat.com>
PR opt/13862
* cselib.c (cselib_record_sets): Don't record multiple sets in
asm insns.
2004-03-03 Mostafa Hagog <mustafa@il.ibm.com>
* common.opt: Add description of the new -fgcse-after-reload flag.

View File

@ -1293,6 +1293,29 @@ cselib_record_sets (rtx insn)
locations may go away. */
note_stores (body, cselib_invalidate_rtx, NULL);
/* If this is an asm, look for duplicate sets. This can happen when the
user uses the same value as an output multiple times. This is valid
if the outputs are not actually used thereafter. Treat this case as
if the value isn't actually set. We do this by smashing the destination
to pc_rtx, so that we won't record the value later. */
if (n_sets >= 2 && asm_noperands (body) >= 0)
{
for (i = 0; i < n_sets; i++)
{
rtx dest = sets[i].dest;
if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM)
{
int j;
for (j = i + 1; j < n_sets; j++)
if (rtx_equal_p (dest, sets[j].dest))
{
sets[i].dest = pc_rtx;
sets[j].dest = pc_rtx;
}
}
}
}
/* Now enter the equivalences in our tables. */
for (i = 0; i < n_sets; i++)
{

View File

@ -0,0 +1,61 @@
/* PR opt/13862 */
/* { dg-do compile { target i?86-*-* } } */
/* { dg-options "-O" } */
typedef struct _fame_syntax_t_ {
} fame_syntax_t;
typedef struct _fame_bitbuffer_t_
{
unsigned char * base;
unsigned char * data;
unsigned long shift;
} fame_bitbuffer_t;
#define fast_bitbuffer_write(data, shift, c, l) \
{ \
int d; \
\
asm("add %1, %%ecx\n" /* ecx = shift + length */ \
"shrd %%cl, %2, %3\n" /* adjust code to fit in */ \
"shr %%cl, %2\n" /* adjust code to fit in */ \
"mov %%ecx, %1\n" /* shift += length */ \
"bswap %2\n" /* reverse byte order of code */ \
"shr $5, %%ecx\n" /* get dword increment */ \
"or %2, (%0)\n" /* put first 32 bits */ \
"bswap %3\n" /* reverse byte order of code */ \
"lea (%0, %%ecx, 4), %0\n" /* data += (ecx>32) */ \
"andl $31, %1\n" /* mask shift */ \
"orl %3, (%0)\n" /* put last 32 bits */ \
: "=r"(data), "=r"(shift), "=a"(d), "=d"(d), "=c"(d) \
: "0"(data), "1"(shift), "2"((unsigned long) c), "3"(0), \
"c"((unsigned long) l) \
: "memory"); \
}
#define bitbuffer_write(bb, c, l) \
fast_bitbuffer_write((bb)->data, (bb)->shift, c, l)
typedef enum { frame_type_I, frame_type_P } frame_type_t;
typedef struct _fame_syntax_mpeg1_t_ {
fame_bitbuffer_t buffer;
frame_type_t frame_type;
} fame_syntax_mpeg1_t;
#define FAME_SYNTAX_MPEG1(x) ((fame_syntax_mpeg1_t *) x)
void mpeg1_start_picture(fame_syntax_t *syntax)
{
fame_syntax_mpeg1_t *syntax_mpeg1 = FAME_SYNTAX_MPEG1(syntax);
bitbuffer_write(&syntax_mpeg1->buffer, 0xFFFF, 16);
switch(syntax_mpeg1->frame_type) {
case frame_type_I:
bitbuffer_write(&syntax_mpeg1->buffer, 0, 1);
break;
case frame_type_P:
bitbuffer_write(&syntax_mpeg1->buffer, 0, 1);
break;
}
}