This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Question regarding constraint usage within inline asm


On Wed, Feb 20, 2019 at 10:08:07AM -0600, Peter Bergner wrote:
> On 2/19/19 9:09 PM, Alan Modra wrote:
> > On Mon, Feb 18, 2019 at 01:13:31PM -0600, Peter Bergner wrote:
> >> long input;
> >> long
> >> bug (void)
> >> {
> >>   register long output asm ("r3");
> >>   asm ("blah %0, %1, %2" : "=&r" (output) : "r" (input), "0" (input));
> >>   return output;
> >> }

> > Without the asm("r3") gcc will provide your "blah" instruction with
> > one register for %0 and %2, and another register for %1.  Both
> > registers will be initialised with the value of "input".
> 
> That's not what I'm seeing.  I see one pseudo (123) used for the output
> operand and one pseudo (121) used for both input operands.  Like so:
> 
> (insn 8 6 7 (parallel [
>             (set (reg:DI 123 [ outputD.2831 ])
>                 (asm_operands:DI ("blah %0, %1, %2") ("=&r") 0 [
>                         (reg/v:DI 121 [ <retval> ]) repeated x2
>                     ]
>                      [
>                         (asm_input:DI ("r") bug.i:6)
>                         (asm_input:DI ("0") bug.i:6)
>                     ]
>                      [] bug.i:6))
>             (clobber (reg:SI 76 ca))
>         ]) "bug.i":6:3 -1
>      (nil))

expand already uses only one pseudo:

;; __asm__("blah %0, %1, %2" : "=&r" output : "r" input.0_1, "0" input.0_1);

(insn 7 6 0 (parallel [
            (set (reg/v:DI 3 3 [ output ])
                (asm_operands:DI ("blah %0, %1, %2") ("=&r") 0 [
                        (reg:DI 121 [ input.0_1 ]) repeated x2
                    ]
                     [
                        (asm_input:DI ("r") test.c:6)
                        (asm_input:DI ("0") test.c:6)
                    ]
                     [] test.c:6))
            (clobber (reg:SI 76 ca))
        ]) "test.c":6:3 -1
     (nil))

and that is a bad idea.  The asmcons pass makes pseudo 121 equal to hard
reg 3, and there is no way to recover from that.

Without the local register asm you get the same pseudo for the output as
well as both inputs, just as bad, but LRA can handle this:

            0 Early clobber: reject++
            0 Conflict early clobber reload: reject--
          alt=0,overall=6,losers=1,rld_nregs=0
         Choosing alt 0 in insn 8:  (0) =&r  (1) r  (2) 0
      Creating newreg=126 from oldreg=123, assigning class GENERAL_REGS to r126
    8: {r123:DI=asm_operands;clobber ca:SI;}
      REG_UNUSED ca:SI
    Inserting insn reload before:
   19: r126:DI=r123:DI

So expand shouldn't do this, but also asmcons should probably be improved


Segher


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]