From b42633db8e3711e54a5bd10495b1436b8e362801 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 3 Apr 2018 11:38:13 +1000 Subject: [PATCH] glsl: always call do_lower_jumps() after loop unrolling This fixes a bug in radeonsi where LLVM cannot handle the case where a break exists but its not the last instruction in the block. LLVM would fail with: Terminator found in the middle of a basic block! LLVM ERROR: Broken function found, compilation aborted! Fixes: 96fe8834f539 "glsl_to_tgsi: do fewer optimizations with GLSLOptimizeConservatively" Reviewed-by: Matt Turner Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105317 --- src/compiler/glsl/glsl_parser_extras.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index 275c4d7..0cc57f5 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -2242,6 +2242,24 @@ do_common_optimization(exec_list *ir, bool linked, loop_progress = false; loop_progress |= do_constant_propagation(ir); loop_progress |= do_if_simplification(ir); + + /* Some drivers only call do_common_optimization() once rather + * than in a loop. So we must call do_lower_jumps() after + * unrolling a loop because for drivers that use LLVM validation + * will fail if a jump is not the last instruction in the block. + * For example the following will fail LLVM validation: + * + * (loop ( + * ... + * break + * (assign (x) (var_ref v124) (expression int + (var_ref v124) + * (constant int (1)) ) ) + * )) + */ + loop_progress |= do_lower_jumps(ir, true, true, + options->EmitNoMainReturn, + options->EmitNoCont, + options->EmitNoLoops); } progress |= loop_progress; } -- 2.7.4