On October 14, 2014 6:02:19 PM CEST, Jakub Jelinek <ja...@redhat.com> wrote:
>Hi!
>
>When hacking on range reassoc opt, I've noticed we can emit
>code with undefined behavior even when there wasn't one originally,
>in particular for:
>   (X - 43U) <= 3U || (X - 75U) <= 3U
>   and this loop can transform that into
>   ((X - 43U) & ~(75U - 43U)) <= 3U.  */
>we actually don't transform it to what the comment says, but
>   ((X - 43) & ~(75U - 43U)) <= 3U
>i.e. the initial subtraction can be performed in signed type,
>if in here X is e.g. INT_MIN or INT_MIN + 42, the subtraction
>at gimple level would be UB (not caught by -fsanitize=undefined,
>because that is handled much earlier).
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

>2014-10-14  Jakub Jelinek  <ja...@redhat.com>
>
>       * tree-ssa-reassoc.c (optimize_range_tests_diff): Perform
>       MINUS_EXPR in unsigned type to avoid undefined behavior.
>
>--- gcc/tree-ssa-reassoc.c.jj  2014-10-13 17:54:33.000000000 +0200
>+++ gcc/tree-ssa-reassoc.c     2014-10-13 17:58:07.312705218 +0200
>@@ -2250,8 +2250,13 @@ optimize_range_tests_diff (enum tree_cod
>   if (tree_log2 (tem1) < 0)
>     return false;
> 
>+  type = unsigned_type_for (type);
>+  tem1 = fold_convert (type, tem1);
>+  tem2 = fold_convert (type, tem2);
>+  lowi = fold_convert (type, lowi);
>   mask = fold_build1 (BIT_NOT_EXPR, type, tem1);
>-  tem1 = fold_binary (MINUS_EXPR, type, rangei->exp, lowi);
>+  tem1 = fold_binary (MINUS_EXPR, type,
>+                    fold_convert (type, rangei->exp), lowi);
>   tem1 = fold_build2 (BIT_AND_EXPR, type, tem1, mask);
>   lowj = build_int_cst (type, 0);
>   if (update_range_test (rangei, rangej, 1, opcode, ops, tem1,
>
>       Jakub


Reply via email to