summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/compiler/brw_vec4_nir.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/intel/compiler/brw_vec4_nir.cpp b/src/intel/compiler/brw_vec4_nir.cpp
index d84b0f6b235..882e97a1bf1 100644
--- a/src/intel/compiler/brw_vec4_nir.cpp
+++ b/src/intel/compiler/brw_vec4_nir.cpp
@@ -1008,6 +1008,66 @@ vec4_visitor::emit_conversion_to_double(dst_reg dst, src_reg src,
inst->saturate = saturate;
}
+/**
+ * Try to use an immediate value for source 1
+ *
+ * In cases of flow control, constant propagation is sometimes unable to
+ * determine that a register contains a constant value. To work around this,
+ * try to emit a literal as the second source here.
+ */
+static void
+try_immediate_source(const nir_alu_instr *instr, src_reg *op,
+ MAYBE_UNUSED const gen_device_info *devinfo)
+{
+ if (nir_src_num_components(instr->src[1].src) != 1 ||
+ nir_src_bit_size(instr->src[1].src) != 32 ||
+ !nir_src_is_const(instr->src[1].src))
+ return;
+
+ const enum brw_reg_type old_type = op->type;
+
+ switch (old_type) {
+ case BRW_REGISTER_TYPE_D:
+ case BRW_REGISTER_TYPE_UD: {
+ int d = nir_src_as_int(instr->src[1].src);
+
+ if (op->abs)
+ d = MAX2(-d, d);
+
+ if (op->negate) {
+ /* On Gen8+ a negation source modifier on a logical operation means
+ * something different. Nothing should generate this, so assert that
+ * it does not occur.
+ */
+ assert(devinfo->gen < 8 || (instr->op != nir_op_iand &&
+ instr->op != nir_op_ior &&
+ instr->op != nir_op_ixor));
+ d = -d;
+ }
+
+ *op = retype(src_reg(brw_imm_d(d)), old_type);
+ break;
+ }
+
+ case BRW_REGISTER_TYPE_F: {
+ float f = nir_src_as_float(instr->src[1].src);
+
+ if (op->abs)
+ f = fabs(f);
+
+ if (op->negate)
+ f = -f;
+
+ *op = src_reg(brw_imm_f(f));
+ assert(op->type == old_type);
+ break;
+ }
+
+ default:
+ unreachable("Non-32bit type.");
+ }
+}
+
void
vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
{
@@ -1066,6 +1126,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
assert(nir_dest_bit_size(instr->dest.dest) < 64);
/* fall through */
case nir_op_fadd:
+ try_immediate_source(instr, &op[1], devinfo);
inst = emit(ADD(dst, op[0], op[1]));
inst->saturate = instr->dest.saturate;
break;
@@ -1077,6 +1138,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
break;
case nir_op_fmul:
+ try_immediate_source(instr, &op[1], devinfo);
inst = emit(MUL(dst, op[0], op[1]));
inst->saturate = instr->dest.saturate;
break;
@@ -1304,6 +1366,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
assert(nir_dest_bit_size(instr->dest.dest) < 64);
/* fall through */
case nir_op_fmin:
+ try_immediate_source(instr, &op[1], devinfo);
inst = emit_minmax(BRW_CONDITIONAL_L, dst, op[0], op[1]);
inst->saturate = instr->dest.saturate;
break;
@@ -1313,6 +1376,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
assert(nir_dest_bit_size(instr->dest.dest) < 64);
/* fall through */
case nir_op_fmax:
+ try_immediate_source(instr, &op[1], devinfo);
inst = emit_minmax(BRW_CONDITIONAL_GE, dst, op[0], op[1]);
inst->saturate = instr->dest.saturate;
break;
@@ -1341,6 +1405,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
brw_conditional_for_nir_comparison(instr->op);
if (nir_src_bit_size(instr->src[0].src) < 64) {
+ try_immediate_source(instr, &op[1], devinfo);
emit(CMP(dst, op[0], op[1], conditional_mod));
} else {
/* Produce a 32-bit boolean result from the DF comparison by selecting
@@ -1410,6 +1475,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
op[0] = resolve_source_modifiers(op[0]);
op[1] = resolve_source_modifiers(op[1]);
}
+ try_immediate_source(instr, &op[1], devinfo);
emit(XOR(dst, op[0], op[1]));
break;
@@ -1419,6 +1485,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
op[0] = resolve_source_modifiers(op[0]);
op[1] = resolve_source_modifiers(op[1]);
}
+ try_immediate_source(instr, &op[1], devinfo);
emit(OR(dst, op[0], op[1]));
break;
@@ -1428,6 +1495,7 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
op[0] = resolve_source_modifiers(op[0]);
op[1] = resolve_source_modifiers(op[1]);
}
+ try_immediate_source(instr, &op[1], devinfo);
emit(AND(dst, op[0], op[1]));
break;
@@ -1737,16 +1805,19 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
case nir_op_ishl:
assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ try_immediate_source(instr, &op[1], devinfo);
emit(SHL(dst, op[0], op[1]));
break;
case nir_op_ishr:
assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ try_immediate_source(instr, &op[1], devinfo);
emit(ASR(dst, op[0], op[1]));
break;
case nir_op_ushr:
assert(nir_dest_bit_size(instr->dest.dest) < 64);
+ try_immediate_source(instr, &op[1], devinfo);
emit(SHR(dst, op[0], op[1]));
break;