r600/sb: do not convert if-blocks that contain indirect array access
authorGert Wollny <gw.fossdev@gmail.com>
Wed, 6 Dec 2017 16:42:02 +0000 (17:42 +0100)
committerDave Airlie <airlied@redhat.com>
Wed, 6 Dec 2017 23:48:41 +0000 (09:48 +1000)
If an array is accessed within an if block, then currently it is not known
whether the value in the address register is involved in the evaluation of the
if condition, and converting the if condition may actually result in
out-of-bounds array access. Consequently, if blocks that contain indirect array
access should not be converted.

Fixes piglits on r600/BARTS:
spec/glsl-1.10/execution/variable-indexing/
  vs-output-array-float-index-wr
  vs-output-array-vec3-index-wr
  vs-output-array-vec4-index-wr

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104143

Signed-off-by: Gert Wollny <gw.fossdev@gmail.com>
Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/sb/sb_if_conversion.cpp
src/gallium/drivers/r600/sb/sb_ir.cpp
src/gallium/drivers/r600/sb/sb_ir.h

index 3f2b1b1b925a37085cf13628c4313ddfed5d7a9e..3f6431b80f5dc0dd25e92cd37cbbbcc3d7fe091f 100644 (file)
@@ -136,7 +136,7 @@ bool if_conversion::check_and_convert(region_node *r) {
        );
 
        if (s.region_count || s.fetch_count || s.alu_kill_count ||
-                       s.if_count != 1 || s.repeat_count)
+                       s.if_count != 1 || s.repeat_count || s.uses_ar)
                return false;
 
        unsigned real_alu_count = s.alu_count - s.alu_copy_mov_count;
index d989dce62c9c409a886642f355a457dc9761b4c9..fe068ab99b7cfde8de8b7c9bcbaf3c9274f75060 100644 (file)
@@ -461,6 +461,8 @@ void container_node::collect_stats(node_stats& s) {
                                ++s.alu_kill_count;
                        else if (a->is_copy_mov())
                                ++s.alu_copy_mov_count;
+                       if (a->uses_ar())
+                          s.uses_ar = true;
                } else if (n->is_fetch_inst())
                        ++s.fetch_count;
                else if (n->is_cf_inst())
index ec973e7bfc21ba63b192b36d9419d62d01c2f886..67c7cd8aa488232ac0bdf376e59b5aacf5570585 100644 (file)
@@ -726,11 +726,12 @@ struct node_stats {
        unsigned depart_count;
        unsigned repeat_count;
        unsigned if_count;
+       bool uses_ar;
 
        node_stats() : alu_count(), alu_kill_count(), alu_copy_mov_count(),
                        cf_count(), fetch_count(), region_count(),
                        loop_count(), phi_count(), loop_phi_count(), depart_count(),
-                       repeat_count(), if_count() {}
+                       repeat_count(), if_count(), uses_ar(false) {}
 
        void dump();
 };