linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] output *memory* operands need their address as *input*
@ 2021-02-21 22:28 Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 1/3] asm: add testcase for problem with output addresses Luc Van Oostenryck
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-02-21 22:28 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

These patches fix a problem with the linearization of asm statements
with output memory operands. These operands need to have their address
generated before the asm instruction but was generated after it.

Note: the problem wasn't visible when the address was a symbol
      because the OP_SYMADDR producing the address is simplified
      away at some later stage with the symbol directly handled
      by the memory operation.

Luc Van Oostenryck (3):
  asm: add testcase for problem with output addresses
  asm: factor out add_asm_rule() from add_asm_{in,out}put()
  asm: output *memory* operands need their address as *input*

 linearize.c                  | 54 +++++++++++++++++++++++-------------
 validation/linear/asm-out0.c | 25 +++++++++++++++++
 2 files changed, 60 insertions(+), 19 deletions(-)
 create mode 100644 validation/linear/asm-out0.c


base-commit: 60c1f2706e30eacc29296e6cb5d9327c85a01340
-- 
2.30.0


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

* [PATCH 1/3] asm: add testcase for problem with output addresses
  2021-02-21 22:28 [PATCH 0/3] output *memory* operands need their address as *input* Luc Van Oostenryck
@ 2021-02-21 22:28 ` Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 2/3] asm: factor out add_asm_rule() from add_asm_{in,out}put() Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 3/3] asm: output *memory* operands need their address as *input* Luc Van Oostenryck
  2 siblings, 0 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-02-21 22:28 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

The addresses needed by memory output operands are linearized
(and placed) after the ASM instruction needing them.

So, add a test case for this.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/linear/asm-out0.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 validation/linear/asm-out0.c

diff --git a/validation/linear/asm-out0.c b/validation/linear/asm-out0.c
new file mode 100644
index 000000000000..64d154ed5ad7
--- /dev/null
+++ b/validation/linear/asm-out0.c
@@ -0,0 +1,26 @@
+static void asm_out0(void)
+{
+	int mem;
+	asm volatile ("[%1] <= 0" : "=m" (mem));
+}
+
+/*
+ * check-name: asm-out0
+ * check-command: test-linearize -fdump-ir $file
+ * check-known-to-fail
+ *
+ * check-output-start
+asm_out0:
+.L0:
+	<entry-point>
+	symaddr.64  %r1 <- mem
+	asm         "[%1] <= 0"
+		out: "=m" (%r1)
+	br          .L1
+
+.L1:
+	ret
+
+
+ * check-output-end
+ */
-- 
2.30.0


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

* [PATCH 2/3] asm: factor out add_asm_rule() from add_asm_{in,out}put()
  2021-02-21 22:28 [PATCH 0/3] output *memory* operands need their address as *input* Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 1/3] asm: add testcase for problem with output addresses Luc Van Oostenryck
@ 2021-02-21 22:28 ` Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 3/3] asm: output *memory* operands need their address as *input* Luc Van Oostenryck
  2 siblings, 0 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-02-21 22:28 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

The functions add_asm_input() and add_asm_output() are very similar.
So, factorize out the common part.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/linearize.c b/linearize.c
index 7a6f745fd4fc..6efa47492869 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2127,22 +2127,27 @@ static pseudo_t linearize_range(struct entrypoint *ep, struct statement *stmt)
 ALLOCATOR(asm_rules, "asm rules");
 ALLOCATOR(asm_constraint, "asm constraints");
 
-static void add_asm_input(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
+static void add_asm_rule(struct instruction *insn, struct asm_constraint_list **list, struct asm_operand *op, pseudo_t pseudo)
 {
-	pseudo_t pseudo = linearize_expression(ep, op->expr);
 	struct asm_constraint *rule = __alloc_asm_constraint(0);
-
+	rule->is_memory = op->is_memory;
 	rule->ident = op->name;
 	rule->constraint = op->constraint ? op->constraint->string->data : "";
 	use_pseudo(insn, pseudo, &rule->pseudo);
-	add_ptr_list(&insn->asm_rules->inputs, rule);
+	add_ptr_list(list, rule);
+}
+
+static void add_asm_input(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
+{
+	pseudo_t pseudo = linearize_expression(ep, op->expr);
+
+	add_asm_rule(insn, &insn->asm_rules->inputs, op, pseudo);
 }
 
 static void add_asm_output(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
 {
 	struct access_data ad = { NULL, };
 	pseudo_t pseudo;
-	struct asm_constraint *rule;
 
 	if (op->is_memory) {
 		pseudo = linearize_expression(ep, op->expr);
@@ -2152,12 +2157,8 @@ static void add_asm_output(struct entrypoint *ep, struct instruction *insn, stru
 		pseudo = alloc_pseudo(insn);
 		linearize_store_gen(ep, pseudo, &ad);
 	}
-	rule = __alloc_asm_constraint(0);
-	rule->is_memory = op->is_memory;
-	rule->ident = op->name;
-	rule->constraint = op->constraint ? op->constraint->string->data : "";
-	use_pseudo(insn, pseudo, &rule->pseudo);
-	add_ptr_list(&insn->asm_rules->outputs, rule);
+
+	add_asm_rule(insn, &insn->asm_rules->outputs, op, pseudo);
 }
 
 static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement *stmt)
-- 
2.30.0


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

* [PATCH 3/3] asm: output *memory* operands need their address as *input*
  2021-02-21 22:28 [PATCH 0/3] output *memory* operands need their address as *input* Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 1/3] asm: add testcase for problem with output addresses Luc Van Oostenryck
  2021-02-21 22:28 ` [PATCH 2/3] asm: factor out add_asm_rule() from add_asm_{in,out}put() Luc Van Oostenryck
@ 2021-02-21 22:28 ` Luc Van Oostenryck
  2 siblings, 0 replies; 4+ messages in thread
From: Luc Van Oostenryck @ 2021-02-21 22:28 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

The addresses needed by memory output operands are linearized
(and placed) after the ASM instruction needing them.

So, split add_asm_output() in 2 parts: one generating only the
addresses for memory operands and called before issuing the body,
and another one doing the usual copy of (non-memory) output operands
back into their corresponding variables.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c                  | 31 +++++++++++++++++++++++--------
 validation/linear/asm-out0.c |  1 -
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/linearize.c b/linearize.c
index 6efa47492869..33d641b40de6 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2144,19 +2144,29 @@ static void add_asm_input(struct entrypoint *ep, struct instruction *insn, struc
 	add_asm_rule(insn, &insn->asm_rules->inputs, op, pseudo);
 }
 
+static void add_asm_output_address(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
+{
+	pseudo_t pseudo;
+
+	if (!op->is_memory)
+		return;
+
+	pseudo = linearize_expression(ep, op->expr);
+	add_asm_rule(insn, &insn->asm_rules->outputs, op, pseudo);
+}
+
 static void add_asm_output(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
 {
 	struct access_data ad = { NULL, };
 	pseudo_t pseudo;
 
-	if (op->is_memory) {
-		pseudo = linearize_expression(ep, op->expr);
-	} else {
-		if (!linearize_address_gen(ep, op->expr, &ad))
-			return;
-		pseudo = alloc_pseudo(insn);
-		linearize_store_gen(ep, pseudo, &ad);
-	}
+	if (op->is_memory)
+		return;
+
+	if (!linearize_address_gen(ep, op->expr, &ad))
+		return;
+	pseudo = alloc_pseudo(insn);
+	linearize_store_gen(ep, pseudo, &ad);
 
 	add_asm_rule(insn, &insn->asm_rules->outputs, op, pseudo);
 }
@@ -2184,6 +2194,11 @@ static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement
 		add_asm_input(ep, insn, op);
 	} END_FOR_EACH_PTR(op);
 
+	/* ... and the addresses for memory outputs */
+	FOR_EACH_PTR(stmt->asm_outputs, op) {
+		add_asm_output_address(ep, insn, op);
+	} END_FOR_EACH_PTR(op);
+
 	add_one_insn(ep, insn);
 
 	/* Assign the outputs */
diff --git a/validation/linear/asm-out0.c b/validation/linear/asm-out0.c
index 64d154ed5ad7..a8e0be693d87 100644
--- a/validation/linear/asm-out0.c
+++ b/validation/linear/asm-out0.c
@@ -7,7 +7,6 @@ static void asm_out0(void)
 /*
  * check-name: asm-out0
  * check-command: test-linearize -fdump-ir $file
- * check-known-to-fail
  *
  * check-output-start
 asm_out0:
-- 
2.30.0


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

end of thread, other threads:[~2021-02-21 22:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-21 22:28 [PATCH 0/3] output *memory* operands need their address as *input* Luc Van Oostenryck
2021-02-21 22:28 ` [PATCH 1/3] asm: add testcase for problem with output addresses Luc Van Oostenryck
2021-02-21 22:28 ` [PATCH 2/3] asm: factor out add_asm_rule() from add_asm_{in,out}put() Luc Van Oostenryck
2021-02-21 22:28 ` [PATCH 3/3] asm: output *memory* operands need their address as *input* Luc Van Oostenryck

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 NNTP newsgroup(s).