public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/113280] New: Strange error for empty inline assembly with +X constraint
@ 2024-01-08 18:36 david at westcontrol dot com
  2024-01-08 19:09 ` [Bug rtl-optimization/113280] " pinskia at gcc dot gnu.org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: david at westcontrol dot com @ 2024-01-08 18:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

            Bug ID: 113280
           Summary: Strange error for empty inline assembly with +X
                    constraint
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: david at westcontrol dot com
  Target Milestone: ---

I am getting strange results with an empty inline assembly line, used as an
optimisation barrier.  This is the test code I've tried in different setups:

#define opt 1

typedef int T;
T test(T a, T b) {
    T x = a + b;
#if opt == 1
    asm ("" : "+X" (x));   
#endif
#if opt == 2
    asm ("" : "+X" (x) : "0" (x));
#endif
#if opt == 3
    asm ("" :: "X" (x));
    asm ("" : "+X" (x));   
#endif
    return x - b;
} 

The idea of the assembly line is to be an optimisation barrier - it forces the
compiler to calculate the value of "x" before the assembly line, and has to use
that value (rather than any pre-calculated information) after the assembly
line.  This makes it something like an "asm("" ::: "memory")" barrier, but
focused on a single variable, which may not need to be moved out of registers. 
I've found this kind of construct "asm("" : "+g" (x))" useful to control
ordering of code around disabled interrupt sections of embedded code, and it
can also force the order of floating point calculations even while -ffast-math
is used.  Usually I've used "g" as the operand constraint, and that has worked
perfectly for everything except floating point types on targets that have
dedicated floating point registers.

I had expected "+X" (option 1 above) to work smoothly for floating point types.
 And it does, sometimes - other times I get an error:

    error: inconsistent operand constraints in an 'asm'

I've tested mainly on x86-64 (current trunk, which will be 14.0) and ARM 32-bit
(13.2), with -O2 optimisation.  I get no errors with -O0, but there is no need
of an optimisation barrier if optimisation is not enabled!  The exact compiler
version does not seem to make a difference, but the target does, as does the
type T.

I can't see why there should be a difference in the way these three variations
work, or why some combinations give errors.  When there is no compiler error,
the code (in all my testing) has been optimal as intended.

Some test results:

T = float :
  opt 1   arm-32 fail  x86-64 fail
  opt 2   arm-32 fail  x86-64 ok
  opt 3   arm-32 ok  x86-64 ok

T = int :
  opt 1   arm-32 fail  x86-64 fail
  opt 2   arm-32 fail  x86-64 ok
  opt 3   arm-32 ok  x86-64 ok

T = double :
  opt 1   arm-32 fail  x86-64 fail
  opt 2   arm-32 fail  x86-64 ok
  opt 3   arm-32 ok  x86-64 ok

T = long long int :
  opt 1   arm-32 ok  x86-64 fail
  opt 2   arm-32 ok  x86-64 ok
  opt 3   arm-32 ok  x86-64 ok

T = _Complex double :
  opt 1   arm-32 ok  x86-64 ok
  opt 2   arm-32 fail  x86-64 fail
  opt 3   arm-32 ok  x86-64 ok

T = long double :
  (arm-32 has 64-bit long double, so the results are not relevant)
  opt 1 gives "inconsistent operand constraints in an asm"
  opt 2 and 3 give "output constraint 0 must specify a single register", which
is an understandable error.


It looks like the "+X" constraint only works reliably if preceded by the
assembly line with the "X" input constraint.  For my own use, I can live with
that - it all goes in a macro anyway.  But maybe it points to a deeper issue,
or at least a potential for neatening things up.

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
@ 2024-01-08 19:09 ` pinskia at gcc dot gnu.org
  2024-01-08 19:12 ` pinskia at gcc dot gnu.org
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-08 19:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|ra                          |
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2024-01-08
          Component|middle-end                  |rtl-optimization
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
So the problem seems like combine decides somehow to 
combine:
```
(insn 7 4 9 2 (set (reg/v:SF 100 [ xD.4459 ])
        (plus:SF (reg/v:SF 102 [ aD.4455 ])
            (reg/v:SF 103 [ bD.4456 ]))) "/app/example.cpp":6:7 1043 {addsf3}
     (expr_list:REG_DEAD (reg/v:SF 102 [ aD.4455 ])
        (nil)))
(insn 9 7 10 2 (set (reg:SF 104 [ xD.4459 ])
        (asm_operands:SF ("") ("=X") 0 [
                (reg/v:SF 100 [ xD.4459 ])
            ]
             [
                (asm_input:SF ("0") /app/example.cpp:8)
            ]
             [] /app/example.cpp:8)) "/app/example.cpp":8:5 -1
     (expr_list:REG_DEAD (reg/v:SF 100 [ xD.4459 ])
        (nil)))
into:
```
(insn 9 7 10 2 (set (reg:SF 104 [ xD.4459 ])
        (asm_operands:SF ("") ("=X") 0 [
                (plus:SF (reg:SF 106)
                    (reg/v:SF 103 [ bD.4456 ]))
            ]
             [
                (asm_input:SF ("0") /app/example.cpp:8)
            ]
             [] /app/example.cpp:8)) "/app/example.cpp":8:5 -1
     (expr_list:REG_DEAD (reg:SF 106)
        (nil)))
```

But the dump from combine does not make sense:
```
Trying 7 -> 9:
    7: r100:SF=r106:SF+r103:SF
      REG_DEAD r106:SF
    9: r104:SF=asm_operands
      REG_DEAD r100:SF
Failed to match this instruction:
(set (reg:SF 104 [ xD.4459 ])
    (asm_operands:SF ("") ("=X") 0 [
            (plus:SF (reg:SF 106)
                (reg/v:SF 103 [ bD.4456 ]))
        ]
         [
            (asm_input:SF ("0") /app/example.cpp:8)
        ]
         [] /app/example.cpp:8))
allowing combination of insns 7 and 9
original costs 8 + 4 = 12
replacement cost 4
deferring deletion of insn with uid = 7.
modifying insn i3     9: r104:SF=asm_operands
      REG_DEAD r106:SF
deferring rescan insn with uid = 9.
```

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
  2024-01-08 19:09 ` [Bug rtl-optimization/113280] " pinskia at gcc dot gnu.org
@ 2024-01-08 19:12 ` pinskia at gcc dot gnu.org
  2024-01-09  8:29 ` rguenth at gcc dot gnu.org
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-01-08 19:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> So the problem seems like combine decides somehow to 
> combine:
> ```
> (insn 7 4 9 2 (set (reg/v:SF 100 [ xD.4459 ])
>         (plus:SF (reg/v:SF 102 [ aD.4455 ])
>             (reg/v:SF 103 [ bD.4456 ]))) "/app/example.cpp":6:7 1043 {addsf3}
>      (expr_list:REG_DEAD (reg/v:SF 102 [ aD.4455 ])
>         (nil)))
> (insn 9 7 10 2 (set (reg:SF 104 [ xD.4459 ])
>         (asm_operands:SF ("") ("=X") 0 [
>                 (reg/v:SF 100 [ xD.4459 ])
>             ]
>              [
>                 (asm_input:SF ("0") /app/example.cpp:8)
>             ]
>              [] /app/example.cpp:8)) "/app/example.cpp":8:5 -1
>      (expr_list:REG_DEAD (reg/v:SF 100 [ xD.4459 ])
>         (nil)))
> into:
> ```
> (insn 9 7 10 2 (set (reg:SF 104 [ xD.4459 ])
>         (asm_operands:SF ("") ("=X") 0 [
>                 (plus:SF (reg:SF 106)
>                     (reg/v:SF 103 [ bD.4456 ]))
>             ]
>              [
>                 (asm_input:SF ("0") /app/example.cpp:8)
>             ]
>              [] /app/example.cpp:8)) "/app/example.cpp":8:5 -1
>      (expr_list:REG_DEAD (reg:SF 106)
>         (nil)))
> ```
> 
> But the dump from combine does not make sense:
> ```
> Trying 7 -> 9:
>     7: r100:SF=r106:SF+r103:SF
>       REG_DEAD r106:SF
>     9: r104:SF=asm_operands
>       REG_DEAD r100:SF
> Failed to match this instruction:
> (set (reg:SF 104 [ xD.4459 ])
>     (asm_operands:SF ("") ("=X") 0 [
>             (plus:SF (reg:SF 106)
>                 (reg/v:SF 103 [ bD.4456 ]))
>         ]
>          [
>             (asm_input:SF ("0") /app/example.cpp:8)
>         ]
>          [] /app/example.cpp:8))
> allowing combination of insns 7 and 9
> original costs 8 + 4 = 12
> replacement cost 4
> deferring deletion of insn with uid = 7.
> modifying insn i3     9: r104:SF=asm_operands
>       REG_DEAD r106:SF
> deferring rescan insn with uid = 9.
> ```

So basically check_asm_operands accepts the insn because the plus matches the
operand but this is an output operand which does not work as it is not an
lvalue ...

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
  2024-01-08 19:09 ` [Bug rtl-optimization/113280] " pinskia at gcc dot gnu.org
  2024-01-08 19:12 ` pinskia at gcc dot gnu.org
@ 2024-01-09  8:29 ` rguenth at gcc dot gnu.org
  2024-01-09  8:42 ` segher at gcc dot gnu.org
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-01-09  8:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |segher at gcc dot gnu.org
           Keywords|                            |rejects-valid

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
I wonder if this ever worked - at least I don't remember any combiner changes
for asms.

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (2 preceding siblings ...)
  2024-01-09  8:29 ` rguenth at gcc dot gnu.org
@ 2024-01-09  8:42 ` segher at gcc dot gnu.org
  2024-01-09  8:43 ` segher at gcc dot gnu.org
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: segher at gcc dot gnu.org @ 2024-01-09  8:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #4 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Nothing has changed here.

opt == 2 and opt == 3 should use "=X", not "+X", btw.

combine is perfectly correct that "X" allows *any operand whatsoever*, also
those
that you cannot really use as an output.  Maybe we should not allow "X" for
output
operands at all?

The error happens during reloading btw.  Which makes sense, I would be much
more
surprised if the compiler figured out a way to move data into an addition :-)

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (3 preceding siblings ...)
  2024-01-09  8:42 ` segher at gcc dot gnu.org
@ 2024-01-09  8:43 ` segher at gcc dot gnu.org
  2024-01-09  9:00 ` amonakov at gcc dot gnu.org
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: segher at gcc dot gnu.org @ 2024-01-09  8:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #5 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Oh, and if the goal of the code is to put and keep the datum in a register, the
code should really use "+r" anyway!

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (4 preceding siblings ...)
  2024-01-09  8:43 ` segher at gcc dot gnu.org
@ 2024-01-09  9:00 ` amonakov at gcc dot gnu.org
  2024-01-09 10:14 ` david at westcontrol dot com
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: amonakov at gcc dot gnu.org @ 2024-01-09  9:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amonakov at gcc dot gnu.org

--- Comment #6 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
From the context given in the gcc-help thread, the goal is to place an
optimization barrier in a sequence of floating-point calculation. "+r" is
inappropriate for floats, as it usually incurs a reload from a floating-point
register to a GPR and back, and there's no universal constraint for FP regs
(e.g. on amd64 it is "+x" for SSE registers, but "+t" for long double (or x87
FPU on 32-bit x86)).

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (5 preceding siblings ...)
  2024-01-09  9:00 ` amonakov at gcc dot gnu.org
@ 2024-01-09 10:14 ` david at westcontrol dot com
  2024-01-09 10:26 ` david at westcontrol dot com
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: david at westcontrol dot com @ 2024-01-09 10:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #7 from David Brown <david at westcontrol dot com> ---
Yes, the goal is an optimisation barrier with the least possible impact on the
code.  For most uses, asm("" : "+g" (x)) has been ideal, as far as I have
tested.  Typically it ensures "x" is evaluated in a register before the
assembly "executes", and uses that register for "x" afterwards.  But "g" also
matches memory, so if "x" happens to be in a stack slot, it gets left there -
there is no extra movement in and out of a register.

But "g" does not match floating point or SIMD registers.  So if "x" is in one
of these registers, extra moves are generated, and I'd like to avoid them.  So
the ideal constraint would be one that matches memory or any register that can
contain data.  That's not quite the same as "match anything" - it should not
match immediate values, nor "special" registers such as PC, SP, or a flags
register, or the extra registers many processors have for floating point
settings, link registers, interrupt state registers, and so on.  But it might
include registers for other accelerators that some chips have.

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (6 preceding siblings ...)
  2024-01-09 10:14 ` david at westcontrol dot com
@ 2024-01-09 10:26 ` david at westcontrol dot com
  2024-01-09 11:00 ` segher at gcc dot gnu.org
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: david at westcontrol dot com @ 2024-01-09 10:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #8 from David Brown <david at westcontrol dot com> ---
(In reply to Segher Boessenkool from comment #4)
> Nothing has changed here.
> 
> opt == 2 and opt == 3 should use "=X", not "+X", btw.
> 

I realise (since you told me - thanks) that

    asm ("" : "+X" (x))

and

    asm ("" : "=X" (x) : "0" (x))

are the same.  However, it seems that 

    asm ("" : "+X" (x) : "0" (x))

is different.  If I change "opt == 2" to use "=X", then it acts exactly like
the "opt == 1" version (as expected), but having "+X" in "opt == 2" gives
different results.  I don't know /why/ this seems to be treated differently,
since it is just repeating the input in the same target, but it is.

As for using "=X" in the "opt == 3" case, I worry that that could lead to
errors as the two assembly lines are independent.  The first says "put X
anywhere", and the second - if it had "=X" - says "take X from anywhere". 
These don't have to be the same "anywhere" unless the input and output are in
the same statement - and if the compiler picked different anywheres, the code
would not work.

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (7 preceding siblings ...)
  2024-01-09 10:26 ` david at westcontrol dot com
@ 2024-01-09 11:00 ` segher at gcc dot gnu.org
  2024-01-09 11:04 ` segher at gcc dot gnu.org
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: segher at gcc dot gnu.org @ 2024-01-09 11:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #9 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Alexander Monakov from comment #6)
> From the context given in the gcc-help thread, the goal is to place an
> optimization barrier in a sequence of floating-point calculation. "+r" is
> inappropriate for floats, as it usually incurs a reload from a
> floating-point register to a GPR and back, and there's no universal
> constraint for FP regs (e.g. on amd64 it is "+x" for SSE registers, but "+t"
> for long double (or x87 FPU on 32-bit x86)).

Yup.  "Some target-specific register constraint" :-)

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (8 preceding siblings ...)
  2024-01-09 11:00 ` segher at gcc dot gnu.org
@ 2024-01-09 11:04 ` segher at gcc dot gnu.org
  2024-01-09 11:07 ` segher at gcc dot gnu.org
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: segher at gcc dot gnu.org @ 2024-01-09 11:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #10 from Segher Boessenkool <segher at gcc dot gnu.org> ---
> But the dump from combine does not make sense:

What about this does not make sense to you?
> Failed to match this instruction:
and then still doing stuff?  That is normal.  I'll work on making that look
better / make more sense, it always irked me as well.

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (9 preceding siblings ...)
  2024-01-09 11:04 ` segher at gcc dot gnu.org
@ 2024-01-09 11:07 ` segher at gcc dot gnu.org
  2024-01-09 11:54 ` david at westcontrol dot com
  2024-03-22 22:46 ` pinskia at gcc dot gnu.org
  12 siblings, 0 replies; 14+ messages in thread
From: segher at gcc dot gnu.org @ 2024-01-09 11:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #11 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to David Brown from comment #8)
> As for using "=X" in the "opt == 3" case, I worry that that could lead to
> errors as the two assembly lines are independent.  The first says "put X
> anywhere", and the second - if it had "=X" - says "take X from anywhere". 
> These don't have to be the same "anywhere" unless the input and output are
> in the same statement - and if the compiler picked different anywheres, the
> code would not work.

This cannot lead to errors.  The compiler knows where "x" is (it put it there
itself!)

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (10 preceding siblings ...)
  2024-01-09 11:07 ` segher at gcc dot gnu.org
@ 2024-01-09 11:54 ` david at westcontrol dot com
  2024-03-22 22:46 ` pinskia at gcc dot gnu.org
  12 siblings, 0 replies; 14+ messages in thread
From: david at westcontrol dot com @ 2024-01-09 11:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

--- Comment #12 from David Brown <david at westcontrol dot com> ---
(In reply to Segher Boessenkool from comment #11)
> (In reply to David Brown from comment #8)
> > As for using "=X" in the "opt == 3" case, I worry that that could lead to
> > errors as the two assembly lines are independent.  The first says "put X
> > anywhere", and the second - if it had "=X" - says "take X from anywhere". 
> > These don't have to be the same "anywhere" unless the input and output are
> > in the same statement - and if the compiler picked different anywheres, the
> > code would not work.
> 
> This cannot lead to errors.  The compiler knows where "x" is (it put it there
> itself!)

If I write :

    int regtest(int a, int x) {
        (void) a;    // Ignore first parameter
        return x;
    }

I get the assembly (x86-64) :

    movl %esi, %eax
    ret

or (arm 32-bit)

    mov r0, r1
    bx lr


That's all fine, and as expected.  But with this :

    int regtest(int a, int x) {
        (void) a;    // Ignore first parameter
        asm("" :: "X" (x);
        asm("" : "=X" (x);
        return x;
    }

the result is just a "ret" or a "bx lr" instruction.  The register move is
missing, because for the first assembly the "anywhere" is picked as esi/r1, and
for the second assembly the "anywhere" is picked as eax/r0.  This is a
perfectly valid choice of registers for the compiler, but it is not what we
want in this use-case.

It is only if I use "+X" (or add a "0" (x) input), rather than "=X", that the
compiler picks the same register for input and output, because it is within the
one assembly instruction.

(The same applies to "=g" / "+g".)

I don't understand why having a "asm("" :: "X" (x))" seems to be necessary
sometimes for "asm("" : "+X" (x))" to work the way I expect, without a compiler
error, but I /do/ understand why "asm("" :: "X" (x))" followed by "asm("" :
"=X" (x))" will sometimes not give the results I am looking for.

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

* [Bug rtl-optimization/113280] Strange error for empty inline assembly with +X constraint
  2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
                   ` (11 preceding siblings ...)
  2024-01-09 11:54 ` david at westcontrol dot com
@ 2024-03-22 22:46 ` pinskia at gcc dot gnu.org
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-22 22:46 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113280

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|NEW                         |RESOLVED

--- Comment #13 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup.

*** This bug has been marked as a duplicate of bug 94180 ***

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

end of thread, other threads:[~2024-03-22 22:47 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-08 18:36 [Bug c/113280] New: Strange error for empty inline assembly with +X constraint david at westcontrol dot com
2024-01-08 19:09 ` [Bug rtl-optimization/113280] " pinskia at gcc dot gnu.org
2024-01-08 19:12 ` pinskia at gcc dot gnu.org
2024-01-09  8:29 ` rguenth at gcc dot gnu.org
2024-01-09  8:42 ` segher at gcc dot gnu.org
2024-01-09  8:43 ` segher at gcc dot gnu.org
2024-01-09  9:00 ` amonakov at gcc dot gnu.org
2024-01-09 10:14 ` david at westcontrol dot com
2024-01-09 10:26 ` david at westcontrol dot com
2024-01-09 11:00 ` segher at gcc dot gnu.org
2024-01-09 11:04 ` segher at gcc dot gnu.org
2024-01-09 11:07 ` segher at gcc dot gnu.org
2024-01-09 11:54 ` david at westcontrol dot com
2024-03-22 22:46 ` pinskia at gcc dot gnu.org

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).