[PR98096] inline-asm: Take inout operands into account for access to labels by names.

GCC splits inout operands into output and new matched input operands
during gimplfication.  Addressing operands by name or number is not
problem as the new input operands are added at the end of existing
input operands.  However it became a problem for labels in asm goto
with output reloads.  Addressing labels should take into account the
new input operands.  The patch solves the problem.

gcc/ChangeLog:

	PR inline-asm/98096
	* stmt.c (resolve_operand_name_1): Take inout operands into account
	for access to labels by names.
	* doc/extend.texi: Describe counting operands for accessing labels.

gcc/testsuite/ChangeLog:

	PR inline-asm/98096
	* gcc.c-torture/compile/pr98096.c: New.
This commit is contained in:
Vladimir N. Makarov 2021-02-16 10:27:56 -05:00
parent ebf9b6c13f
commit 72d78655a9
3 changed files with 32 additions and 11 deletions

View File

@ -10680,16 +10680,23 @@ should use @samp{+} constraint modifier meaning that the operand is
input and output one. With this modifier you will have the correct
values on all possible paths from the @code{asm goto}.
To reference a label in the assembler template,
prefix it with @samp{%l} (lowercase @samp{L}) followed
by its (zero-based) position in @var{GotoLabels} plus the number of input
operands. For example, if the @code{asm} has three inputs and references two
labels, refer to the first label as @samp{%l3} and the second as @samp{%l4}).
To reference a label in the assembler template, prefix it with
@samp{%l} (lowercase @samp{L}) followed by its (zero-based) position
in @var{GotoLabels} plus the number of input and output operands.
Output operand with constraint modifier @samp{+} is counted as two
operands because it is considered as one output and one input operand.
For example, if the @code{asm} has three inputs, one output operand
with constraint modifier @samp{+} and one output operand with
constraint modifier @samp{=} and references two labels, refer to the
first label as @samp{%l6} and the second as @samp{%l7}).
Alternately, you can reference labels using the actual C label name enclosed
in brackets. For example, to reference a label named @code{carry}, you can
use @samp{%l[carry]}. The label must still be listed in the @var{GotoLabels}
section when using this approach.
Alternately, you can reference labels using the actual C label name
enclosed in brackets. For example, to reference a label named
@code{carry}, you can use @samp{%l[carry]}. The label must still be
listed in the @var{GotoLabels} section when using this approach. It
is better to use the named references for labels as in this case you
can avoid counting input and output operands and special treatment of
output operands with constraint modifier @samp{+}.
Here is an example of @code{asm goto} for i386:

View File

@ -611,7 +611,7 @@ static char *
resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
{
char *q;
int op;
int op, op_inout;
tree t;
/* Collect the operand name. */
@ -624,11 +624,14 @@ resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
*q = '\0';
/* Resolve the name to a number. */
for (op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
{
tree name = TREE_PURPOSE (TREE_PURPOSE (t));
if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
goto found;
tree constraint = TREE_VALUE (TREE_PURPOSE (t));
if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
op_inout++;
}
for (t = inputs; t ; t = TREE_CHAIN (t), op++)
{
@ -636,6 +639,7 @@ resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
goto found;
}
op += op_inout;
for (t = labels; t ; t = TREE_CHAIN (t), op++)
{
tree name = TREE_PURPOSE (t);

View File

@ -0,0 +1,10 @@
/* Test for correct naming of label operands in asm goto in case of presence of
input/output operands. */
/* { dg-do compile } */
int i, j;
int f(void) {
asm goto ("# %0 %2" : "+r" (i) ::: jmp);
i += 2;
asm goto ("# %0 %1 %l[jmp]" : "+r" (i), "+r" (j) ::: jmp);
jmp: return i;
}