On Mon, Aug 24, 2026 at 8:53 AM Eric Botcazou <[email protected]> wrote:
>
> Hi,
>
> This is a regression present on the mainline, 16 and 15 branches. The problem
> is that the DSE3 pass incorrectly deletes a store to an up-level reference to
> an array with negative low bound:
>
> Deleted dead store: FRAME.19.s[0]{lb: 18446744073709551613 sz: 8} = 0.0;
>
> because IPA modref incorrectly flags it as dead for this call:
>
> ipa-modref: call stmt opt110.term (1, 0,
> 2.37000000000000010658141036401502788066864013671875e+0,
> 2.79323000000000001818989403545856475830078125e+3); [static-chain: &FRAME.19]
> ipa-modref: call to Opt110.Term/3 does not use ref: FRAME.19.s[0]{lb:
> 18446744073709551613 sz: 8} alias sets: 13->11
>
> The array at stake is declared with a negative low bound:
>
> N : constant := 3;
>
> S : array (-N..0) of REAL;
>
>
> The origin of the problem is visible when you compare the modref1 and modref2
> dump files:
>
> - Analyzing load: CHAIN.20_21(D)->s[_7]{lb: 18446744073709551613 sz: 8}
> (can throw; marking side effects) - Recording base_set=0 ref_set=0 Static
> chain param offset:0 offset:960 size:64 max_size:256
>
> vs
>
> - Analyzing load: CHAIN.20_12(D)->s[_4]{lb: 18446744073709551613 sz: 8}
> (can throw; marking side effects) - Recording base_set=0 ref_set=0 Static
> chain param offset:0 offset:960 size:64 max_size:192
>
> The max_size has been incorrectly shrunk from 256 to 192 bits, the missing 64
> bits being the FRAME.19.s[0]{lb: 18446744073709551613 sz: 8} element.
>
>
> The problematic code is in get_ref_base_and_extent:
>
> if (TREE_CODE (index) == SSA_NAME
> && (low_bound = array_ref_low_bound (exp),
> poly_int_tree_p (low_bound))
> && (unit_size = array_ref_element_size (exp),
> TREE_CODE (unit_size) == INTEGER_CST)
> && query->range_of_expr (vr, index)
> && !vr.varying_p ()
> && !vr.undefined_p ())
> {
> wide_int min = vr.lower_bound ();
> wide_int max = vr.upper_bound ();
> poly_offset_int lbound = wi::to_poly_offset (low_bound);
> /* Try to constrain maxsize with range information. */
>
> It uses the range of the index expression to constrain the maxsize:
>
> [irange] sizetype [0, 0][18446744073709551613, +INF]
>
> but that's not correct in the general case, the correct range being instead
> the range of the difference between the low bound and the index expression,
> as implemented by the model computation in get_inner_reference:
>
> [irange] sizetype [0, 3]
>
> Of course this makes no difference for the C family of languages where the low
> bound is always 0. There is also the problematic case where this low bound is
> a poly_int instead of an integer, given that ranges do not support poly_ints,
> but I'm not sure whether that's a practical concern; that's why I'm proposing
> two versions of the fix, one filtering it out and the other keeping it.
>
> Bootstrapped/regtested on x86-64/Linux, OK for the mainline as well as the 16
> and 15 branches? If so, which version?
The first version, requiring INTEGER_CST low_bound. But ...
&& query->range_of_expr (vr, index)
&& !vr.varying_p ()
- && !vr.undefined_p ())
+ && !vr.undefined_p ()
+ && (integer_zerop (low_bound)
+ || query->range_of_expr
+ (vr,
+ build2 (MINUS_EXPR, TREE_TYPE (index),
+ index, low_bound))))
can you try to use
range_op_handler op (MINUS_EXPR);
|| !op.fold_range (vr, TREE_TYPE (index), vr, low_bound_range)
with building a constant range for low_bound (not exactly sure how to
best do that)? I think you'll also need to repeat the
!vr.varying_p () / !vr.undefined_p () checks -- possibly they
could be simply delayed and feeding fold_range with those could
be OK.
I have CCed Andrew who sould be able to give better guidance.
I'll note the existing code tried to account for low_bound != 0, I trust
you identified where it failed to, I refrained from trying to understand it ;)
Thanks,
Richard.
>
>
> 2026-08-24 Eric Botcazou <[email protected]>
>
> PR ada/125984
> * tree-dfa.cc (get_ref_base_and_extent) <ARRAY_REF>: Use the range
> of the difference between the index expression and the low bound,
> instead of that of the index expression itself, to constrain the
> maximum size of the access.
>
>
> 2026-08-24 Eric Botcazou <[email protected]>
>
> * gnat.dg/opt110.adb: New test.
>
> --
> Eric Botcazou