This is a regression present on all the active branches. The compiler generates code that doesn't execute the expected number of iterations for a loop with a dynamic upper bound whose value is exactly the upper bound of the base index type and is obtained through a narrowing conversion.
Tested on x86_64-suse-linux, applied on all the active branches. 2013-08-13 Eric Botcazou <ebotca...@adacore.com> * gcc-interface/trans.c (can_equal_min_or_max_val_p): Be prepared for values outside of the range of the type. 2013-08-13 Eric Botcazou <ebotca...@adacore.com> * gnat.dg/loop_optimization16.adb: New test. * gnat.dg/loop_optimization16_pkg.ad[sb]: New helper. -- Eric Botcazou
Index: gcc-interface/trans.c =================================================================== --- gcc-interface/trans.c (revision 201622) +++ gcc-interface/trans.c (working copy) @@ -2391,7 +2391,10 @@ can_equal_min_or_max_val_p (tree val, tr if (TREE_CODE (val) != INTEGER_CST) return true; - return tree_int_cst_equal (val, min_or_max_val) == 1; + if (max) + return tree_int_cst_lt (val, min_or_max_val) == 0; + else + return tree_int_cst_lt (min_or_max_val, val) == 0; } /* Return true if VAL (of type TYPE) can equal the minimum value of TYPE.
-- { dg-do run } with Loop_Optimization16_Pkg; use Loop_Optimization16_Pkg; procedure Loop_Optimization16 is Counter : Natural := 0; C : constant Natural := F; subtype Index_T is Index_Base range 1 .. Index_Base (C); begin for I in Index_T'First .. Index_T'Last loop Counter := Counter + 1; exit when Counter > 200; end loop; if Counter > 200 then raise Program_Error; end if; end Loop_Optimization16;
package body Loop_Optimization16_Pkg is function F return Natural is begin return Natural (Index_Base'Last); end; end Loop_Optimization16_Pkg;
package Loop_Optimization16_Pkg is type Index_Base is range 0 .. 127; function F return Natural; end Loop_Optimization16_Pkg;