diff mbox series

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

Message ID 7fe3a966-2309-05b1-b517-a8d523821a53@redhat.com
State New
Headers show
Series PR98096: inline-asm: Take inout operands into account for access to labels by names. | expand

Commit Message

Vladimir Makarov Feb. 4, 2021, 9:29 p.m. UTC
The following patch solves

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

The patch is for a new GCC extension -- asm goto with output reloads.

GCC splits inout operands (with constraint "+") into output and new 
matched input operands during gimplfication.  Addressing input or output 
operands by name or number is not a 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 added matched input 
operands.  The patch solves the problem.

The patch was successfully bootstrapped and tested on x86-64.

Is it ok to commit into the trunk?

Comments

Jeff Law Feb. 15, 2021, 11:35 p.m. UTC | #1
On 2/4/21 2:29 PM, Vladimir Makarov wrote:
> The following patch solves
>
>    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98096
>
> The patch is for a new GCC extension -- asm goto with output reloads.
>
> GCC splits inout operands (with constraint "+") into output and new
> matched input operands during gimplfication.  Addressing input or
> output operands by name or number is not a 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 added matched
> input operands.  The patch solves the problem.
>
> The patch was successfully bootstrapped and tested on x86-64.
>
> Is it ok to commit into the trunk?
Yes.  I think one can easily argue the inconsistent operand numbering is
a diagnostic regression.

jeff
diff mbox series

Patch

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8daa1c67974..71b35252b84 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -10656,16 +10656,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}).
-
-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.
+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.  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:
 
diff --git a/gcc/stmt.c b/gcc/stmt.c
index bd836d8f65f..f52ffaf8e75 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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);
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr98096.c b/gcc/testsuite/gcc.c-torture/compile/pr98096.c
new file mode 100644
index 00000000000..95ad55c81aa
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr98096.c
@@ -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;
+}