diff --git a/src/gallium/drivers/r300/compiler/radeon_dataflow.c b/src/gallium/drivers/r300/compiler/radeon_dataflow.c index 302576b9fed..c0acb3ee681 100644 --- a/src/gallium/drivers/r300/compiler/radeon_dataflow.c +++ b/src/gallium/drivers/r300/compiler/radeon_dataflow.c @@ -688,6 +688,7 @@ static void get_readers_for_single_write( unsigned int branch_depth = 0; struct rc_instruction * endloop = NULL; unsigned int abort_on_read_at_endloop = 0; + int readers_before_endloop = -1; struct get_readers_callback_data * d = userdata; d->ReaderData->Writer = writer; @@ -695,6 +696,7 @@ static void get_readers_for_single_write( d->ReaderData->AbortOnWrite = 0; d->ReaderData->LoopDepth = 0; d->ReaderData->InElse = 0; + d->ReaderData->ReadersAfterEndloop = false; d->DstFile = dst_file; d->DstIndex = dst_index; d->DstMask = dst_mask; @@ -780,11 +782,19 @@ static void get_readers_for_single_write( get_readers_pair_read_callback, d); } + /* Writer was in loop and we have some readers after it. + * Set a flag so we can be extra careful in copy propagate. + */ + if (readers_before_endloop != -1 && + d->ReaderData->ReaderCount > readers_before_endloop) + d->ReaderData->ReadersAfterEndloop = true; + /* This can happen when we jump from an ENDLOOP to BGNLOOP */ if (tmp == writer) { tmp = endloop; endloop = NULL; d->ReaderData->AbortOnRead = abort_on_read_at_endloop; + readers_before_endloop = d->ReaderData->ReaderCount; continue; } rc_for_all_writes_mask(tmp, get_readers_write_callback, d); diff --git a/src/gallium/drivers/r300/compiler/radeon_dataflow.h b/src/gallium/drivers/r300/compiler/radeon_dataflow.h index bb8d48206e2..ef8e2bfe851 100644 --- a/src/gallium/drivers/r300/compiler/radeon_dataflow.h +++ b/src/gallium/drivers/r300/compiler/radeon_dataflow.h @@ -31,6 +31,8 @@ #include "radeon_program_constants.h" +#include + struct radeon_compiler; struct rc_instruction; struct rc_swizzle_caps; @@ -91,6 +93,7 @@ struct rc_reader_data { unsigned int AbortOnWrite; unsigned int LoopDepth; unsigned int InElse; + bool ReadersAfterEndloop; struct rc_instruction * Writer; unsigned int ReaderCount; diff --git a/src/gallium/drivers/r300/compiler/radeon_optimize.c b/src/gallium/drivers/r300/compiler/radeon_optimize.c index a7e9445ce11..5a9f4a529df 100644 --- a/src/gallium/drivers/r300/compiler/radeon_optimize.c +++ b/src/gallium/drivers/r300/compiler/radeon_optimize.c @@ -154,7 +154,7 @@ static void copy_propagate(struct radeon_compiler * c, struct rc_instruction * i copy_propagate_scan_read, NULL, is_src_clobbered_scan_write); - if (reader_data.Abort || reader_data.ReaderCount == 0) + if (reader_data.Abort || reader_data.ReaderCount == 0 || reader_data.ReadersAfterEndloop) return; /* We can propagate SaturateMode if all the readers are MOV instructions