Hello!

My last mail was misleading. The described behaviour (continue out of loop 
etc.) occurs with mesa's current glsl compiler. The attached patch tries to 
fix that.

I appologize for the faulty description and hope it was the cause for the lack 
of feedback to my last mail.

I also attached two piglit tests to demonstrate the bug.

Fabian

On Friday 26 November 2010 02:09:31 Fabian Bieler wrote:
> Hello!
>
> This patch fixes a bug in the lower_jumps pass if lower_sub_return is set
> to true.
>
> Subroutines such as
>
> void sub() {
>   for (int i = 0; i < 2; ++i) {
>     if (i)
>       return;
>   }
> }
>
> a continue instruction is inserted outside of the loop.
>
> Subroutines such as
>
> void sub() {
>   for (int j = 0; j < 2; ++j) {
>     for (int i = 0; i < 2; ++i) {
>       if (i)
>         return;
>     }
>   }
>   alter_some_global_variable();
>   return;
> }
>
> get transformed to
>
> void sub() {
>   bool return_flag = false;
>   for (int j = 0; j < 2; ++j) {
>     for (int i = 0; i < 2; ++i) {
>       if (i) {
>         return_flag = true;
>         break;
>       }
>     }
>     if (return_flag)
>       break;
>   }
>   alter_some_global_variable();
>   return;
> }
>
> Please review
>
> Fabian


From 001a40b4033f072c2683426d13bd67cbc793da8c Mon Sep 17 00:00:00 2001
From: Fabian Bieler <[email protected]>
Date: Wed, 1 Dec 2010 14:44:58 +0100
Subject: [PATCH] glsl: fix lowering conditional returns in subroutines

this fix applies to the lower_sub_return 'branch' of the lower_jumps pass
---
 src/glsl/lower_jumps.cpp |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/src/glsl/lower_jumps.cpp b/src/glsl/lower_jumps.cpp
index e1e7a5b..9009495 100644
--- a/src/glsl/lower_jumps.cpp
+++ b/src/glsl/lower_jumps.cpp
@@ -490,7 +490,11 @@ lower_continue:
       if(this->loop.may_set_return_flag) {
          assert(this->function.return_flag);
          ir_if* return_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->function.return_flag));
-         return_if->then_instructions.push_tail(new(ir) ir_loop_jump(saved_loop.loop ? ir_loop_jump::jump_break : ir_loop_jump::jump_continue));
+         saved_loop.may_set_return_flag = true;
+         if(saved_loop.loop)
+            return_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
+         else
+            move_outer_block_inside(ir, &return_if->else_instructions);
          ir->insert_after(return_if);
       }
 
-- 
1.7.1

[require]
GL >= 2.0
GLSL >= 1.10

[vertex shader]
void main()
{
	gl_Position = gl_Vertex;
}

[fragment shader]
float val = 0.0;
void sub() {
	for (int i = 0; i < 3; ++i) {
		if (i == 1)
			return;
		val = 0.5;
	}
	val = 1.0;
}

void main() {
	sub();
	gl_FragColor = vec4(val);
}

[test]
draw rect -1 -1 2 2
probe all rgb 0.5 0.5 0.5 0.5
[require]
GL >= 2.0
GLSL >= 1.10

[vertex shader]
void main()
{
	gl_Position = gl_Vertex;
}

[fragment shader]
float val = 0.0;
void sub() {
	for (int i = 0; i < 3; ++i) {
		for (int j = 0; j < 3; ++j) {
			if (i == 1 && j == 1)
				return;
			val = 0.5;
		}
	}
	val = 1.0;
}

void main() {
	sub();
	gl_FragColor = vec4(val);
}

[test]
draw rect -1 -1 2 2
probe all rgb 0.5 0.5 0.5 0.5
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to