All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/27] LLVM fixes
@ 2017-03-11  9:06 Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 01/27] give a type to OP_PHISOURCE Luc Van Oostenryck
                   ` (28 more replies)
  0 siblings, 29 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

This series solves a number of issues in sparse-llvm,
mainly about wrong or missing type information as needed
to build LLVM IR.
These issues have been reported and investigated by
Dibyendu Majumdar.

* patches 1-4 adds missing type info in sparse's IR
* patch   4 is not needed by this serie but logically belong
	  to the same group as patches 1-3. It can be dropped.
* patches 5-7 are fixes
* patch	  8 makes debugging easier
* patches 8-10 are preparatory steps for patch 11
* patches 11 & 12 are fixes
* patch   13 is a preparatory step for patch 14
* patch   14 solves a lot of issues
* patches 15-18 are test cases solved by patch 14
* patch   19 & 20 are fixes
* patches 21, 23-27 are cleanups
* patch   22 makes debugging easier
	  

These patches already allow to compile a lot more code to LLVM
but there is still known issues with sparse-llvm:
- it won't work on bitfields
- it won't work on computed gotos
- it won't work on label-as-value
- it won't work on exotic instructions (OP_SPLICE)
- few things are working correctly with floats
  (but this is not specific to sparse-llvm).
There is most probably a bunch of others issues too.

For convenience, this serie is also available at:
  https://github.com/lucvoo/sparse/tree/llvm-fixes-v2


Luc Van Oostenryck (27):
  give a type to OP_PHISOURCE
  give a type to OP_SEL, always
  give a type to OP_SYMADDR
  give a type to PSEUDO_ARGs
  llvm: fix translation of PSEUDO_VALs into a ValueRefs
  llvm: fix output_op_store() which modify its operand
  llvm: fix output_op_[ptr]cast()
  llvm: give a name to call return values
  llvm: add test cases for the type of constants
  add ptr_list_nth_entry()
  llvm: fix type of literal integer passed as arguments
  llvm: fix output OP_ADD mixed with pointers
  llvm: add support for OP_SYMADDR
  keep OP_SYMADDR instructions
  llvm: add test cases for symbol's address
  llvm: add test cases for pointers passed as argument
  llvm: add test cases for arrays passed as argument
  llvm: add test cases for degenerated pointers
  llvm: add support for OP_NEG
  llvm: fix pointer/float mixup in comparisons
  llvm: use pseudo_list_size() instead of open coding it
  llvm: give arguments a name
  llvm: remove unneeded arg 'module'
  llvm: remove unneeded arg 'fn'
  llvm: remove unneeded 'generation'
  llvm: remove unneeded function::type
  llvm: reduce scope of 'bb_nr'

 flow.c                              |   2 +-
 linearize.c                         |  31 +++--
 linearize.h                         |   8 +-
 memops.c                            |   2 +-
 ptrlist.c                           |  18 +++
 ptrlist.h                           |   1 +
 simplify.c                          |   2 +-
 sparse-llvm.c                       | 254 ++++++++++++++++++++++++++----------
 symbol.h                            |   5 +
 validation/backend/degenerate-ptr.c |  72 ++++++++++
 validation/backend/function-ptr.c   | 149 +++++++++++++++++++++
 validation/backend/null.c           |  24 ++++
 validation/backend/pointer-add.c    |  54 ++++++++
 validation/backend/pointer-cmp.c    |   9 ++
 validation/backend/pointer-param.c  |  42 ++++++
 validation/backend/store-x2.c       |  16 +++
 validation/backend/symaddr.c        |  70 ++++++++++
 validation/backend/type-constant.c  |  23 ++++
 validation/symaddr.c                |  35 +++++
 19 files changed, 724 insertions(+), 93 deletions(-)
 create mode 100644 validation/backend/degenerate-ptr.c
 create mode 100644 validation/backend/null.c
 create mode 100644 validation/backend/pointer-add.c
 create mode 100644 validation/backend/pointer-cmp.c
 create mode 100644 validation/backend/pointer-param.c
 create mode 100644 validation/backend/store-x2.c
 create mode 100644 validation/backend/symaddr.c
 create mode 100644 validation/backend/type-constant.c
 create mode 100644 validation/symaddr.c

-- 
2.11.1


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

* [PATCH v2 01/27] give a type to OP_PHISOURCE
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 02/27] give a type to OP_SEL, always Luc Van Oostenryck
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Currently, OP_PHISOURCEs are given a size but not a type.

There is no good reasons for that and it complicates
further correct processing or makes it impossible.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 flow.c      |  2 +-
 linearize.c | 16 +++++++---------
 linearize.h |  2 +-
 memops.c    |  2 +-
 4 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/flow.c b/flow.c
index a5332203f..8111e1ae6 100644
--- a/flow.c
+++ b/flow.c
@@ -370,7 +370,7 @@ found_dominator:
 		if (dominators && phisrc_in_bb(*dominators, parent))
 			continue;
 		br = delete_last_instruction(&parent->insns);
-		phi = alloc_phi(parent, one->target, one->size);
+		phi = alloc_phi(parent, one->target, one->type);
 		phi->ident = phi->ident ? : pseudo->ident;
 		add_instruction(&parent->insns, br);
 		use_pseudo(insn, phi, add_pseudo(dominators, phi));
diff --git a/linearize.c b/linearize.c
index 5199b6b02..3a9c8f2e2 100644
--- a/linearize.c
+++ b/linearize.c
@@ -815,9 +815,9 @@ static pseudo_t argument_pseudo(struct entrypoint *ep, int nr)
 	return pseudo;
 }
 
-pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size)
+pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *type)
 {
-	struct instruction *insn = alloc_instruction(OP_PHISOURCE, size);
+	struct instruction *insn = alloc_typed_instruction(OP_PHISOURCE, type);
 	pseudo_t phi = __alloc_pseudo(0);
 	static int nr = 0;
 
@@ -1350,19 +1350,18 @@ static pseudo_t linearize_short_conditional(struct entrypoint *ep, struct expres
 	struct basic_block *bb_false;
 	struct basic_block *merge = alloc_basic_block(ep, expr->pos);
 	pseudo_t phi1, phi2;
-	int size = type_size(expr->ctype);
 
 	if (!expr_false || !ep->active)
 		return VOID;
 
 	bb_false = alloc_basic_block(ep, expr_false->pos);
 	src1 = linearize_expression(ep, cond);
-	phi1 = alloc_phi(ep->active, src1, size);
+	phi1 = alloc_phi(ep->active, src1, expr->ctype);
 	add_branch(ep, expr, src1, merge, bb_false);
 
 	set_activeblock(ep, bb_false);
 	src2 = linearize_expression(ep, expr_false);
-	phi2 = alloc_phi(ep->active, src2, size);
+	phi2 = alloc_phi(ep->active, src2, expr->ctype);
 	set_activeblock(ep, merge);
 
 	return add_join_conditional(ep, expr, phi1, phi2);
@@ -1376,7 +1375,6 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
 	pseudo_t src1, src2;
 	pseudo_t phi1, phi2;
 	struct basic_block *bb_true, *bb_false, *merge;
-	int size = type_size(expr->ctype);
 
 	if (!cond || !expr_true || !expr_false || !ep->active)
 		return VOID;
@@ -1388,12 +1386,12 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
 
 	set_activeblock(ep, bb_true);
 	src1 = linearize_expression(ep, expr_true);
-	phi1 = alloc_phi(ep->active, src1, size);
+	phi1 = alloc_phi(ep->active, src1, expr->ctype);
 	add_goto(ep, merge); 
 
 	set_activeblock(ep, bb_false);
 	src2 = linearize_expression(ep, expr_false);
-	phi2 = alloc_phi(ep->active, src2, size);
+	phi2 = alloc_phi(ep->active, src2, expr->ctype);
 	set_activeblock(ep, merge);
 
 	return add_join_conditional(ep, expr, phi1, phi2);
@@ -1875,7 +1873,7 @@ static pseudo_t linearize_return(struct entrypoint *ep, struct statement *stmt)
 			phi_node->bb = bb_return;
 			add_instruction(&bb_return->insns, phi_node);
 		}
-		phi = alloc_phi(active, src, type_size(expr->ctype));
+		phi = alloc_phi(active, src, expr->ctype);
 		phi->ident = &return_ident;
 		use_pseudo(phi_node, phi, add_pseudo(&phi_node->phi_list, phi));
 	}
diff --git a/linearize.h b/linearize.h
index bac82d7ff..c03940eea 100644
--- a/linearize.h
+++ b/linearize.h
@@ -331,7 +331,7 @@ struct entrypoint {
 extern void insert_select(struct basic_block *bb, struct instruction *br, struct instruction *phi, pseudo_t if_true, pseudo_t if_false);
 extern void insert_branch(struct basic_block *bb, struct instruction *br, struct basic_block *target);
 
-pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size);
+pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, struct symbol *type);
 pseudo_t alloc_pseudo(struct instruction *def);
 pseudo_t value_pseudo(long long val);
 
diff --git a/memops.c b/memops.c
index 5efdd6f2d..187a63284 100644
--- a/memops.c
+++ b/memops.c
@@ -52,7 +52,7 @@ no_dominance:
 
 found_dominator:
 		br = delete_last_instruction(&parent->insns);
-		phi = alloc_phi(parent, one->target, one->size);
+		phi = alloc_phi(parent, one->target, one->type);
 		phi->ident = phi->ident ? : one->target->ident;
 		add_instruction(&parent->insns, br);
 		use_pseudo(insn, phi, add_pseudo(dominators, phi));
-- 
2.11.1


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

* [PATCH v2 02/27] give a type to OP_SEL, always
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 01/27] give a type to OP_PHISOURCE Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 03/27] give a type to OP_SYMADDR Luc Van Oostenryck
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Currently, when a phi-node is converted into a OP_SEL
this instruction is given a size but not a type but when
created directly it is given a type.

There is no good reasons for that and it complicates
further correct processing or makes it impossible.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linearize.c b/linearize.c
index 3a9c8f2e2..9321cde21 100644
--- a/linearize.c
+++ b/linearize.c
@@ -679,7 +679,7 @@ void insert_select(struct basic_block *bb, struct instruction *br, struct instru
 	/* Remove the 'br' */
 	delete_last_instruction(&bb->insns);
 
-	select = alloc_instruction(OP_SEL, phi_node->size);
+	select = alloc_typed_instruction(OP_SEL, phi_node->type);
 	select->bb = bb;
 
 	assert(br->cond);
-- 
2.11.1


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

* [PATCH v2 03/27] give a type to OP_SYMADDR
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 01/27] give a type to OP_PHISOURCE Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 02/27] give a type to OP_SEL, always Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 04/27] give a type to PSEUDO_ARGs Luc Van Oostenryck
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Currently, OP_SYMADDR are given a size but not a type.

There is no good reasons for that and it complicates
further correct processing or makes it impossible because
we've lost this type information.

Fix this by using alloc_typed_instruction() when creating
OP_SYMADDRs instructions.

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

diff --git a/linearize.c b/linearize.c
index 9321cde21..ea4616f80 100644
--- a/linearize.c
+++ b/linearize.c
@@ -982,9 +982,10 @@ static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct e
 	return target;
 }
 
-static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *sym)
+static pseudo_t add_symbol_address(struct entrypoint *ep, struct expression *expr)
 {
-	struct instruction *insn = alloc_instruction(OP_SYMADDR, bits_in_pointer);
+	struct instruction *insn = alloc_typed_instruction(OP_SYMADDR, expr->ctype);
+	struct symbol *sym = expr->symbol;
 	pseudo_t target = alloc_pseudo(insn);
 
 	insn->target = target;
@@ -1552,7 +1553,7 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
 	switch (expr->type) {
 	case EXPR_SYMBOL:
 		linearize_one_symbol(ep, expr->symbol);
-		return add_symbol_address(ep, expr->symbol);
+		return add_symbol_address(ep, expr);
 
 	case EXPR_VALUE:
 		return value_pseudo(expr->value);
-- 
2.11.1


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

* [PATCH v2 04/27] give a type to PSEUDO_ARGs
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 03/27] give a type to OP_SYMADDR Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 05/27] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Currently, PSEUDO_ARGs are created as if being produce/defined
by the OP_ENTRY instruction.

While there is certainly some logics behind it, it's also not
much useful. Worse, the others pseudo which define the 'def'
member (PSEUDO_REG) often use it to get the type corresponding
to the pseudo with 'pseudo->def->type'. Of course, the OP_ENTRY
can't be used so.

Furthermore, when the type (or the size) of an argument we need
to retrieve this information from the function prototype while
this info could already be given to the pseudo at its creation.

Fix this by using the 'sym' field of PSEUDO_ARG to store the
argument's type (and now the 'def' field become meaningless).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c | 6 +++---
 linearize.h | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/linearize.c b/linearize.c
index ea4616f80..255231c60 100644
--- a/linearize.c
+++ b/linearize.c
@@ -801,14 +801,14 @@ pseudo_t value_pseudo(long long val)
 	return pseudo;
 }
 
-static pseudo_t argument_pseudo(struct entrypoint *ep, int nr)
+static pseudo_t argument_pseudo(struct entrypoint *ep, int nr, struct symbol *arg)
 {
 	pseudo_t pseudo = __alloc_pseudo(0);
 	struct instruction *entry = ep->entry;
 
 	pseudo->type = PSEUDO_ARG;
 	pseudo->nr = nr;
-	pseudo->def = entry;
+	pseudo->sym = arg;
 	add_pseudo(&entry->arg_list, pseudo);
 
 	/* Argument pseudos have neither usage nor def */
@@ -1540,7 +1540,7 @@ static void linearize_argument(struct entrypoint *ep, struct symbol *arg, int nr
 	ad.source_type = arg;
 	ad.result_type = arg;
 	ad.address = symbol_pseudo(ep, arg);
-	linearize_store_gen(ep, argument_pseudo(ep, nr), &ad);
+	linearize_store_gen(ep, argument_pseudo(ep, nr, arg), &ad);
 	finish_address_gen(ep, &ad);
 }
 
diff --git a/linearize.h b/linearize.h
index c03940eea..9d192f7aa 100644
--- a/linearize.h
+++ b/linearize.h
@@ -34,9 +34,9 @@ struct pseudo {
 	struct pseudo_user_list *users;
 	struct ident *ident;
 	union {
-		struct symbol *sym;
-		struct instruction *def;
-		long long value;
+		struct symbol *sym;	// PSEUDO_SYM & ARG
+		struct instruction *def;// PSEUDO_REG & PHI
+		long long value;	// PSEUDO_VAL
 	};
 	void *priv;
 };
-- 
2.11.1


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

* [PATCH v2 05/27] llvm: fix translation of PSEUDO_VALs into a ValueRefs
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (3 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 04/27] give a type to PSEUDO_ARGs Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 06/27] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

In sparse-llvm there is the assumption that a PSEUDO_VAL is always
of integer type. But this is not always the case: constant pointers,
like NULL, are also of the PSEUDO_VAL kind.

Fix this by adding a helper 'val_to_value()' and using the
instruction's type where this pseudo is used as the type of the value.

Note: while this patch improve the situation, like for example for the
test cases added here, it's still not correct because now we're making
the assumption that 'insn->type' is the type we need for the pseudo.
This is often true, but certainly not always.
For example this is not true for:
- OP_STORE/OP_LOAD's insn->src
- OP_SET{EQ,...}'s   insn->src[12]
- probably some  others ones
- in general, obviously, for any instructions where the target has
  a different type than the operands.

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c             | 26 +++++++++++++++++++++++++-
 validation/backend/null.c | 24 ++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 validation/backend/null.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 9f362b3ed..d48b3b20a 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -303,6 +303,30 @@ static void pseudo_name(pseudo_t pseudo, char *buf)
 	}
 }
 
+static LLVMValueRef val_to_value(struct function *fn, unsigned long long val, struct symbol *ctype)
+{
+	LLVMTypeRef dtype;
+	LLVMTypeRef itype;
+	LLVMValueRef result;
+
+	assert(ctype);
+	dtype = symbol_type(fn->module, ctype);
+	switch (LLVMGetTypeKind(dtype)) {
+	case LLVMPointerTypeKind:
+		itype = LLVMIntType(bits_in_pointer);
+		result = LLVMConstInt(itype, val, 1);
+		result = LLVMConstIntToPtr(result, dtype);
+		break;
+	case LLVMIntegerTypeKind:
+		result = LLVMConstInt(dtype, val, 1);
+		break;
+	default:
+		assert(0);
+	}
+
+	return result;
+}
+
 static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
 {
 	LLVMValueRef result = NULL;
@@ -360,7 +384,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 		break;
 	}
 	case PSEUDO_VAL:
-		result = LLVMConstInt(insn_symbol_type(fn->module, insn), pseudo->value, 1);
+		result = val_to_value(fn, pseudo->value, insn->type);
 		break;
 	case PSEUDO_ARG: {
 		result = LLVMGetParam(fn->fn, pseudo->nr - 1);
diff --git a/validation/backend/null.c b/validation/backend/null.c
new file mode 100644
index 000000000..5c595c70b
--- /dev/null
+++ b/validation/backend/null.c
@@ -0,0 +1,24 @@
+extern int *ip[];
+
+void foo(void);
+void foo(void)
+{
+	ip[0] = (void *)0L;
+	ip[1] = (int *)0L;
+	ip[2] = (void *)0;
+	ip[3] = (int *)0;
+	ip[4] = (void *)(long)0;
+	ip[5] = (int *)(long)0;
+	ip[6] = (void *)123;
+	ip[7] = (int *)123;
+	ip[8] = (void *)123L;
+	ip[9] = (int *)123L;
+	ip[10] = (void *)(long)123;
+	ip[11] = (int *)(long)123;
+}
+
+/*
+ * check-name: store constants to pointer
+ * check-command: sparse-llvm $file
+ * check-output-ignore
+ */
-- 
2.11.1


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

* [PATCH v2 06/27] llvm: fix output_op_store() which modify its operand
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (4 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 05/27] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 07/27] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

In sparse-llvm the field 'priv' of a pseudo is used to store
the corresponding LLVMValueRef. This field is normaly assigned
when processing the instruction that produces the speudo.

In output_op_store(), the field insn->target->priv is overwritten
by the LLVMValueRef returned by LLVMBuildStore().
It's unclear what this return value is:
- this corrupts the pseudo, making it unusable in subsequent
  instructions.
- there is no reason to change this field anyway.

Fix this by removing the assignment to insn->target->priv
in output_op_store().

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                 |  6 ++----
 validation/backend/store-x2.c | 16 ++++++++++++++++
 2 files changed, 18 insertions(+), 4 deletions(-)
 create mode 100644 validation/backend/store-x2.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index d48b3b20a..665b6c7dc 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -646,16 +646,14 @@ static void output_op_load(struct function *fn, struct instruction *insn)
 
 static void output_op_store(struct function *fn, struct instruction *insn)
 {
-	LLVMValueRef addr, target, target_in;
+	LLVMValueRef addr, target_in;
 
 	addr = calc_memop_addr(fn, insn);
 
 	target_in = pseudo_to_value(fn, insn, insn->target);
 
 	/* perform store */
-	target = LLVMBuildStore(fn->builder, target_in, addr);
-
-	insn->target->priv = target;
+	LLVMBuildStore(fn->builder, target_in, addr);
 }
 
 static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
diff --git a/validation/backend/store-x2.c b/validation/backend/store-x2.c
new file mode 100644
index 000000000..5ccc9b43a
--- /dev/null
+++ b/validation/backend/store-x2.c
@@ -0,0 +1,16 @@
+void foo(int *p, int a, int b);
+void foo(int *p, int a, int b)
+{
+	int c = a + b;
+
+	p[0] = c;
+	p[1] = c;
+}
+
+/*
+ * check-name: store-x2
+ * check-command: sparsec -c $file -o tmp.o
+ * check-description: Verify in output_op_store() that
+ *	the first store doesn't mess anymore with the
+ *	'target' and thus making the second store unusable.
+ */
-- 
2.11.1


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

* [PATCH v2 07/27] llvm: fix output_op_[ptr]cast()
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (5 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 06/27] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 08/27] llvm: give a name to call return values Luc Van Oostenryck
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

OP_PTRCASTs can't always be directly translated into LLVM bitcasts and
OP_[S]CASTs can't always be translated into LLVM's trunc/sext/zext
because integer to pointer and pointer to integer must be handled too.

Fix this in output_op_ptrcast() & output_op_cast() by issuing
LLVMBuildIntToPtr/PtrToInt when appropriate.

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 665b6c7dc..c593f831f 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -787,6 +787,8 @@ static void output_op_phi(struct function *fn, struct instruction *insn)
 static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 {
 	LLVMValueRef src, target;
+	LLVMTypeRef dtype;
+	LLVMOpcode op;
 	char target_name[64];
 
 	src = insn->src->priv;
@@ -797,15 +799,31 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 
 	assert(!symbol_is_fp_type(insn->type));
 
-	target = LLVMBuildBitCast(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
+	dtype = insn_symbol_type(fn->module, insn);
+	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
+	case LLVMPointerTypeKind:
+		op = LLVMBitCast;
+		break;
+	case LLVMIntegerTypeKind:
+		op = LLVMIntToPtr;
+		break;
+	default:
+		assert(0);
+	}
 
+	target = LLVMBuildCast(fn->builder, op, src, dtype, target_name);
 	insn->target->priv = target;
 }
 
 static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOpcode op)
 {
 	LLVMValueRef src, target;
+	LLVMTypeRef dtype;
 	char target_name[64];
+	unsigned int width;
+
+	if (is_ptr_type(insn->type))
+		return output_op_ptrcast(fn, insn);
 
 	src = insn->src->priv;
 	if (!src)
@@ -815,11 +833,23 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 
 	assert(!symbol_is_fp_type(insn->type));
 
-	if (insn->size < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
-		target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
-	else
-		target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(fn->module, insn), target_name);
+	dtype = insn_symbol_type(fn->module, insn);
+	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
+	case LLVMPointerTypeKind:
+		op = LLVMPtrToInt;
+		break;
+	case LLVMIntegerTypeKind:
+		width = LLVMGetIntTypeWidth(LLVMTypeOf(src));
+		if (insn->size < width)
+			op = LLVMTrunc;
+		else if (insn->size == width)
+			op = LLVMBitCast;
+		break;
+	default:
+		assert(0);
+	}
 
+	target = LLVMBuildCast(fn->builder, op, src, dtype, target_name);
 	insn->target->priv = target;
 }
 
-- 
2.11.1


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

* [PATCH v2 08/27] llvm: give a name to call return values
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (6 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 07/27] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 09/27] llvm: add test cases for the type of constants Luc Van Oostenryck
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Currently, a name is given to the result of instruction like
binops, compares, ... but not to function calls.

Functionally, it doesn't change anything but those names are
useful by easing reading while debugging, reading the generated
code, ...

Fix this by giving a name to OP_CALL's result too.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index c593f831f..c143cfb28 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -298,6 +298,9 @@ static void pseudo_name(pseudo_t pseudo, char *buf)
 	case PSEUDO_PHI:
 		snprintf(buf, MAX_PSEUDO_NAME, "PHI%d", pseudo->nr);
 		break;
+	case PSEUDO_VOID:
+		buf[0] = '\0';
+		break;
 	default:
 		assert(0);
 	}
@@ -731,6 +734,8 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 	int n_arg = 0, i;
 	struct pseudo *arg;
 	LLVMValueRef *args;
+	char name[64];
+
 
 	FOR_EACH_PTR(insn->arguments, arg) {
 		n_arg++;
@@ -744,7 +749,8 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 	} END_FOR_EACH_PTR(arg);
 
 	func = pseudo_to_value(fn, insn, insn->func);
-	target = LLVMBuildCall(fn->builder, func, args, n_arg, "");
+	pseudo_name(insn->target, name);
+	target = LLVMBuildCall(fn->builder, func, args, n_arg, name);
 
 	insn->target->priv = target;
 }
-- 
2.11.1


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

* [PATCH v2 09/27] llvm: add test cases for the type of constants
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (7 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 08/27] llvm: give a name to call return values Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 10/27] add ptr_list_nth_entry() Luc Van Oostenryck
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/backend/type-constant.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 validation/backend/type-constant.c

diff --git a/validation/backend/type-constant.c b/validation/backend/type-constant.c
new file mode 100644
index 000000000..cded7f2ea
--- /dev/null
+++ b/validation/backend/type-constant.c
@@ -0,0 +1,23 @@
+char creti(void) { return 3; }
+int  ireti(void) { return 3; }
+long lreti(void) { return 3; }
+
+char cinii(void) { char r = 3; return r; }
+int  iinii(void) { int  r = 3; return r; }
+long linii(void) { long r = 3; return r; }
+
+
+void *vretn(void) { return (void*)0; }
+char *cretn(void) { return (void*)0; }
+int  *iretn(void) { return (void*)0; }
+long *lretn(void) { return (void*)0; }
+
+void *vinin(void) { void *r = (void*)0; return r; }
+char *cinin(void) { char *r = (void*)0; return r; }
+int  *iinin(void) { int  *r = (void*)0; return r; }
+long *linin(void) { long *r = (void*)0; return r; }
+
+/*
+ * check-name: type-constant
+ * check-command: ./sparsec -Wno-decl -c $file -o r.o
+ */
-- 
2.11.1


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

* [PATCH v2 10/27] add ptr_list_nth_entry()
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (8 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 09/27] llvm: add test cases for the type of constants Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 11/27] llvm: fix type of literal integer passed as arguments Luc Van Oostenryck
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Usually ptr lists are accessed iteratively via the FOR/END macros
but in few case we may need to access a given element in a list,
like for example when accessing a given argument of a function.

Create an helper doing that instead of open coding it.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 ptrlist.c | 18 ++++++++++++++++++
 ptrlist.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/ptrlist.c b/ptrlist.c
index 5dc1117c5..29aafac7d 100644
--- a/ptrlist.c
+++ b/ptrlist.c
@@ -246,3 +246,21 @@ void __free_ptr_list(struct ptr_list **listp)
 
 	*listp = NULL;
 }
+
+void *ptr_list_nth_entry(struct ptr_list *list, unsigned int idx)
+{
+	struct ptr_list *head = list;
+
+	if (!head)
+		return NULL;
+
+	do {
+		unsigned int nr = list->nr;
+
+		if (idx < nr)
+			return list->list[idx];
+		else
+			idx -= nr;
+	} while ((list = list->next) != head);
+	return NULL;
+}
diff --git a/ptrlist.h b/ptrlist.h
index d09be2f51..bf171f89f 100644
--- a/ptrlist.h
+++ b/ptrlist.h
@@ -44,6 +44,7 @@ extern void concat_ptr_list(struct ptr_list *a, struct ptr_list **b);
 extern void __free_ptr_list(struct ptr_list **);
 extern int ptr_list_size(struct ptr_list *);
 extern int linearize_ptr_list(struct ptr_list *, void **, int);
+extern void *ptr_list_nth_entry(struct ptr_list *, unsigned int idx);
 
 /*
  * Hey, who said that you can't do overloading in C?
-- 
2.11.1


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

* [PATCH v2 11/27] llvm: fix type of literal integer passed as arguments
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (9 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 10/27] add ptr_list_nth_entry() Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 12/27] llvm: fix output OP_ADD mixed with pointers Luc Van Oostenryck
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Like for all others instructions, LLVM needs the type
of each operands. However this information is not always
available via the pseudo. An example of such situation
is when passing a integer constant as argument since,
for sparse, constants are typeless.

Fix this by getting the type via the function prototype.
Two cases need to be handled:
- normal function call (prototype easiy acccessible).
- call via function pointer (a bit more complex).

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                     |  22 +++++-
 symbol.h                          |   5 ++
 validation/backend/function-ptr.c | 137 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index c143cfb28..5ea0e5229 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -728,6 +728,14 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 	insn->target->priv = target;
 }
 
+static struct symbol *get_function_basetype(struct symbol *type)
+{
+	if (type->type == SYM_PTR)
+		type = type->ctype.base_type;
+	assert(type->type == SYM_FN);
+	return type;
+}
+
 static void output_op_call(struct function *fn, struct instruction *insn)
 {
 	LLVMValueRef target, func;
@@ -745,7 +753,19 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 
 	i = 0;
 	FOR_EACH_PTR(insn->arguments, arg) {
-		args[i++] = pseudo_to_value(fn, insn, arg);
+		struct symbol *ftype = get_function_basetype(insn->fntype);
+		LLVMValueRef value;
+		if (arg->type == PSEUDO_VAL) {
+			struct symbol *atype;
+
+			atype = get_nth_symbol(ftype->arguments, i);
+			/* Value pseudos do not have type information. */
+			/* Use the function prototype to get the type. */
+			value = val_to_value(fn, arg->value, atype);
+		} else {
+			value = pseudo_to_value(fn, insn, arg);
+		}
+		args[i++] = value;
 	} END_FOR_EACH_PTR(arg);
 
 	func = pseudo_to_value(fn, insn, insn->func);
diff --git a/symbol.h b/symbol.h
index 36f8345b5..5823cd621 100644
--- a/symbol.h
+++ b/symbol.h
@@ -416,6 +416,11 @@ static inline int get_sym_type(struct symbol *type)
 	return type->type;
 }
 
+static inline struct symbol *get_nth_symbol(struct symbol_list *list, unsigned int idx)
+{
+	return ptr_list_nth_entry((struct ptr_list *)list, idx);
+}
+
 static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace ns)
 {
 	if (!ident->keyword)
diff --git a/validation/backend/function-ptr.c b/validation/backend/function-ptr.c
index fc022b3cd..e035fe958 100644
--- a/validation/backend/function-ptr.c
+++ b/validation/backend/function-ptr.c
@@ -5,6 +5,143 @@ static int run(fn_t fn, int x, int y)
 	return fn(x, y);
 }
 
+extern int ival;
+extern int *ipval;
+extern int array[3];
+extern int matrix[3][3];
+extern int fun(int);
+
+// via an argument
+void arg(int a, int *p, int (*fb)(unsigned char), int (*fi)(int), int (*fl)(long), int (*fv)(void), int (*fip)(int *), int (*fim)(int (*)[3]), int (*fvp)(void *), int (*ffp)(int (*)(int)));
+void arg(int a, int *p, int (*fb)(unsigned char), int (*fi)(int), int (*fl)(long), int (*fv)(void), int (*fip)(int *), int (*fim)(int (*)[3]), int (*fvp)(void *), int (*ffp)(int (*)(int)))
+{
+	fv();
+
+	fb(a);
+	fi(a);
+	fl(a);
+	fb(123);
+	fi(123);
+	fl(123);
+	fb(123L);
+	fi(123L);
+	fl(123L);
+	fb(ival);
+	fi(ival);
+	fl(ival);
+
+	fip(p);
+	fip((void*)0);
+	fip(ipval);
+	fip(&ival);
+
+	fvp(p);
+	fvp((void*)0);
+	fvp(ipval);
+	fvp(&ival);
+
+	fvp(fun);
+	fvp(&fun);
+	ffp(fun);
+	ffp(&fun);
+}
+
+// a global
+extern int (*fb)(unsigned char);
+extern int (*fi)(int);
+extern int (*fl)(long);
+extern int (*fv)(void);
+extern int (*fip)(int *);
+extern int (*fim)(int (*)[3]);
+extern int (*fvp)(void *);
+extern int (*ffp)(int (*)(int));
+
+void glb(int a, int *p);
+void glb(int a, int *p)
+{
+	fv();
+
+	fb(a);
+	fi(a);
+	fl(a);
+	fb(123);
+	fi(123);
+	fl(123);
+	fb(123L);
+	fi(123L);
+	fl(123L);
+	fb(ival);
+	fi(ival);
+	fl(ival);
+
+	fip(p);
+	fip((void*)0);
+	fip(ipval);
+	fip(&ival);
+
+	fvp(p);
+	fvp((void*)0);
+	fvp(ipval);
+	fvp(&ival);
+
+	fvp(fun);
+	fvp(&fun);
+	ffp(fun);
+	ffp(&fun);
+}
+
+// via a struct member:
+// -> force to create a register containing the function pointer
+struct ops {
+	int (*fb)(unsigned char);
+	int (*fi)(int);
+	int (*fl)(long);
+	int (*fv)(void);
+	int (*fip)(int *);
+	int (*fim)(int (*)[3]);
+	int (*fvp)(void *);
+	int (*ffp)(int (*)(int));
+
+	int (*const cfi)(int);		// for the fun of it
+};
+
+void ops(int a, int *p, struct ops *ops);
+void ops(int a, int *p, struct ops *ops)
+{
+	ops->fv();
+
+	ops->fb(a);
+	ops->fi(a);
+	ops->fl(a);
+	ops->fb(123);
+	ops->fi(123);
+	ops->fl(123);
+	ops->fb(123L);
+	ops->fi(123L);
+	ops->fl(123L);
+	ops->fb(ival);
+	ops->fi(ival);
+	ops->fl(ival);
+
+	ops->fip(p);
+	ops->fip((void*)0);
+	ops->fip(ipval);
+	ops->fip(&ival);
+
+	ops->fvp(p);
+	ops->fvp((void*)0);
+	ops->fvp(ipval);
+	ops->fvp(&ival);
+
+	ops->fvp(fun);
+	ops->fvp(&fun);
+	ops->ffp(fun);
+	ops->ffp(&fun);
+	ops->fvp(fi);
+
+	ops->cfi(42);
+}
+
 /*
  * check-name: Function pointer code generation
  * check-command: ./sparsec -c $file -o tmp.o
-- 
2.11.1


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

* [PATCH v2 12/27] llvm: fix output OP_ADD mixed with pointers
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (10 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 11/27] llvm: fix type of literal integer passed as arguments Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 13/27] llvm: add support for OP_SYMADDR Luc Van Oostenryck
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

In sparse, pointer arithmetic and accessing the field
of a structure or an array is simply done via OP_ADD,
the offset being calculated at evaluation time.
On the other hand, LLVM allows addition only on two
integers and pointer arithmetic/member access must be
done either via 'getelementptr' or the pointer must be
casted to and for an integer.

sparse-llvm didn't took this in account which resulted
in type error in 'add' instructions.

Fix this by catching addition involving pointer and
the already existing helper calc_gep() for these.

Originally-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                    |  4 +++
 validation/backend/pointer-add.c | 54 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 validation/backend/pointer-add.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 5ea0e5229..e3c8cafed 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -475,6 +475,10 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 	case OP_ADD:
 		if (symbol_is_fp_type(insn->type))
 			target = LLVMBuildFAdd(fn->builder, lhs, rhs, target_name);
+		else if (LLVMGetTypeKind(LLVMTypeOf(lhs)) == LLVMPointerTypeKind)
+			target = calc_gep(fn->builder, lhs, rhs);
+		else if (LLVMGetTypeKind(LLVMTypeOf(rhs)) == LLVMPointerTypeKind)
+			target = calc_gep(fn->builder, rhs, lhs);
 		else
 			target = LLVMBuildAdd(fn->builder, lhs, rhs, target_name);
 		break;
diff --git a/validation/backend/pointer-add.c b/validation/backend/pointer-add.c
new file mode 100644
index 000000000..f92c892b8
--- /dev/null
+++ b/validation/backend/pointer-add.c
@@ -0,0 +1,54 @@
+char *caddv(char *p, int o) { char *r = p; r = r + o; return r; }
+void *vaddv(void *p, int o) { void *r = p; r = r + o; return r; }
+int  *iaddv(int  *p, int o) { int  *r = p; r = r + o; return r; }
+
+char *caddc(char *p, int o) { char *r = p; r = r + 3; return r; }
+void *vaddc(void *p, int o) { void *r = p; r = r + 3; return r; }
+int  *iaddc(int  *p, int o) { int  *r = p; r = r + 3; return r; }
+
+char *cincv(char *p, int o) { char *r = p; r += o; return r; }
+void *vincv(void *p, int o) { void *r = p; r += o; return r; }
+int  *iincv(int  *p, int o) { int  *r = p; r += o; return r; }
+
+char *cincc(char *p, int o) { char *r = p; r += 3; return r; }
+void *vincc(void *p, int o) { void *r = p; r += 3; return r; }
+int  *iincc(int  *p, int o) { int  *r = p; r += 3; return r; }
+
+
+char *ciniaddv(char *p, int o) { char *r = p + o; return r; }
+void *viniaddv(void *p, int o) { void *r = p + o; return r; }
+int  *iiniaddv(int  *p, int o) { int  *r = p + o; return r; }
+
+char *ciniaddc(char *p, int o) { char *r = p + 3; return r; }
+void *viniaddc(void *p, int o) { void *r = p + 3; return r; }
+int  *iiniaddc(int  *p, int o) { int  *r = p + 3; return r; }
+
+char *ciniincv(char *p, int o) { char *r = p += o; return r; }
+void *viniincv(void *p, int o) { void *r = p += o; return r; }
+int  *iiniincv(int  *p, int o) { int  *r = p += o; return r; }
+
+char *ciniincc(char *p, int o) { char *r = p += 3; return r; }
+void *viniincc(void *p, int o) { void *r = p += 3; return r; }
+int  *iiniincc(int  *p, int o) { int  *r = p += 3; return r; }
+
+
+char *cretaddv(char *p, int o) { return p + o; }
+void *vretaddv(void *p, int o) { return p + o; }
+int  *iretaddv(int  *p, int o) { return p + o; }
+
+char *cretaddc(char *p, int o) { return p + 3; }
+void *vretaddc(void *p, int o) { return p + 3; }
+int  *iretaddc(int  *p, int o) { return p + 3; }
+
+char *cretincv(char *p, int o) { return p += o; }
+void *vretincv(void *p, int o) { return p += o; }
+int  *iretincv(int  *p, int o) { return p += o; }
+
+char *cretincc(char *p, int o) { return p += 3; }
+void *vretincc(void *p, int o) { return p += 3; }
+int  *iretincc(int  *p, int o) { return p += 3; }
+
+/*
+ * check-name: pointer-add
+ * check-command: ./sparsec -Wno-decl -c $file -o r.o
+ */
-- 
2.11.1


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

* [PATCH v2 13/27] llvm: add support for OP_SYMADDR
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (11 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 12/27] llvm: fix output OP_ADD mixed with pointers Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 14/27] keep OP_SYMADDR instructions Luc Van Oostenryck
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

sparse-llvm don't yet support OP_SYMADDR instructions.

Fix this by add the needed support for it.

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index e3c8cafed..a3606a86e 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -895,9 +895,18 @@ static void output_insn(struct function *fn, struct instruction *insn)
 	case OP_CBR:
 		output_op_cbr(fn, insn);
 		break;
-	case OP_SYMADDR:
-		assert(0);
+	case OP_SYMADDR: {
+		LLVMValueRef res, src;
+		LLVMTypeRef dtype;
+		char name[64];
+
+		src = pseudo_to_value(fn, insn, insn->symbol);
+		dtype = symbol_type(fn->module, insn->type);
+		pseudo_name(insn->target, name);
+		res = LLVMBuildBitCast(fn->builder, src, dtype, name);
+		insn->target->priv = res;
 		break;
+	}
 	case OP_SETVAL:
 		assert(0);
 		break;
-- 
2.11.1


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

* [PATCH v2 14/27] keep OP_SYMADDR instructions
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (12 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 13/27] llvm: add support for OP_SYMADDR Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 15/27] llvm: add test cases for symbol's address Luc Van Oostenryck
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

OP_SYMADDR instructions are systematically eliminated during
simplification phase, their target address being simply replaced
by the symbol itself.

While it's not wrong per se (as it all depends to the semantic
we want to give to pseudos and the instructions and how high-
or low-level we want the IR to be), it's not clear if this
simplification was really intentional and don't seems to have
any advantages.

OP_SYMADDRs allow to make a clear separation between a symbol
(a name with a type and info for storage & linkage) and its address
(which can be stored in memory or in a register and on which
arithmetic operations can then be done on it). Once these addresses
are replaced by the symbol itself, those symbols can appears almost
everywhere in the linearized code:
- in calls' arguments,
- in adds and subs (while doing pointer arithmetic),
- in casts,
- in load & stores,
- ...
and they complicate things considerably once you begin to be
interested concretly in things after linearization & simplification
since soon or later you will need the address anyway.

Change this by removing the 'simplification' of OP_SYMADDR.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 simplify.c           |  2 +-
 validation/symaddr.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 validation/symaddr.c

diff --git a/simplify.c b/simplify.c
index 5d00937f1..a84e4787f 100644
--- a/simplify.c
+++ b/simplify.c
@@ -1159,7 +1159,7 @@ int simplify_instruction(struct instruction *insn)
 	case OP_SYMADDR:
 		if (dead_insn(insn, NULL, NULL, NULL))
 			return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
-		return replace_with_pseudo(insn, insn->symbol);
+		return 0;
 	case OP_CAST:
 	case OP_SCAST:
 	case OP_FPCAST:
diff --git a/validation/symaddr.c b/validation/symaddr.c
new file mode 100644
index 000000000..4fe776c21
--- /dev/null
+++ b/validation/symaddr.c
@@ -0,0 +1,35 @@
+int g;
+int a[3];
+int b[3];
+
+void usep(int*);
+
+int foo(void)
+{
+	int r = 0;
+	usep(&g);
+	usep(a);
+	usep(b + 1);
+	return r;
+}
+
+/*
+ * check-name: symaddr
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+foo:
+.L0:
+	<entry-point>
+	symaddr.64  %r1 <- g
+	call        usep, %r1
+	symaddr.64  %r2 <- a
+	call        usep, %r2
+	symaddr.64  %r3 <- b
+	add.64      %r4 <- %r3, $4
+	call        usep, %r4
+	ret.32      $0
+
+
+ * check-output-end
+ */
-- 
2.11.1


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

* [PATCH v2 15/27] llvm: add test cases for symbol's address
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (13 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 14/27] keep OP_SYMADDR instructions Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 16/27] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

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

diff --git a/validation/backend/symaddr.c b/validation/backend/symaddr.c
new file mode 100644
index 000000000..71fb9deff
--- /dev/null
+++ b/validation/backend/symaddr.c
@@ -0,0 +1,70 @@
+extern void useip(int *);
+extern void useia(int (*)[3]);
+extern void usevp(void *);
+static int  sfun(void) { return 0; }
+static int  spun(void) { return 0; }
+
+void lfoo(int *p, int a)
+{
+	int larra[3], larrb[3], larrc[3], larrd[3], larre[3], larrf[3];
+	useip(p);
+	useip(larra);
+	useip(larrb + 1);
+	useip(larrc + a);
+	useip(&larrd[1]);
+	useip(&larre[a]);
+	useia(&larrf);
+}
+
+static int sarra[3], sarrb[3], sarrc[3], sarrd[3], sarre[3], sarrf[3];
+static int s, sfun(void), spun(void);
+void sfoo(int *p, int a)
+{
+	useip(p);
+	useip(&s);
+	useip(sarra);
+	useip(sarrb + 1);
+	useip(sarrc + a);
+	useip(&sarrd[1]);
+	useip(&sarre[a]);
+	useia(&sarrf);
+	usevp(sfun);
+	usevp(&spun);
+}
+
+extern int xarra[3], xarrb[3], xarrc[3], xarrd[3], xarre[3], xarrf[3];
+extern int x, xfun(void), xpun(void);
+void xfoo(int *p, int a)
+{
+	useip(p);
+	useip(&x);
+	useip(xarra);
+	useip(xarrb + 1);
+	useip(xarrc + a);
+	useip(&xarrd[1]);
+	useip(&xarre[a]);
+	useia(&xarrf);
+	usevp(xfun);
+	usevp(&xpun);
+}
+
+int garra[3], garrb[3], garrc[3], garrd[3], garre[3], garrf[3];
+int g, gfun(void), gpun(void);
+void gfoo(int *p, int a)
+{
+	useip(p);
+	useip(&g);
+	useip(garra);
+	useip(garrb + 1);
+	useip(garrc + a);
+	useip(&garrd[1]);
+	useip(&garre[a]);
+	useia(&garrf);
+	usevp(gfun);
+	usevp(&gpun);
+}
+
+/*
+ * check-name: symbol address
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
-- 
2.11.1


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

* [PATCH v2 16/27] llvm: add test cases for pointers passed as argument
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (14 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 15/27] llvm: add test cases for symbol's address Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 17/27] llvm: add test cases for arrays " Luc Van Oostenryck
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/backend/pointer-param.c | 42 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 validation/backend/pointer-param.c

diff --git a/validation/backend/pointer-param.c b/validation/backend/pointer-param.c
new file mode 100644
index 000000000..b705e6f4d
--- /dev/null
+++ b/validation/backend/pointer-param.c
@@ -0,0 +1,42 @@
+extern int gfun(int);
+static int sfun(int a) { return a; }
+
+void usei(int *);
+void usef(int (*)(int));
+void usev(void *);
+
+void foo(int *p, int a[5], int (*pfun)(int));
+void foo(int *p, int a[5], int (*pfun)(int))
+{
+	extern int valg[5], valh[5], vali[5];
+	static int vals[5], valt[5], valr[5];
+	       int vala[5], valb[5], valc[5];
+
+	usei(p);
+	usei(valg);
+	usei(&valh[0]);
+	usei(&vali[1]);
+	usei(vals);
+	usei(&valt[0]);
+	usei(&valr[1]);
+	usei(vala);
+	usei(&valb[0]);
+	usei(&valc[1]);
+
+	usef(pfun);
+	usef(gfun);
+	usef(&gfun);
+	usef(sfun);
+	usef(&sfun);
+
+	usev(pfun);
+	usev(gfun);
+	usev(&gfun);
+	usev(sfun);
+	usev(&sfun);
+}
+
+/*
+ * check-name: pointer-param
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
-- 
2.11.1


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

* [PATCH v2 17/27] llvm: add test cases for arrays passed as argument
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (15 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 16/27] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 18/27] llvm: add test cases for degenerated pointers Luc Van Oostenryck
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/backend/function-ptr.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/validation/backend/function-ptr.c b/validation/backend/function-ptr.c
index e035fe958..e44352312 100644
--- a/validation/backend/function-ptr.c
+++ b/validation/backend/function-ptr.c
@@ -34,11 +34,15 @@ void arg(int a, int *p, int (*fb)(unsigned char), int (*fi)(int), int (*fl)(long
 	fip((void*)0);
 	fip(ipval);
 	fip(&ival);
+	fip(array);
+	fim(matrix);
 
 	fvp(p);
 	fvp((void*)0);
 	fvp(ipval);
 	fvp(&ival);
+	fvp(array);
+	fvp(matrix);
 
 	fvp(fun);
 	fvp(&fun);
@@ -78,11 +82,15 @@ void glb(int a, int *p)
 	fip((void*)0);
 	fip(ipval);
 	fip(&ival);
+	fip(array);
+	fim(matrix);
 
 	fvp(p);
 	fvp((void*)0);
 	fvp(ipval);
 	fvp(&ival);
+	fvp(array);
+	fvp(matrix);
 
 	fvp(fun);
 	fvp(&fun);
@@ -127,11 +135,15 @@ void ops(int a, int *p, struct ops *ops)
 	ops->fip((void*)0);
 	ops->fip(ipval);
 	ops->fip(&ival);
+	ops->fip(array);
+	ops->fim(matrix);
 
 	ops->fvp(p);
 	ops->fvp((void*)0);
 	ops->fvp(ipval);
 	ops->fvp(&ival);
+	ops->fvp(array);
+	ops->fvp(matrix);
 
 	ops->fvp(fun);
 	ops->fvp(&fun);
-- 
2.11.1


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

* [PATCH v2 18/27] llvm: add test cases for degenerated pointers
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (16 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 17/27] llvm: add test cases for arrays " Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 19/27] llvm: add support for OP_NEG Luc Van Oostenryck
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/backend/degenerate-ptr.c | 72 +++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 validation/backend/degenerate-ptr.c

diff --git a/validation/backend/degenerate-ptr.c b/validation/backend/degenerate-ptr.c
new file mode 100644
index 000000000..8de979e06
--- /dev/null
+++ b/validation/backend/degenerate-ptr.c
@@ -0,0 +1,72 @@
+extern int array[3];
+extern int matrix[3][3];
+extern int fun(int);
+
+extern int fia(int []);
+extern int fip(int *);
+extern int fim(int (*)[3]);
+extern int fvp(void *);
+extern int ffp(int (*)(int));
+
+void call(void);
+void call(void)
+{
+	fia(array);
+
+	fip(array);
+	fim(matrix);
+
+	fvp(array);
+	fvp(matrix);
+
+	fvp(fun);
+	fvp(&fun);
+	ffp(fun);
+	ffp(&fun);
+}
+
+void local(void);
+void local(void)
+{
+	int *ip;
+	int (*im)[3];
+	void *vp;
+	int (*fp)(int);
+
+	ip = array;
+	im = matrix;
+
+	vp = array;
+	vp = matrix;
+
+	vp = fun;
+	vp = &fun;
+	fp = fun;
+	fp = &fun;
+}
+
+
+extern int *ip;
+extern int (*im)[3];
+extern void *vp;
+extern int (*fp)(int);
+
+void global(void);
+void global(void)
+{
+	ip = array;
+	im = matrix;
+
+	vp = array;
+	vp = matrix;
+
+	vp = fun;
+	vp = &fun;
+	fp = fun;
+	fp = &fun;
+}
+
+/*
+ * check-name: degenerated pointer handling
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
-- 
2.11.1


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

* [PATCH v2 19/27] llvm: add support for OP_NEG
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (17 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 18/27] llvm: add test cases for degenerated pointers Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:06 ` [PATCH v2 20/27] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

sparse-llvm has not yet support for OP_NEG and stop on an assert
if one is encountered.

Fix this by invoking the appropriate LLVMBuild[F]Neg().

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index a3606a86e..ccc019322 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -977,9 +977,22 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		insn->target->priv = target;
 		break;
 	}
-	case OP_NEG:
-		assert(0);
+	case OP_NEG: {
+		LLVMValueRef src, target;
+		char target_name[64];
+
+		src = pseudo_to_value(fn, insn, insn->src);
+
+		pseudo_name(insn->target, target_name);
+
+		if (symbol_is_fp_type(insn->type))
+			target = LLVMBuildFNeg(fn->builder, src, target_name);
+		else
+			target = LLVMBuildNeg(fn->builder, src, target_name);
+
+		insn->target->priv = target;
 		break;
+	}
 	case OP_CONTEXT:
 		assert(0);
 		break;
-- 
2.11.1


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

* [PATCH v2 20/27] llvm: fix pointer/float mixup in comparisons
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (18 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 19/27] llvm: add support for OP_NEG Luc Van Oostenryck
@ 2017-03-11  9:06 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 21/27] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:06 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

In output_op_compare() everything that is not of interger
type is treated as floats. Pointers disagree.

Fix this by rearranging the code and treat pointers like integers
as required for LLVM's icmp.

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                    | 17 +++++++++++++++--
 validation/backend/pointer-cmp.c |  9 +++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 validation/backend/pointer-cmp.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index ccc019322..18a38a339 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -590,14 +590,27 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 
 	LLVMTypeRef dst_type = insn_symbol_type(fn->module, insn);
 
-	if (LLVMGetTypeKind(LLVMTypeOf(lhs)) == LLVMIntegerTypeKind) {
+	switch  (LLVMGetTypeKind(LLVMTypeOf(lhs))) {
+	case LLVMPointerTypeKind:
+	case LLVMIntegerTypeKind: {
 		LLVMIntPredicate op = translate_op(insn->opcode);
 
 		target = LLVMBuildICmp(fn->builder, op, lhs, rhs, target_name);
-	} else {
+		break;
+	}
+	case LLVMHalfTypeKind:
+	case LLVMFloatTypeKind:
+	case LLVMDoubleTypeKind:
+	case LLVMX86_FP80TypeKind:
+	case LLVMFP128TypeKind:
+	case LLVMPPC_FP128TypeKind: {
 		LLVMRealPredicate op = translate_fop(insn->opcode);
 
 		target = LLVMBuildFCmp(fn->builder, op, lhs, rhs, target_name);
+		break;
+	}
+	default:
+		assert(0);
 	}
 
 	target = LLVMBuildZExt(fn->builder, target, dst_type, target_name);
diff --git a/validation/backend/pointer-cmp.c b/validation/backend/pointer-cmp.c
new file mode 100644
index 000000000..fa76d1b57
--- /dev/null
+++ b/validation/backend/pointer-cmp.c
@@ -0,0 +1,9 @@
+int cmpint(   int x,   int y)	{ return x == y; }
+int cmpflt( float x, float y)	{ return x == y; }
+int cmpvptr(void *x, void *y)	{ return x == y; }
+int cmpiptr(int  *x, int  *y)	{ return x == y; }
+
+/*
+ * check-name: pointer comparison
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
-- 
2.11.1


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

* [PATCH v2 21/27] llvm: use pseudo_list_size() instead of open coding it
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (19 preceding siblings ...)
  2017-03-11  9:06 ` [PATCH v2 20/27] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 22/27] llvm: give arguments a name Luc Van Oostenryck
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 18a38a339..bbff47877 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -761,11 +761,7 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 	LLVMValueRef *args;
 	char name[64];
 
-
-	FOR_EACH_PTR(insn->arguments, arg) {
-		n_arg++;
-	} END_FOR_EACH_PTR(arg);

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

* [PATCH v2 22/27] llvm: give arguments a name
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (20 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 21/27] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 23/27] llvm: remove unneeded arg 'module' Luc Van Oostenryck
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Arguments, like all LLVMValues, are given a default name
but these name are simply '%0', '%1', ... and are thus not
very readable.

Fix this by giving them an explicit name 'ARG1', ... to
match the names used in sparse's linearized code.

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index bbff47877..825bd0347 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -1076,6 +1076,17 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	static int nr_bb;
 
+	/* give a name to each argument */
+	for (int i = 0; i < nr_args; i++) {
+		char name[MAX_PSEUDO_NAME];
+		LLVMValueRef arg;
+
+		arg = LLVMGetParam(function.fn, i);
+		snprintf(name, sizeof(name), "ARG%d", i+1);
+		LLVMSetValueName(arg, name);
+	}
+
+	/* create the BBs */
 	FOR_EACH_PTR(ep->bbs, bb) {
 		if (bb->generation == generation)
 			continue;
-- 
2.11.1


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

* [PATCH v2 23/27] llvm: remove unneeded arg 'module'
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (21 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 22/27] llvm: give arguments a name Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 24/27] llvm: remove unneeded arg 'fn' Luc Van Oostenryck
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 74 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 825bd0347..824bd790e 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -34,14 +34,14 @@ static inline bool symbol_is_fp_type(struct symbol *sym)
 	return sym->ctype.base_type == &fp_type;
 }
 
-static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym);
+static LLVMTypeRef symbol_type(struct symbol *sym);
 
-static LLVMTypeRef func_return_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef func_return_type(struct symbol *sym)
 {
-	return symbol_type(module, sym->ctype.base_type);
+	return symbol_type(sym->ctype.base_type);
 }
 
-static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef sym_func_type(struct symbol *sym)
 {
 	LLVMTypeRef *arg_type;
 	LLVMTypeRef func_type;
@@ -55,7 +55,7 @@ static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
 	 * symbol declaration info.
 	 */
 
-	ret_type = func_return_type(module, sym);
+	ret_type = func_return_type(sym);
 
 	/* count args, build argument type information */
 	FOR_EACH_PTR(sym->arguments, arg) {
@@ -68,7 +68,7 @@ static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
 	FOR_EACH_PTR(sym->arguments, arg) {
 		struct symbol *arg_sym = arg->ctype.base_type;
 
-		arg_type[idx++] = symbol_type(module, arg_sym);
+		arg_type[idx++] = symbol_type(arg_sym);
 	} END_FOR_EACH_PTR(arg);
 	func_type = LLVMFunctionType(ret_type, arg_type, n_arg,
 				     sym->variadic);
@@ -76,7 +76,7 @@ static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
 	return func_type;
 }
 
-static LLVMTypeRef sym_array_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef sym_array_type(struct symbol *sym)
 {
 	LLVMTypeRef elem_type;
 	struct symbol *base_type;
@@ -85,7 +85,7 @@ static LLVMTypeRef sym_array_type(LLVMModuleRef module, struct symbol *sym)
 	/* empty struct is undefined [6.7.2.1(8)] */
 	assert(base_type->bit_size > 0);
 
-	elem_type = symbol_type(module, base_type);
+	elem_type = symbol_type(base_type);
 	if (!elem_type)
 		return NULL;
 
@@ -94,7 +94,7 @@ static LLVMTypeRef sym_array_type(LLVMModuleRef module, struct symbol *sym)
 
 #define MAX_STRUCT_MEMBERS 64
 
-static LLVMTypeRef sym_struct_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef sym_struct_type(struct symbol *sym)
 {
 	LLVMTypeRef elem_types[MAX_STRUCT_MEMBERS];
 	struct symbol *member;
@@ -112,7 +112,7 @@ static LLVMTypeRef sym_struct_type(LLVMModuleRef module, struct symbol *sym)
 
 		assert(nr < MAX_STRUCT_MEMBERS);
 
-		member_type = symbol_type(module, member);
+		member_type = symbol_type(member);
 
 		elem_types[nr++] = member_type; 
 	} END_FOR_EACH_PTR(member);
@@ -121,7 +121,7 @@ static LLVMTypeRef sym_struct_type(LLVMModuleRef module, struct symbol *sym)
 	return ret;
 }
 
-static LLVMTypeRef sym_union_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef sym_union_type(struct symbol *sym)
 {
 	LLVMTypeRef elements;
 	unsigned union_size;
@@ -138,7 +138,7 @@ static LLVMTypeRef sym_union_type(LLVMModuleRef module, struct symbol *sym)
 	return LLVMStructType(&elements, 1, 0 /* packed? */);
 }
 
-static LLVMTypeRef sym_ptr_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef sym_ptr_type(struct symbol *sym)
 {
 	LLVMTypeRef type;
 
@@ -146,7 +146,7 @@ static LLVMTypeRef sym_ptr_type(LLVMModuleRef module, struct symbol *sym)
 	if (is_void_type(sym->ctype.base_type))
 		type = LLVMInt8Type();
 	else
-		type = symbol_type(module, sym->ctype.base_type);
+		type = symbol_type(sym->ctype.base_type);
 
 	return LLVMPointerType(type, 0);
 }
@@ -199,13 +199,13 @@ static LLVMTypeRef sym_basetype_type(struct symbol *sym)
 	return ret;
 }
 
-static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
+static LLVMTypeRef symbol_type(struct symbol *sym)
 {
 	LLVMTypeRef ret = NULL;
 
 	/* don't cache the result for SYM_NODE */
 	if (sym->type == SYM_NODE)
-		return symbol_type(module, sym->ctype.base_type);
+		return symbol_type(sym->ctype.base_type);
 
 	if (sym->aux)
 		return sym->aux;
@@ -213,25 +213,25 @@ static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
 	switch (sym->type) {
 	case SYM_BITFIELD:
 	case SYM_ENUM:
-		ret = symbol_type(module, sym->ctype.base_type);
+		ret = symbol_type(sym->ctype.base_type);
 		break;
 	case SYM_BASETYPE:
 		ret = sym_basetype_type(sym);
 		break;
 	case SYM_PTR:
-		ret = sym_ptr_type(module, sym);
+		ret = sym_ptr_type(sym);
 		break;
 	case SYM_UNION:
-		ret = sym_union_type(module, sym);
+		ret = sym_union_type(sym);
 		break;
 	case SYM_STRUCT:
-		ret = sym_struct_type(module, sym);
+		ret = sym_struct_type(sym);
 		break;
 	case SYM_ARRAY:
-		ret = sym_array_type(module, sym);
+		ret = sym_array_type(sym);
 		break;
 	case SYM_FN:
-		ret = sym_func_type(module, sym);
+		ret = sym_func_type(sym);
 		break;
 	default:
 		assert(0);
@@ -242,10 +242,10 @@ static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
 	return ret;
 }
 
-static LLVMTypeRef insn_symbol_type(LLVMModuleRef module, struct instruction *insn)
+static LLVMTypeRef insn_symbol_type(struct instruction *insn)
 {
 	if (insn->type)
-		return symbol_type(module, insn->type);
+		return symbol_type(insn->type);
 
 	switch (insn->size) {
 		case 8:		return LLVMInt8Type();
@@ -313,7 +313,7 @@ static LLVMValueRef val_to_value(struct function *fn, unsigned long long val, st
 	LLVMValueRef result;
 
 	assert(ctype);
-	dtype = symbol_type(fn->module, ctype);
+	dtype = symbol_type(ctype);
 	switch (LLVMGetTypeKind(dtype)) {
 	case LLVMPointerTypeKind:
 		itype = LLVMIntType(bits_in_pointer);
@@ -372,7 +372,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 			}
 		} else {
 			const char *name = show_ident(sym->ident);
-			LLVMTypeRef type = symbol_type(fn->module, sym);
+			LLVMTypeRef type = symbol_type(sym);
 
 			if (LLVMGetTypeKind(type) == LLVMFunctionTypeKind) {
 				result = LLVMGetNamedFunction(fn->module, name);
@@ -550,7 +550,7 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 		rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, "");
 		target = LLVMBuildAnd(fn->builder, lhs_nz, rhs_nz, target_name);
 
-		dst_type = insn_symbol_type(fn->module, insn);
+		dst_type = insn_symbol_type(insn);
 		target = LLVMBuildZExt(fn->builder, target, dst_type, target_name);
 		break;
 	}
@@ -562,7 +562,7 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 		rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, "");
 		target = LLVMBuildOr(fn->builder, lhs_nz, rhs_nz, target_name);
 
-		dst_type = insn_symbol_type(fn->module, insn);
+		dst_type = insn_symbol_type(insn);
 		target = LLVMBuildZExt(fn->builder, target, dst_type, target_name);
 		break;
 	}
@@ -588,7 +588,7 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 
 	pseudo_name(insn->target, target_name);
 
-	LLVMTypeRef dst_type = insn_symbol_type(fn->module, insn);
+	LLVMTypeRef dst_type = insn_symbol_type(insn);
 
 	switch  (LLVMGetTypeKind(LLVMTypeOf(lhs))) {
 	case LLVMPointerTypeKind:
@@ -643,7 +643,7 @@ static LLVMValueRef calc_memop_addr(struct function *fn, struct instruction *ins
 	/* convert src to the effective pointer type */
 	src = pseudo_to_value(fn, insn, insn->src);
 	as = LLVMGetPointerAddressSpace(LLVMTypeOf(src));
-	addr_type = LLVMPointerType(insn_symbol_type(fn->module, insn), as);
+	addr_type = LLVMPointerType(insn_symbol_type(insn), as);
 	src = LLVMBuildPointerCast(fn->builder, src, addr_type, "");
 
 	/* addr = src + off */
@@ -838,7 +838,7 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 
 	assert(!symbol_is_fp_type(insn->type));
 
-	dtype = insn_symbol_type(fn->module, insn);
+	dtype = insn_symbol_type(insn);
 	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
 	case LLVMPointerTypeKind:
 		op = LLVMBitCast;
@@ -872,7 +872,7 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 
 	assert(!symbol_is_fp_type(insn->type));
 
-	dtype = insn_symbol_type(fn->module, insn);
+	dtype = insn_symbol_type(insn);
 	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
 	case LLVMPointerTypeKind:
 		op = LLVMPtrToInt;
@@ -910,7 +910,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		char name[64];
 
 		src = pseudo_to_value(fn, insn, insn->symbol);
-		dtype = symbol_type(fn->module, insn->type);
+		dtype = symbol_type(insn->type);
 		pseudo_name(insn->target, name);
 		res = LLVMBuildBitCast(fn->builder, src, dtype, name);
 		insn->target->priv = res;
@@ -1058,12 +1058,12 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 	FOR_EACH_PTR(base_type->arguments, arg) {
 		struct symbol *arg_base_type = arg->ctype.base_type;
 
-		arg_types[nr_args++] = symbol_type(module, arg_base_type);
+		arg_types[nr_args++] = symbol_type(arg_base_type);
 	} END_FOR_EACH_PTR(arg);
 
 	name = show_ident(sym->ident);
 
-	return_type = symbol_type(module, ret_type);
+	return_type = symbol_type(ret_type);
 
 	function.type = LLVMFunctionType(return_type, arg_types, nr_args, 0);
 
@@ -1111,7 +1111,7 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 			/* insert alloca into entry block */
 			entrybbr = LLVMGetEntryBasicBlock(function.fn);
 			LLVMPositionBuilderAtEnd(function.builder, entrybbr);
-			phi_type = insn_symbol_type(module, insn);
+			phi_type = insn_symbol_type(insn);
 			ptr = LLVMBuildAlloca(function.builder, phi_type, "");
 			/* emit forward load for phi */
 			LLVMClearInsertionPosition(function.builder);
@@ -1141,7 +1141,7 @@ static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym)
 	if (initializer) {
 		switch (initializer->type) {
 		case EXPR_VALUE:
-			initial_value = LLVMConstInt(symbol_type(module, sym), initializer->value, 1);
+			initial_value = LLVMConstInt(symbol_type(sym), initializer->value, 1);
 			break;
 		case EXPR_SYMBOL: {
 			struct symbol *sym = initializer->symbol;
@@ -1161,7 +1161,7 @@ static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym)
 			assert(0);
 		}
 	} else {
-		LLVMTypeRef type = symbol_type(module, sym);
+		LLVMTypeRef type = symbol_type(sym);
 
 		initial_value = LLVMConstNull(type);
 	}
-- 
2.11.1


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

* [PATCH v2 24/27] llvm: remove unneeded arg 'fn'
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (22 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 23/27] llvm: remove unneeded arg 'module' Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 25/27] llvm: remove unneeded 'generation' Luc Van Oostenryck
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 824bd790e..e35ac01a2 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -306,7 +306,7 @@ static void pseudo_name(pseudo_t pseudo, char *buf)
 	}
 }
 
-static LLVMValueRef val_to_value(struct function *fn, unsigned long long val, struct symbol *ctype)
+static LLVMValueRef val_to_value(unsigned long long val, struct symbol *ctype)
 {
 	LLVMTypeRef dtype;
 	LLVMTypeRef itype;
@@ -387,7 +387,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 		break;
 	}
 	case PSEUDO_VAL:
-		result = val_to_value(fn, pseudo->value, insn->type);
+		result = val_to_value(pseudo->value, insn->type);
 		break;
 	case PSEUDO_ARG: {
 		result = LLVMGetParam(fn->fn, pseudo->nr - 1);
@@ -774,7 +774,7 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 			atype = get_nth_symbol(ftype->arguments, i);
 			/* Value pseudos do not have type information. */
 			/* Use the function prototype to get the type. */
-			value = val_to_value(fn, arg->value, atype);
+			value = val_to_value(arg->value, atype);
 		} else {
 			value = pseudo_to_value(fn, insn, arg);
 		}
-- 
2.11.1


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

* [PATCH v2 25/27] llvm: remove unneeded 'generation'
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (23 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 24/27] llvm: remove unneeded arg 'fn' Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 26/27] llvm: remove unneeded function::type Luc Van Oostenryck
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

It's not needed here since there is no recursive access to BBs.

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index e35ac01a2..4fc5777c7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -1024,12 +1024,10 @@ static void output_insn(struct function *fn, struct instruction *insn)
 	}
 }
 
-static void output_bb(struct function *fn, struct basic_block *bb, unsigned long generation)
+static void output_bb(struct function *fn, struct basic_block *bb)
 {
 	struct instruction *insn;
 
-	bb->generation = generation;
-
 	FOR_EACH_PTR(bb->insns, insn) {
 		if (!insn->bb)
 			continue;
@@ -1043,7 +1041,6 @@ static void output_bb(struct function *fn, struct basic_block *bb, unsigned long
 
 static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 {
-	unsigned long generation = ++bb_generation;
 	struct symbol *sym = ep->name;
 	struct symbol *base_type = sym->ctype.base_type;
 	struct symbol *ret_type = sym->ctype.base_type->ctype.base_type;
@@ -1088,9 +1085,6 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	/* create the BBs */
 	FOR_EACH_PTR(ep->bbs, bb) {
-		if (bb->generation == generation)
-			continue;
-
 		LLVMBasicBlockRef bbr;
 		char bbname[32];
 		struct instruction *insn;
@@ -1121,12 +1115,9 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 	END_FOR_EACH_PTR(bb);
 
 	FOR_EACH_PTR(ep->bbs, bb) {
-		if (bb->generation == generation)
-			continue;

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

* [PATCH v2 26/27] llvm: remove unneeded function::type
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (24 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 25/27] llvm: remove unneeded 'generation' Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11  9:07 ` [PATCH v2 27/27] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 4fc5777c7..831a56207 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -21,7 +21,6 @@
 
 struct function {
 	LLVMBuilderRef			builder;
-	LLVMTypeRef			type;
 	LLVMValueRef			fn;
 	LLVMModuleRef			module;
 };
@@ -1046,6 +1045,7 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 	struct symbol *ret_type = sym->ctype.base_type->ctype.base_type;
 	LLVMTypeRef arg_types[MAX_ARGS];
 	LLVMTypeRef return_type;
+	LLVMTypeRef fun_type;
 	struct function function = { .module = module };
 	struct basic_block *bb;
 	struct symbol *arg;
@@ -1062,9 +1062,9 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	return_type = symbol_type(ret_type);
 
-	function.type = LLVMFunctionType(return_type, arg_types, nr_args, 0);
+	fun_type = LLVMFunctionType(return_type, arg_types, nr_args, 0);
 
-	function.fn = LLVMAddFunction(module, name, function.type);
+	function.fn = LLVMAddFunction(module, name, fun_type);
 	LLVMSetFunctionCallConv(function.fn, LLVMCCallConv);
 
 	LLVMSetLinkage(function.fn, function_linkage(sym));
-- 
2.11.1


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

* [PATCH v2 27/27] llvm: reduce scope of 'bb_nr'
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (25 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 26/27] llvm: remove unneeded function::type Luc Van Oostenryck
@ 2017-03-11  9:07 ` Luc Van Oostenryck
  2017-03-11 11:12 ` [PATCH v2 00/27] LLVM fixes Dibyendu Majumdar
  2017-03-14  6:18 ` Christopher Li
  28 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11  9:07 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik,
	Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 831a56207..70a495267 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -1071,8 +1071,6 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	function.builder = LLVMCreateBuilder();
 
-	static int nr_bb;

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (26 preceding siblings ...)
  2017-03-11  9:07 ` [PATCH v2 27/27] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
@ 2017-03-11 11:12 ` Dibyendu Majumdar
  2017-03-11 11:49   ` Luc Van Oostenryck
  2017-03-14  6:18 ` Christopher Li
  28 siblings, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 11:12 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

Hi Luc,

On 11 March 2017 at 09:06, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> This series solves a number of issues in sparse-llvm,
> mainly about wrong or missing type information as needed
> to build LLVM IR.
> These issues have been reported and investigated by
> Dibyendu Majumdar.
>
> * patches 1-4 adds missing type info in sparse's IR
> * patch   4 is not needed by this serie but logically belong
>           to the same group as patches 1-3. It can be dropped.
> * patches 5-7 are fixes
> * patch   8 makes debugging easier
> * patches 8-10 are preparatory steps for patch 11
> * patches 11 & 12 are fixes
> * patch   13 is a preparatory step for patch 14
> * patch   14 solves a lot of issues
> * patches 15-18 are test cases solved by patch 14
> * patch   19 & 20 are fixes
> * patches 21, 23-27 are cleanups
> * patch   22 makes debugging easier
>
>

Thank you very much for this series of patches. I have merged them
into my project and things are better. We still cannot invoke
functions via pointers to functions using the (*ident)(arg) syntax due
to the incorrect load operation output by the linearizer.

I have been trying to compile a smallish program (AVL Tree
implementation) - making progress but it still fails to compile, so I
will report the next issue!

Thanks and Regards
Dibyendu

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 11:12 ` [PATCH v2 00/27] LLVM fixes Dibyendu Majumdar
@ 2017-03-11 11:49   ` Luc Van Oostenryck
  2017-03-11 11:54     ` Dibyendu Majumdar
  2017-03-12  2:35     ` Dibyendu Majumdar
  0 siblings, 2 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 11:49 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On Sat, Mar 11, 2017 at 11:12:20AM +0000, Dibyendu Majumdar wrote:
> We still cannot invoke
> functions via pointers to functions using the (*ident)(arg) syntax due
> to the incorrect load operation output by the linearizer.

Yes, I'm working on it.

> I have been trying to compile a smallish program (AVL Tree
> implementation) - making progress but it still fails to compile, so I
> will report the next issue!

Good. 

-- Luc Van Oostenryck

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 11:49   ` Luc Van Oostenryck
@ 2017-03-11 11:54     ` Dibyendu Majumdar
  2017-03-11 12:30       ` Luc Van Oostenryck
  2017-03-12  2:35     ` Dibyendu Majumdar
  1 sibling, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 11:54 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On 11 March 2017 at 11:49, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Sat, Mar 11, 2017 at 11:12:20AM +0000, Dibyendu Majumdar wrote:
>> We still cannot invoke
>> functions via pointers to functions using the (*ident)(arg) syntax due
>> to the incorrect load operation output by the linearizer.
>
> Yes, I'm working on it.
>
>> I have been trying to compile a smallish program (AVL Tree
>> implementation) - making progress but it still fails to compile, so I
>> will report the next issue!
>
> Good.
>

PSEUDO_VAL strikes again!

struct avl_node {
 struct avl_node *right;
 struct avl_node *left;
};
#define NULL ((void *)0)
static int test_null_comp(int height_changed, struct avl_node *node) {
 return node != NULL && height_changed;
}

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 11:54     ` Dibyendu Majumdar
@ 2017-03-11 12:30       ` Luc Van Oostenryck
  2017-03-11 13:36         ` Dibyendu Majumdar
  0 siblings, 1 reply; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 12:30 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On Sat, Mar 11, 2017 at 11:54:56AM +0000, Dibyendu Majumdar wrote:
> PSEUDO_VAL strikes again!
> 
> struct avl_node {
>  struct avl_node *right;
>  struct avl_node *left;
> };
> #define NULL ((void *)0)
> static int test_null_comp(int height_changed, struct avl_node *node) {
>  return node != NULL && height_changed;
> }

See the message of "llvm: fix translation of PSEUDO_VALs into a ValueRefs"
    Note: while this patch improve the situation, like for example for the
    test cases added here, it's still not correct because now we're making
    the assumption that 'insn->type' is the type we need for the pseudo.
    This is often true, but certainly not always.
    For example this is not true for:
    - OP_STORE/OP_LOAD's insn->src
    - OP_SET{EQ,...}'s   insn->src[12]
    - probably some  others ones
    - in general, obviously, for any instructions where the target has
      a different type than the operands.

Here you're hitting the OP_SET{EQ,...} case.

-- Luc

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 12:30       ` Luc Van Oostenryck
@ 2017-03-11 13:36         ` Dibyendu Majumdar
  2017-03-11 14:12           ` Luc Van Oostenryck
  0 siblings, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 13:36 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On 11 March 2017 at 12:30, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Sat, Mar 11, 2017 at 11:54:56AM +0000, Dibyendu Majumdar wrote:
>> PSEUDO_VAL strikes again!
>>
>> struct avl_node {
>>  struct avl_node *right;
>>  struct avl_node *left;
>> };
>> #define NULL ((void *)0)
>> static int test_null_comp(int height_changed, struct avl_node *node) {
>>  return node != NULL && height_changed;
>> }
>
> See the message of "llvm: fix translation of PSEUDO_VALs into a ValueRefs"
>     Note: while this patch improve the situation, like for example for the
>     test cases added here, it's still not correct because now we're making
>     the assumption that 'insn->type' is the type we need for the pseudo.
>     This is often true, but certainly not always.
>     For example this is not true for:
>     - OP_STORE/OP_LOAD's insn->src
>     - OP_SET{EQ,...}'s   insn->src[12]
>     - probably some  others ones
>     - in general, obviously, for any instructions where the target has
>       a different type than the operands.
>
> Here you're hitting the OP_SET{EQ,...} case.
>

Here is my attempt to fix:

static struct symbol *pseudo_get_type(pseudo_t pseudo) {
 switch (pseudo->type) {
 case PSEUDO_SYM:
 case PSEUDO_ARG:
  return pseudo->sym;
 case PSEUDO_PHI:
 case PSEUDO_REG:
  return pseudo->def->type;
 default:
  assert(0);
  return NULL;
 }
}
static void output_op_compare(struct function *fn, struct instruction *insn)
{
 LLVMValueRef lhs, rhs, target;
 char target_name[64];
 if (insn->src1->type == PSEUDO_VAL)
  lhs = val_to_value(fn, insn->src1->value, pseudo_get_type(insn->src2));
 else
  lhs = pseudo_to_value(fn, insn, insn->src1);
 if (insn->src2->type == PSEUDO_VAL)
  //rhs = LLVMConstInt(LLVMTypeOf(lhs), insn->src2->value, 1);
  rhs = val_to_value(fn, insn->src2->value, pseudo_get_type(insn->src1));
 else
  rhs = pseudo_to_value(fn, insn, insn->src2);


Does this look like the right thing to do?

Regards
Dibyendu

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 13:36         ` Dibyendu Majumdar
@ 2017-03-11 14:12           ` Luc Van Oostenryck
  2017-03-11 14:16             ` Dibyendu Majumdar
  0 siblings, 1 reply; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 14:12 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On Sat, Mar 11, 2017 at 01:36:30PM +0000, Dibyendu Majumdar wrote:
> > Here you're hitting the OP_SET{EQ,...} case.
> >
> 
> Here is my attempt to fix:
> 
> static struct symbol *pseudo_get_type(pseudo_t pseudo) {
>  switch (pseudo->type) {
>  case PSEUDO_SYM:
>  case PSEUDO_ARG:
>   return pseudo->sym;
>  case PSEUDO_PHI:
>  case PSEUDO_REG:
>   return pseudo->def->type;
>  default:
>   assert(0);
>   return NULL;
>  }
> }
> static void output_op_compare(struct function *fn, struct instruction *insn)
> {
>  LLVMValueRef lhs, rhs, target;
>  char target_name[64];
>  if (insn->src1->type == PSEUDO_VAL)
>   lhs = val_to_value(fn, insn->src1->value, pseudo_get_type(insn->src2));
>  else
>   lhs = pseudo_to_value(fn, insn, insn->src1);
>  if (insn->src2->type == PSEUDO_VAL)
>   //rhs = LLVMConstInt(LLVMTypeOf(lhs), insn->src2->value, 1);
>   rhs = val_to_value(fn, insn->src2->value, pseudo_get_type(insn->src1));
>  else
>   rhs = pseudo_to_value(fn, insn, insn->src2);
> 
> 
> Does this look like the right thing to do?

I didn't tested it but it looks correct and it is certainly OK for now.
I made the patch "give a type to PSEUDO_ARGs" with this in mind.

I'll take it the others ones.

However I'm slowly looking at a more generic solution.
For example, it would certainly be easier if there would be a
OP_PTRCAST between a constant-value-used-as-a-pointer and its use.
The cost would be some missing optimizations, or more complex ones
or a sort of normalization pass.

-- Luc Van Oostenryck

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 14:12           ` Luc Van Oostenryck
@ 2017-03-11 14:16             ` Dibyendu Majumdar
  2017-03-11 14:28               ` Luc Van Oostenryck
  2017-03-11 15:10               ` Jeff Garzik
  0 siblings, 2 replies; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 14:16 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On 11 March 2017 at 14:12, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Sat, Mar 11, 2017 at 01:36:30PM +0000, Dibyendu Majumdar wrote:
>> > Here you're hitting the OP_SET{EQ,...} case.
>> >
>>
>> Here is my attempt to fix:
>>
>> static struct symbol *pseudo_get_type(pseudo_t pseudo) {
>>  switch (pseudo->type) {
>>  case PSEUDO_SYM:
>>  case PSEUDO_ARG:
>>   return pseudo->sym;
>>  case PSEUDO_PHI:
>>  case PSEUDO_REG:
>>   return pseudo->def->type;
>>  default:
>>   assert(0);
>>   return NULL;
>>  }
>> }
>> static void output_op_compare(struct function *fn, struct instruction *insn)
>> {
>>  LLVMValueRef lhs, rhs, target;
>>  char target_name[64];
>>  if (insn->src1->type == PSEUDO_VAL)
>>   lhs = val_to_value(fn, insn->src1->value, pseudo_get_type(insn->src2));
>>  else
>>   lhs = pseudo_to_value(fn, insn, insn->src1);
>>  if (insn->src2->type == PSEUDO_VAL)
>>   //rhs = LLVMConstInt(LLVMTypeOf(lhs), insn->src2->value, 1);
>>   rhs = val_to_value(fn, insn->src2->value, pseudo_get_type(insn->src1));
>>  else
>>   rhs = pseudo_to_value(fn, insn, insn->src2);
>>
>>
>> Does this look like the right thing to do?
>
> I didn't tested it but it looks correct and it is certainly OK for now.
> I made the patch "give a type to PSEUDO_ARGs" with this in mind.
>
> I'll take it the others ones.
>

Good news is that with this fix and by using a function pointer call
syntax that doesn't use (*f)() - I am able to successfully compile an
AVL Tree implementation. Whether the generated code is correct is
still to be checked but this is a big step forward I think - so many
thanks for the help!

> However I'm slowly looking at a more generic solution.
> For example, it would certainly be easier if there would be a
> OP_PTRCAST between a constant-value-used-as-a-pointer and its use.
> The cost would be some missing optimizations, or more complex ones
> or a sort of normalization pass.
>

I still think pseudo values should have a type - then we won't need
all the complexity!

Regards
Dibyendu

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 14:16             ` Dibyendu Majumdar
@ 2017-03-11 14:28               ` Luc Van Oostenryck
  2017-03-11 15:10               ` Jeff Garzik
  1 sibling, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 14:28 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On Sat, Mar 11, 2017 at 02:16:59PM +0000, Dibyendu Majumdar wrote:
> 
> Good news is that with this fix and by using a function pointer call
> syntax that doesn't use (*f)() - I am able to successfully compile an
> AVL Tree implementation. Whether the generated code is correct is
> still to be checked but this is a big step forward I think - so many
> thanks for the help!

Great. You're welcome.

> > However I'm slowly looking at a more generic solution.
> > For example, it would certainly be easier if there would be a
> > OP_PTRCAST between a constant-value-used-as-a-pointer and its use.
> > The cost would be some missing optimizations, or more complex ones
> > or a sort of normalization pass.
> >
> 
> I still think pseudo values should have a type - then we won't need
> all the complexity!

Yes, but it would need an additional pointer for all pseudos and
it's a cost we won't do (but this just gave me an idea).

-- Luc Van Oostenryck

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 14:16             ` Dibyendu Majumdar
  2017-03-11 14:28               ` Luc Van Oostenryck
@ 2017-03-11 15:10               ` Jeff Garzik
  2017-03-11 15:51                 ` Luc Van Oostenryck
  1 sibling, 1 reply; 53+ messages in thread
From: Jeff Garzik @ 2017-03-11 15:10 UTC (permalink / raw)
  To: Dibyendu Majumdar
  Cc: Luc Van Oostenryck, Linux-Sparse, Christopher Li, Pekka Enberg

On Sat, Mar 11, 2017 at 9:16 AM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
> I still think pseudo values should have a type - then we won't need
> all the complexity!

Yep, agreed - giving pseudos a type is both natural and intentional -
it is a natural outcome of the operation, and should be available
without any further lookups.  Giving pseudos a type actually
simplifies complexity and makes tree manipulation (optimizer) easier.

 ...of course we need to maintain that type information correctly in
all cases and through all transformations...

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 15:10               ` Jeff Garzik
@ 2017-03-11 15:51                 ` Luc Van Oostenryck
  2017-03-11 18:08                   ` Dibyendu Majumdar
  0 siblings, 1 reply; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 15:51 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Dibyendu Majumdar, Linux-Sparse, Christopher Li, Pekka Enberg

On Sat, Mar 11, 2017 at 10:10:27AM -0500, Jeff Garzik wrote:
> On Sat, Mar 11, 2017 at 9:16 AM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
> > I still think pseudo values should have a type - then we won't need
> > all the complexity!
> 
> Yep, agreed - giving pseudos a type is both natural and intentional -
> it is a natural outcome of the operation, and should be available
> without any further lookups.  Giving pseudos a type actually
> simplifies complexity and makes tree manipulation (optimizer) easier.
> 
>  ...of course we need to maintain that type information correctly in
> all cases and through all transformations...

OK. The mini-serie I just posted *should* give (correct?) type
information to all PSEUDO_VALs.

Dibyendu, can you look if we can make good use of it?

-- Luc Van Oostenryck

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 15:51                 ` Luc Van Oostenryck
@ 2017-03-11 18:08                   ` Dibyendu Majumdar
  2017-03-11 20:44                     ` Luc Van Oostenryck
  0 siblings, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 18:08 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Jeff Garzik, Linux-Sparse, Christopher Li, Pekka Enberg

On 11 March 2017 at 15:51, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Sat, Mar 11, 2017 at 10:10:27AM -0500, Jeff Garzik wrote:
>> On Sat, Mar 11, 2017 at 9:16 AM, Dibyendu Majumdar
>> <mobile@majumdar.org.uk> wrote:
>> > I still think pseudo values should have a type - then we won't need
>> > all the complexity!
>>
>> Yep, agreed - giving pseudos a type is both natural and intentional -
>> it is a natural outcome of the operation, and should be available
>> without any further lookups.  Giving pseudos a type actually
>> simplifies complexity and makes tree manipulation (optimizer) easier.
>>
>>  ...of course we need to maintain that type information correctly in
>> all cases and through all transformations...
>
> OK. The mini-serie I just posted *should* give (correct?) type
> information to all PSEUDO_VALs.
>
> Dibyendu, can you look if we can make good use of it?
>

Sure. We may need to rework some of the previous changes but one case
comes straight to mind - that of variadic functions such as printf.

Regards

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 18:08                   ` Dibyendu Majumdar
@ 2017-03-11 20:44                     ` Luc Van Oostenryck
  2017-03-11 21:21                       ` Dibyendu Majumdar
  0 siblings, 1 reply; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 20:44 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: Jeff Garzik, Linux-Sparse, Christopher Li, Pekka Enberg

On Sat, Mar 11, 2017 at 06:08:04PM +0000, Dibyendu Majumdar wrote:
> On 11 March 2017 at 15:51, Luc Van Oostenryck
> <luc.vanoostenryck@gmail.com> wrote:
> > On Sat, Mar 11, 2017 at 10:10:27AM -0500, Jeff Garzik wrote:
> >> On Sat, Mar 11, 2017 at 9:16 AM, Dibyendu Majumdar
> >> <mobile@majumdar.org.uk> wrote:
> >> > I still think pseudo values should have a type - then we won't need
> >> > all the complexity!
> >>
> >> Yep, agreed - giving pseudos a type is both natural and intentional -
> >> it is a natural outcome of the operation, and should be available
> >> without any further lookups.  Giving pseudos a type actually
> >> simplifies complexity and makes tree manipulation (optimizer) easier.
> >>
> >>  ...of course we need to maintain that type information correctly in
> >> all cases and through all transformations...
> >
> > OK. The mini-serie I just posted *should* give (correct?) type
> > information to all PSEUDO_VALs.
> >
> > Dibyendu, can you look if we can make good use of it?
> >
> 
> Sure. We may need to rework some of the previous changes but one case
> comes straight to mind - that of variadic functions such as printf.

Yes, two patches from series can be dropped.
But there is still some bad issues that remains,
for example pointer subtraction with NULL and some
optimization that destroy correct typing info.
They're bad enough to make me doubt of the value of this change.

Here are some failing cases:
	#define NULL ((void *)0)
	int  tst(int  *ip) { return !ip; }
	int  foo(int  *ip) { return ip != NULL; }
	long bar(void *vp) { return vp - NULL; }
	long baz(int  *ip) { return ip - ((int *)0); }

For variadic functions, this is yet another story.

-- Luc

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 20:44                     ` Luc Van Oostenryck
@ 2017-03-11 21:21                       ` Dibyendu Majumdar
  2017-03-11 22:30                         ` Luc Van Oostenryck
  0 siblings, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 21:21 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Jeff Garzik, Linux-Sparse, Christopher Li, Pekka Enberg

On 11 March 2017 at 20:44, Luc Van Oostenryck > But there is still
some bad issues that remains,
> for example pointer subtraction with NULL and some
> optimization that destroy correct typing info.
> They're bad enough to make me doubt of the value of this change.
>
> Here are some failing cases:
>         #define NULL ((void *)0)
>         int  tst(int  *ip) { return !ip; }
>         int  foo(int  *ip) { return ip != NULL; }
>         long bar(void *vp) { return vp - NULL; }
>         long baz(int  *ip) { return ip - ((int *)0); }
>

I only get a failure on the last one. But I am synced with master - so
it may be an issue with sparse-next branch?

For the last one, looks like linearized output is incorrect?

baz:
.L6:
        <entry-point>
        divs.64     %r13 <- %arg1, $4
        scast.32    %r14 <- (64) %r13
        ret.32      %r14

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 21:21                       ` Dibyendu Majumdar
@ 2017-03-11 22:30                         ` Luc Van Oostenryck
  2017-03-11 22:57                           ` Dibyendu Majumdar
  0 siblings, 1 reply; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 22:30 UTC (permalink / raw)
  To: Dibyendu Majumdar; +Cc: Jeff Garzik, Linux-Sparse, Christopher Li, Pekka Enberg

On Sat, Mar 11, 2017 at 09:21:34PM +0000, Dibyendu Majumdar wrote:
> On 11 March 2017 at 20:44, Luc Van Oostenryck > But there is still
> some bad issues that remains,
> > for example pointer subtraction with NULL and some
> > optimization that destroy correct typing info.
> > They're bad enough to make me doubt of the value of this change.
> >
> > Here are some failing cases:
> >         #define NULL ((void *)0)
> >         int  tst(int  *ip) { return !ip; }
> >         int  foo(int  *ip) { return ip != NULL; }
> >         long bar(void *vp) { return vp - NULL; }
> >         long baz(int  *ip) { return ip - ((int *)0); }
> >
> 
> I only get a failure on the last one. But I am synced with master - so
> it may be an issue with sparse-next branch?

It's on my development branch:
	next
	+ today's 2nd serie
	+ today's 1st serie - 2 patches now unneeded.
So it's normal that you don't the same.

> For the last one, looks like linearized output is incorrect?
> 
> baz:
> .L6:
>         <entry-point>
>         divs.64     %r13 <- %arg1, $4
>         scast.32    %r14 <- (64) %r13
>         ret.32      %r14

It's not incorrect, only that the scast is unneeded.
But strangely, I don't see that cast here.

-- Luc

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 22:30                         ` Luc Van Oostenryck
@ 2017-03-11 22:57                           ` Dibyendu Majumdar
  2017-03-11 23:02                             ` Linus Torvalds
  0 siblings, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 22:57 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Jeff Garzik, Linux-Sparse, Christopher Li, Pekka Enberg

On 11 March 2017 at 22:30, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
>> >         long baz(int  *ip) { return ip - ((int *)0); }
>> >
>>
> baz:
>> .L6:
>>         <entry-point>
>>         divs.64     %r13 <- %arg1, $4
>>         scast.32    %r14 <- (64) %r13
>>         ret.32      %r14
>
> It's not incorrect, only that the scast is unneeded.
> But strangely, I don't see that cast here.
>

Why the division? That seems incorrect to me.

Regards

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 22:57                           ` Dibyendu Majumdar
@ 2017-03-11 23:02                             ` Linus Torvalds
  2017-03-11 23:04                               ` Dibyendu Majumdar
  0 siblings, 1 reply; 53+ messages in thread
From: Linus Torvalds @ 2017-03-11 23:02 UTC (permalink / raw)
  To: Dibyendu Majumdar
  Cc: Luc Van Oostenryck, Jeff Garzik, Linux-Sparse, Christopher Li,
	Pekka Enberg

On Sat, Mar 11, 2017 at 2:57 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
>
> Why the division? That seems incorrect to me.

Pointer differences are not byte differences, but index differences.
So with an "int *" you need to divide the difference by 4 (you don't
see the subtraction, since subtracting NULL ends up being a no-op).

                   Linus

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 23:02                             ` Linus Torvalds
@ 2017-03-11 23:04                               ` Dibyendu Majumdar
  2017-03-11 23:12                                 ` Luc Van Oostenryck
  0 siblings, 1 reply; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-11 23:04 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Luc Van Oostenryck, Jeff Garzik, Linux-Sparse, Christopher Li,
	Pekka Enberg

On 11 March 2017 at 23:02, Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Sat, Mar 11, 2017 at 2:57 PM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
>>
>> Why the division? That seems incorrect to me.
>
> Pointer differences are not byte differences, but index differences.
> So with an "int *" you need to divide the difference by 4 (you don't
> see the subtraction, since subtracting NULL ends up being a no-op).
>

Okay that makes sense.

Regards

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 23:04                               ` Dibyendu Majumdar
@ 2017-03-11 23:12                                 ` Luc Van Oostenryck
  0 siblings, 0 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-11 23:12 UTC (permalink / raw)
  To: Dibyendu Majumdar
  Cc: Linus Torvalds, Jeff Garzik, Linux-Sparse, Christopher Li, Pekka Enberg

On Sun, Mar 12, 2017 at 12:04 AM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
> On 11 March 2017 at 23:02, Linus Torvalds <torvalds@linux-foundation.org> wrote:
>> On Sat, Mar 11, 2017 at 2:57 PM, Dibyendu Majumdar
>> <mobile@majumdar.org.uk> wrote:
>>>
>>> Why the division? That seems incorrect to me.
>>
>> Pointer differences are not byte differences, but index differences.
>> So with an "int *" you need to divide the difference by 4 (you don't
>> see the subtraction, since subtracting NULL ends up being a no-op).
>>
>
> Okay that makes sense.

Yes, as Linus explained.
In fact I made the test cases to create this as I suspected some difficulties
there since it's the kind of operation that by its nature mix different types.

-- Luc

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11 11:49   ` Luc Van Oostenryck
  2017-03-11 11:54     ` Dibyendu Majumdar
@ 2017-03-12  2:35     ` Dibyendu Majumdar
  1 sibling, 0 replies; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-12  2:35 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Christopher Li, Pekka Enberg, Jeff Garzik

On 11 March 2017 at 11:49, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Sat, Mar 11, 2017 at 11:12:20AM +0000, Dibyendu Majumdar wrote:
>> I have been trying to compile a smallish program (AVL Tree
>> implementation) - making progress but it still fails to compile, so I
>> will report the next issue!
>
> Good.
>

Sadly it crashes when run using lli.

You can see the test programs I am using here:

https://github.com/dibyendumajumdar/dmr_c/tree/master/tests

I do not have driver scripts yet - but the README identifies the
programs that fail.

Regards
Dibyendu

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
                   ` (27 preceding siblings ...)
  2017-03-11 11:12 ` [PATCH v2 00/27] LLVM fixes Dibyendu Majumdar
@ 2017-03-14  6:18 ` Christopher Li
  2017-03-16 16:41   ` Luc Van Oostenryck
  28 siblings, 1 reply; 53+ messages in thread
From: Christopher Li @ 2017-03-14  6:18 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik

On Sat, Mar 11, 2017 at 5:06 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> This series solves a number of issues in sparse-llvm,
> mainly about wrong or missing type information as needed
> to build LLVM IR.
> These issues have been reported and investigated by
> Dibyendu Majumdar.

Hi,

I am on a trip again. I will apply the patch towards the end of this week.

Looking forward to it.

Chris

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-14  6:18 ` Christopher Li
@ 2017-03-16 16:41   ` Luc Van Oostenryck
  2017-03-17 14:06     ` Dibyendu Majumdar
  2017-03-17 17:04     ` Christopher Li
  0 siblings, 2 replies; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-16 16:41 UTC (permalink / raw)
  To: Christopher Li; +Cc: Linux-Sparse, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik

On Tue, Mar 14, 2017 at 02:18:30PM +0800, Christopher Li wrote:
> On Sat, Mar 11, 2017 at 5:06 PM, Luc Van Oostenryck
> <luc.vanoostenryck@gmail.com> wrote:
> > This series solves a number of issues in sparse-llvm,
> > mainly about wrong or missing type information as needed
> > to build LLVM IR.
> > These issues have been reported and investigated by
> > Dibyendu Majumdar.
> 
> Hi,
> 
> I am on a trip again. I will apply the patch towards the end of this week.
> 
> Looking forward to it.

OK. No hurry anyway as I have to update the serie anyway.

-- Luc 

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-16 16:41   ` Luc Van Oostenryck
@ 2017-03-17 14:06     ` Dibyendu Majumdar
  2017-03-17 17:04     ` Christopher Li
  1 sibling, 0 replies; 53+ messages in thread
From: Dibyendu Majumdar @ 2017-03-17 14:06 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Christopher Li, Linux-Sparse, Pekka Enberg, Jeff Garzik

Hi Luc,

On 16 March 2017 at 16:41, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Tue, Mar 14, 2017 at 02:18:30PM +0800, Christopher Li wrote:
>> On Sat, Mar 11, 2017 at 5:06 PM, Luc Van Oostenryck
>> <luc.vanoostenryck@gmail.com> wrote:
>> > This series solves a number of issues in sparse-llvm,
>> > mainly about wrong or missing type information as needed
>> > to build LLVM IR.
>> > These issues have been reported and investigated by
>> > Dibyendu Majumdar.
>>
>> I am on a trip again. I will apply the patch towards the end of this week.
>>
>> Looking forward to it.
>
> OK. No hurry anyway as I have to update the serie anyway.
>

I have reported a bunch of issues and fixes in the past few days.
Please let me know how we should proceed with those. I can submit
patches if that would help - I will wait for the current set of
patches to be updated before submitting any. Alternatively the changes
are all reflected in my repository - and if you prefer you can rework
them if necessary and submit.

Thanks and Regards
Dibyendu

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-16 16:41   ` Luc Van Oostenryck
  2017-03-17 14:06     ` Dibyendu Majumdar
@ 2017-03-17 17:04     ` Christopher Li
  2017-03-17 17:41       ` Luc Van Oostenryck
  1 sibling, 1 reply; 53+ messages in thread
From: Christopher Li @ 2017-03-17 17:04 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik

On Thu, Mar 16, 2017 at 9:41 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> OK. No hurry anyway as I have to update the serie anyway.

I am look at the patches now. Do you have a new series coming up soon?

Chris

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-17 17:04     ` Christopher Li
@ 2017-03-17 17:41       ` Luc Van Oostenryck
  2017-03-17 18:05         ` Christopher Li
  0 siblings, 1 reply; 53+ messages in thread
From: Luc Van Oostenryck @ 2017-03-17 17:41 UTC (permalink / raw)
  To: Christopher Li; +Cc: Linux-Sparse, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik

On Fri, Mar 17, 2017 at 10:04:45AM -0700, Christopher Li wrote:
> On Thu, Mar 16, 2017 at 9:41 AM, Luc Van Oostenryck
> <luc.vanoostenryck@gmail.com> wrote:
> > OK. No hurry anyway as I have to update the serie anyway.
> 
> I am look at the patches now. Do you have a new series coming up soon?

Yes, probably tomorrow.

Some of the patches of this serie are useless now and need
to be removed and I need to integrate with the OP_PUSH+OP_CALL
I sent some hours ago.

-- Luc 

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

* Re: [PATCH v2 00/27] LLVM fixes
  2017-03-17 17:41       ` Luc Van Oostenryck
@ 2017-03-17 18:05         ` Christopher Li
  0 siblings, 0 replies; 53+ messages in thread
From: Christopher Li @ 2017-03-17 18:05 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Linux-Sparse, Dibyendu Majumdar, Pekka Enberg, Jeff Garzik

On Fri, Mar 17, 2017 at 10:41 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Fri, Mar 17, 2017 at 10:04:45AM -0700, Christopher Li wrote:
>> On Thu, Mar 16, 2017 at 9:41 AM, Luc Van Oostenryck
>> <luc.vanoostenryck@gmail.com> wrote:
>> > OK. No hurry anyway as I have to update the serie anyway.
>>
>> I am look at the patches now. Do you have a new series coming up soon?
>
> Yes, probably tomorrow.
>
> Some of the patches of this serie are useless now and need
> to be removed and I need to integrate with the OP_PUSH+OP_CALL
> I sent some hours ago.

OK. I will wait for it a bit to update sparse-next then.

Chris

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

end of thread, other threads:[~2017-03-17 18:06 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-11  9:06 [PATCH v2 00/27] LLVM fixes Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 01/27] give a type to OP_PHISOURCE Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 02/27] give a type to OP_SEL, always Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 03/27] give a type to OP_SYMADDR Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 04/27] give a type to PSEUDO_ARGs Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 05/27] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 06/27] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 07/27] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 08/27] llvm: give a name to call return values Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 09/27] llvm: add test cases for the type of constants Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 10/27] add ptr_list_nth_entry() Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 11/27] llvm: fix type of literal integer passed as arguments Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 12/27] llvm: fix output OP_ADD mixed with pointers Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 13/27] llvm: add support for OP_SYMADDR Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 14/27] keep OP_SYMADDR instructions Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 15/27] llvm: add test cases for symbol's address Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 16/27] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 17/27] llvm: add test cases for arrays " Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 18/27] llvm: add test cases for degenerated pointers Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 19/27] llvm: add support for OP_NEG Luc Van Oostenryck
2017-03-11  9:06 ` [PATCH v2 20/27] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 21/27] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 22/27] llvm: give arguments a name Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 23/27] llvm: remove unneeded arg 'module' Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 24/27] llvm: remove unneeded arg 'fn' Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 25/27] llvm: remove unneeded 'generation' Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 26/27] llvm: remove unneeded function::type Luc Van Oostenryck
2017-03-11  9:07 ` [PATCH v2 27/27] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
2017-03-11 11:12 ` [PATCH v2 00/27] LLVM fixes Dibyendu Majumdar
2017-03-11 11:49   ` Luc Van Oostenryck
2017-03-11 11:54     ` Dibyendu Majumdar
2017-03-11 12:30       ` Luc Van Oostenryck
2017-03-11 13:36         ` Dibyendu Majumdar
2017-03-11 14:12           ` Luc Van Oostenryck
2017-03-11 14:16             ` Dibyendu Majumdar
2017-03-11 14:28               ` Luc Van Oostenryck
2017-03-11 15:10               ` Jeff Garzik
2017-03-11 15:51                 ` Luc Van Oostenryck
2017-03-11 18:08                   ` Dibyendu Majumdar
2017-03-11 20:44                     ` Luc Van Oostenryck
2017-03-11 21:21                       ` Dibyendu Majumdar
2017-03-11 22:30                         ` Luc Van Oostenryck
2017-03-11 22:57                           ` Dibyendu Majumdar
2017-03-11 23:02                             ` Linus Torvalds
2017-03-11 23:04                               ` Dibyendu Majumdar
2017-03-11 23:12                                 ` Luc Van Oostenryck
2017-03-12  2:35     ` Dibyendu Majumdar
2017-03-14  6:18 ` Christopher Li
2017-03-16 16:41   ` Luc Van Oostenryck
2017-03-17 14:06     ` Dibyendu Majumdar
2017-03-17 17:04     ` Christopher Li
2017-03-17 17:41       ` Luc Van Oostenryck
2017-03-17 18:05         ` Christopher Li

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.