All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/30] LLVM fixes
@ 2017-03-19  1:41 Luc Van Oostenryck
  2017-03-19  1:41 ` [PATCH v3 01/30] fix usage of inlined calls Luc Van Oostenryck
                   ` (31 more replies)
  0 siblings, 32 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:41 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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.
Most of these issues have been reported and investigated by
Dibyendu Majumdar.

Changes since v2:
- remove the changes tha gave a type to PSEUDO_VALs
- introduction of OP_PUSH instructions
- move toward generic solution using the instruction's type
- some more fixes
- temporary remove changes related to OP_SYMADDR

* patches 1 & 2 are fixes/improvement of inlined call
	  unrelated to LLVM
* patch   3 add support of OP_PUSH and solve variadic + constant
* patches 4 & 5 add missing type to some instructions
* patches 6-14 are preparatory cleanups
* patch   15 fix a problme with floats & SYM_NODE
* patch   16 improve the typing of contants
* patches 17 & 18 are fixes
* patch	  19 fix issues with degenerated pointers
* patches 20-23 add test cases solved by patch 19
* patches 24-30 are fixes

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)
- there is a bunch of problems 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-v3


Luc Van Oostenryck (30):
  fix usage of inlined calls
  inlined calls should not block BB packing
  give function's arguments a type via OP_PUSH
  give a type to OP_PHISOURCE
  give a type to OP_SEL, always
  llvm: remove unneeded arg 'module'
  llvm: remove unneeded 'generation'
  llvm: remove unneeded function::type
  llvm: reduce scope of 'bb_nr'
  llvm: use pseudo_list_size() instead of open coding it
  llvm: give arguments a name
  llvm: give a name to call's return values
  llvm: avoid useless temp variable
  llvm: extract get_sym_value() from pseudo_to_value()
  llvm: fix test of floating-point type
  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: take care of degenerated rvalues
  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: fix type in comparison with an address constant
  llvm: give correct type to binops
  llvm: adjust OP_RET's type
  llvm: variadic functions are not being marked as such
  llvm: fix type of switch constants

 example.c                              |   4 +-
 flow.c                                 |   3 +-
 linearize.c                            |  53 +++--
 linearize.h                            |  12 +-
 liveness.c                             |  14 +-
 memops.c                               |   2 +-
 simplify.c                             |  11 +-
 sparse-llvm.c                          | 412 +++++++++++++++++++++------------
 validation/backend/compare-with-null.c |  12 +
 validation/backend/constant-pointer.c  |  24 ++
 validation/backend/degenerate-ptr.c    |  72 ++++++
 validation/backend/function-ptr.c      | 148 +++++++++++-
 validation/backend/pointer-add.c       |  54 +++++
 validation/backend/pointer-cmp.c       |   9 +
 validation/backend/pointer-param.c     |  42 ++++
 validation/backend/pointer-sub.c       |  17 ++
 validation/backend/store-x2.c          |  16 ++
 validation/backend/symaddr.c           |  70 ++++++
 validation/backend/type-constant.c     |  23 ++
 validation/call-inlined.c              |  58 +++++
 validation/call-variadic.c             |  31 +++
 validation/loop-linearization.c        |   9 +-
 validation/optim/call-inlined.c        |  30 +++
 23 files changed, 943 insertions(+), 183 deletions(-)
 create mode 100644 validation/backend/compare-with-null.c
 create mode 100644 validation/backend/constant-pointer.c
 create mode 100644 validation/backend/degenerate-ptr.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/pointer-sub.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/call-inlined.c
 create mode 100644 validation/call-variadic.c
 create mode 100644 validation/optim/call-inlined.c

-- 
2.12.0


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

* [PATCH v3 01/30] fix usage of inlined calls
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
@ 2017-03-19  1:41 ` Luc Van Oostenryck
  2017-03-19  1:41 ` [PATCH v3 02/30] inlined calls should not block BB packing Luc Van Oostenryck
                   ` (30 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:41 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

OP_INLINED_CALL are there only as a sort of annotation
for debugging purpose. It is thus wrong to associate
pseudo's usage to them (even if the pseudo are the arguments
of the function now inlined).

Fix this by removing the use_pseudo() for each arguments.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c               |  2 +-
 validation/call-inlined.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 validation/call-inlined.c

diff --git a/linearize.c b/linearize.c
index 5199b6b02..5337723e2 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1680,7 +1680,7 @@ static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement *
 		concat_symbol_list(args->declaration, &ep->syms);
 		FOR_EACH_PTR(args->declaration, sym) {
 			pseudo_t value = linearize_one_symbol(ep, sym);
-			use_pseudo(insn, value, add_pseudo(&insn->arguments, value));
+			add_pseudo(&insn->arguments, value);
 		} END_FOR_EACH_PTR(sym);
 	}
 
diff --git a/validation/call-inlined.c b/validation/call-inlined.c
new file mode 100644
index 000000000..6fd94edcb
--- /dev/null
+++ b/validation/call-inlined.c
@@ -0,0 +1,58 @@
+static const char messg[] = "def";
+
+static inline int add(int a, int b)
+{
+	return a + b;
+}
+
+int  foo(int a, int b) { return add(a + b, 1); }
+void bar(int a, int b) {        add(a + b, 1); }
+
+
+static inline const char *lstrip(const char *str)
+{
+	return str + 1;
+}
+
+const char *bas(void) { return lstrip("abc"); }
+const char *qus(void) { return lstrip(messg); }
+
+/*
+ * check-name: call-inlined
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+foo:
+.L0:
+	<entry-point>
+	add.32      %r3 <- %arg1, %arg2
+	add.32      %r5 <- %r3, $1
+	# call      %r5 <- add, %r3, $1
+	ret.32      %r5
+
+
+bar:
+.L3:
+	<entry-point>
+	# call      %r12 <- add, %r10, $1
+	ret
+
+
+bas:
+.L6:
+	<entry-point>
+	add.64      %r16 <- "abc", $1
+	# call      %r16 <- lstrip, %r14
+	ret.64      %r16
+
+
+qus:
+.L9:
+	<entry-point>
+	add.64      %r21 <- messg, $1
+	# call      %r21 <- lstrip, %r19
+	ret.64      %r21
+
+
+ * check-output-end
+ */
-- 
2.12.0


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

* [PATCH v3 02/30] inlined calls should not block BB packing
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
  2017-03-19  1:41 ` [PATCH v3 01/30] fix usage of inlined calls Luc Van Oostenryck
@ 2017-03-19  1:41 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 03/30] give function's arguments a type via OP_PUSH Luc Van Oostenryck
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:41 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

OP_INLINED_CALL are there only as a sort of annotation
for debugging purpose.
Their presence should thus not block the packing of
basic blocks.

Fix this by ignoring OP_INLINED_CALL when trying to pack
a basic block.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 flow.c                          |  1 +
 validation/optim/call-inlined.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 validation/optim/call-inlined.c

diff --git a/flow.c b/flow.c
index 237c9f1fa..ec7e3f22c 100644
--- a/flow.c
+++ b/flow.c
@@ -949,6 +949,7 @@ void pack_basic_blocks(struct entrypoint *ep)
 				continue;
 			switch (first->opcode) {
 			case OP_NOP: case OP_LNOP: case OP_SNOP:
+			case OP_INLINED_CALL:
 				continue;
 			case OP_CBR:
 			case OP_BR: {
diff --git a/validation/optim/call-inlined.c b/validation/optim/call-inlined.c
new file mode 100644
index 000000000..00698a4b1
--- /dev/null
+++ b/validation/optim/call-inlined.c
@@ -0,0 +1,30 @@
+static const char messg[] = "def";
+
+static inline int add(int a, int b)
+{
+	return a + b;
+}
+
+int foo(int a, int b, int p)
+{
+	if (p) {
+		add(a + b, 1);
+		return p;
+	}
+	return 0;
+}
+
+/*
+ * check-name: call-inlined
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+foo:
+.L0:
+	<entry-point>
+	select.32   %r9 <- %arg3, %arg3, $0
+	ret.32      %r9
+
+
+ * check-output-end
+ */
-- 
2.12.0


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

* [PATCH v3 03/30] give function's arguments a type via OP_PUSH
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
  2017-03-19  1:41 ` [PATCH v3 01/30] fix usage of inlined calls Luc Van Oostenryck
  2017-03-19  1:41 ` [PATCH v3 02/30] inlined calls should not block BB packing Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 04/30] give a type to OP_PHISOURCE Luc Van Oostenryck
                   ` (28 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

The linearized code, sparse's IR, have no use of C's complex type
system. Those types are checked in previous phases and the pseudos
doesn't a type directly attached to them as all needed type info
are now conveyed by the instructions (like (register) size,
signedness (OP_DIVU vs OP_DIVS), ...).

In particular, PSEUDO_VAL (used for integer and address constants)
are completely typeless.
There is a problem with this when calling a variadic function
with a constant argument as in this case there is no type in the
function prototype (for the variadic part, of course) and there is
no defining instructions holding the type of the argument.

Fix this by adding a new instruction, OP_PUSH, which will be used
to pass arguments to function calls and whose purpose is to give
a correct type/size to function's arguments.

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Idea-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 example.c                       |  4 ++--
 linearize.c                     | 35 +++++++++++++++++++++++++++--------
 linearize.h                     | 10 +++++++++-
 liveness.c                      | 14 ++++++++------
 simplify.c                      | 11 ++++++++++-
 sparse-llvm.c                   |  4 ++--
 validation/call-variadic.c      | 31 +++++++++++++++++++++++++++++++
 validation/loop-linearization.c |  9 ++++++---
 8 files changed, 95 insertions(+), 23 deletions(-)
 create mode 100644 validation/call-variadic.c

diff --git a/example.c b/example.c
index 691e0f97c..69e00b325 100644
--- a/example.c
+++ b/example.c
@@ -1121,11 +1121,11 @@ static void generate_ret(struct bb_state *state, struct instruction *ret)
  */
 static void generate_call(struct bb_state *state, struct instruction *insn)
 {
+	struct instruction *arg;
 	int offset = 0;
-	pseudo_t arg;
 
 	FOR_EACH_PTR(insn->arguments, arg) {
-		output_insn(state, "pushl %s", generic(state, arg));
+		output_insn(state, "pushl %s", generic(state, arg->src));
 		offset += 4;
 	} END_FOR_EACH_PTR(arg);
 	flush_reg(state, hardregs+0);
diff --git a/linearize.c b/linearize.c
index 5337723e2..54752a1a2 100644
--- a/linearize.c
+++ b/linearize.c
@@ -233,6 +233,7 @@ static const char *opcodes[] = {
 	[OP_FPCAST] = "fpcast",
 	[OP_PTRCAST] = "ptrcast",
 	[OP_INLINED_CALL] = "# call",
+	[OP_PUSH] = "push",
 	[OP_CALL] = "call",
 	[OP_VANEXT] = "va_next",
 	[OP_VAARG] = "va_arg",
@@ -407,17 +408,21 @@ const char *show_instruction(struct instruction *insn)
 	case OP_STORE: case OP_SNOP:
 		buf += sprintf(buf, "%s -> %d[%s]", show_pseudo(insn->target), insn->offset, show_pseudo(insn->src));
 		break;
+	case OP_PUSH:
+		buf += sprintf(buf, "%s", show_pseudo(insn->src));
+		break;
 	case OP_INLINED_CALL:
-	case OP_CALL: {
-		struct pseudo *arg;
+	case OP_CALL:
 		if (insn->target && insn->target != VOID)
 			buf += sprintf(buf, "%s <- ", show_pseudo(insn->target));
 		buf += sprintf(buf, "%s", show_pseudo(insn->func));
-		FOR_EACH_PTR(insn->arguments, arg) {
-			buf += sprintf(buf, ", %s", show_pseudo(arg));
-		} END_FOR_EACH_PTR(arg);
+		if (opcode == OP_INLINED_CALL) {
+			struct pseudo *arg;
+			FOR_EACH_PTR(insn->inlined_args, arg) {
+				buf += sprintf(buf, ", %s", show_pseudo(arg));
+			} END_FOR_EACH_PTR(arg);
+		}
 		break;
-	}
 	case OP_CAST:
 	case OP_SCAST:
 	case OP_FPCAST:
@@ -1197,6 +1202,20 @@ static pseudo_t linearize_assignment(struct entrypoint *ep, struct expression *e
 	return value;
 }
 
+/*
+ * Add an argument for a call.
+ *   -) insn->opcode == O_CALL | OP_INLINE_CALL
+ *   -) ctype = typeof(arg)
+ */
+static void push_argument(struct entrypoint *ep, struct instruction *insn, pseudo_t arg, struct symbol *ctype)
+{
+	struct instruction *push = alloc_typed_instruction(OP_PUSH, ctype);
+	push->call = insn;
+	use_pseudo(push, arg, &push->src);
+	add_instruction(&insn->arguments, push);
+	add_one_insn(ep, push);
+}
+
 static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expression *expr)
 {
 	struct expression *arg, *fn;
@@ -1213,7 +1232,7 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
 
 	FOR_EACH_PTR(expr->args, arg) {
 		pseudo_t new = linearize_expression(ep, arg);
-		use_pseudo(insn, new, add_pseudo(&insn->arguments, new));
+		push_argument(ep, insn, new, arg->ctype);
 	} END_FOR_EACH_PTR(arg);
 
 	fn = expr->fn;
@@ -1680,7 +1699,7 @@ static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement *
 		concat_symbol_list(args->declaration, &ep->syms);
 		FOR_EACH_PTR(args->declaration, sym) {
 			pseudo_t value = linearize_one_symbol(ep, sym);
-			add_pseudo(&insn->arguments, value);
+			add_pseudo(&insn->inlined_args, value);
 		} END_FOR_EACH_PTR(sym);
 	}
 
diff --git a/linearize.h b/linearize.h
index bac82d7ff..0cdd0fa9a 100644
--- a/linearize.h
+++ b/linearize.h
@@ -112,9 +112,16 @@ struct instruction {
 		};
 		struct /* call */ {
 			pseudo_t func;
-			struct pseudo_list *arguments;
+			union {
+				struct instruction_list *arguments;
+				struct pseudo_list *inlined_args;
+			};
 			struct symbol *fntype;
 		};
+		struct /* push/arg */ {
+			pseudo_t arg;			/* same as src, src1 & symbol */
+			struct instruction *call;
+		};
 		struct /* context */ {
 			int increment;
 			int check;
@@ -201,6 +208,7 @@ enum opcode {
 	OP_FPCAST,
 	OP_PTRCAST,
 	OP_INLINED_CALL,
+	OP_PUSH,
 	OP_CALL,
 	OP_VANEXT,
 	OP_VAARG,
diff --git a/liveness.c b/liveness.c
index 7461738b4..7b5b1693a 100644
--- a/liveness.c
+++ b/liveness.c
@@ -46,13 +46,12 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
 	void (*def)(struct basic_block *, pseudo_t),
 	void (*use)(struct basic_block *, pseudo_t))
 {
-	pseudo_t pseudo;
-
 	#define USES(x)		use(bb, insn->x)
 	#define DEFINES(x)	def(bb, insn->x)
 
 	switch (insn->opcode) {
 	case OP_RET:
+	case OP_PUSH:
 		USES(src);
 		break;
 
@@ -118,14 +117,17 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
 		USES(src); DEFINES(target);
 		break;
 
-	case OP_CALL:
+	case OP_CALL: {
+		struct instruction *arg;
+
 		USES(func);
 		if (insn->target != VOID)
 			DEFINES(target);
-		FOR_EACH_PTR(insn->arguments, pseudo) {
-			use(bb, pseudo);
-		} END_FOR_EACH_PTR(pseudo);
+		FOR_EACH_PTR(insn->arguments, arg) {
+			use(bb, arg->src);
+		} END_FOR_EACH_PTR(arg);
 		break;
+	}
 
 	case OP_SLICE:
 		USES(base); DEFINES(target);
diff --git a/simplify.c b/simplify.c
index 5d00937f1..9a3abdff4 100644
--- a/simplify.c
+++ b/simplify.c
@@ -182,6 +182,14 @@ static void kill_use_list(struct pseudo_list *list)
 	} END_FOR_EACH_PTR(p);
 }
 
+static void kill_insn_list(struct instruction_list *list)
+{
+	struct instruction *insn;
+	FOR_EACH_PTR(list, insn) {
+		kill_insn(insn, 0);
+	} END_FOR_EACH_PTR(insn);
+}
+
 /*
  * kill an instruction:
  * - remove it from its bb
@@ -213,6 +221,7 @@ void kill_insn(struct instruction *insn, int force)
 	case OP_SETVAL:
 	case OP_NOT: case OP_NEG:
 	case OP_SLICE:
+	case OP_PUSH:
 		kill_use(&insn->src1);
 		break;
 
@@ -240,7 +249,7 @@ void kill_insn(struct instruction *insn, int force)
 			if (!(insn->func->sym->ctype.modifiers & MOD_PURE))
 				return;
 		}
-		kill_use_list(insn->arguments);
+		kill_insn_list(insn->arguments);
 		if (insn->func->type == PSEUDO_REG)
 			kill_use(&insn->func);
 		break;
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 9f362b3ed..ecc4f032f 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -707,7 +707,7 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 {
 	LLVMValueRef target, func;
 	int n_arg = 0, i;
-	struct pseudo *arg;
+	struct instruction *arg;
 	LLVMValueRef *args;
 
 	FOR_EACH_PTR(insn->arguments, arg) {
@@ -718,7 +718,7 @@ 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);
+		args[i++] = pseudo_to_value(fn, arg, arg->src);
 	} END_FOR_EACH_PTR(arg);
 
 	func = pseudo_to_value(fn, insn, insn->func);
diff --git a/validation/call-variadic.c b/validation/call-variadic.c
new file mode 100644
index 000000000..cbb8aa68b
--- /dev/null
+++ b/validation/call-variadic.c
@@ -0,0 +1,31 @@
+#define NULL	((void*)0)
+
+extern int print(const char *msg, ...);
+
+int foo(const char *fmt, int a, long l, int *p)
+{
+	print("msg %c: %d %d/%ld %ld/%p %p\n", 'x', a, __LINE__, l, 0L, p, NULL);
+}
+
+/*
+ * check-name: call-variadic
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+foo:
+.L0:
+	<entry-point>
+	push.64     "msg %c: %d %d/%ld %ld/%p %p\n"
+	push.32     $120
+	push.32     %arg2
+	push.32     $7
+	push.64     %arg3
+	push.64     $0
+	push.64     %arg4
+	push.64     $0
+	call.32     %r5 <- print
+	ret.32      %r5
+
+
+ * check-output-end
+ */
diff --git a/validation/loop-linearization.c b/validation/loop-linearization.c
index 25c6dfb87..d53366bde 100644
--- a/validation/loop-linearization.c
+++ b/validation/loop-linearization.c
@@ -48,7 +48,8 @@ ffor:
 	cbr         %r2, .L1, .L3
 
 .L1:
-	call.32     %r4 <- p, %r1(i)
+	push.32     %r1(i)
+	call.32     %r4 <- p
 	cbr         %r4, .L2, .L5
 
 .L5:
@@ -81,7 +82,8 @@ fwhile:
 	cbr         %r9, .L9, .L11
 
 .L9:
-	call.32     %r11 <- p, %r8(i)
+	push.32     %r8(i)
+	call.32     %r11 <- p
 	cbr         %r11, .L14, .L13
 
 .L13:
@@ -110,7 +112,8 @@ fdo:
 
 .L17:
 	phi.32      %r15(i) <- %phi16(i), %phi17(i)
-	call.32     %r16 <- p, %r15(i)
+	push.32     %r15(i)
+	call.32     %r16 <- p
 	cbr         %r16, .L18, .L20
 
 .L20:
-- 
2.12.0


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

* [PATCH v3 04/30] give a type to OP_PHISOURCE
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 03/30] give function's arguments a type via OP_PUSH Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 05/30] give a type to OP_SEL, always Luc Van Oostenryck
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

For consistency, give it a type too.

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 ec7e3f22c..9265a099d 100644
--- a/flow.c
+++ b/flow.c
@@ -371,7 +371,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 54752a1a2..6eacb2e36 100644
--- a/linearize.c
+++ b/linearize.c
@@ -820,9 +820,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;
 
@@ -1369,19 +1369,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);
@@ -1395,7 +1394,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;
@@ -1407,12 +1405,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);
@@ -1894,7 +1892,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 0cdd0fa9a..d437e268d 100644
--- a/linearize.h
+++ b/linearize.h
@@ -339,7 +339,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.12.0


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

* [PATCH v3 05/30] give a type to OP_SEL, always
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (3 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 04/30] give a type to OP_PHISOURCE Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 06/30] llvm: remove unneeded arg 'module' Luc Van Oostenryck
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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.

For consistency, give it a type too.

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 6eacb2e36..4ebd6d6d8 100644
--- a/linearize.c
+++ b/linearize.c
@@ -684,7 +684,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.12.0


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

* [PATCH v3 06/30] llvm: remove unneeded arg 'module'
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (4 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 05/30] give a type to OP_SEL, always Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 07/30] llvm: remove unneeded 'generation' Luc Van Oostenryck
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 ecc4f032f..9b702863d 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();
@@ -345,7 +345,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);
@@ -360,7 +360,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 = LLVMConstInt(insn_symbol_type(insn), pseudo->value, 1);
 		break;
 	case PSEUDO_ARG: {
 		result = LLVMGetParam(fn->fn, pseudo->nr - 1);
@@ -519,7 +519,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;
 	}
@@ -531,7 +531,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;
 	}
@@ -557,7 +557,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);
 
 	if (LLVMGetTypeKind(LLVMTypeOf(lhs)) == LLVMIntegerTypeKind) {
 		LLVMIntPredicate op = translate_op(insn->opcode);
@@ -599,7 +599,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 */
@@ -775,7 +775,7 @@ 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);
+	target = LLVMBuildBitCast(fn->builder, src, insn_symbol_type(insn), target_name);
 
 	insn->target->priv = target;
 }
@@ -794,9 +794,9 @@ 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);
+		target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(insn), target_name);
 	else
-		target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(fn->module, insn), target_name);
+		target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(insn), target_name);
 
 	insn->target->priv = target;
 }
@@ -945,12 +945,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);
 
@@ -987,7 +987,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);
@@ -1017,7 +1017,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;
@@ -1037,7 +1037,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.12.0


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

* [PATCH v3 07/30] llvm: remove unneeded 'generation'
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (5 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 06/30] llvm: remove unneeded arg 'module' Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 08/30] llvm: remove unneeded function::type Luc Van Oostenryck
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 9b702863d..f41fbe6e3 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -911,12 +911,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;
@@ -930,7 +928,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;
@@ -964,9 +961,6 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 	static int nr_bb;
 
 	FOR_EACH_PTR(ep->bbs, bb) {
-		if (bb->generation == generation)
-			continue;
-
 		LLVMBasicBlockRef bbr;
 		char bbname[32];
 		struct instruction *insn;
@@ -997,12 +991,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] 36+ messages in thread

* [PATCH v3 08/30] llvm: remove unneeded function::type
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (6 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 07/30] llvm: remove unneeded 'generation' Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 09/30] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 f41fbe6e3..68bd94181 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -21,7 +21,6 @@
 
 struct function {
 	LLVMBuilderRef			builder;
-	LLVMTypeRef			type;
 	LLVMValueRef			fn;
 	LLVMModuleRef			module;
 };
@@ -933,6 +932,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;
@@ -949,9 +949,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.12.0


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

* [PATCH v3 09/30] llvm: reduce scope of 'bb_nr'
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (7 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 08/30] llvm: remove unneeded function::type Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 10/30] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 68bd94181..51fd6a96a 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -958,9 +958,8 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	function.builder = LLVMCreateBuilder();
 
-	static int nr_bb;

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

* [PATCH v3 10/30] llvm: use pseudo_list_size() instead of open coding it
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (8 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 09/30] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 11/30] llvm: give arguments a name Luc Van Oostenryck
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 51fd6a96a..23ae482e1 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -709,10 +709,7 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 	struct instruction *arg;
 	LLVMValueRef *args;
 
-	FOR_EACH_PTR(insn->arguments, arg) {
-		n_arg++;
-	} END_FOR_EACH_PTR(arg);

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

* [PATCH v3 11/30] llvm: give arguments a name
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (9 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 10/30] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 12/30] llvm: give a name to call's return values Luc Van Oostenryck
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 23ae482e1..b9176e19d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -955,6 +955,17 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	function.builder = LLVMCreateBuilder();
 
+	/* 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) {
 		static int nr_bb;
 		LLVMBasicBlockRef bbr;
-- 
2.12.0


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

* [PATCH v3 12/30] llvm: give a name to call's return values
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (10 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 11/30] llvm: give arguments a name Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 13/30] llvm: avoid useless temp variable Luc Van Oostenryck
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 b9176e19d..dd7ff3398 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -297,6 +297,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);
 	}
@@ -708,6 +711,8 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 	int n_arg = 0, i;
 	struct instruction *arg;
 	LLVMValueRef *args;
+	char name[64];
+
 
 	n_arg = instruction_list_size(insn->arguments);
 	args = calloc(n_arg, sizeof(LLVMValueRef));
@@ -718,7 +723,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.12.0


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

* [PATCH v3 13/30] llvm: avoid useless temp variable
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (11 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 12/30] llvm: give a name to call's return values Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 14/30] llvm: extract get_sym_value() from pseudo_to_value() Luc Van Oostenryck
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index dd7ff3398..072cf2638 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -932,9 +932,8 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 {
 	struct symbol *sym = ep->name;
 	struct symbol *base_type = sym->ctype.base_type;
-	struct symbol *ret_type = sym->ctype.base_type->ctype.base_type;
 	LLVMTypeRef arg_types[MAX_ARGS];
-	LLVMTypeRef return_type;
+	LLVMTypeRef ret_type = symbol_type(base_type->ctype.base_type);
 	LLVMTypeRef fun_type;
 	struct function function = { .module = module };
 	struct basic_block *bb;
@@ -950,9 +949,7 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	name = show_ident(sym->ident);
 
-	return_type = symbol_type(ret_type);

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

* [PATCH v3 14/30] llvm: extract get_sym_value() from pseudo_to_value()
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (12 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 13/30] llvm: avoid useless temp variable Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 15/30] llvm: fix test of floating-point type Luc Van Oostenryck
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 072cf2638..d7e8ee725 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -305,6 +305,57 @@ static void pseudo_name(pseudo_t pseudo, char *buf)
 	}
 }
 
+static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
+{
+	LLVMValueRef result = NULL;
+	struct expression *expr;
+
+	assert(sym->bb_target == NULL);
+
+	expr = sym->initializer;
+	if (expr) {
+		switch (expr->type) {
+		case EXPR_STRING: {
+			const char *s = expr->string->data;
+			LLVMValueRef indices[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
+			LLVMValueRef data;
+
+			data = LLVMAddGlobal(fn->module, LLVMArrayType(LLVMInt8Type(), strlen(s) + 1), ".str");
+			LLVMSetLinkage(data, LLVMPrivateLinkage);
+			LLVMSetGlobalConstant(data, 1);
+			LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
+
+			result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
+			break;
+		}
+		case EXPR_SYMBOL: {
+			struct symbol *sym = expr->symbol;
+
+			result = LLVMGetNamedGlobal(fn->module, show_ident(sym->ident));
+			assert(result != NULL);
+			break;
+		}
+		default:
+			assert(0);
+		}
+	} else {
+		const char *name = show_ident(sym->ident);
+		LLVMTypeRef type = symbol_type(sym);
+
+		if (LLVMGetTypeKind(type) == LLVMFunctionTypeKind) {
+			result = LLVMGetNamedFunction(fn->module, name);
+			if (!result)
+				result = LLVMAddFunction(fn->module, name, type);
+		} else {
+			result = LLVMGetNamedGlobal(fn->module, name);
+			if (!result)
+				result = LLVMAddGlobal(fn->module, type, name);
+		}
+	}
+
+	return result;
+}
+
 static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
 {
 	LLVMValueRef result = NULL;
@@ -313,54 +364,9 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 	case PSEUDO_REG:
 		result = pseudo->priv;
 		break;
-	case PSEUDO_SYM: {
-		struct symbol *sym = pseudo->sym;
-		struct expression *expr;
-
-		assert(sym->bb_target == NULL);
-
-		expr = sym->initializer;
-		if (expr) {
-			switch (expr->type) {
-			case EXPR_STRING: {
-				const char *s = expr->string->data;
-				LLVMValueRef indices[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
-				LLVMValueRef data;
-
-				data = LLVMAddGlobal(fn->module, LLVMArrayType(LLVMInt8Type(), strlen(s) + 1), ".str");
-				LLVMSetLinkage(data, LLVMPrivateLinkage);
-				LLVMSetGlobalConstant(data, 1);
-				LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
-
-				result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
-				break;
-			}
-			case EXPR_SYMBOL: {
-				struct symbol *sym = expr->symbol;
-
-				result = LLVMGetNamedGlobal(fn->module, show_ident(sym->ident));
-				assert(result != NULL);
-				break;
-			}
-			default:
-				assert(0);
-			}
-		} else {
-			const char *name = show_ident(sym->ident);
-			LLVMTypeRef type = symbol_type(sym);

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

* [PATCH v3 15/30] llvm: fix test of floating-point type
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (13 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 14/30] llvm: extract get_sym_value() from pseudo_to_value() Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 16/30] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index d7e8ee725..ee3857c49 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -25,14 +25,6 @@ struct function {
 	LLVMModuleRef			module;
 };
 
-static inline bool symbol_is_fp_type(struct symbol *sym)
-{
-	if (!sym)
-		return false;
-
-	return sym->ctype.base_type == &fp_type;
-}
-
 static LLVMTypeRef symbol_type(struct symbol *sym);
 
 static LLVMTypeRef func_return_type(struct symbol *sym)
@@ -154,7 +146,7 @@ static LLVMTypeRef sym_basetype_type(struct symbol *sym)
 {
 	LLVMTypeRef ret = NULL;
 
-	if (symbol_is_fp_type(sym)) {
+	if (is_float_type(sym)) {
 		switch (sym->bit_size) {
 		case 32:
 			ret = LLVMFloatType();
@@ -454,69 +446,69 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 	switch (insn->opcode) {
 	/* Binary */
 	case OP_ADD:
-		if (symbol_is_fp_type(insn->type))
+		if (is_float_type(insn->type))
 			target = LLVMBuildFAdd(fn->builder, lhs, rhs, target_name);
 		else
 			target = LLVMBuildAdd(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_SUB:
-		if (symbol_is_fp_type(insn->type))
+		if (is_float_type(insn->type))
 			target = LLVMBuildFSub(fn->builder, lhs, rhs, target_name);
 		else
 			target = LLVMBuildSub(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_MULU:
-		if (symbol_is_fp_type(insn->type))
+		if (is_float_type(insn->type))
 			target = LLVMBuildFMul(fn->builder, lhs, rhs, target_name);
 		else
 			target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_MULS:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_DIVU:
-		if (symbol_is_fp_type(insn->type))
+		if (is_float_type(insn->type))
 			target = LLVMBuildFDiv(fn->builder, lhs, rhs, target_name);
 		else
 			target = LLVMBuildUDiv(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_DIVS:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildSDiv(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_MODU:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildURem(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_MODS:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildSRem(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_SHL:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildShl(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_LSR:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildLShr(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_ASR:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildAShr(fn->builder, lhs, rhs, target_name);
 		break;
 	
 	/* Logical */
 	case OP_AND:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildAnd(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_OR:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildOr(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_XOR:
-		assert(!symbol_is_fp_type(insn->type));
+		assert(!is_float_type(insn->type));
 		target = LLVMBuildXor(fn->builder, lhs, rhs, target_name);
 		break;
 	case OP_AND_BOOL: {
@@ -781,7 +773,7 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 
 	pseudo_name(insn->target, target_name);
 
-	assert(!symbol_is_fp_type(insn->type));
+	assert(!is_float_type(insn->type));
 
 	target = LLVMBuildBitCast(fn->builder, src, insn_symbol_type(insn), target_name);
 
@@ -799,7 +791,7 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 
 	pseudo_name(insn->target, target_name);
 
-	assert(!symbol_is_fp_type(insn->type));
+	assert(!is_float_type(insn->type));
 
 	if (insn->size < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
 		target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(insn), target_name);
-- 
2.12.0


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

* [PATCH v3 16/30] llvm: fix translation of PSEUDO_VALs into a ValueRefs
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (14 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 15/30] llvm: fix test of floating-point type Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 17/30] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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                         | 31 ++++++++++++++++++++++++++++++-
 validation/backend/constant-pointer.c | 24 ++++++++++++++++++++++++
 validation/backend/type-constant.c    | 23 +++++++++++++++++++++++
 3 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 validation/backend/constant-pointer.c
 create mode 100644 validation/backend/type-constant.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index ee3857c49..94ebc9577 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -348,6 +348,35 @@ static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
 	return result;
 }
 
+static LLVMValueRef constant_value(unsigned long long val, LLVMTypeRef dtype)
+{
+	LLVMTypeRef itype;
+	LLVMValueRef result;
+
+	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 val_to_value(unsigned long long val, struct symbol *ctype)
+{
+	LLVMTypeRef dtype;
+
+	assert(ctype);
+	dtype = symbol_type(ctype);
+	return constant_value(val, dtype);
+}
+
 static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
 {
 	LLVMValueRef result = NULL;
@@ -360,7 +389,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 		result = get_sym_value(fn, pseudo->sym);
 		break;
 	case PSEUDO_VAL:
-		result = LLVMConstInt(insn_symbol_type(insn), pseudo->value, 1);
+		result = val_to_value(pseudo->value, insn->type);
 		break;
 	case PSEUDO_ARG: {
 		result = LLVMGetParam(fn->fn, pseudo->nr - 1);
diff --git a/validation/backend/constant-pointer.c b/validation/backend/constant-pointer.c
new file mode 100644
index 000000000..9012c7843
--- /dev/null
+++ b/validation/backend/constant-pointer.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: constant pointers
+ * check-command: sparse-llvm $file
+ * check-output-ignore
+ */
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.12.0


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

* [PATCH v3 17/30] llvm: fix output_op_store() which modify its operand
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (15 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 16/30] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 18/30] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 94ebc9577..e01406281 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -651,16 +651,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.12.0


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

* [PATCH v3 18/30] llvm: fix output_op_[ptr]cast()
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (16 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 17/30] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 19/30] llvm: take care of degenerated rvalues Luc Van Oostenryck
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 e01406281..733fc467c 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -792,6 +792,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;
@@ -802,15 +804,31 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 
 	assert(!is_float_type(insn->type));
 
-	target = LLVMBuildBitCast(fn->builder, src, insn_symbol_type(insn), target_name);
+	dtype = insn_symbol_type(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)
@@ -820,11 +838,23 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 
 	assert(!is_float_type(insn->type));
 
-	if (insn->size < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
-		target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(insn), target_name);
-	else
-		target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(insn), target_name);
+	dtype = insn_symbol_type(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.12.0


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

* [PATCH v3 19/30] llvm: take care of degenerated rvalues
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (17 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 18/30] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 20/30] llvm: add test cases for symbol's address Luc Van Oostenryck
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 733fc467c..57445e83e 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -408,6 +408,14 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 	return result;
 }
 
+static LLVMValueRef pseudo_to_rvalue(struct function *fn, struct instruction *insn, pseudo_t pseudo)
+{
+	LLVMValueRef val = pseudo_to_value(fn, insn, pseudo);
+	LLVMTypeRef dtype = symbol_type(insn->type);
+
+	return LLVMBuildBitCast(fn->builder, val, dtype, "");
+}
+
 static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValueRef off)
 {
 	LLVMTypeRef type = LLVMTypeOf(base);
@@ -655,7 +663,7 @@ static void output_op_store(struct function *fn, struct instruction *insn)
 
 	addr = calc_memop_addr(fn, insn);
 
-	target_in = pseudo_to_value(fn, insn, insn->target);
+	target_in = pseudo_to_rvalue(fn, insn, insn->target);
 
 	/* perform store */
 	LLVMBuildStore(fn->builder, target_in, addr);
@@ -744,7 +752,7 @@ 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, arg, arg->src);
+		args[i++] = pseudo_to_rvalue(fn, arg, arg->src);
 	} END_FOR_EACH_PTR(arg);
 
 	func = pseudo_to_value(fn, insn, insn->func);
-- 
2.12.0


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

* [PATCH v3 20/30] llvm: add test cases for symbol's address
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (18 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 19/30] llvm: take care of degenerated rvalues Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 21/30] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/backend/symaddr.c | 62 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 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..71bca2d76
--- /dev/null
+++ b/validation/backend/symaddr.c
@@ -0,0 +1,62 @@
+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(&larrd[1]);
+	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(&sarrd[1]);
+	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(&xarrd[1]);
+	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(&garrd[1]);
+	useia(&garrf);
+	usevp(gfun);
+	usevp(&gpun);
+}
+
+/*
+ * check-name: symbol address
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v3 21/30] llvm: add test cases for pointers passed as argument
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (19 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 20/30] llvm: add test cases for symbol's address Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 22/30] llvm: add test cases for arrays " Luc Van Oostenryck
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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.12.0


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

* [PATCH v3 22/30] llvm: add test cases for arrays passed as argument
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (20 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 21/30] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 23/30] llvm: add test cases for degenerated pointers Luc Van Oostenryck
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

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

diff --git a/validation/backend/function-ptr.c b/validation/backend/function-ptr.c
index fc022b3cd..47e85deab 100644
--- a/validation/backend/function-ptr.c
+++ b/validation/backend/function-ptr.c
@@ -1,8 +1,150 @@
-typedef int (*fn_t)(int x, int y);
+extern int ival;
+extern int *ipval;
+extern int array[3];
+extern int matrix[3][3];
+extern int fun(int);
 
-static int run(fn_t fn, int x, int y)
+// 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)))
 {
-	return fn(x, y);
+	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);
+	fip(array);
+	fim(matrix);
+
+	fvp(p);
+	fvp((void*)0);
+	fvp(ipval);
+	fvp(&ival);
+	fvp(array);
+	fvp(matrix);
+
+	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);
+	fip(array);
+	fim(matrix);
+
+	fvp(p);
+	fvp((void*)0);
+	fvp(ipval);
+	fvp(&ival);
+	fvp(array);
+	fvp(matrix);
+
+	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->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);
+	ops->ffp(fun);
+	ops->ffp(&fun);
+	ops->fvp(fi);
+
+	ops->cfi(42);
 }
 
 /*
-- 
2.12.0


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

* [PATCH v3 23/30] llvm: add test cases for degenerated pointers
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (21 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 22/30] llvm: add test cases for arrays " Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 24/30] llvm: add support for OP_NEG Luc Van Oostenryck
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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.12.0


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

* [PATCH v3 24/30] llvm: add support for OP_NEG
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (22 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 23/30] llvm: add test cases for degenerated pointers Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 25/30] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 57445e83e..833fb20df 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -951,9 +951,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 (is_float_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.12.0


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

* [PATCH v3 25/30] llvm: fix pointer/float mixup in comparisons
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (23 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 24/30] llvm: add support for OP_NEG Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 26/30] llvm: fix type in comparison with an address constant Luc Van Oostenryck
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, 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 833fb20df..55843950d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -596,14 +596,27 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 
 	LLVMTypeRef dst_type = insn_symbol_type(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.12.0


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

* [PATCH v3 26/30] llvm: fix type in comparison with an address constant
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (24 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 25/30] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 27/30] llvm: give correct type to binops Luc Van Oostenryck
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

Since sparse's constant are typeless comparing a pointer with
an address constant lack correct type information.

Fix this by casting the constant to the same type as the LHS.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                          |  3 +--
 validation/backend/compare-with-null.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)
 create mode 100644 validation/backend/compare-with-null.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 55843950d..fda9484d7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -586,9 +586,8 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 	char target_name[64];
 
 	lhs = pseudo_to_value(fn, insn, insn->src1);
-
 	if (insn->src2->type == PSEUDO_VAL)
-		rhs = LLVMConstInt(LLVMTypeOf(lhs), insn->src2->value, 1);
+		rhs = constant_value(insn->src2->value, LLVMTypeOf(lhs));
 	else
 		rhs = pseudo_to_value(fn, insn, insn->src2);
 
diff --git a/validation/backend/compare-with-null.c b/validation/backend/compare-with-null.c
new file mode 100644
index 000000000..e23562bc5
--- /dev/null
+++ b/validation/backend/compare-with-null.c
@@ -0,0 +1,12 @@
+int  tstv(void *p) { return !p; }
+int  cmpv(void *p) { return p == ((void*)0); }
+
+int  tsti(int  *p) { return !p; }
+int  cmpi(int  *p) { return p == ((int *)0); }
+int  cmpx(int  *p) { return p == ((void*)0); }
+
+/*
+ * check-name: compare-with-null
+ * check-command: sparsec -Wno-decl -c $file -o tmp.o
+ * check-output-ignore
+ */
-- 
2.12.0


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

* [PATCH v3 27/30] llvm: give correct type to binops
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (25 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 26/30] llvm: fix type in comparison with an address constant Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 28/30] llvm: adjust OP_RET's type Luc Van Oostenryck
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

Pointer arithmetic and/or simplification can mixup pointer
and integer types.

Fix this by adding casts before all non-floating point binops
and adjust the result type if needed to match the instructio.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                    | 30 ++++++++++++++++++++++
 validation/backend/pointer-add.c | 54 ++++++++++++++++++++++++++++++++++++++++
 validation/backend/pointer-sub.c | 18 ++++++++++++++
 validation/backend/symaddr.c     |  8 ++++++
 4 files changed, 110 insertions(+)
 create mode 100644 validation/backend/pointer-add.c
 create mode 100644 validation/backend/pointer-sub.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index fda9484d7..332a5e2a1 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -416,6 +416,33 @@ static LLVMValueRef pseudo_to_rvalue(struct function *fn, struct instruction *in
 	return LLVMBuildBitCast(fn->builder, val, dtype, "");
 }
 
+static LLVMValueRef value_to_ivalue(struct function *fn, LLVMValueRef val)
+{
+	if (LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMPointerTypeKind) {
+		LLVMTypeRef dtype = LLVMIntType(bits_in_pointer);
+		val = LLVMBuildPtrToInt(fn->builder, val, dtype, "");
+	}
+	return val;
+}
+
+static LLVMValueRef value_to_pvalue(struct function *fn, struct symbol *ctype, LLVMValueRef val)
+{
+	if (LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMIntegerTypeKind) {
+		LLVMTypeRef dtype = symbol_type(ctype);
+		val = LLVMBuildIntToPtr(fn->builder, val, dtype, "");
+	}
+	return val;
+}
+
+static LLVMValueRef adjust_type(struct function *fn, struct symbol *ctype, LLVMValueRef val)
+{
+	if (is_int_type(ctype))
+		return value_to_ivalue(fn, val);
+	if (is_ptr_type(ctype))
+		return value_to_pvalue(fn, ctype, val);
+	return val;
+}
+
 static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValueRef off)
 {
 	LLVMTypeRef type = LLVMTypeOf(base);
@@ -475,8 +502,10 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 	char target_name[64];
 
 	lhs = pseudo_to_value(fn, insn, insn->src1);
+	lhs = value_to_ivalue(fn, lhs);
 
 	rhs = pseudo_to_value(fn, insn, insn->src2);
+	rhs = value_to_ivalue(fn, rhs);
 
 	pseudo_name(insn->target, target_name);
 
@@ -577,6 +606,7 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 		break;
 	}
 
+	target = adjust_type(fn, insn->type, target);
 	insn->target->priv = target;
 }
 
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
+ */
diff --git a/validation/backend/pointer-sub.c b/validation/backend/pointer-sub.c
new file mode 100644
index 000000000..4017faf69
--- /dev/null
+++ b/validation/backend/pointer-sub.c
@@ -0,0 +1,18 @@
+long subv0(void *p, int   a) { return p - ((void*)0); }
+long subvc(void *p, int   a) { return p - ((void*)8); }
+long subva(void *p, int   a) { return p - ((void*)a); }
+long subvq(void *p, void *q) { return p - q; }
+
+long subi0(int  *p, int   a) { return p - ((int *)0); }
+long subic(int  *p, int   a) { return p - ((int *)8); }
+long subia(int  *p, int   a) { return p - ((int *)a); }
+long subiq(int  *p, int  *q) { return p - q; }
+
+long subvm3(void *p, int   a) { return (p - ((void*)0)) * 3; }
+long subvx3(void *p, int   a) { return (p - ((void*)0)) ^ 3; }
+
+/*
+ * check-name: pointer-sub
+ * check-command: sparsec -Wno-decl -c $file -o tmp.o
+ * check-known-to-fail
+ */
diff --git a/validation/backend/symaddr.c b/validation/backend/symaddr.c
index 71bca2d76..71fb9deff 100644
--- a/validation/backend/symaddr.c
+++ b/validation/backend/symaddr.c
@@ -10,7 +10,9 @@ void lfoo(int *p, int a)
 	useip(p);
 	useip(larra);
 	useip(larrb + 1);
+	useip(larrc + a);
 	useip(&larrd[1]);
+	useip(&larre[a]);
 	useia(&larrf);
 }
 
@@ -22,7 +24,9 @@ void sfoo(int *p, int a)
 	useip(&s);
 	useip(sarra);
 	useip(sarrb + 1);
+	useip(sarrc + a);
 	useip(&sarrd[1]);
+	useip(&sarre[a]);
 	useia(&sarrf);
 	usevp(sfun);
 	usevp(&spun);
@@ -36,7 +40,9 @@ void xfoo(int *p, int a)
 	useip(&x);
 	useip(xarra);
 	useip(xarrb + 1);
+	useip(xarrc + a);
 	useip(&xarrd[1]);
+	useip(&xarre[a]);
 	useia(&xarrf);
 	usevp(xfun);
 	usevp(&xpun);
@@ -50,7 +56,9 @@ void gfoo(int *p, int a)
 	useip(&g);
 	useip(garra);
 	useip(garrb + 1);
+	useip(garrc + a);
 	useip(&garrd[1]);
+	useip(&garre[a]);
 	useia(&garrf);
 	usevp(gfun);
 	usevp(&gpun);
-- 
2.12.0


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

* [PATCH v3 28/30] llvm: adjust OP_RET's type
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (26 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 27/30] llvm: give correct type to binops Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 29/30] llvm: variadic functions are not being marked as such Luc Van Oostenryck
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                    | 1 +
 validation/backend/pointer-sub.c | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 332a5e2a1..f320f7288 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -660,6 +660,7 @@ static void output_op_ret(struct function *fn, struct instruction *insn)
 	if (pseudo && pseudo != VOID) {
 		LLVMValueRef result = pseudo_to_value(fn, insn, pseudo);
 
+		result = adjust_type(fn, insn->type, result);
 		LLVMBuildRet(fn->builder, result);
 	} else
 		LLVMBuildRetVoid(fn->builder);
diff --git a/validation/backend/pointer-sub.c b/validation/backend/pointer-sub.c
index 4017faf69..3cb8f5a9d 100644
--- a/validation/backend/pointer-sub.c
+++ b/validation/backend/pointer-sub.c
@@ -14,5 +14,4 @@ long subvx3(void *p, int   a) { return (p - ((void*)0)) ^ 3; }
 /*
  * check-name: pointer-sub
  * check-command: sparsec -Wno-decl -c $file -o tmp.o
- * check-known-to-fail
  */
-- 
2.12.0


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

* [PATCH v3 29/30] llvm: variadic functions are not being marked as such
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (27 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 28/30] llvm: adjust OP_RET's type Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19  1:42 ` [PATCH v3 30/30] llvm: fix type of switch constants Luc Van Oostenryck
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

It appears that when a function is compiled, its variadic flag is not
being set in LLVM so LLVM complains when at call sites variable
arguments are passed.

Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Originally-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index f320f7288..bae55de3b 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -1068,7 +1068,7 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	name = show_ident(sym->ident);
 
-	fun_type = LLVMFunctionType(ret_type, arg_types, nr_args, 0);
+	fun_type = LLVMFunctionType(ret_type, arg_types, nr_args, base_type->variadic);
 
 	function.fn = LLVMAddFunction(module, name, fun_type);
 	LLVMSetFunctionCallConv(function.fn, LLVMCCallConv);
-- 
2.12.0


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

* [PATCH v3 30/30] llvm: fix type of switch constants
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (28 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 29/30] llvm: variadic functions are not being marked as such Luc Van Oostenryck
@ 2017-03-19  1:42 ` Luc Van Oostenryck
  2017-03-19 16:09 ` [PATCH 00/30] LLVM fixes Dibyendu Majumdar
  2017-03-19 16:28 ` Christopher Li
  31 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19  1:42 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Dibyendu Majumdar, Luc Van Oostenryck

In sparse-llvm, the type of switch constants are hardcoded
to 'i32'.

Fix this by using the right type as given by the instruction.

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index bae55de3b..c01d3ea41 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -771,7 +771,7 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 	FOR_EACH_PTR(insn->multijmp_list, jmp) {
 		if (jmp->begin == jmp->end) {		/* case N */
 			LLVMAddCase(target,
-				LLVMConstInt(LLVMInt32Type(), jmp->begin, 0),
+				val_to_value(jmp->begin, insn->type),
 				jmp->target->priv);
 		} else if (jmp->begin < jmp->end) {	/* case M..N */
 			assert(0);
-- 
2.12.0


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

* Re: [PATCH 00/30] LLVM fixes
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (29 preceding siblings ...)
  2017-03-19  1:42 ` [PATCH v3 30/30] llvm: fix type of switch constants Luc Van Oostenryck
@ 2017-03-19 16:09 ` Dibyendu Majumdar
  2017-03-19 18:41   ` Dibyendu Majumdar
  2017-03-19 16:28 ` Christopher Li
  31 siblings, 1 reply; 36+ messages in thread
From: Dibyendu Majumdar @ 2017-03-19 16:09 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse, Christopher Li

Hi Luc,

On 19 March 2017 at 01:41, 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.
> Most of these issues have been reported and investigated by
> Dibyendu Majumdar.
>
> Changes since v2:
> - remove the changes tha gave a type to PSEUDO_VALs
> - introduction of OP_PUSH instructions
> - move toward generic solution using the instruction's type
> - some more fixes
> - temporary remove changes related to OP_SYMADDR
>
> * patches 1 & 2 are fixes/improvement of inlined call
>           unrelated to LLVM
> * patch   3 add support of OP_PUSH and solve variadic + constant
> * patches 4 & 5 add missing type to some instructions
> * patches 6-14 are preparatory cleanups
> * patch   15 fix a problme with floats & SYM_NODE
> * patch   16 improve the typing of contants
> * patches 17 & 18 are fixes
> * patch   19 fix issues with degenerated pointers
> * patches 20-23 add test cases solved by patch 19
> * patches 24-30 are fixes
>
> 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)
> - there is a bunch of problems 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-v3
>
>
> Luc Van Oostenryck (30):
>   fix usage of inlined calls
>   inlined calls should not block BB packing
>   give function's arguments a type via OP_PUSH
>   give a type to OP_PHISOURCE
>   give a type to OP_SEL, always
>   llvm: remove unneeded arg 'module'
>   llvm: remove unneeded 'generation'
>   llvm: remove unneeded function::type
>   llvm: reduce scope of 'bb_nr'
>   llvm: use pseudo_list_size() instead of open coding it
>   llvm: give arguments a name
>   llvm: give a name to call's return values
>   llvm: avoid useless temp variable
>   llvm: extract get_sym_value() from pseudo_to_value()
>   llvm: fix test of floating-point type
>   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: take care of degenerated rvalues
>   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: fix type in comparison with an address constant
>   llvm: give correct type to binops
>   llvm: adjust OP_RET's type
>   llvm: variadic functions are not being marked as such
>   llvm: fix type of switch constants
>

Thank you for posting this series. I have applied the OP_PUSH changes
to my repository and removed the previous solution of types on
PSEUDO_VALs, and I am happy to report that it did not cause any new
failures in my test cases. I haven't yet checked some of the other
fixes above as I already had fixes for these, so I am not yet able to
confirm whether these resolve the issues I faced. I will try them out
over the next few days and report back.

Regards
Dibyendu

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

* Re: [PATCH 00/30] LLVM fixes
  2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
                   ` (30 preceding siblings ...)
  2017-03-19 16:09 ` [PATCH 00/30] LLVM fixes Dibyendu Majumdar
@ 2017-03-19 16:28 ` Christopher Li
  2017-03-19 16:51   ` Luc Van Oostenryck
  31 siblings, 1 reply; 36+ messages in thread
From: Christopher Li @ 2017-03-19 16:28 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse, Dibyendu Majumdar

On Sat, Mar 18, 2017 at 6:41 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.
> Most of these issues have been reported and investigated by
> Dibyendu Majumdar.


Thanks for the patches.

I will take a look and try it on sparse-next.

Chris

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

* Re: [PATCH 00/30] LLVM fixes
  2017-03-19 16:28 ` Christopher Li
@ 2017-03-19 16:51   ` Luc Van Oostenryck
  2017-03-19 21:02     ` Luc Van Oostenryck
  0 siblings, 1 reply; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19 16:51 UTC (permalink / raw)
  To: Christopher Li; +Cc: Linux-Sparse, Dibyendu Majumdar

On Sun, Mar 19, 2017 at 09:28:31AM -0700, Christopher Li wrote:
> On Sat, Mar 18, 2017 at 6:41 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.
> > Most of these issues have been reported and investigated by
> > Dibyendu Majumdar.
> 
> 
> Thanks for the patches.
> 
> I will take a look and try it on sparse-next.

OK, thanks.
It seems that you will need to drop patch 2 as a late addition
of a test case cause a failure of in the test suite (but the code itself
is OK).

I'll respin the serie later after your review.

-- Luc 

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

* Re: [PATCH 00/30] LLVM fixes
  2017-03-19 16:09 ` [PATCH 00/30] LLVM fixes Dibyendu Majumdar
@ 2017-03-19 18:41   ` Dibyendu Majumdar
  0 siblings, 0 replies; 36+ messages in thread
From: Dibyendu Majumdar @ 2017-03-19 18:41 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse, Christopher Li

Hi Luc,

On 19 March 2017 at 16:09, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote:
> On 19 March 2017 at 01:41, 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.
>> Most of these issues have been reported and investigated by
>> Dibyendu Majumdar.
>>
>> Changes since v2:
>> - remove the changes tha gave a type to PSEUDO_VALs
>> - introduction of OP_PUSH instructions
>> - move toward generic solution using the instruction's type
>> - some more fixes
>> - temporary remove changes related to OP_SYMADDR
>>
>> * patches 1 & 2 are fixes/improvement of inlined call
>>           unrelated to LLVM
>> * patch   3 add support of OP_PUSH and solve variadic + constant
>> * patches 4 & 5 add missing type to some instructions
>> * patches 6-14 are preparatory cleanups
>> * patch   15 fix a problme with floats & SYM_NODE
>> * patch   16 improve the typing of contants
>> * patches 17 & 18 are fixes
>> * patch   19 fix issues with degenerated pointers
>> * patches 20-23 add test cases solved by patch 19
>> * patches 24-30 are fixes
>>
>> 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)
>> - there is a bunch of problems 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-v3
>>
>>
>> Luc Van Oostenryck (30):
>>   fix usage of inlined calls
>>   inlined calls should not block BB packing
>>   give function's arguments a type via OP_PUSH
>>   give a type to OP_PHISOURCE
>>   give a type to OP_SEL, always
>>   llvm: remove unneeded arg 'module'
>>   llvm: remove unneeded 'generation'
>>   llvm: remove unneeded function::type
>>   llvm: reduce scope of 'bb_nr'
>>   llvm: use pseudo_list_size() instead of open coding it
>>   llvm: give arguments a name
>>   llvm: give a name to call's return values
>>   llvm: avoid useless temp variable
>>   llvm: extract get_sym_value() from pseudo_to_value()
>>   llvm: fix test of floating-point type
>>   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: take care of degenerated rvalues
>>   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: fix type in comparison with an address constant
>>   llvm: give correct type to binops
>>   llvm: adjust OP_RET's type
>>   llvm: variadic functions are not being marked as such
>>   llvm: fix type of switch constants
>>
>
> Thank you for posting this series. I have applied the OP_PUSH changes
> to my repository and removed the previous solution of types on
> PSEUDO_VALs, and I am happy to report that it did not cause any new
> failures in my test cases. I haven't yet checked some of the other
> fixes above as I already had fixes for these, so I am not yet able to
> confirm whether these resolve the issues I faced. I will try them out
> over the next few days and report back.
>

I have successfully tested the binary ops changes, but the comparison
and rvalue changes appear to not cover all cases. I will see if I can
submit tests.

Thanks and Regards
Dibyendu

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

* Re: [PATCH 00/30] LLVM fixes
  2017-03-19 16:51   ` Luc Van Oostenryck
@ 2017-03-19 21:02     ` Luc Van Oostenryck
  0 siblings, 0 replies; 36+ messages in thread
From: Luc Van Oostenryck @ 2017-03-19 21:02 UTC (permalink / raw)
  To: Christopher Li; +Cc: Linux-Sparse, Dibyendu Majumdar

On Sun, Mar 19, 2017 at 5:51 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Sun, Mar 19, 2017 at 09:28:31AM -0700, Christopher Li wrote:
>> On Sat, Mar 18, 2017 at 6:41 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.
>> > Most of these issues have been reported and investigated by
>> > Dibyendu Majumdar.
>>
>>
>> Thanks for the patches.
>>
>> I will take a look and try it on sparse-next.
>
> OK, thanks.
> It seems that you will need to drop patch 2 as a late addition
> of a test case cause a failure of in the test suite (but the code itself
> is OK).
>
> I'll respin the serie later after your review.

Also, don't spend too much time on the part involving
..._rvalue(),_ivalue() & _pvalue() as I'm rewritting this
to make it more generic & systematic.

-- Luc

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

end of thread, other threads:[~2017-03-19 21:11 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-19  1:41 [PATCH 00/30] LLVM fixes Luc Van Oostenryck
2017-03-19  1:41 ` [PATCH v3 01/30] fix usage of inlined calls Luc Van Oostenryck
2017-03-19  1:41 ` [PATCH v3 02/30] inlined calls should not block BB packing Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 03/30] give function's arguments a type via OP_PUSH Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 04/30] give a type to OP_PHISOURCE Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 05/30] give a type to OP_SEL, always Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 06/30] llvm: remove unneeded arg 'module' Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 07/30] llvm: remove unneeded 'generation' Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 08/30] llvm: remove unneeded function::type Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 09/30] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 10/30] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 11/30] llvm: give arguments a name Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 12/30] llvm: give a name to call's return values Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 13/30] llvm: avoid useless temp variable Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 14/30] llvm: extract get_sym_value() from pseudo_to_value() Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 15/30] llvm: fix test of floating-point type Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 16/30] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 17/30] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 18/30] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 19/30] llvm: take care of degenerated rvalues Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 20/30] llvm: add test cases for symbol's address Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 21/30] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 22/30] llvm: add test cases for arrays " Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 23/30] llvm: add test cases for degenerated pointers Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 24/30] llvm: add support for OP_NEG Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 25/30] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 26/30] llvm: fix type in comparison with an address constant Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 27/30] llvm: give correct type to binops Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 28/30] llvm: adjust OP_RET's type Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 29/30] llvm: variadic functions are not being marked as such Luc Van Oostenryck
2017-03-19  1:42 ` [PATCH v3 30/30] llvm: fix type of switch constants Luc Van Oostenryck
2017-03-19 16:09 ` [PATCH 00/30] LLVM fixes Dibyendu Majumdar
2017-03-19 18:41   ` Dibyendu Majumdar
2017-03-19 16:28 ` Christopher Li
2017-03-19 16:51   ` Luc Van Oostenryck
2017-03-19 21:02     ` Luc Van Oostenryck

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.