On Thu, 11 Jan 2024, Tamar Christina wrote:

> Hi All,
> 
> When we have a loop with more than 2 exits and a reduction I forgot to fill in
> the PHI value for all alternate exits.
> 
> All alternate exits use the same PHI value so we should loop over the new
> PHI elements and copy the value across since we call the reduction calculation
> code only once for all exits.  This was normally covered up by earlier parts 
> of
> the compiler rejecting loops incorrectly (which has been fixed now).
> 
> Note that while I can use the loop in all cases, the reason I separated out 
> the
> main and alt exit is so that if you pass the wrong edge the macro will assert.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
> and no issues.
> 
> Ok for master?

OK

> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>       PR tree-optimization/113178
>       * tree-vect-loop.cc (vect_create_epilog_for_reduction): Fill in all
>       alternate exits.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR tree-optimization/113178
>       * g++.dg/vect/vect-early-break_6-pr113178.cc: New test.
>       * gcc.dg/vect/vect-early-break_101-pr113178.c: New test.
>       * gcc.dg/vect/vect-early-break_102-pr113178.c: New test.
> 
> --- inline copy of patch -- 
> diff --git a/gcc/testsuite/g++.dg/vect/vect-early-break_6-pr113178.cc 
> b/gcc/testsuite/g++.dg/vect/vect-early-break_6-pr113178.cc
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..da008759a72dd563bf4930decd74470ae35cb98e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/vect/vect-early-break_6-pr113178.cc
> @@ -0,0 +1,34 @@
> +/* { dg-do compile } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +struct PixelWeight {
> +  int m_SrcStart;
> +  int m_Weights[];
> +};
> +struct CWeightTable {
> +  int *GetValueFromPixelWeight(PixelWeight *, int) const;
> +};
> +char ContinueStretchHorz_dest_scan;
> +struct CStretchEngine {
> +  bool ContinueStretchHorz();
> +  CWeightTable m_WeightTable;
> +};
> +int *CWeightTable::GetValueFromPixelWeight(PixelWeight *pWeight,
> +                                           int index) const {
> +  long __trans_tmp_1;
> +  if (index < pWeight->m_SrcStart)
> +    return __trans_tmp_1 ? &pWeight->m_Weights[pWeight->m_SrcStart] : 
> nullptr;
> +}
> +bool CStretchEngine::ContinueStretchHorz() {
> +  {
> +    PixelWeight pPixelWeights;
> +    int dest_g_m;
> +    for (int j; j; j++) {
> +      int pWeight = *m_WeightTable.GetValueFromPixelWeight(&pPixelWeights, 
> j);
> +      dest_g_m += pWeight;
> +    }
> +    ContinueStretchHorz_dest_scan = dest_g_m;
> +  }
> +}
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_101-pr113178.c 
> b/gcc/testsuite/gcc.dg/vect/vect-early-break_101-pr113178.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..8b91112133f0522270bb4d92664355838a405aaf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_101-pr113178.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +
> +struct PixelWeight {
> +  int m_SrcStart;
> +  int m_Weights[16];
> +};
> +char h;
> +void f(struct PixelWeight *pPixelWeights) {
> +    int dest_g_m;
> +    long tt;
> +    for (int j = 0; j < 16; j++) {
> +      int *p = 0;
> +      if (j < pPixelWeights->m_SrcStart)
> +        p = tt ? &pPixelWeights->m_Weights[0] : 0;
> +      int pWeight = *p;
> +      dest_g_m += pWeight;
> +    }
> +    h = dest_g_m;
> +}
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_102-pr113178.c 
> b/gcc/testsuite/gcc.dg/vect/vect-early-break_102-pr113178.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..ad7582e440720e50a2769239c88b1e07517e4c10
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_102-pr113178.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-add-options vect_early_break } */
> +/* { dg-require-effective-target vect_early_break } */
> +/* { dg-require-effective-target vect_int } */
> +/* { dg-additional-options "-std=gnu99 -fpermissive -fgnu89-inline -Ofast 
> -fprofile-generate -w" } */
> +
> +extern int replace_reg_with_saved_mem_i, replace_reg_with_saved_mem_nregs,
> +    replace_reg_with_saved_mem_mem_1;
> +replace_reg_with_saved_mem_mode() {
> +  if (replace_reg_with_saved_mem_i)
> +    return;
> +  while (++replace_reg_with_saved_mem_i < replace_reg_with_saved_mem_nregs)
> +    if (replace_reg_with_saved_mem_i)
> +      break;
> +  if (replace_reg_with_saved_mem_i)
> +    if (replace_reg_with_saved_mem_mem_1)
> +      adjust_address_1();
> +  replace_reg_with_saved_mem_mem_1 ? fancy_abort() : 0;
> +}
> diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
> index 
> 27bb28365936978013a576b64b72d9e92375f361..da2dfa176ecd457ebc11d1131302ca15d77d779d
>  100644
> --- a/gcc/tree-vect-loop.cc
> +++ b/gcc/tree-vect-loop.cc
> @@ -6223,7 +6223,13 @@ vect_create_epilog_for_reduction (loop_vec_info 
> loop_vinfo,
>         phi = create_phi_node (new_def, exit_bb);
>         if (j)
>           def = gimple_get_lhs (vec_stmts[j]);
> -       SET_PHI_ARG_DEF (phi, loop_exit->dest_idx, def);
> +       if (LOOP_VINFO_IV_EXIT (loop_vinfo) == loop_exit)
> +         SET_PHI_ARG_DEF (phi, loop_exit->dest_idx, def);
> +       else
> +         {
> +           for (unsigned k = 0; k < gimple_phi_num_args (phi); k++)
> +             SET_PHI_ARG_DEF (phi, k, def);
> +         }
>         new_def = gimple_convert (&stmts, vectype, new_def);
>         reduc_inputs.quick_push (new_def);
>       }
> 
> 
> 
> 
> 

-- 
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