public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/105769] [11/12/13 Regression] program segmentation fault with -ftree-vectorize and nested lambdas
Date: Mon, 16 Jan 2023 20:30:00 +0000	[thread overview]
Message-ID: <bug-105769-4-TLt1gK4O4Q@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-105769-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105769

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
At least when using g++ 12.1.1 (20220507), the crash is because the
stack slot holding return value from jacknife is clobbered on the
bias = est(map);
line.
I see in main (well, print_cov_ratio and std::function inlined into it):
   0x00000000004016d1 <main()+274>:     lea    0x50(%rsp),%rsi
   0x00000000004016d6 <main()+279>:     lea    0x30(%rsp),%rdi
=> 0x00000000004016db <main()+284>:     call   *0x48(%rsp)
   0x00000000004016df <main()+288>:     jmp    0x401742 <main()+387>
where 0x30(%rsp) seems to be the est argument to jacknife (32 byte est_t) and
0x50(%rsp) the return value from jacknife (32 byte est_t)
(gdb) p/x $rsp+0x50
$49 = 0x7fffffffdd20
where the indirect call calls:
#0  std::_Function_handler<void (std::function<unsigned long (unsigned long)>),
jacknife<2ul, ab>(std::function<vec<2ul, ab> (std::function<unsigned long
(unsigned long)>)>, vec<2ul, vec<2ul, ab> >&, vec<2ul,
ab>&)::{lambda(std::function<unsigned long (unsigned
long)>)#1}>::_M_invoke(std::_Any_data const&, std::function<unsigned long
(unsigned long)>&&) (
    __functor=..., __args#0=...) at /usr/include/c++/12/bits/std_function.h:288
#1  0x00000000004016df in std::function<void (std::function<unsigned long
(unsigned long)>)>::operator()(std::function<unsigned long (unsigned long)>)
const (__args#0=..., 
    this=0x7fffffffdd00) at /usr/include/c++/12/bits/std_function.h:591
#2  print_cov_ratio<ab> () at /usr/src/gcc/obj/gcc/pr105769.C:85
#3  main () at /usr/src/gcc/obj/gcc/pr105769.C:121
But later in
#0  0x00000000004014f3 in jacknife<2ul, ab>(std::function<vec<2ul, ab>
(std::function<unsigned long (unsigned long)>)>, vec<2ul, vec<2ul, ab> >&,
vec<2ul, ab>&)::{lambda(std::function<unsigned long (unsigned
long)>)#1}::operator()(std::function<unsigned long (unsigned long)>) const
(map=..., __closure=0x4172c0) at /usr/src/gcc/obj/gcc/pr105769.C:59
#1  std::__invoke_impl<void, jacknife<2ul, ab>(std::function<vec<2ul, ab>
(std::function<unsigned long (unsigned long)>)>, vec<2ul, vec<2ul, ab> >&,
vec<2ul, ab>&)::{lambda(std::function<unsigned long (unsigned long)>)#1}&,
std::function<unsigned long (unsigned long)> >(std::__invoke_other,
jacknife<2ul, ab>(std::function<vec<2ul, ab> (std::function<unsigned long
(unsigned long)>)>, vec<2ul, vec<2ul, ab> >&, vec<2ul,
ab>&)::{lambda(std::function<unsigned long (unsigned long)>)#1}&,
std::function<unsigned long (unsigned long)>&&) (__f=...)
    at /usr/include/c++/12/bits/invoke.h:61
#2  std::__invoke_r<void, jacknife<2ul, ab>(std::function<vec<2ul, ab>
(std::function<unsigned long (unsigned long)>)>, vec<2ul, vec<2ul, ab> >&,
vec<2ul, ab>&)::{lambda(std::function<unsigned long (unsigned long)>)#1}&,
std::function<unsigned long (unsigned long)> >(jacknife<2ul,
ab>(std::function<vec<2ul, ab> (std::function<unsigned long (unsigned long)>)>,
vec<2ul, vec<2ul, ab> >&, vec<2ul, ab>&)::{lambda(std::function<unsigned long
(unsigned long)>)#1}&, std::function<unsigned long (unsigned long)>&&)
(__fn=...)
    at /usr/include/c++/12/bits/invoke.h:111
#3  std::_Function_handler<void (std::function<unsigned long (unsigned long)>),
jacknife<2ul, ab>(std::function<vec<2ul, ab> (std::function<unsigned long
(unsigned long)>)>, vec<2ul, vec<2ul, ab> >&, vec<2ul,
ab>&)::{lambda(std::function<unsigned long (unsigned
long)>)#1}>::_M_invoke(std::_Any_data const&, std::function<unsigned long
(unsigned long)>&&) (
    __functor=..., __args#0=...) at /usr/include/c++/12/bits/std_function.h:290
#4  0x00000000004016df in std::function<void (std::function<unsigned long
(unsigned long)>)>::operator()(std::function<unsigned long (unsigned long)>)
const (__args#0=..., 
    this=0x7fffffffdd00) at /usr/include/c++/12/bits/std_function.h:591
#5  print_cov_ratio<ab> () at /usr/src/gcc/obj/gcc/pr105769.C:85
#6  main () at /usr/src/gcc/obj/gcc/pr105769.C:121
&bias is equal to the address of the jacknife return value:
$50 = (vec<2, ab> *) 0x7fffffffdd20

To make the dumps more readable, I've patched the testcase:
--- pr105769.C~ 2023-01-16 19:05:01.000000000 +0100
+++ pr105769.C  2023-01-16 20:38:25.101524077 +0100
@@ -40,7 +40,7 @@ using sq_mat = mat<n, n, T>;
 using map_t = std::function<size_t(size_t)>;

 template<class T_v>
-using est_t = std::function<T_v(map_t map)>;
+using est_t = std::function<T_v(map_t map)>; template<class T_v> using est2_t
= std::function<T_v(map_t map)>;

 map_t id_map() {
   return [](size_t j) -> size_t {
@@ -50,7 +50,7 @@ map_t id_map() {


 template<size_t n, class T>
-est_t<void> jacknife(const est_t<vec<n, T>> est,
+est2_t<void> jacknife(const est_t<vec<n, T>> est,
     sq_mat<n, T>& cov, vec<n, T>& bias) {

   return [est, &cov, &bias](
and with that in the *.gimple dump I see:
void print_cov_ratio<ab> ()
[pr105769.C:88:1] {
  struct est2_t D.85904;
  struct est_t D.85869;
  struct ._anon_95 D.85344;
  struct map_t D.85939;
  struct sq_mat cov_jn;
  struct vec bias;
  typedef struct ._anon_95 ._anon_95;

  try
    {
      [pr105769.C:73:16] vec<2, vec<2, ab> >::vec ([pr105769.C:73:16] &cov_jn);
      [pr105769.C:74:13] vec<2, ab>::vec ([pr105769.C:74:13] &bias);
      [pr105769.C:85:23] try
        {
          try
            {
              try
                {
                  [pr105769.C:85:23] std::function<vec<2,
ab>(std::function<long unsigned int(long unsigned
int)>)>::function<print_cov_ratio<ab>()::<lambda(map_t)> > ([pr105769.C:85
                  try
                    {
                      [pr105769.C:85:23] D.85904 = jacknife<2, ab>
([pr105769.C:85:23] &D.85869, [pr105769.C:85:10] &cov_jn, [pr105769.C:85:18]
&bias); [return slot optimization]
                      try
                        {
                          try
                            {
                              [pr105769.C:85:23] D.85939 = id_map (); [return
slot optimization]
                              try
                                {
                                  [pr105769.C:85:23]
std::function<void(std::function<long unsigned int(long unsigned
int)>)>::operator() ([pr105769.C:85:23] &D.85904, [pr105769.C:85
                                }
                              finally
                                {
                                  [pr105769.C:85:23] std::function<long
unsigned int(long unsigned int)>::~function ([pr105769.C:85:23] &D.85939);
                                }
                            }
                          finally
                            {
                              [pr105769.C:85:23] D.85939 = {CLOBBER(eol)};
                            }
                        }
                      finally
                        {
                          [pr105769.C:85:23]
std::function<void(std::function<long unsigned int(long unsigned
int)>)>::~function ([pr105769.C:85:23] &D.85904);
                        }
                    }
                  finally
                    {
                      [pr105769.C:85:23] std::function<vec<2,
ab>(std::function<long unsigned int(long unsigned int)>)>::~function
([pr105769.C:85:23] &D.85869);
                    }
                }
              finally
                {
                  [pr105769.C:77:7] D.85344 = {CLOBBER(eol)};
                }
            }
          finally
            {
              [pr105769.C:85:23] D.85869 = {CLOBBER(eol)};
            }
        }
      finally
        {
          [pr105769.C:85:23] D.85904 = {CLOBBER(eol)};
        }
    }
  finally
    {
      cov_jn = {CLOBBER(eol)};
      bias = {CLOBBER(eol)};
    }
}

D.85904 above is the return value (est2_t), D.85869 is the est argument, and
bias variable is actually constructed even before this, all have 32 bytes in
size.

So, to me this looks like incorrect stack slot reuse.

  parent reply	other threads:[~2023-01-16 20:30 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-29 21:24 [Bug c++/105769] New: " sliwa at ifpan dot edu.pl
2022-05-30 10:14 ` [Bug tree-optimization/105769] " marxin at gcc dot gnu.org
2022-06-02  8:10 ` [Bug tree-optimization/105769] [11/12/13 Regression] " rguenth at gcc dot gnu.org
2022-10-19 10:15 ` rguenth at gcc dot gnu.org
2022-10-19 11:01 ` marxin at gcc dot gnu.org
2023-01-16 20:30 ` jakub at gcc dot gnu.org [this message]
2023-01-16 21:10 ` jakub at gcc dot gnu.org
2023-01-16 21:20 ` jakub at gcc dot gnu.org
2023-01-17 11:52 ` jakub at gcc dot gnu.org
2023-01-17 12:11 ` jakub at gcc dot gnu.org
2023-01-17 12:27 ` rguenth at gcc dot gnu.org
2023-01-17 12:31 ` jakub at gcc dot gnu.org
2023-01-17 12:41 ` jakub at gcc dot gnu.org
2023-01-17 14:08 ` rguenther at suse dot de
2023-01-17 14:45 ` jakub at gcc dot gnu.org
2023-01-17 15:14 ` rguenther at suse dot de
2023-05-29 10:07 ` [Bug tree-optimization/105769] [11/12/13/14 " jakub at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-105769-4-TLt1gK4O4Q@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).