diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-03-03 08:45:36 +0100 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-11-17 10:04:37 +0100 |
| commit | 2d002eb75bfb092f6fed3ba600adfa8e7c13128c (patch) | |
| tree | a79f97860dffba13312d0027c1556f56cdc21cad /sparse-llvm.c | |
| parent | accf7112191ba29f0366c8a10332a8a63644db50 (diff) | |
| download | sparse-dev-2d002eb75bfb092f6fed3ba600adfa8e7c13128c.tar.gz | |
llvm: give correct type to binops
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>
Diffstat (limited to 'sparse-llvm.c')
| -rw-r--r-- | sparse-llvm.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c index c41781f3..e0838f4f 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -408,6 +408,33 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins return result; } +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); @@ -467,8 +494,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); @@ -569,6 +598,7 @@ static void output_op_binary(struct function *fn, struct instruction *insn) break; } + target = adjust_type(fn, insn->type, target); insn->target->priv = target; } |
