i965/vec4: Fix null destination register in 3-source instructions
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 23 Mar 2018 18:46:12 +0000 (11:46 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 26 Mar 2018 15:50:44 +0000 (08:50 -0700)
A recent commit (see below) triggered some cases where conditional
modifier propagation and dead code elimination would cause a MAD
instruction like the following to be generated:

    mad.l.f0  null, ...

Matt pointed out that fs_visitor::fixup_3src_null_dest() fixes cases
like this in the scalar backend.  This commit basically ports that code
to the vec4 backend.

NOTE: I have sent a couple tests to the piglit list that reproduce this
bug *without* the commit mentioned below.  This commit fixes those
tests.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Tested-by: Tapani Pälli <tapani.palli@intel.com>
Cc: mesa-stable@lists.freedesktop.org
Fixes: ee63933a7 ("nir: Distribute binary operations with constants into bcsel")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105704

src/intel/compiler/brw_vec4.cpp
src/intel/compiler/brw_vec4.h

index 6680410a5255488d67e467d67b2d371305a74ce4..2f352a1118f83a4234eaed5f8505801e2a55b0ed 100644 (file)
@@ -1952,6 +1952,30 @@ is_align1_df(vec4_instruction *inst)
    }
 }
 
+/**
+ * Three source instruction must have a GRF/MRF destination register.
+ * ARF NULL is not allowed.  Fix that up by allocating a temporary GRF.
+ */
+void
+vec4_visitor::fixup_3src_null_dest()
+{
+   bool progress = false;
+
+   foreach_block_and_inst_safe (block, vec4_instruction, inst, cfg) {
+      if (inst->is_3src(devinfo) && inst->dst.is_null()) {
+         const unsigned size_written = type_sz(inst->dst.type);
+         const unsigned num_regs = DIV_ROUND_UP(size_written, REG_SIZE);
+
+         inst->dst = retype(dst_reg(VGRF, alloc.allocate(num_regs)),
+                            inst->dst.type);
+         progress = true;
+      }
+   }
+
+   if (progress)
+      invalidate_live_intervals();
+}
+
 void
 vec4_visitor::convert_to_hw_regs()
 {
@@ -2703,6 +2727,8 @@ vec4_visitor::run()
       OPT(scalarize_df);
    }
 
+   fixup_3src_null_dest();
+
    bool allocated_without_spills = reg_allocate();
 
    if (!allocated_without_spills) {
index 39ce51c7dcf2eb699ee997f6bd4fbe43df8c3cc7..71880db969e7f83604bd46fc5ba498529e360593 100644 (file)
@@ -158,6 +158,7 @@ public:
    void opt_set_dependency_control();
    void opt_schedule_instructions();
    void convert_to_hw_regs();
+   void fixup_3src_null_dest();
 
    bool is_supported_64bit_region(vec4_instruction *inst, unsigned arg);
    bool lower_simd_width();