All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/52] LLVM fixes
@ 2017-03-27 21:23 Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 01/52] llvm: remove unneeded arg 'module' Luc Van Oostenryck
                   ` (53 more replies)
  0 siblings, 54 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 v5:
- avoid declare a var inside a for-loop for non C99 compilers
- fix naming of symbol without an indent
- avoid sparsec to leave its tmp file

Changes since v4:
- extract the non sparse-llvm specific patches into
  a separate, preparatory serie.

Changes since v3:
- systematically insure that operands and output values
  have the expected type (which may different than the
  stored with). Some work may still be needed here.
- add support for OP_SWITCH with a range
- add support for floating-point casts (to and from)
- add support for OP_SETVAL (floats & labels)
- fix type of globals having an initializer

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


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-v5

Luc Van Oostenryck (52):
  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: add support for OP_SETVAL with floats
  llvm: add support for OP_SETVAL with labels
  llvm: ignore OP_INLINED_CALL
  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
  llvm: make pseudo_name() more flexible
  llvm: give a name to all values
  llvm: add support for OP_SWITCH with a range
  llvm: fix OP_SWITCH has no target
  llvm: make value_to_pvalue() more flexible
  llvm: make value_to_ivalue() more flexible
  llvm: add test case pointer compare with cast
  llvm: let pseudo_to_value() directly use the type
  llvm: remove unneeded pseudo_to_value() unneeded argument
  llvm: introduce get_ioperand()
  llvm: fix mutating function pointer
  llvm: fix mutated OP_RET
  llvm: fix mutated OP_SEL
  llvm: fix mutated OP_SWITCH
  llvm: fix mutated OP_PHISOURCE
  llvm: fix mutated OP_[PTR]CAST
  llvm: add support for restricted types
  llvm: fix get value from initialized symbol
  llvm: fix get value from non-anonymous symbol
  llvm: fix type of bitfields
  llvm: add support for OP_FPCAST
  llvm: add support for cast from floats
  llvm: cleanup of output_[ptr]cast()
  llvm: fix creation of sparsec's tmp files

 sparse-llvm.c                           | 584 +++++++++++++++++++++-----------
 sparsec                                 |   4 +-
 validation/backend/cast.c               |   7 +-
 validation/backend/compare-with-null.c  |  12 +
 validation/backend/constant-pointer.c   |  24 ++
 validation/backend/degenerate-ptr.c     |  72 ++++
 validation/backend/function-ptr-xtype.c |  37 ++
 validation/backend/function-ptr.c       | 148 +++++++-
 validation/backend/label-as-value.c     |  13 +
 validation/backend/load-global.c        |  21 ++
 validation/backend/pointer-add.c        |  54 +++
 validation/backend/pointer-cmp.c        |  12 +
 validation/backend/pointer-param.c      |  42 +++
 validation/backend/pointer-sub.c        |  17 +
 validation/backend/setval.c             |   7 +
 validation/backend/shift-special.c      |  13 +
 validation/backend/store-x2.c           |  16 +
 validation/backend/string-value.c       |  21 ++
 validation/backend/switch.c             | 248 ++++++++++++++
 validation/backend/symaddr.c            |  70 ++++
 validation/backend/type-constant.c      |  23 ++
 21 files changed, 1233 insertions(+), 212 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/function-ptr-xtype.c
 create mode 100644 validation/backend/label-as-value.c
 create mode 100644 validation/backend/load-global.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/setval.c
 create mode 100644 validation/backend/shift-special.c
 create mode 100644 validation/backend/store-x2.c
 create mode 100644 validation/backend/string-value.c
 create mode 100644 validation/backend/switch.c
 create mode 100644 validation/backend/symaddr.c
 create mode 100644 validation/backend/type-constant.c

-- 
2.12.0


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

* [PATCH v6 01/52] llvm: remove unneeded arg 'module'
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 02/52] llvm: remove unneeded 'generation' Luc Van Oostenryck
                   ` (52 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 02/52] llvm: remove unneeded 'generation'
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 01/52] llvm: remove unneeded arg 'module' Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 03/52] llvm: remove unneeded function::type Luc Van Oostenryck
                   ` (51 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 03/52] llvm: remove unneeded function::type
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 01/52] llvm: remove unneeded arg 'module' Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 02/52] llvm: remove unneeded 'generation' Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 04/52] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
                   ` (50 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 04/52] llvm: reduce scope of 'bb_nr'
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 03/52] llvm: remove unneeded function::type Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 05/52] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
                   ` (49 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 05/52] llvm: use pseudo_list_size() instead of open coding it
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (3 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 04/52] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 06/52] llvm: give arguments a name Luc Van Oostenryck
                   ` (48 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 06/52] llvm: give arguments a name
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (4 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 05/52] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 07/52] llvm: give a name to call's return values Luc Van Oostenryck
                   ` (47 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 23ae482e1..53c13122b 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -935,6 +935,7 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 	struct symbol *arg;
 	const char *name;
 	int nr_args = 0;
+	int i;
 
 	FOR_EACH_PTR(base_type->arguments, arg) {
 		struct symbol *arg_base_type = arg->ctype.base_type;
@@ -955,6 +956,17 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
 
 	function.builder = LLVMCreateBuilder();
 
+	/* give a name to each argument */
+	for (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] 57+ messages in thread

* [PATCH v6 07/52] llvm: give a name to call's return values
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (5 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 06/52] llvm: give arguments a name Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 08/52] llvm: avoid useless temp variable Luc Van Oostenryck
                   ` (46 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 53c13122b..8de144e2a 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] 57+ messages in thread

* [PATCH v6 08/52] llvm: avoid useless temp variable
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (6 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 07/52] llvm: give a name to call's return values Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 09/52] llvm: extract get_sym_value() from pseudo_to_value() Luc Van Oostenryck
                   ` (45 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 8de144e2a..db38bcda5 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;
@@ -951,9 +950,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] 57+ messages in thread

* [PATCH v6 09/52] llvm: extract get_sym_value() from pseudo_to_value()
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (7 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 08/52] llvm: avoid useless temp variable Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 10/52] llvm: fix test of floating-point type Luc Van Oostenryck
                   ` (44 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 db38bcda5..3435295f5 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] 57+ messages in thread

* [PATCH v6 10/52] llvm: fix test of floating-point type
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (8 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 09/52] llvm: extract get_sym_value() from pseudo_to_value() Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 11/52] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
                   ` (43 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 3435295f5..1b19721c8 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] 57+ messages in thread

* [PATCH v6 11/52] llvm: fix translation of PSEUDO_VALs into a ValueRefs
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (9 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 10/52] llvm: fix test of floating-point type Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 12/52] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
                   ` (42 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 1b19721c8..d0ae829f2 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] 57+ messages in thread

* [PATCH v6 12/52] llvm: fix output_op_store() which modify its operand
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (10 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 11/52] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 13/52] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
                   ` (41 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 d0ae829f2..8894c2fa8 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] 57+ messages in thread

* [PATCH v6 13/52] llvm: fix output_op_[ptr]cast()
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (11 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 12/52] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 14/52] llvm: take care of degenerated rvalues Luc Van Oostenryck
                   ` (40 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 8894c2fa8..c5af97141 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))	// cast to void* is OP_CAST ...
+		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] 57+ messages in thread

* [PATCH v6 14/52] llvm: take care of degenerated rvalues
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (12 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 13/52] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 15/52] llvm: add test cases for symbol's address Luc Van Oostenryck
                   ` (39 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 c5af97141..0e7670ed6 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] 57+ messages in thread

* [PATCH v6 15/52] llvm: add test cases for symbol's address
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (13 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 14/52] llvm: take care of degenerated rvalues Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 16/52] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
                   ` (38 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 16/52] llvm: add test cases for pointers passed as argument
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (14 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 15/52] llvm: add test cases for symbol's address Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 17/52] llvm: add test cases for arrays " Luc Van Oostenryck
                   ` (37 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 17/52] llvm: add test cases for arrays passed as argument
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (15 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 16/52] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 18/52] llvm: add test cases for degenerated pointers Luc Van Oostenryck
                   ` (36 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 18/52] llvm: add test cases for degenerated pointers
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (16 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 17/52] llvm: add test cases for arrays " Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 19/52] llvm: add support for OP_NEG Luc Van Oostenryck
                   ` (35 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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] 57+ messages in thread

* [PATCH v6 19/52] llvm: add support for OP_NEG
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (17 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 18/52] llvm: add test cases for degenerated pointers Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 20/52] llvm: add support for OP_SETVAL with floats Luc Van Oostenryck
                   ` (34 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 0e7670ed6..a06ecdb82 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] 57+ messages in thread

* [PATCH v6 20/52] llvm: add support for OP_SETVAL with floats
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (18 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 19/52] llvm: add support for OP_NEG Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 21/52] llvm: add support for OP_SETVAL with labels Luc Van Oostenryck
                   ` (33 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c               | 19 ++++++++++++++++++-
 validation/backend/setval.c |  7 +++++++
 2 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 validation/backend/setval.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index a06ecdb82..abd1d04c2 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -866,6 +866,23 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 	insn->target->priv = target;
 }
 
+static void output_op_setval(struct function *fn, struct instruction *insn)
+{
+	struct expression *val = insn->val;
+	LLVMTypeRef dtype = symbol_type(insn->type);
+	LLVMValueRef target;
+
+	switch (val->type) {
+	case EXPR_FVALUE:
+		target = LLVMConstReal(dtype, val->fvalue);
+		break;
+	default:
+		assert(0);
+	}
+
+	insn->target->priv = target;
+}
+
 static void output_insn(struct function *fn, struct instruction *insn)
 {
 	switch (insn->opcode) {
@@ -882,7 +899,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		assert(0);
 		break;
 	case OP_SETVAL:
-		assert(0);
+		output_op_setval(fn, insn);
 		break;
 	case OP_SWITCH:
 		output_op_switch(fn, insn);
diff --git a/validation/backend/setval.c b/validation/backend/setval.c
new file mode 100644
index 000000000..e3557571d
--- /dev/null
+++ b/validation/backend/setval.c
@@ -0,0 +1,7 @@
+double setfval64(void) { return 1.23; }
+float  setfval32(void) { return 1.23F; }
+
+/*
+ * check-name: setval-float
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v6 21/52] llvm: add support for OP_SETVAL with labels
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (19 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 20/52] llvm: add support for OP_SETVAL with floats Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 22/52] llvm: ignore OP_INLINED_CALL Luc Van Oostenryck
                   ` (32 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index abd1d04c2..9633941e7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -876,6 +876,9 @@ static void output_op_setval(struct function *fn, struct instruction *insn)
 	case EXPR_FVALUE:
 		target = LLVMConstReal(dtype, val->fvalue);
 		break;
+	case EXPR_LABEL:
+		target = LLVMBlockAddress(fn->fn, val->symbol->bb_target->priv);
+		break;
 	default:
 		assert(0);
 	}
diff --git a/validation/backend/label-as-value.c b/validation/backend/label-as-value.c
new file mode 100644
index 000000000..6888c6613
--- /dev/null
+++ b/validation/backend/label-as-value.c
@@ -0,0 +1,13 @@
+void *foo(void *def);
+void *foo(void *def)
+{
+	if (!def)
+yes:		return &&yes;
+
+	return def;
+}
+
+/*
+ * check-name: label-as-value
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v6 22/52] llvm: ignore OP_INLINED_CALL
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (20 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 21/52] llvm: add support for OP_SETVAL with labels Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 23/52] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
                   ` (31 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 9633941e7..c64bfe2f7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -929,7 +929,6 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		assert(0);
 		break;
 	case OP_INLINED_CALL:
-		assert(0);
 		break;
 	case OP_CALL:
 		output_op_call(fn, insn);
-- 
2.12.0


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

* [PATCH v6 23/52] llvm: fix pointer/float mixup in comparisons
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (21 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 22/52] llvm: ignore OP_INLINED_CALL Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 24/52] llvm: fix type in comparison with an address constant Luc Van Oostenryck
                   ` (30 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 c64bfe2f7..86c57ab33 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] 57+ messages in thread

* [PATCH v6 24/52] llvm: fix type in comparison with an address constant
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (22 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 23/52] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 25/52] llvm: give correct type to binops Luc Van Oostenryck
                   ` (29 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 86c57ab33..f81a8c657 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] 57+ messages in thread

* [PATCH v6 25/52] llvm: give correct type to binops
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (23 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 24/52] llvm: fix type in comparison with an address constant Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 26/52] llvm: adjust OP_RET's type Luc Van Oostenryck
                   ` (28 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 f81a8c657..b89b04105 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] 57+ messages in thread

* [PATCH v6 26/52] llvm: adjust OP_RET's type
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (24 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 25/52] llvm: give correct type to binops Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 27/52] llvm: variadic functions are not being marked as such Luc Van Oostenryck
                   ` (27 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 b89b04105..dad330443 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] 57+ messages in thread

* [PATCH v6 27/52] llvm: variadic functions are not being marked as such
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (25 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 26/52] llvm: adjust OP_RET's type Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 28/52] llvm: fix type of switch constants Luc Van Oostenryck
                   ` (26 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 dad330443..7978579f3 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -1088,7 +1088,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] 57+ messages in thread

* [PATCH v6 28/52] llvm: fix type of switch constants
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (26 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 27/52] llvm: variadic functions are not being marked as such Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 29/52] llvm: make pseudo_name() more flexible Luc Van Oostenryck
                   ` (25 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 7978579f3..31411d9d1 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] 57+ messages in thread

* [PATCH v6 29/52] llvm: make pseudo_name() more flexible
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (27 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 28/52] llvm: fix type of switch constants Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 30/52] llvm: give a name to all values Luc Van Oostenryck
                   ` (24 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 31411d9d1..4e4fb2ea5 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -270,31 +270,26 @@ static LLVMLinkage function_linkage(struct symbol *sym)
 
 #define MAX_PSEUDO_NAME 64
 
-static void pseudo_name(pseudo_t pseudo, char *buf)
+static const char *pseudo_name(pseudo_t pseudo, char *buf)
 {
 	switch (pseudo->type) {
 	case PSEUDO_REG:
 		snprintf(buf, MAX_PSEUDO_NAME, "R%d", pseudo->nr);
 		break;
-	case PSEUDO_SYM:
-		assert(0);
-		break;
-	case PSEUDO_VAL:
-		assert(0);
-		break;
-	case PSEUDO_ARG: {
-		assert(0);
-		break;
-	}
 	case PSEUDO_PHI:
 		snprintf(buf, MAX_PSEUDO_NAME, "PHI%d", pseudo->nr);
 		break;
+	case PSEUDO_SYM:
+	case PSEUDO_VAL:
+	case PSEUDO_ARG:
 	case PSEUDO_VOID:
 		buf[0] = '\0';
 		break;
 	default:
 		assert(0);
 	}
+
+	return buf;
 }
 
 static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
-- 
2.12.0


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

* [PATCH v6 30/52] llvm: give a name to all values
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (28 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 29/52] llvm: make pseudo_name() more flexible Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 31/52] llvm: add support for OP_SWITCH with a range Luc Van Oostenryck
                   ` (23 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 4e4fb2ea5..3c7b669fe 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -407,15 +407,18 @@ static LLVMValueRef pseudo_to_rvalue(struct function *fn, struct instruction *in
 {
 	LLVMValueRef val = pseudo_to_value(fn, insn, pseudo);
 	LLVMTypeRef dtype = symbol_type(insn->type);
+	char name[MAX_PSEUDO_NAME];
 
-	return LLVMBuildBitCast(fn->builder, val, dtype, "");
+	pseudo_name(pseudo, name);
+	return LLVMBuildBitCast(fn->builder, val, dtype, name);
 }
 
 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, "");
+		const char *name = LLVMGetValueName(val);
+		val = LLVMBuildPtrToInt(fn->builder, val, dtype, name);
 	}
 	return val;
 }
@@ -424,7 +427,8 @@ static LLVMValueRef value_to_pvalue(struct function *fn, struct symbol *ctype, L
 {
 	if (LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMIntegerTypeKind) {
 		LLVMTypeRef dtype = symbol_type(ctype);
-		val = LLVMBuildIntToPtr(fn->builder, val, dtype, "");
+		const char *name = LLVMGetValueName(val);
+		val = LLVMBuildIntToPtr(fn->builder, val, dtype, name);
 	}
 	return val;
 }
@@ -444,13 +448,14 @@ static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValu
 	unsigned int as = LLVMGetPointerAddressSpace(type);
 	LLVMTypeRef bytep = LLVMPointerType(LLVMInt8Type(), as);
 	LLVMValueRef addr;
+	const char *name = LLVMGetValueName(off);
 
 	/* convert base to char* type */
-	base = LLVMBuildPointerCast(builder, base, bytep, "");
+	base = LLVMBuildPointerCast(builder, base, bytep, name);
 	/* addr = base + off */
-	addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, "");
+	addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, name);
 	/* convert back to the actual pointer type */
-	addr = LLVMBuildPointerCast(builder, addr, type, "");
+	addr = LLVMBuildPointerCast(builder, addr, type, name);
 	return addr;
 }
 
@@ -576,8 +581,8 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 		LLVMValueRef lhs_nz, rhs_nz;
 		LLVMTypeRef dst_type;
 
-		lhs_nz = LLVMBuildIsNotNull(fn->builder, lhs, "");
-		rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, "");
+		lhs_nz = LLVMBuildIsNotNull(fn->builder, lhs, LLVMGetValueName(lhs));
+		rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, LLVMGetValueName(rhs));
 		target = LLVMBuildAnd(fn->builder, lhs_nz, rhs_nz, target_name);
 
 		dst_type = insn_symbol_type(insn);
@@ -588,8 +593,8 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 		LLVMValueRef lhs_nz, rhs_nz;
 		LLVMTypeRef dst_type;
 
-		lhs_nz = LLVMBuildIsNotNull(fn->builder, lhs, "");
-		rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, "");
+		lhs_nz = LLVMBuildIsNotNull(fn->builder, lhs, LLVMGetValueName(lhs));
+		rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, LLVMGetValueName(rhs));
 		target = LLVMBuildOr(fn->builder, lhs_nz, rhs_nz, target_name);
 
 		dst_type = insn_symbol_type(insn);
@@ -675,7 +680,7 @@ static LLVMValueRef calc_memop_addr(struct function *fn, struct instruction *ins
 	src = pseudo_to_value(fn, insn, insn->src);
 	as = LLVMGetPointerAddressSpace(LLVMTypeOf(src));
 	addr_type = LLVMPointerType(insn_symbol_type(insn), as);
-	src = LLVMBuildPointerCast(fn->builder, src, addr_type, "");
+	src = LLVMBuildPointerCast(fn->builder, src, addr_type, LLVMGetValueName(src));
 
 	/* addr = src + off */
 	addr = calc_gep(fn->builder, src, off);
@@ -686,11 +691,13 @@ static LLVMValueRef calc_memop_addr(struct function *fn, struct instruction *ins
 static void output_op_load(struct function *fn, struct instruction *insn)
 {
 	LLVMValueRef addr, target;
+	char name[MAX_PSEUDO_NAME];
 
 	addr = calc_memop_addr(fn, insn);
 
 	/* perform load */
-	target = LLVMBuildLoad(fn->builder, addr, "load_target");
+	pseudo_name(insn->target, name);
+	target = LLVMBuildLoad(fn->builder, addr, name);
 
 	insn->target->priv = target;
 }
@@ -710,7 +717,7 @@ static void output_op_store(struct function *fn, struct instruction *insn)
 static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
 {
 	if (LLVMTypeOf(value) != LLVMInt1Type())
-		value = LLVMBuildIsNotNull(fn->builder, value, "cond");
+		value = LLVMBuildIsNotNull(fn->builder, value, LLVMGetValueName(value));
 
 	return value;
 }
@@ -733,12 +740,14 @@ static void output_op_br(struct function *fn, struct instruction *br)
 static void output_op_sel(struct function *fn, struct instruction *insn)
 {
 	LLVMValueRef target, src1, src2, src3;
+	char name[MAX_PSEUDO_NAME];
 
 	src1 = bool_value(fn, pseudo_to_value(fn, insn, insn->src1));
 	src2 = pseudo_to_value(fn, insn, insn->src2);
 	src3 = pseudo_to_value(fn, insn, insn->src3);
 
-	target = LLVMBuildSelect(fn->builder, src1, src2, src3, "select");
+	pseudo_name(insn->target, name);
+	target = LLVMBuildSelect(fn->builder, src1, src2, src3, name);
 
 	insn->target->priv = target;
 }
-- 
2.12.0


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

* [PATCH v6 31/52] llvm: add support for OP_SWITCH with a range
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (29 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 30/52] llvm: give a name to all values Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 32/52] llvm: fix OP_SWITCH has no target Luc Van Oostenryck
                   ` (22 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 3c7b669fe..5b25bb0c1 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -760,10 +760,8 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 	int n_jmp = 0;
 
 	FOR_EACH_PTR(insn->multijmp_list, jmp) {
-		if (jmp->begin == jmp->end) {		/* case N */
-			n_jmp++;
-		} else if (jmp->begin < jmp->end) {	/* case M..N */
-			assert(0);
+		if (jmp->begin <= jmp->end) {
+			n_jmp += (jmp->end - jmp->begin) + 1;
 		} else					/* default case */
 			def = jmp->target;
 	} END_FOR_EACH_PTR(jmp);
@@ -773,12 +771,11 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 				 def ? def->priv : NULL, n_jmp);
 
 	FOR_EACH_PTR(insn->multijmp_list, jmp) {
-		if (jmp->begin == jmp->end) {		/* case N */
-			LLVMAddCase(target,
-				val_to_value(jmp->begin, insn->type),
-				jmp->target->priv);
-		} else if (jmp->begin < jmp->end) {	/* case M..N */
-			assert(0);
+		long val;
+
+		for (val = jmp->begin; val <= jmp->end; val++) {
+			LLVMValueRef Val = val_to_value(val, insn->type);
+			LLVMAddCase(target, Val, jmp->target->priv);
 		}
 	} END_FOR_EACH_PTR(jmp);
 
-- 
2.12.0


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

* [PATCH v6 32/52] llvm: fix OP_SWITCH has no target
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (30 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 31/52] llvm: add support for OP_SWITCH with a range Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 33/52] llvm: make value_to_pvalue() more flexible Luc Van Oostenryck
                   ` (21 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 5b25bb0c1..884570e1d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -771,15 +771,13 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 				 def ? def->priv : NULL, n_jmp);
 
 	FOR_EACH_PTR(insn->multijmp_list, jmp) {
-		long val;
+		long long val;
 
 		for (val = jmp->begin; val <= jmp->end; val++) {
 			LLVMValueRef Val = val_to_value(val, insn->type);
 			LLVMAddCase(target, Val, jmp->target->priv);
 		}
 	} END_FOR_EACH_PTR(jmp);
-
-	insn->target->priv = target;
 }
 
 static void output_op_call(struct function *fn, struct instruction *insn)
diff --git a/validation/backend/switch.c b/validation/backend/switch.c
new file mode 100644
index 000000000..d77250cc3
--- /dev/null
+++ b/validation/backend/switch.c
@@ -0,0 +1,248 @@
+int def(void);
+int r0(void);
+int r1(void);
+int r2(void);
+int r3(void);
+int r4(void);
+int r5(void);
+int r6(void);
+int r7(void);
+int r8(void);
+int r9(void);
+
+int small(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 1: return r1();
+	case 2: return r2();
+	}
+
+	return def();
+}
+
+int densefull(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 1: return r1();
+	case 2: return r2();
+	case 3: return r3();
+	case 4: return r4();
+	case 5: return r5();
+	case 6: return r6();
+	case 7: return r7();
+	case 8: return r8();
+	case 9: return r9();
+	}
+
+	return def();
+}
+
+int densepart(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 1: return r1();
+	case 2: return r2();
+	case 3: return r3();
+	case 4: return r4();
+
+	case 6: return r6();
+	case 7: return r7();
+	case 8: return r8();
+	case 9: return r9();
+	}
+
+	return def();
+}
+
+int dense_dense_20(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 1: return r1();
+	case 2: return r2();
+	case 3: return r3();
+	case 4: return r4();
+	case 5: return r5();
+	case 6: return r6();
+	case 7: return r7();
+	case 8: return r8();
+	case 9: return r9();
+
+	case 20: return r0();
+	case 21: return r1();
+	case 22: return r2();
+	case 23: return r3();
+	case 24: return r4();
+	case 25: return r5();
+	case 26: return r6();
+	case 27: return r7();
+	case 28: return r8();
+	case 29: return r9();
+	}
+
+	return def();
+}
+
+int dense_dense_100(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 1: return r1();
+	case 2: return r2();
+	case 3: return r3();
+	case 4: return r4();
+	case 5: return r5();
+	case 6: return r6();
+	case 7: return r7();
+	case 8: return r8();
+	case 9: return r9();
+
+	case 100: return r0();
+	case 101: return r1();
+	case 102: return r2();
+	case 103: return r3();
+	case 104: return r4();
+	case 105: return r5();
+	case 106: return r6();
+	case 107: return r7();
+	case 108: return r8();
+	case 109: return r9();
+	}
+
+	return def();
+}
+
+int dense_dense_1000(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 1: return r1();
+	case 2: return r2();
+	case 3: return r3();
+	case 4: return r4();
+	case 5: return r5();
+	case 6: return r6();
+	case 7: return r7();
+	case 8: return r8();
+	case 9: return r9();
+
+	case 1000: return r0();
+	case 1001: return r1();
+	case 1002: return r2();
+	case 1003: return r3();
+	case 1004: return r4();
+	case 1005: return r5();
+	case 1006: return r6();
+	case 1007: return r7();
+	case 1008: return r8();
+	case 1009: return r9();
+	}
+
+	return def();
+}
+
+int sparse(int a)
+{
+	switch (a) {
+	case 0: return r0();
+	case 3: return r1();
+	case 12: return r2();
+	case 31: return r3();
+	case 54: return r4();
+	case 75: return r5();
+	case 96: return r6();
+	case 107: return r7();
+	case 189: return r8();
+	case 999: return r9();
+	}
+
+	return def();
+}
+
+int range_simple(int a)
+{
+	switch (a) {
+	case 1 ... 9: return r0();
+	}
+
+	return def();
+}
+
+int range_complex(int a)
+{
+	switch (a) {
+	case -1: return r0();
+	case 1 ... 9: return r0();
+	case 10 ... 19: return r1();
+	case 200 ... 202: return r2();
+	case 300 ... 303: return r3();
+	}
+
+	return def();
+}
+
+void switch_call(int a)
+{
+	int r;
+
+	switch (a) {
+	case 0: r0(); break;
+	case 1: r1(); break;
+	case 2: r2(); break;
+	case 3: r3(); break;
+	case 4: r4(); break;
+	case 5: r5(); break;
+	case 6: r6(); break;
+	case 7: r7(); break;
+	case 8: r8(); break;
+	case 9: r9(); break;
+	}
+}
+
+int switch_retcall(int a)
+{
+	int r = 0;
+
+	switch (a) {
+	case 0: r = r0(); break;
+	case 1: r = r1(); break;
+	case 2: r = r2(); break;
+	case 3: r = r3(); break;
+	case 4: r = r4(); break;
+	case 5: r = r5(); break;
+	case 6: r = r6(); break;
+	case 7: r = r7(); break;
+	case 8: r = r8(); break;
+	case 9: r = r9(); break;
+	}
+
+	return r;
+}
+
+int switch_cmov(int a)
+{
+	int r;
+
+	switch (a) {
+	case 0: r = 3; break;
+	case 1: r = 1; break;
+	case 2: r = 7; break;
+	case 3: r = 2; break;
+	case 4: r = 9; break;
+
+	case 6: r = 5; break;
+	case 7: r = 8; break;
+	case 8: r = 6; break;
+	case 9: r = 4; break;
+	}
+
+	return r;
+}
+
+/*
+ * check-name: llvm-switch
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v6 33/52] llvm: make value_to_pvalue() more flexible
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (31 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 32/52] llvm: fix OP_SWITCH has no target Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 34/52] llvm: make value_to_ivalue() " Luc Van Oostenryck
                   ` (20 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 884570e1d..57f662a79 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -425,10 +425,19 @@ static LLVMValueRef value_to_ivalue(struct function *fn, LLVMValueRef val)
 
 static LLVMValueRef value_to_pvalue(struct function *fn, struct symbol *ctype, LLVMValueRef val)
 {
-	if (LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMIntegerTypeKind) {
-		LLVMTypeRef dtype = symbol_type(ctype);
-		const char *name = LLVMGetValueName(val);
+	const char *name = LLVMGetValueName(val);
+	LLVMTypeRef dtype = symbol_type(ctype);
+
+	assert(is_ptr_type(ctype));
+	switch (LLVMGetTypeKind(LLVMTypeOf(val))) {
+	case LLVMIntegerTypeKind:
 		val = LLVMBuildIntToPtr(fn->builder, val, dtype, name);
+		break;
+	case LLVMPointerTypeKind:
+		val = LLVMBuildBitCast(fn->builder, val, dtype, name);
+		break;
+	default:
+		break;
 	}
 	return val;
 }
-- 
2.12.0


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

* [PATCH v6 34/52] llvm: make value_to_ivalue() more flexible
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (32 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 33/52] llvm: make value_to_pvalue() more flexible Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:23 ` [PATCH v6 35/52] llvm: add test case pointer compare with cast Luc Van Oostenryck
                   ` (19 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                      | 15 ++++++++++-----
 validation/backend/shift-special.c | 13 +++++++++++++
 2 files changed, 23 insertions(+), 5 deletions(-)
 create mode 100644 validation/backend/shift-special.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 57f662a79..4be3e4358 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -413,13 +413,18 @@ static LLVMValueRef pseudo_to_rvalue(struct function *fn, struct instruction *in
 	return LLVMBuildBitCast(fn->builder, val, dtype, name);
 }
 
-static LLVMValueRef value_to_ivalue(struct function *fn, LLVMValueRef val)
+static LLVMValueRef value_to_ivalue(struct function *fn, struct symbol *ctype, LLVMValueRef val)
 {
+	const char *name = LLVMGetValueName(val);
+	LLVMTypeRef dtype = symbol_type(ctype);
+
 	if (LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMPointerTypeKind) {
 		LLVMTypeRef dtype = LLVMIntType(bits_in_pointer);
-		const char *name = LLVMGetValueName(val);
 		val = LLVMBuildPtrToInt(fn->builder, val, dtype, name);
 	}
+	if (ctype && is_int_type(ctype)) {
+		val = LLVMBuildIntCast(fn->builder, val, dtype, name);
+	}
 	return val;
 }
 
@@ -445,7 +450,7 @@ static LLVMValueRef value_to_pvalue(struct function *fn, struct symbol *ctype, L
 static LLVMValueRef adjust_type(struct function *fn, struct symbol *ctype, LLVMValueRef val)
 {
 	if (is_int_type(ctype))
-		return value_to_ivalue(fn, val);
+		return value_to_ivalue(fn, ctype, val);
 	if (is_ptr_type(ctype))
 		return value_to_pvalue(fn, ctype, val);
 	return val;
@@ -511,10 +516,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);
+	lhs = value_to_ivalue(fn, insn->type, lhs);
 
 	rhs = pseudo_to_value(fn, insn, insn->src2);
-	rhs = value_to_ivalue(fn, rhs);
+	rhs = value_to_ivalue(fn, insn->type, rhs);
 
 	pseudo_name(insn->target, target_name);
 
diff --git a/validation/backend/shift-special.c b/validation/backend/shift-special.c
new file mode 100644
index 000000000..d5e4d3d32
--- /dev/null
+++ b/validation/backend/shift-special.c
@@ -0,0 +1,13 @@
+long shift(long a, short b);
+long shift(long a, short b)
+{
+	long r1 = a << b;
+	long r2 = b << a;
+
+	return r1 + r2;
+}
+
+/*
+ * check-name: shift-special
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v6 35/52] llvm: add test case pointer compare with cast
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (33 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 34/52] llvm: make value_to_ivalue() " Luc Van Oostenryck
@ 2017-03-27 21:23 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 36/52] llvm: let pseudo_to_value() directly use the type Luc Van Oostenryck
                   ` (18 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:23 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/validation/backend/pointer-cmp.c b/validation/backend/pointer-cmp.c
index fa76d1b57..d1eec0ed2 100644
--- a/validation/backend/pointer-cmp.c
+++ b/validation/backend/pointer-cmp.c
@@ -3,6 +3,9 @@ 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; }
 
+int cmpmptr(long  x, int  *y)	{ return (int*)x == y; }
+int cmpnptr(int  *x, long  y)	{ return x == (int*)y; }
+
 /*
  * check-name: pointer comparison
  * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
-- 
2.12.0


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

* [PATCH v6 36/52] llvm: let pseudo_to_value() directly use the type
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (34 preceding siblings ...)
  2017-03-27 21:23 ` [PATCH v6 35/52] llvm: add test case pointer compare with cast Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 37/52] llvm: remove unneeded pseudo_to_value() unneeded argument Luc Van Oostenryck
                   ` (17 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 4be3e4358..29f0c079d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -372,7 +372,7 @@ static LLVMValueRef val_to_value(unsigned long long val, struct symbol *ctype)
 	return constant_value(val, dtype);
 }
 
-static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
+static LLVMValueRef pseudo_to_value(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
 {
 	LLVMValueRef result = NULL;
 
@@ -384,7 +384,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 		result = get_sym_value(fn, pseudo->sym);
 		break;
 	case PSEUDO_VAL:
-		result = val_to_value(pseudo->value, insn->type);
+		result = val_to_value(pseudo->value, ctype);
 		break;
 	case PSEUDO_ARG: {
 		result = LLVMGetParam(fn->fn, pseudo->nr - 1);
@@ -405,7 +405,7 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
 
 static LLVMValueRef pseudo_to_rvalue(struct function *fn, struct instruction *insn, pseudo_t pseudo)
 {
-	LLVMValueRef val = pseudo_to_value(fn, insn, pseudo);
+	LLVMValueRef val = pseudo_to_value(fn, insn->type, pseudo);
 	LLVMTypeRef dtype = symbol_type(insn->type);
 	char name[MAX_PSEUDO_NAME];
 
@@ -515,10 +515,10 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 	LLVMValueRef lhs, rhs, target;
 	char target_name[64];
 
-	lhs = pseudo_to_value(fn, insn, insn->src1);
+	lhs = pseudo_to_value(fn, insn->type, insn->src1);
 	lhs = value_to_ivalue(fn, insn->type, lhs);
 
-	rhs = pseudo_to_value(fn, insn, insn->src2);
+	rhs = pseudo_to_value(fn, insn->type, insn->src2);
 	rhs = value_to_ivalue(fn, insn->type, rhs);
 
 	pseudo_name(insn->target, target_name);
@@ -629,11 +629,11 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 	LLVMValueRef lhs, rhs, target;
 	char target_name[64];
 
-	lhs = pseudo_to_value(fn, insn, insn->src1);
+	lhs = pseudo_to_value(fn, insn->type, insn->src1);
 	if (insn->src2->type == PSEUDO_VAL)
 		rhs = constant_value(insn->src2->value, LLVMTypeOf(lhs));
 	else
-		rhs = pseudo_to_value(fn, insn, insn->src2);
+		rhs = pseudo_to_value(fn, insn->type, insn->src2);
 
 	pseudo_name(insn->target, target_name);
 
@@ -672,7 +672,7 @@ static void output_op_ret(struct function *fn, struct instruction *insn)
 	pseudo_t pseudo = insn->src;
 
 	if (pseudo && pseudo != VOID) {
-		LLVMValueRef result = pseudo_to_value(fn, insn, pseudo);
+		LLVMValueRef result = pseudo_to_value(fn, insn->type, pseudo);
 
 		result = adjust_type(fn, insn->type, result);
 		LLVMBuildRet(fn->builder, result);
@@ -691,7 +691,7 @@ static LLVMValueRef calc_memop_addr(struct function *fn, struct instruction *ins
 	off = LLVMConstInt(int_type, insn->offset, 0);
 
 	/* convert src to the effective pointer type */
-	src = pseudo_to_value(fn, insn, insn->src);
+	src = pseudo_to_value(fn, insn->type, insn->src);
 	as = LLVMGetPointerAddressSpace(LLVMTypeOf(src));
 	addr_type = LLVMPointerType(insn_symbol_type(insn), as);
 	src = LLVMBuildPointerCast(fn->builder, src, addr_type, LLVMGetValueName(src));
@@ -739,7 +739,7 @@ static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
 static void output_op_cbr(struct function *fn, struct instruction *br)
 {
 	LLVMValueRef cond = bool_value(fn,
-			pseudo_to_value(fn, br, br->cond));
+			pseudo_to_value(fn, br->type, br->cond));
 
 	LLVMBuildCondBr(fn->builder, cond,
 			br->bb_true->priv,
@@ -756,9 +756,9 @@ static void output_op_sel(struct function *fn, struct instruction *insn)
 	LLVMValueRef target, src1, src2, src3;
 	char name[MAX_PSEUDO_NAME];
 
-	src1 = bool_value(fn, pseudo_to_value(fn, insn, insn->src1));
-	src2 = pseudo_to_value(fn, insn, insn->src2);
-	src3 = pseudo_to_value(fn, insn, insn->src3);
+	src1 = bool_value(fn, pseudo_to_value(fn, insn->type, insn->src1));
+	src2 = pseudo_to_value(fn, insn->type, insn->src2);
+	src3 = pseudo_to_value(fn, insn->type, insn->src3);
 
 	pseudo_name(insn->target, name);
 	target = LLVMBuildSelect(fn->builder, src1, src2, src3, name);
@@ -780,7 +780,7 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 			def = jmp->target;
 	} END_FOR_EACH_PTR(jmp);
 
-	sw_val = pseudo_to_value(fn, insn, insn->target);
+	sw_val = pseudo_to_value(fn, insn->type, insn->target);
 	target = LLVMBuildSwitch(fn->builder, sw_val,
 				 def ? def->priv : NULL, n_jmp);
 
@@ -811,7 +811,7 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 		args[i++] = pseudo_to_rvalue(fn, arg, arg->src);
 	} END_FOR_EACH_PTR(arg);
 
-	func = pseudo_to_value(fn, insn, insn->func);
+	func = pseudo_to_value(fn, insn->type, insn->func);
 	pseudo_name(insn->target, name);
 	target = LLVMBuildCall(fn->builder, func, args, n_arg, name);
 
@@ -826,7 +826,7 @@ static void output_op_phisrc(struct function *fn, struct instruction *insn)
 	assert(insn->target->priv == NULL);
 
 	/* target = src */
-	v = pseudo_to_value(fn, insn, insn->phi_src);
+	v = pseudo_to_value(fn, insn->type, insn->phi_src);
 
 	FOR_EACH_PTR(insn->phi_users, phi) {
 		LLVMValueRef load, ptr;
@@ -862,7 +862,7 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 
 	src = insn->src->priv;
 	if (!src)
-		src = pseudo_to_value(fn, insn, insn->src);
+		src = pseudo_to_value(fn, insn->type, insn->src);
 
 	pseudo_name(insn->target, target_name);
 
@@ -896,7 +896,7 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 
 	src = insn->src->priv;
 	if (!src)
-		src = pseudo_to_value(fn, insn, insn->src);
+		src = pseudo_to_value(fn, insn->type, insn->src);
 
 	pseudo_name(insn->target, target_name);
 
@@ -1017,7 +1017,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		LLVMValueRef src, target;
 		char target_name[64];
 
-		src = pseudo_to_value(fn, insn, insn->src);
+		src = pseudo_to_value(fn, insn->type, insn->src);
 
 		pseudo_name(insn->target, target_name);
 
@@ -1030,7 +1030,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		LLVMValueRef src, target;
 		char target_name[64];
 
-		src = pseudo_to_value(fn, insn, insn->src);
+		src = pseudo_to_value(fn, insn->type, insn->src);
 
 		pseudo_name(insn->target, target_name);
 
-- 
2.12.0


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

* [PATCH v6 37/52] llvm: remove unneeded pseudo_to_value() unneeded argument
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (35 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 36/52] llvm: let pseudo_to_value() directly use the type Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 38/52] llvm: introduce get_ioperand() Luc Van Oostenryck
                   ` (16 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 29f0c079d..58fe8e213 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -629,11 +629,11 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 	LLVMValueRef lhs, rhs, target;
 	char target_name[64];
 
-	lhs = pseudo_to_value(fn, insn->type, insn->src1);
+	lhs = pseudo_to_value(fn, NULL, insn->src1);
 	if (insn->src2->type == PSEUDO_VAL)
 		rhs = constant_value(insn->src2->value, LLVMTypeOf(lhs));
 	else
-		rhs = pseudo_to_value(fn, insn->type, insn->src2);
+		rhs = pseudo_to_value(fn, NULL, insn->src2);
 
 	pseudo_name(insn->target, target_name);
 
@@ -739,7 +739,7 @@ static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
 static void output_op_cbr(struct function *fn, struct instruction *br)
 {
 	LLVMValueRef cond = bool_value(fn,
-			pseudo_to_value(fn, br->type, br->cond));
+			pseudo_to_value(fn, NULL, br->cond));
 
 	LLVMBuildCondBr(fn->builder, cond,
 			br->bb_true->priv,
@@ -756,7 +756,7 @@ static void output_op_sel(struct function *fn, struct instruction *insn)
 	LLVMValueRef target, src1, src2, src3;
 	char name[MAX_PSEUDO_NAME];
 
-	src1 = bool_value(fn, pseudo_to_value(fn, insn->type, insn->src1));
+	src1 = bool_value(fn, pseudo_to_value(fn, NULL, insn->src1));
 	src2 = pseudo_to_value(fn, insn->type, insn->src2);
 	src3 = pseudo_to_value(fn, insn->type, insn->src3);
 
@@ -811,7 +811,7 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 		args[i++] = pseudo_to_rvalue(fn, arg, arg->src);
 	} END_FOR_EACH_PTR(arg);
 
-	func = pseudo_to_value(fn, insn->type, insn->func);
+	func = pseudo_to_value(fn, NULL, insn->func);
 	pseudo_name(insn->target, name);
 	target = LLVMBuildCall(fn->builder, func, args, n_arg, name);
 
-- 
2.12.0


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

* [PATCH v6 38/52] llvm: introduce get_ioperand()
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (36 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 37/52] llvm: remove unneeded pseudo_to_value() unneeded argument Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 39/52] llvm: fix mutating function pointer Luc Van Oostenryck
                   ` (15 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 58fe8e213..0c92eab23 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -456,6 +456,27 @@ static LLVMValueRef adjust_type(struct function *fn, struct symbol *ctype, LLVMV
 	return val;
 }
 
+/*
+ * Get the LLVMValue corresponding to the pseudo
+ * and force the type corresponding to ctype.
+ */
+static LLVMValueRef get_operand(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
+{
+	LLVMValueRef target = pseudo_to_value(fn, ctype, pseudo);
+	return adjust_type(fn, ctype, target);
+}
+
+/*
+ * Get the LLVMValue corresponding to the pseudo
+ * and force the type corresponding to ctype but
+ * map all pointers to intptr_t.
+ */
+static LLVMValueRef get_ioperand(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
+{
+	LLVMValueRef target = pseudo_to_value(fn, ctype, pseudo);
+	return value_to_ivalue(fn, ctype, target);
+}
+
 static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValueRef off)
 {
 	LLVMTypeRef type = LLVMTypeOf(base);
@@ -515,11 +536,8 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
 	LLVMValueRef lhs, rhs, target;
 	char target_name[64];
 
-	lhs = pseudo_to_value(fn, insn->type, insn->src1);
-	lhs = value_to_ivalue(fn, insn->type, lhs);

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

* [PATCH v6 39/52] llvm: fix mutating function pointer
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (37 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 38/52] llvm: introduce get_ioperand() Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 40/52] llvm: fix mutated OP_RET Luc Van Oostenryck
                   ` (14 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                           |  5 ++++-
 validation/backend/function-ptr-xtype.c | 37 +++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 validation/backend/function-ptr-xtype.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 0c92eab23..af540033d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -829,7 +829,10 @@ static void output_op_call(struct function *fn, struct instruction *insn)
 		args[i++] = pseudo_to_rvalue(fn, arg, arg->src);
 	} END_FOR_EACH_PTR(arg);
 
-	func = pseudo_to_value(fn, NULL, insn->func);
+	if (insn->func->type == PSEUDO_REG || insn->func->type == PSEUDO_PHI)
+		func = get_operand(fn, insn->fntype, insn->func);
+	else
+		func = pseudo_to_value(fn, insn->fntype, insn->func);
 	pseudo_name(insn->target, name);
 	target = LLVMBuildCall(fn->builder, func, args, n_arg, name);
 
diff --git a/validation/backend/function-ptr-xtype.c b/validation/backend/function-ptr-xtype.c
new file mode 100644
index 000000000..9cdfab051
--- /dev/null
+++ b/validation/backend/function-ptr-xtype.c
@@ -0,0 +1,37 @@
+typedef int  (*binop_t)(int, int);
+typedef int  (*unop_t)(int);
+typedef int  (*idef_t)(void);
+typedef long (*ldef_t)(void);
+typedef void (*use_t)(int);
+
+// We want to 'fn' have several different types.
+// The goal is for the ->priv member to be used
+// with a type different from what it was first stored.
+
+int foo(void *fn, int arg1, int arg2);
+int foo(void *fn, int arg1, int arg2)
+{
+	int res = 0;
+
+	res += ((binop_t)fn)(arg1, arg2);
+	res += ((unop_t)fn)(arg1);
+	res += ((ldef_t)fn)();
+	res += ((idef_t)fn)();
+	((use_t)fn)(res);
+	return res;
+}
+
+int bar(int (*fn)(int), int arg1, int arg2);
+int bar(int (*fn)(int), int arg1, int arg2)
+{
+	int res = 0;
+
+	res += ((binop_t)fn)(arg1, arg2);
+	res += fn(arg1);
+	return res;
+}
+
+/*
+ * check-name: mutate function pointer's type
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v6 40/52] llvm: fix mutated OP_RET
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (38 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 39/52] llvm: fix mutating function pointer Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 41/52] llvm: fix mutated OP_SEL Luc Van Oostenryck
                   ` (13 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index af540033d..9d8ece69d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -690,9 +690,7 @@ static void output_op_ret(struct function *fn, struct instruction *insn)
 	pseudo_t pseudo = insn->src;
 
 	if (pseudo && pseudo != VOID) {
-		LLVMValueRef result = pseudo_to_value(fn, insn->type, pseudo);

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

* [PATCH v6 41/52] llvm: fix mutated OP_SEL
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (39 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 40/52] llvm: fix mutated OP_RET Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 42/52] llvm: fix mutated OP_SWITCH Luc Van Oostenryck
                   ` (12 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, 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 9d8ece69d..8051f19f7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -773,13 +773,13 @@ static void output_op_sel(struct function *fn, struct instruction *insn)
 	char name[MAX_PSEUDO_NAME];
 
 	src1 = bool_value(fn, pseudo_to_value(fn, NULL, insn->src1));
-	src2 = pseudo_to_value(fn, insn->type, insn->src2);
-	src3 = pseudo_to_value(fn, insn->type, insn->src3);
+	src2 = get_operand(fn, insn->type, insn->src2);
+	src3 = get_operand(fn, insn->type, insn->src3);
 
 	pseudo_name(insn->target, name);
 	target = LLVMBuildSelect(fn->builder, src1, src2, src3, name);
 
-	insn->target->priv = target;
+	insn->target->priv = adjust_type(fn, insn->type, target);
 }
 
 static void output_op_switch(struct function *fn, struct instruction *insn)
-- 
2.12.0


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

* [PATCH v6 42/52] llvm: fix mutated OP_SWITCH
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (40 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 41/52] llvm: fix mutated OP_SEL Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 43/52] llvm: fix mutated OP_PHISOURCE Luc Van Oostenryck
                   ` (11 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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 8051f19f7..50b82e221 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -796,7 +796,7 @@ static void output_op_switch(struct function *fn, struct instruction *insn)
 			def = jmp->target;
 	} END_FOR_EACH_PTR(jmp);
 
-	sw_val = pseudo_to_value(fn, insn->type, insn->target);
+	sw_val = get_ioperand(fn, insn->type, insn->target);
 	target = LLVMBuildSwitch(fn->builder, sw_val,
 				 def ? def->priv : NULL, n_jmp);
 
-- 
2.12.0


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

* [PATCH v6 43/52] llvm: fix mutated OP_PHISOURCE
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (41 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 42/52] llvm: fix mutated OP_SWITCH Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 44/52] llvm: fix mutated OP_[PTR]CAST Luc Van Oostenryck
                   ` (10 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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 50b82e221..4e9bf930b 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -845,7 +845,7 @@ static void output_op_phisrc(struct function *fn, struct instruction *insn)
 	assert(insn->target->priv == NULL);
 
 	/* target = src */
-	v = pseudo_to_value(fn, insn->type, insn->phi_src);
+	v = get_operand(fn, insn->type, insn->phi_src);
 
 	FOR_EACH_PTR(insn->phi_users, phi) {
 		LLVMValueRef load, ptr;
-- 
2.12.0


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

* [PATCH v6 44/52] llvm: fix mutated OP_[PTR]CAST
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (42 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 43/52] llvm: fix mutated OP_PHISOURCE Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 45/52] llvm: add support for restricted types Luc Van Oostenryck
                   ` (9 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 4e9bf930b..cd527eb1c 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -876,13 +876,12 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 {
 	LLVMValueRef src, target;
 	LLVMTypeRef dtype;
+	struct symbol *otype = insn->orig_type;
 	LLVMOpcode op;
 	char target_name[64];
 
-	src = insn->src->priv;
-	if (!src)
-		src = pseudo_to_value(fn, insn->type, insn->src);
 
+	src = get_operand(fn, otype, insn->src);
 	pseudo_name(insn->target, target_name);
 
 	assert(!is_float_type(insn->type));
@@ -907,16 +906,15 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 {
 	LLVMValueRef src, target;
 	LLVMTypeRef dtype;
+	struct symbol *otype = insn->orig_type;
 	char target_name[64];
 	unsigned int width;
 
 	if (is_ptr_type(insn->type))	// cast to void* is OP_CAST ...
 		return output_op_ptrcast(fn, insn);
 
-	src = insn->src->priv;
-	if (!src)
-		src = pseudo_to_value(fn, insn->type, insn->src);
 
+	src = get_operand(fn, otype, insn->src);
 	pseudo_name(insn->target, target_name);
 
 	assert(!is_float_type(insn->type));
-- 
2.12.0


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

* [PATCH v6 45/52] llvm: add support for restricted types
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (43 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 44/52] llvm: fix mutated OP_[PTR]CAST Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 46/52] llvm: fix get value from initialized symbol Luc Van Oostenryck
                   ` (8 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index cd527eb1c..8b170b4bf 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -203,6 +203,7 @@ static LLVMTypeRef symbol_type(struct symbol *sym)
 
 	switch (sym->type) {
 	case SYM_BITFIELD:
+	case SYM_RESTRICT:
 	case SYM_ENUM:
 		ret = symbol_type(sym->ctype.base_type);
 		break;
-- 
2.12.0


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

* [PATCH v6 46/52] llvm: fix get value from initialized symbol
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (44 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 45/52] llvm: add support for restricted types Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 47/52] llvm: fix get value from non-anonymous symbol Luc Van Oostenryck
                   ` (7 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 8b170b4bf..65b859f4b 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -295,6 +295,8 @@ static const char *pseudo_name(pseudo_t pseudo, char *buf)
 
 static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
 {
+	const char *name = show_ident(sym->ident);
+	LLVMTypeRef type = symbol_type(sym);
 	LLVMValueRef result = NULL;
 	struct expression *expr;
 
@@ -314,7 +316,7 @@ static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
 			LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
 
 			result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
-			break;
+			return result;
 		}
 		case EXPR_SYMBOL: {
 			struct symbol *sym = expr->symbol;
@@ -324,21 +326,18 @@ static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
 			break;
 		}
 		default:
-			assert(0);
+			break;
 		}
-	} 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);
-		}
+	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;
-- 
2.12.0


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

* [PATCH v6 47/52] llvm: fix get value from non-anonymous symbol
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (45 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 46/52] llvm: fix get value from initialized symbol Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 48/52] llvm: fix type of bitfields Luc Van Oostenryck
                   ` (6 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c                     | 11 ++---------
 validation/backend/load-global.c  | 21 +++++++++++++++++++++
 validation/backend/string-value.c | 21 +++++++++++++++++++++
 3 files changed, 44 insertions(+), 9 deletions(-)
 create mode 100644 validation/backend/load-global.c
 create mode 100644 validation/backend/string-value.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 65b859f4b..c1aefc682 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -303,7 +303,7 @@ static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
 	assert(sym->bb_target == NULL);
 
 	expr = sym->initializer;
-	if (expr) {
+	if (expr && !sym->ident) {
 		switch (expr->type) {
 		case EXPR_STRING: {
 			const char *s = expr->string->data;
@@ -318,13 +318,6 @@ static LLVMValueRef get_sym_value(struct function *fn, struct symbol *sym)
 			result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
 			return result;
 		}
-		case EXPR_SYMBOL: {
-			struct symbol *sym = expr->symbol;
-
-			result = LLVMGetNamedGlobal(fn->module, show_ident(sym->ident));
-			assert(result != NULL);
-			break;
-		}
 		default:
 			break;
 		}
@@ -1212,7 +1205,7 @@ static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym)
 		initial_value = LLVMConstNull(type);
 	}
 
-	name = show_ident(sym->ident);
+	name = sym->ident ? show_ident(sym->ident) : "" ;
 
 	data = LLVMAddGlobal(module, LLVMTypeOf(initial_value), name);
 
diff --git a/validation/backend/load-global.c b/validation/backend/load-global.c
new file mode 100644
index 000000000..dedb35f3b
--- /dev/null
+++ b/validation/backend/load-global.c
@@ -0,0 +1,21 @@
+const char *s = "abc";
+int x = 4;
+int y;
+
+int *p = &x;
+int *q;
+
+int loadn(void) { return y; }
+int loadi(void) { return x; }
+
+const char *loads(void) { return s; }
+
+int *retpn(void) { return  q; }
+int loadpn(void) { return *q; }
+int *retpi(void) { return  p; }
+int loadpi(void) { return *p; }
+
+/*
+ * check-name: use simple value from global vars
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
diff --git a/validation/backend/string-value.c b/validation/backend/string-value.c
new file mode 100644
index 000000000..8cdec4a2d
--- /dev/null
+++ b/validation/backend/string-value.c
@@ -0,0 +1,21 @@
+extern void use(const char *);
+
+const char *ret(void)
+{
+	return "abc";
+}
+
+const char *add(void)
+{
+	return "def" + 1;
+}
+
+void call(void)
+{
+	use("ijk");
+}
+
+/*
+ * check-name: string-value
+ * check-command: ./sparsec -Wno-decl -c $file -o tmp.o
+ */
-- 
2.12.0


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

* [PATCH v6 48/52] llvm: fix type of bitfields
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (46 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 47/52] llvm: fix get value from non-anonymous symbol Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 49/52] llvm: add support for OP_FPCAST Luc Van Oostenryck
                   ` (5 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index c1aefc682..840e8c6ba 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -203,6 +203,8 @@ static LLVMTypeRef symbol_type(struct symbol *sym)
 
 	switch (sym->type) {
 	case SYM_BITFIELD:
+		ret = LLVMIntType(sym->bit_size);
+		break;
 	case SYM_RESTRICT:
 	case SYM_ENUM:
 		ret = symbol_type(sym->ctype.base_type);
-- 
2.12.0


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

* [PATCH v6 49/52] llvm: add support for OP_FPCAST
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (47 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 48/52] llvm: fix type of bitfields Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 50/52] llvm: add support for cast from floats Luc Van Oostenryck
                   ` (4 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c             | 22 +++++++++++++++++++++-
 validation/backend/cast.c |  5 +++--
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 840e8c6ba..604b96842 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -934,6 +934,26 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 	insn->target->priv = target;
 }
 
+static void output_op_fpcast(struct function *fn, struct instruction *insn)
+{
+	LLVMTypeRef dtype = symbol_type(insn->type);
+	LLVMValueRef src, target;
+	struct symbol *otype = insn->orig_type;
+	char name[64];
+
+	assert(is_float_type(insn->type));
+
+	pseudo_name(insn->target, name);
+	src = get_operand(fn, otype, insn->src);
+	if (is_float_type(otype))
+		target = LLVMBuildFPCast(fn->builder, src, dtype, name);
+	else if (is_signed_type(otype))
+		target = LLVMBuildSIToFP(fn->builder, src, dtype, name);
+	else
+		target = LLVMBuildUIToFP(fn->builder, src, dtype, name);
+	insn->target->priv = target;
+}
+
 static void output_op_setval(struct function *fn, struct instruction *insn)
 {
 	struct expression *val = insn->val;
@@ -1008,7 +1028,7 @@ static void output_insn(struct function *fn, struct instruction *insn)
 		output_op_cast(fn, insn, LLVMSExt);
 		break;
 	case OP_FPCAST:
-		assert(0);
+		output_op_fpcast(fn, insn);
 		break;
 	case OP_PTRCAST:
 		output_op_ptrcast(fn, insn);
diff --git a/validation/backend/cast.c b/validation/backend/cast.c
index 598b16aab..4c308dfe8 100644
--- a/validation/backend/cast.c
+++ b/validation/backend/cast.c
@@ -1,4 +1,5 @@
 typedef _Bool bool;
+typedef   signed char schar;
 typedef unsigned char uchar;
 typedef unsigned short ushort;
 typedef unsigned int uint;
@@ -14,6 +15,7 @@ typedef unsigned long long ulonglong;
 #define DEFINE_CASTS(from)			\
 	DEFINE_CAST(from, bool)			\
 	DEFINE_CAST(from, char)			\
+	DEFINE_CAST(from, schar)		\
 	DEFINE_CAST(from, uchar)		\
 	DEFINE_CAST(from, short)		\
 	DEFINE_CAST(from, ushort)		\
@@ -23,13 +25,12 @@ typedef unsigned long long ulonglong;
 	DEFINE_CAST(from, ulong)		\
 	DEFINE_CAST(from, longlong)		\
 	DEFINE_CAST(from, ulonglong)		\
-/*
 	DEFINE_CAST(from, float)		\
 	DEFINE_CAST(from, double)
-*/
 
 DEFINE_CASTS(bool)
 DEFINE_CASTS(char)
+DEFINE_CASTS(schar)
 DEFINE_CASTS(uchar)
 DEFINE_CASTS(short)
 DEFINE_CASTS(ushort)
-- 
2.12.0


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

* [PATCH v6 50/52] llvm: add support for cast from floats
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (48 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 49/52] llvm: add support for OP_FPCAST Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 51/52] llvm: cleanup of output_[ptr]cast() Luc Van Oostenryck
                   ` (3 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse-llvm.c             | 10 +++++++++-
 validation/backend/cast.c |  2 --
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/sparse-llvm.c b/sparse-llvm.c
index 604b96842..a0b4293fa 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -914,7 +914,7 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 
 	assert(!is_float_type(insn->type));
 
-	dtype = insn_symbol_type(insn);
+	dtype = symbol_type(insn->type);
 	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
 	case LLVMPointerTypeKind:
 		op = LLVMPtrToInt;
@@ -926,6 +926,14 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 		else if (insn->size == width)
 			op = LLVMBitCast;
 		break;
+	case LLVMHalfTypeKind:
+	case LLVMFloatTypeKind:
+	case LLVMDoubleTypeKind:
+	case LLVMX86_FP80TypeKind:
+	case LLVMFP128TypeKind:
+	case LLVMPPC_FP128TypeKind:
+		op = (op == LLVMZExt) ? LLVMFPToUI : LLVMFPToSI;
+		break;
 	default:
 		assert(0);
 	}
diff --git a/validation/backend/cast.c b/validation/backend/cast.c
index 4c308dfe8..b3728c21e 100644
--- a/validation/backend/cast.c
+++ b/validation/backend/cast.c
@@ -40,10 +40,8 @@ DEFINE_CASTS(long)
 DEFINE_CASTS(ulong)
 DEFINE_CASTS(longlong)
 DEFINE_CASTS(ulonglong)
-/*
 DEFINE_CASTS(float)
 DEFINE_CASTS(double)
-*/
 
 /*
  * check-name: Cast code generation
-- 
2.12.0


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

* [PATCH v6 51/52] llvm: cleanup of output_[ptr]cast()
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (49 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 50/52] llvm: add support for cast from floats Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-27 21:24 ` [PATCH v6 52/52] llvm: fix creation of sparsec's tmp files Luc Van Oostenryck
                   ` (2 subsequent siblings)
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

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

diff --git a/sparse-llvm.c b/sparse-llvm.c
index a0b4293fa..b82fbefa1 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -875,21 +875,17 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
 	LLVMOpcode op;
 	char target_name[64];
 
+	assert(is_ptr_type(insn->type));
 
 	src = get_operand(fn, otype, insn->src);
 	pseudo_name(insn->target, target_name);
 
-	assert(!is_float_type(insn->type));
-
-	dtype = insn_symbol_type(insn);
-	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
-	case LLVMPointerTypeKind:
+	dtype = symbol_type(insn->type);
+	if (is_ptr_type(otype)) {
 		op = LLVMBitCast;
-		break;
-	case LLVMIntegerTypeKind:
+	} else if (is_int_type(otype)) {
 		op = LLVMIntToPtr;
-		break;
-	default:
+	} else {
 		assert(0);
 	}
 
@@ -903,38 +899,27 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
 	LLVMTypeRef dtype;
 	struct symbol *otype = insn->orig_type;
 	char target_name[64];
-	unsigned int width;
 
 	if (is_ptr_type(insn->type))	// cast to void* is OP_CAST ...
 		return output_op_ptrcast(fn, insn);
 
+	assert(is_int_type(insn->type));
 
 	src = get_operand(fn, otype, insn->src);
 	pseudo_name(insn->target, target_name);
 
-	assert(!is_float_type(insn->type));
-
 	dtype = symbol_type(insn->type);
-	switch (LLVMGetTypeKind(LLVMTypeOf(src))) {
-	case LLVMPointerTypeKind:
+	if (is_ptr_type(otype)) {
 		op = LLVMPtrToInt;
-		break;
-	case LLVMIntegerTypeKind:
-		width = LLVMGetIntTypeWidth(LLVMTypeOf(src));
+	} else if (is_float_type(otype)) {
+		op = (op == LLVMZExt) ? LLVMFPToUI : LLVMFPToSI;
+	} else if (is_int_type(otype)) {
+		unsigned int width = otype->bit_size;
 		if (insn->size < width)
 			op = LLVMTrunc;
 		else if (insn->size == width)
 			op = LLVMBitCast;
-		break;
-	case LLVMHalfTypeKind:
-	case LLVMFloatTypeKind:
-	case LLVMDoubleTypeKind:
-	case LLVMX86_FP80TypeKind:
-	case LLVMFP128TypeKind:
-	case LLVMPPC_FP128TypeKind:
-		op = (op == LLVMZExt) ? LLVMFPToUI : LLVMFPToSI;
-		break;
-	default:
+	} else {
 		assert(0);
 	}
 
-- 
2.12.0


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

* [PATCH v6 52/52] llvm: fix creation of sparsec's tmp files
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (50 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 51/52] llvm: cleanup of output_[ptr]cast() Luc Van Oostenryck
@ 2017-03-27 21:24 ` Luc Van Oostenryck
  2017-03-31  5:28 ` [PATCH v6 00/52] LLVM fixes Christopher Li
  2017-04-01 10:53 ` [GIT PULL v6] " Luc Van Oostenryck
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-27 21:24 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li, Luc Van Oostenryck

It seems the intention was to create the tmp files with
the suffixes but the files are create without the suffixes
(while the filename that is used later is with the suffixes).

In all case the non-suffixed file that is created by the
mktemp command is never removed and after a while these
files begin to pile-up. Better to remove them.

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

diff --git a/sparsec b/sparsec
index 9dc96c956..e421776e2 100755
--- a/sparsec
+++ b/sparsec
@@ -29,8 +29,8 @@ while [ $# -gt 0 ]; do
 	shift
 done
 
-TMPLLVM=`mktemp -t tmp.XXXXXX`".llvm"
-TMPFILE=`mktemp -t tmp.XXXXXX`".o"
+TMPLLVM=`mktemp -t tmp.XXXXXX.llvm`
+TMPFILE=`mktemp -t tmp.XXXXXX.o`
 
 $DIRNAME/sparse-llvm $SPARSEOPTS > $TMPLLVM
 
-- 
2.12.0


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

* Re: [PATCH v6 00/52] LLVM fixes
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (51 preceding siblings ...)
  2017-03-27 21:24 ` [PATCH v6 52/52] llvm: fix creation of sparsec's tmp files Luc Van Oostenryck
@ 2017-03-31  5:28 ` Christopher Li
  2017-03-31  5:32   ` Christopher Li
  2017-04-01 10:53 ` [GIT PULL v6] " Luc Van Oostenryck
  53 siblings, 1 reply; 57+ messages in thread
From: Christopher Li @ 2017-03-31  5:28 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse

On Tue, Mar 28, 2017 at 5:23 AM, 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 v5:
> - avoid declare a var inside a for-loop for non C99 compilers
> - fix naming of symbol without an indent
> - avoid sparsec to leave its tmp file
>
> Changes since v4:
> - extract the non sparse-llvm specific patches into
>   a separate, preparatory serie.

V4 has 63 patches. V5 has 51 and V6 has 52 patches.

I assume I just drop the 63 patches in V4 and use the 52 patches instead?

Chris

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

* Re: [PATCH v6 00/52] LLVM fixes
  2017-03-31  5:28 ` [PATCH v6 00/52] LLVM fixes Christopher Li
@ 2017-03-31  5:32   ` Christopher Li
  2017-03-31  8:56     ` Luc Van Oostenryck
  0 siblings, 1 reply; 57+ messages in thread
From: Christopher Li @ 2017-03-31  5:32 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Linux-Sparse

On Fri, Mar 31, 2017 at 1:28 PM, Christopher Li <sparse@chrisli.org> wrote:
> V4 has 63 patches. V5 has 51 and V6 has 52 patches.
>
> I assume I just drop the 63 patches in V4 and use the 52 patches instead?
>

Ah, I see what you are doing. V6 has 1-15 and 1-52 two series..

Chris

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

* Re: [PATCH v6 00/52] LLVM fixes
  2017-03-31  5:32   ` Christopher Li
@ 2017-03-31  8:56     ` Luc Van Oostenryck
  0 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-03-31  8:56 UTC (permalink / raw)
  To: Christopher Li; +Cc: Linux-Sparse

On Fri, Mar 31, 2017 at 7:32 AM, Christopher Li <sparse@chrisli.org> wrote:
> On Fri, Mar 31, 2017 at 1:28 PM, Christopher Li <sparse@chrisli.org> wrote:
>> V4 has 63 patches. V5 has 51 and V6 has 52 patches.
>>
>> I assume I just drop the 63 patches in V4 and use the 52 patches instead?
>>
>
> Ah, I see what you are doing. V6 has 1-15 and 1-52 two series..

Yes, I extracted the non-LLVM specific part in a separate series.

Luc

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

* [GIT PULL v6] LLVM fixes
  2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
                   ` (52 preceding siblings ...)
  2017-03-31  5:28 ` [PATCH v6 00/52] LLVM fixes Christopher Li
@ 2017-04-01 10:53 ` Luc Van Oostenryck
  53 siblings, 0 replies; 57+ messages in thread
From: Luc Van Oostenryck @ 2017-04-01 10:53 UTC (permalink / raw)
  To: linux-sparse; +Cc: Christopher Li

This series is available at:
	git://github.com/lucvoo/sparse.git llvm-fixes-v6
based on commit:
	263f8ce449097da4caacfac4e00144f626c6e6a7 (pre-llvm-fixes-v6)
up to commit:
	6c5ee5c931d480043d04644cfda5593bfb52e40c


-- Luc Van Oostenryck

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

end of thread, other threads:[~2017-04-01 10:53 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-27 21:23 [PATCH v6 00/52] LLVM fixes Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 01/52] llvm: remove unneeded arg 'module' Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 02/52] llvm: remove unneeded 'generation' Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 03/52] llvm: remove unneeded function::type Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 04/52] llvm: reduce scope of 'bb_nr' Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 05/52] llvm: use pseudo_list_size() instead of open coding it Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 06/52] llvm: give arguments a name Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 07/52] llvm: give a name to call's return values Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 08/52] llvm: avoid useless temp variable Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 09/52] llvm: extract get_sym_value() from pseudo_to_value() Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 10/52] llvm: fix test of floating-point type Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 11/52] llvm: fix translation of PSEUDO_VALs into a ValueRefs Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 12/52] llvm: fix output_op_store() which modify its operand Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 13/52] llvm: fix output_op_[ptr]cast() Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 14/52] llvm: take care of degenerated rvalues Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 15/52] llvm: add test cases for symbol's address Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 16/52] llvm: add test cases for pointers passed as argument Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 17/52] llvm: add test cases for arrays " Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 18/52] llvm: add test cases for degenerated pointers Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 19/52] llvm: add support for OP_NEG Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 20/52] llvm: add support for OP_SETVAL with floats Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 21/52] llvm: add support for OP_SETVAL with labels Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 22/52] llvm: ignore OP_INLINED_CALL Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 23/52] llvm: fix pointer/float mixup in comparisons Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 24/52] llvm: fix type in comparison with an address constant Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 25/52] llvm: give correct type to binops Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 26/52] llvm: adjust OP_RET's type Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 27/52] llvm: variadic functions are not being marked as such Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 28/52] llvm: fix type of switch constants Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 29/52] llvm: make pseudo_name() more flexible Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 30/52] llvm: give a name to all values Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 31/52] llvm: add support for OP_SWITCH with a range Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 32/52] llvm: fix OP_SWITCH has no target Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 33/52] llvm: make value_to_pvalue() more flexible Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 34/52] llvm: make value_to_ivalue() " Luc Van Oostenryck
2017-03-27 21:23 ` [PATCH v6 35/52] llvm: add test case pointer compare with cast Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 36/52] llvm: let pseudo_to_value() directly use the type Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 37/52] llvm: remove unneeded pseudo_to_value() unneeded argument Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 38/52] llvm: introduce get_ioperand() Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 39/52] llvm: fix mutating function pointer Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 40/52] llvm: fix mutated OP_RET Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 41/52] llvm: fix mutated OP_SEL Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 42/52] llvm: fix mutated OP_SWITCH Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 43/52] llvm: fix mutated OP_PHISOURCE Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 44/52] llvm: fix mutated OP_[PTR]CAST Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 45/52] llvm: add support for restricted types Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 46/52] llvm: fix get value from initialized symbol Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 47/52] llvm: fix get value from non-anonymous symbol Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 48/52] llvm: fix type of bitfields Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 49/52] llvm: add support for OP_FPCAST Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 50/52] llvm: add support for cast from floats Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 51/52] llvm: cleanup of output_[ptr]cast() Luc Van Oostenryck
2017-03-27 21:24 ` [PATCH v6 52/52] llvm: fix creation of sparsec's tmp files Luc Van Oostenryck
2017-03-31  5:28 ` [PATCH v6 00/52] LLVM fixes Christopher Li
2017-03-31  5:32   ` Christopher Li
2017-03-31  8:56     ` Luc Van Oostenryck
2017-04-01 10:53 ` [GIT PULL v6] " 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.