On Mon, 24 Feb 2025, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase is miscompiled due to a bug in
> optimize_range_tests_to_bit_test.  It is trying to optimize
> check for a in [-34,-34] or [-26,-26] or [-6,-6] or [-4,inf] ranges.
> Another reassoc optimization folds the the test for the first
> two ranges into (a + 34U) & ~8U in [0U,0U] range, and extract_bit_test_mask
> actually has code to virtually undo it and treat that again as test
> for a being -34 or -26.  The problem is that optimize_range_tests_to_bit_test
> remembers in the type variable TREE_TYPE (ranges[i].exp); from the first
> range.  If extract_bit_test_mask doesn't do that virtual undoing of the
> BIT_AND_EXPR handling, that is just fine, the returned exp is ranges[i].exp.
> But if the first range is BIT_AND_EXPR, the type could be different, the
> BIT_AND_EXPR form has the optional cast to corresponding unsigned type
> in order to avoid introducing UB.  Now, type was used to fill in the
> max value if ranges[j].high was missing in subsequently tested range,
> and so in this particular testcase the [-4,inf] range which was
> signed int and so [-4,INT_MAX] was treated as [-4,UINT_MAX] instead.
> And we were subtracting values of 2 different types and trying to make
> sense out of that.
> 
> The following patch fixes this by using the type of the low bound
> (which is always non-NULL) for the max value of the high bound instead.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2025-02-24  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/118915
>       * tree-ssa-reassoc.cc (optimize_range_tests_to_bit_test): For
>       highj == NULL_TREE use TYPE_MAX_VALUE (TREE_TYPE (lowj)) rather
>       than TYPE_MAX_VALUE (type).
> 
>       * gcc.c-torture/execute/pr118915.c: New test.
> 
> --- gcc/tree-ssa-reassoc.cc.jj        2025-02-13 19:59:56.157572421 +0100
> +++ gcc/tree-ssa-reassoc.cc   2025-02-20 22:47:42.646500373 +0100
> @@ -3362,7 +3362,7 @@ optimize_range_tests_to_bit_test (enum t
>           continue;
>         highj = ranges[j].high;
>         if (highj == NULL_TREE)
> -         highj = TYPE_MAX_VALUE (type);
> +         highj = TYPE_MAX_VALUE (TREE_TYPE (lowj));
>         wide_int mask2;
>         exp2 = extract_bit_test_mask (ranges[j].exp, prec, lowi, lowj,
>                                       highj, &mask2, NULL);
> --- gcc/testsuite/gcc.c-torture/execute/pr118915.c.jj 2025-02-20 
> 22:46:21.960212578 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/pr118915.c    2025-02-20 
> 22:46:01.019137888 +0100
> @@ -0,0 +1,22 @@
> +/* PR tree-optimization/118915 */
> +
> +int a;
> +
> +int
> +foo (int c, int d, int e, int f)
> +{
> +  if (!d || !e)
> +    return -22;
> +  if (c > 16)
> +    return -22;
> +  if (!f)
> +    return -22;
> +  return 2;
> +}
> +
> +int
> +main ()
> +{
> +  if (foo (a + 21, a + 6, a + 34, a + 26) != -22)
> +    __builtin_abort ();
> +}
>       Jakub
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to