Hello,

On Mon, Jan 12 2026, Andrew MacLeod wrote:
> On 1/6/26 12:35, Andrew MacLeod wrote:
>> VRP1 is allowed to remove a __builtin_unreachable () if it determines 
>> that the other edge in the branch dominates all uses of all exports 
>> from the block.
>>
>> ie
>>
>> <bb 3>:
>>   x_8 = 1 << i_7;
>>   if (x_8 <= 0)               <<-- this is the branch in BB3
>>     goto <bb 4>; [INV]
>>   else
>>     goto <bb 5>; [INV]
>>
>>   <bb 4> :
>>   __builtin_unreachable ();
>>
>> we can remove the branch  and edge to bb 4 if we can prove that there 
>> are no uses of x_8 or i_7 in or dominated by the edge 3->5.  We can 
>> then set the global ranges of i_7 and x_8 and move along.
>>
>> This PR demonstrates that this normally works, but with rangers 
>> ability to recompute values, we also have to look at the dependencies 
>> of all the exports.
>>
>> IN this case i_7 is defined:
>>  <bb 7> :
>>   # i_2 = PHI <i_7(5), n_4(D)(2), i_7(6)>
>>   i_7 = i_2 + -1;
>>   if (i_2 > 0)
>>     goto <bb 3>; [INV]
>>   else
>>     goto <bb 8>; [INV]
>>
>> so althoug the uses of i_7 Are dominated by 3->5,  it does NOT 
>> dominate the use of i_2 in bb_7.   When early removal changes the 
>> global value of i_7, ranger happily recomputes i_2 in the branch and 
>> decides that if i_7 is now [0, +INF], i_2 must always be > 0 and 
>> removes the branch.
>>
>> Which is clearly incorrect.  This patch teaches the early removal code 
>> that it can only remove the unreachable call if x_8, i_7 and ALL the 
>> dependencies used to calculate either name are ALL dominated by the 
>> edge.    This information is all trivially available in GORI, so its 
>> noly a minor tweak.
>>
>> Performance impact over a build of GCC is minimal. a 0.03% slowdown in 
>> VRP.
>>
>> In the PR I mentioned not removing it if any of the dependencies had 
>> more than a single use, but that turned out to be too limiting.  This 
>> solution works much better.
>>
>> Bootstraps on x86_64-pc-linux-gnu with no regressions.  OK?
>>
>> Andrew
>>
> Patch applied to GCC 15.   OK for branch or not?
>

I think you have attached a wrong patch?  This one already is part of
GCC 15, I think.

Martin



> Andrew
> From e43f8d4b1e0317cd90d3f1da4c61993a0e2e2c60 Mon Sep 17 00:00:00 2001
> From: Andrew MacLeod <[email protected]>
> Date: Fri, 2 May 2025 15:48:08 -0400
> Subject: [PATCH] Allow IPA_CP to handle UNDEFINED as VARYING.
>
> When applying a bitmask to reflect ranges, it is sometimes deferred and
> this can result in an UNDEFINED result.  IPA is not expecting this, and
> add a check for it, and convert to VARYING if encountered.
>
>       PR tree-optimization/120048
>       gcc/
>       * ipa-cp.cc (ipcp_store_vr_results): Check for UNDEFINED.
>
>       gcc/testsuite/
>       * gcc.dg/pr120048.c: New.
> ---
>  gcc/ipa-cp.cc                   | 10 ++++++++++
>  gcc/testsuite/gcc.dg/pr120048.c | 12 ++++++++++++
>  2 files changed, 22 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/pr120048.c
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index 806c2bdc97f..a8ff3c87073 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -6398,6 +6398,11 @@ ipcp_store_vr_results (void)
>                                                    TYPE_PRECISION (type),
>                                                    TYPE_SIGN (type)));
>                 tmp.update_bitmask (bm);
> +               // Reflecting the bitmask on the ranges can sometime
> +               // produce an UNDEFINED value if the the bitmask update
> +               // was previously deferred.  See PR 120048.
> +               if (tmp.undefined_p ())
> +                 tmp.set_varying (type);
>                 ipa_vr vr (tmp);
>                 ts->m_vr->quick_push (vr);
>               }
> @@ -6419,6 +6424,11 @@ ipcp_store_vr_results (void)
>                                                TYPE_PRECISION (type),
>                                                TYPE_SIGN (type)));
>             tmp.update_bitmask (bm);
> +           // Reflecting the bitmask on the ranges can sometime
> +           // produce an UNDEFINED value if the the bitmask update
> +           // was previously deferred.  See PR 120048.
> +           if (tmp.undefined_p ())
> +             tmp.set_varying (type);
>             ipa_vr vr (tmp);
>             ts->m_vr->quick_push (vr);
>           }
> diff --git a/gcc/testsuite/gcc.dg/pr120048.c b/gcc/testsuite/gcc.dg/pr120048.c
> new file mode 100644
> index 00000000000..6bb34b0e168
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr120048.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-tree-vrp -fno-tree-fre" } */
> +
> +int a, b, c;
> +static int d(short e) { return e || (a && e) ? 0 : a; }
> +static void f(int e) {
> +  if (!e) {
> +    d(0);
> +    b = d(e);
> +  }
> +}
> +int main() { f(c | 1); }
> -- 
> 2.45.0

Reply via email to