@@ -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;
}
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(-)