public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* confused by 990130-1.c
@ 1999-03-01 20:18 Zack Weinberg
       [not found] ` < 199903020417.XAA20209@blastula.phys.columbia.edu >
  1999-03-31 23:46 ` Zack Weinberg
  0 siblings, 2 replies; 4+ messages in thread
From: Zack Weinberg @ 1999-03-01 20:18 UTC (permalink / raw)
  To: egcs; +Cc: rth

Test case 990130-1.c fails compilation at all optimization levels.
The offending code is like this:

extern int *bar (void);

void foo (void)
{
  asm ("# %0" : "+r" (*bar()));
}

Current CVS produces this assembly for foo (-O2):

foo:
        pushl %ebp
        movl %esp,%ebp
        call bar
        movl (%eax),%edx
#APP
        # %edx
#NO_APP
        movl %edx,(%eax)
        movl %ebp,%esp
        popl %ebp
        ret

which is, as far as I can tell, correct.  At the same time, we get
this error message:

test.c: In function `foo':
test.c:5: output number 0 not restored to memory

I found the code in stmt.c that produces this message, and I don't
understand it.  It objects to (set (mem:X ...) (asm_operands ...))
when the output of the asm_operands has a register constraint.  That's
precisely the case here - initial RTL is this:

(insn 12 11 0 (set (mem:SI (reg:SI 22) 1)
        (asm_operands ("# %0") ("=r") 0[ 
                (mem:SI (reg:SI 22) 1)
            ] 
            [ 
                (asm_input:SI ("0"))
            ]  ("test.c") 5)) -1 (insn_list 11 (nil))
    (expr_list:REG_DEAD (reg:SI 22)
        (nil)))

But reload is able to fix this up:

(insn 22 11 12 (set (reg:SI 1 %edx)
        (mem:SI (reg:SI 0 %eax) 1)) 54 {movsi+2} (nil)
    (nil))

(insn 12 22 25 (set (reg:SI 1 %edx)
        (asm_operands ("# %0") ("=r") 0[ 
                (reg:SI 1 %edx)
            ] 
            [ 
                (asm_input:SI ("0"))
            ]  ("test.c") 5)) -1 (insn_list 11 (nil))
    (nil))

(insn 25 12 19 (set (mem:SI (reg:SI 0 %eax) 1)
        (reg:SI 1 %edx)) 54 {movsi+2} (nil)
    (nil))

which becomes the final assembly output above.  

I can think of a number of explanations for stmt.c's behavior, all of
which are probably wrong.  I'm guessing this error message was added
by this change:

revision 1.60
date: 1999/02/01 20:03:23;  author: rth;  state: Exp;  lines: +27 -6
        * recog.c (check_asm_operands): Treat indeterminate operand ok
        results as success.  Try harder to resolve a matching constraint.
        * stmt.c (expand_asm_operands): Recognize when an output operand's
        constraint does not allow memory.  Treat indeterminate operand ok
        results as failure.  Try harder to resolve a matching constraint.

-- Is the real problem not triggered by my simplified example?
(990130-1.c doesn't seem to trigger it either, then.)  Is reload not
supposed to have to deal with this?

zw

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: confused by 990130-1.c
       [not found] ` < 199903020417.XAA20209@blastula.phys.columbia.edu >
@ 1999-03-05 13:32   ` Richard Henderson
  1999-03-31 23:46     ` Richard Henderson
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Henderson @ 1999-03-05 13:32 UTC (permalink / raw)
  To: Zack Weinberg, egcs

On Mon, Mar 01, 1999 at 11:17:57PM -0500, Zack Weinberg wrote:
> void foo (void)
> {
>   asm ("# %0" : "+r" (*bar()));
> }
[...]
> test.c: In function `foo':
> test.c:5: output number 0 not restored to memory
[...]
> (insn 12 11 0 (set (mem:SI (reg:SI 22) 1)
>         (asm_operands ("# %0") ("=r") 0[ 
>                 (mem:SI (reg:SI 22) 1)
>             ] 
>             [ 
>                 (asm_input:SI ("0"))
>             ]  ("test.c") 5)) -1 (insn_list 11 (nil))
>     (expr_list:REG_DEAD (reg:SI 22)
>         (nil)))

The problem is that the code in question is trying to reduce the
work for reload.  Doing so greatly increases the chances that we'll
not run out of reload registers trying to process the asm.  Thus
that example would best generate the rtl

	(set (reg:SI tmp) (mem:SI (reg:SI 22)))
	(set (reg:SI tmp)
          (asm_operands ("# %0") ("=r") 0[ 
                  (reg:SI tmp)
              ] 
              [ 
                  (asm_input:SI ("0"))
              ]  ("test.c") 5))
	(set (mem:SI (reg:SI 22)) (reg:SI tmp))

since "+r" wants a register not a memory.  But that was trickier than
I wanted to tackle at the time so I printed the warning and bailed; I'm
marginally surprised that it does do the right thing.  I added the test
to remind me to revisit the problem.


r~

^ permalink raw reply	[flat|nested] 4+ messages in thread

* confused by 990130-1.c
  1999-03-01 20:18 confused by 990130-1.c Zack Weinberg
       [not found] ` < 199903020417.XAA20209@blastula.phys.columbia.edu >
@ 1999-03-31 23:46 ` Zack Weinberg
  1 sibling, 0 replies; 4+ messages in thread
From: Zack Weinberg @ 1999-03-31 23:46 UTC (permalink / raw)
  To: egcs; +Cc: rth

Test case 990130-1.c fails compilation at all optimization levels.
The offending code is like this:

extern int *bar (void);

void foo (void)
{
  asm ("# %0" : "+r" (*bar()));
}

Current CVS produces this assembly for foo (-O2):

foo:
        pushl %ebp
        movl %esp,%ebp
        call bar
        movl (%eax),%edx
#APP
        # %edx
#NO_APP
        movl %edx,(%eax)
        movl %ebp,%esp
        popl %ebp
        ret

which is, as far as I can tell, correct.  At the same time, we get
this error message:

test.c: In function `foo':
test.c:5: output number 0 not restored to memory

I found the code in stmt.c that produces this message, and I don't
understand it.  It objects to (set (mem:X ...) (asm_operands ...))
when the output of the asm_operands has a register constraint.  That's
precisely the case here - initial RTL is this:

(insn 12 11 0 (set (mem:SI (reg:SI 22) 1)
        (asm_operands ("# %0") ("=r") 0[ 
                (mem:SI (reg:SI 22) 1)
            ] 
            [ 
                (asm_input:SI ("0"))
            ]  ("test.c") 5)) -1 (insn_list 11 (nil))
    (expr_list:REG_DEAD (reg:SI 22)
        (nil)))

But reload is able to fix this up:

(insn 22 11 12 (set (reg:SI 1 %edx)
        (mem:SI (reg:SI 0 %eax) 1)) 54 {movsi+2} (nil)
    (nil))

(insn 12 22 25 (set (reg:SI 1 %edx)
        (asm_operands ("# %0") ("=r") 0[ 
                (reg:SI 1 %edx)
            ] 
            [ 
                (asm_input:SI ("0"))
            ]  ("test.c") 5)) -1 (insn_list 11 (nil))
    (nil))

(insn 25 12 19 (set (mem:SI (reg:SI 0 %eax) 1)
        (reg:SI 1 %edx)) 54 {movsi+2} (nil)
    (nil))

which becomes the final assembly output above.  

I can think of a number of explanations for stmt.c's behavior, all of
which are probably wrong.  I'm guessing this error message was added
by this change:

revision 1.60
date: 1999/02/01 20:03:23;  author: rth;  state: Exp;  lines: +27 -6
        * recog.c (check_asm_operands): Treat indeterminate operand ok
        results as success.  Try harder to resolve a matching constraint.
        * stmt.c (expand_asm_operands): Recognize when an output operand's
        constraint does not allow memory.  Treat indeterminate operand ok
        results as failure.  Try harder to resolve a matching constraint.

-- Is the real problem not triggered by my simplified example?
(990130-1.c doesn't seem to trigger it either, then.)  Is reload not
supposed to have to deal with this?

zw

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: confused by 990130-1.c
  1999-03-05 13:32   ` Richard Henderson
@ 1999-03-31 23:46     ` Richard Henderson
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 1999-03-31 23:46 UTC (permalink / raw)
  To: Zack Weinberg, egcs

On Mon, Mar 01, 1999 at 11:17:57PM -0500, Zack Weinberg wrote:
> void foo (void)
> {
>   asm ("# %0" : "+r" (*bar()));
> }
[...]
> test.c: In function `foo':
> test.c:5: output number 0 not restored to memory
[...]
> (insn 12 11 0 (set (mem:SI (reg:SI 22) 1)
>         (asm_operands ("# %0") ("=r") 0[ 
>                 (mem:SI (reg:SI 22) 1)
>             ] 
>             [ 
>                 (asm_input:SI ("0"))
>             ]  ("test.c") 5)) -1 (insn_list 11 (nil))
>     (expr_list:REG_DEAD (reg:SI 22)
>         (nil)))

The problem is that the code in question is trying to reduce the
work for reload.  Doing so greatly increases the chances that we'll
not run out of reload registers trying to process the asm.  Thus
that example would best generate the rtl

	(set (reg:SI tmp) (mem:SI (reg:SI 22)))
	(set (reg:SI tmp)
          (asm_operands ("# %0") ("=r") 0[ 
                  (reg:SI tmp)
              ] 
              [ 
                  (asm_input:SI ("0"))
              ]  ("test.c") 5))
	(set (mem:SI (reg:SI 22)) (reg:SI tmp))

since "+r" wants a register not a memory.  But that was trickier than
I wanted to tackle at the time so I printed the warning and bailed; I'm
marginally surprised that it does do the right thing.  I added the test
to remind me to revisit the problem.


r~

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1999-03-31 23:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-03-01 20:18 confused by 990130-1.c Zack Weinberg
     [not found] ` < 199903020417.XAA20209@blastula.phys.columbia.edu >
1999-03-05 13:32   ` Richard Henderson
1999-03-31 23:46     ` Richard Henderson
1999-03-31 23:46 ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).