Message ID | patch-18149-tamar@arm.com |
---|---|
State | New |
Headers | show |
Series | middle-end: fill in reduction PHI for all alt exits [PR113144] | expand |
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); > } > > > > >
--- /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); }