static void propagate_return_type(RzCore *core, RzAnalysisOp *aop, RzAnalysisOp *next_op, RzILTraceInstruction *trace, struct ReturnTypeAnalysisCtx *ctx, RzPVector *used_vars) {
	char src[REGNAME_SIZE] = { 0 };
	void **uvit;

	// TODO : handle multiple registers case, this is a temporary solution
	RzILTraceRegOp *single_write_reg = NULL;
	if (trace && (trace->stats & RZ_IL_TRACE_INS_HAS_REG_W)) {
		single_write_reg = rz_pvector_at(trace->write_reg_ops, 0);
	}

	get_src_regname(core, aop->addr, src, sizeof(src));
	ut32 type = aop->type & RZ_ANALYSIS_OP_TYPE_MASK;
	if (ctx->ret_reg && *src && strstr(ctx->ret_reg, src)) {
		if (used_vars && !rz_pvector_empty(used_vars) && aop->direction == RZ_ANALYSIS_OP_DIR_WRITE) {
			rz_pvector_foreach (used_vars, uvit) {
				RzAnalysisVar *var = *uvit;
				var_type_set(core->analysis, var, ctx->ret_type, false);
			}
			ctx->resolved = true;
		} else if (type == RZ_ANALYSIS_OP_TYPE_MOV) {
			RZ_FREE(ctx->ret_reg);
			if (single_write_reg && single_write_reg->reg_name) {
				ctx->ret_reg = strdup(single_write_reg->reg_name);
			}
		}
	} else if (single_write_reg) {
		if (ctx->ret_reg &&
			(single_write_reg->reg_name && strstr(ctx->ret_reg, single_write_reg->reg_name))) {
			ctx->resolved = true;
		} else if (type == RZ_ANALYSIS_OP_TYPE_MOV &&
			(next_op && next_op->type == RZ_ANALYSIS_OP_TYPE_MOV)) {
			// Progate return type passed using pointer
			propagate_return_type_pointer(core, aop, used_vars, next_op->addr, ctx);
		}
	}
}
static void propagate_return_type(RzCore *core, RzAnalysisOp *aop, RzAnalysisOp *next_op, RzILTraceInstruction *trace, struct ReturnTypeAnalysisCtx *ctx, RzPVector *used_vars) {
	char src[REGNAME_SIZE] = { 0 };
	void **uvit;

	 
	RzILTraceRegOp *single_write_reg = NULL;
	if (trace && (trace->stats & RZ_IL_TRACE_INS_HAS_REG_W)) {
		single_write_reg = rz_pvector_at(trace->write_reg_ops, 0);
	}

	get_src_regname(core, aop->addr, src, sizeof(src));
	ut32 type = aop->type & RZ_ANALYSIS_OP_TYPE_MASK;
	if (ctx->ret_reg && *src && strstr(ctx->ret_reg, src)) {
		if (used_vars && !rz_pvector_empty(used_vars) && aop->direction == RZ_ANALYSIS_OP_DIR_WRITE) {
			rz_pvector_foreach (used_vars, uvit) {
				RzAnalysisVar *var = *uvit;
				var_type_set(core->analysis, var, ctx->ret_type, false);
			}
			ctx->resolved = true;
		} else if (type == RZ_ANALYSIS_OP_TYPE_MOV) {
			RZ_FREE(ctx->ret_reg);
			if (single_write_reg && single_write_reg->reg_name) {
				ctx->ret_reg = strdup(single_write_reg->reg_name);
			}
		}
	} else if (single_write_reg) {
		if (ctx->ret_reg &&
			(single_write_reg->reg_name && strstr(ctx->ret_reg, single_write_reg->reg_name))) {
			ctx->resolved = true;
		} else if (type == RZ_ANALYSIS_OP_TYPE_MOV &&
			(next_op && next_op->type == RZ_ANALYSIS_OP_TYPE_MOV)) {
			 
			propagate_return_type_pointer(core, aop, used_vars, next_op->addr, ctx);
		}
	}
}