aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-03-19 21:40:44 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-17 10:04:37 +0100
commit0f753a946feda65dbb1d6f0cb90206c5316cf90d (patch)
tree64a8b553434df5715a9b90d4a2bfcc2ecd1044f0
parent2fb8e679d470c6c69662291731f13f9bf9816e5c (diff)
downloadsparse-dev-0f753a946feda65dbb1d6f0cb90206c5316cf90d.tar.gz
llvm: make value_to_ivalue() more flexible
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--sparse-llvm.c15
-rw-r--r--validation/backend/shift-special.c13
2 files changed, 23 insertions, 5 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 6c2d0176..75e396e5 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -403,13 +403,18 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins
return result;
}
-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;
}
@@ -435,7 +440,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;
@@ -501,10 +506,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 00000000..d5e4d3d3
--- /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
+ */