gallivm: Fix TGSI_OPCODE_ARR's translation.

Like TGSI_OPCODE_ARL, destination should be an integer.

This fixes invalid LLVM IR on an internal state tracker (currently Mesa
never emits this opcode).

In the future consider making ADDR register also a integer-as-float array,
like all other register kinds, or simply replace ADDR & ARR/ARL with
integer temp and instructions.

Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
José Fonseca 2012-02-20 20:49:03 +00:00
parent d394bc5853
commit a206c4cd69
3 changed files with 22 additions and 2 deletions

View File

@ -102,8 +102,9 @@ arr_emit(
struct lp_build_tgsi_context * bld_base,
struct lp_build_emit_data * emit_data)
{
emit_data->output[emit_data->chan] = lp_build_emit_llvm_unary(bld_base,
TGSI_OPCODE_ROUND, emit_data->args[0]);
LLVMValueRef tmp = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ROUND, emit_data->args[0]);
emit_data->output[emit_data->chan] = LLVMBuildFPToSI(bld_base->base.gallivm->builder, tmp,
bld_base->uint_bld.vec_type, "");
}
/* TGSI_OPCODE_CLAMP */
@ -820,6 +821,16 @@ arl_emit_cpu(
bld_base->uint_bld.vec_type, "");
}
/* TGSI_OPCODE_ARR (CPU Only) */
static void
arr_emit_cpu(
const struct lp_build_tgsi_action * action,
struct lp_build_tgsi_context * bld_base,
struct lp_build_emit_data * emit_data)
{
emit_data->output[emit_data->chan] = lp_build_iround(&bld_base->base, emit_data->args[0]);
}
/* TGSI_OPCODE_CEIL (CPU Only) */
static void
ceil_emit_cpu(
@ -1166,6 +1177,7 @@ lp_set_default_actions_cpu(
bld_base->op_actions[TGSI_OPCODE_ABS].emit = abs_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ADD].emit = add_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ARL].emit = arl_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ARR].emit = arr_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_CEIL].emit = ceil_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_CND].emit = cnd_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_COS].emit = cos_emit_cpu;

View File

@ -1027,6 +1027,8 @@ emit_store_chan(
break;
case TGSI_FILE_ADDRESS:
assert(dtype == TGSI_TYPE_SIGNED);
assert(LLVMTypeOf(value) == bld_base->base.int_vec_type);
lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value,
bld->addr[reg->Register.Index][chan_index]);
break;
@ -1377,6 +1379,11 @@ lp_emit_declaration_soa(
break;
case TGSI_FILE_ADDRESS:
/* ADDR registers are the only allocated with an integer LLVM IR type,
* as they are guaranteed to always have integers.
* XXX: Not sure if this exception is worthwhile (or the whole idea of
* an ADDR register for that matter).
*/
assert(idx < LP_MAX_TGSI_ADDRS);
for (i = 0; i < TGSI_NUM_CHANNELS; i++)
bld->addr[idx][i] = lp_build_alloca(gallivm, bld_base->base.int_vec_type, "addr");

View File

@ -333,6 +333,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
case TGSI_OPCODE_MOD:
case TGSI_OPCODE_UARL:
case TGSI_OPCODE_ARL:
case TGSI_OPCODE_ARR:
case TGSI_OPCODE_IABS:
case TGSI_OPCODE_ISSG:
return TGSI_TYPE_SIGNED;