[Bug c++/106627] New: Exception from multiversion function cannot be caught

2022-08-15 Thread gcc.gnu at vvalter dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106627

Bug ID: 106627
   Summary: Exception from multiversion function cannot be caught
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gcc.gnu at vvalter dot com
  Target Milestone: ---

An exception thrown by a multiversioned function cannot be caught in the called
function. I expect the following program to exit with status code 0, but it
gets terminated because of an uncaught exception. With clang, the program works
as expected. According to godbolt.org it's also broken in gcc trunk and all
other versions that I checked: https://godbolt.org/z/564c6q8xo

__attribute__((target("default")))
void f() {
throw 1;
}

__attribute__((target("sse4.2,bmi")))
void f() {
throw 2;
}

int main()
{
try {
f();
}
catch(... )
{
return 0;
}
return 1;
}

Output of g++ -v:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr
--mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --enable-libstdcxx-backtrace
--with-linker-hash-style=gnu --enable-plugin --enable-initfini-array
--with-isl=/builddir/build/BUILD/gcc-12.1.1-20220507/obj-x86_64-redhat-linux/isl-install
--enable-offload-targets=nvptx-none --without-cuda-driver
--enable-offload-defaulted --enable-gnu-indirect-function --enable-cet
--with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
--with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.1 20220507 (Red Hat 12.1.1-1) (GCC)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 /usr/libexec/gcc/x86_64-redhat-linux/12/cc1plus -E -quiet -v -D_GNU_SOURCE
bug.cpp -mtune=generic -march=x86-64 -fpch-preprocess -o a-bug.ii
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/12/include-fixed"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12

/usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/x86_64-redhat-linux
 /usr/lib/gcc/x86_64-redhat-linux/12/../../../../include/c++/12/backward
 /usr/lib/gcc/x86_64-redhat-linux/12/include
 /usr/local/include
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 /usr/libexec/gcc/x86_64-redhat-linux/12/cc1plus -fpreprocessed a-bug.ii -quiet
-dumpdir a- -dumpbase bug.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64
-version -o a-bug.s
GNU C++17 (GCC) version 12.1.1 20220507 (Red Hat 12.1.1-1)
(x86_64-redhat-linux)
compiled by GNU C version 12.1.1 20220507 (Red Hat 12.1.1-1), GMP
version 6.2.1, MPFR version 4.1.0-p13, MPC version 1.2.1, isl version
isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++17 (GCC) version 12.1.1 20220507 (Red Hat 12.1.1-1)
(x86_64-redhat-linux)
compiled by GNU C version 12.1.1 20220507 (Red Hat 12.1.1-1), GMP
version 6.2.1, MPFR version 4.1.0-p13, MPC version 1.2.1, isl version
isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 2b1c93ff5f3b69a44b0e1b07f6437558
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 as -v --64 -o a-bug.o a-bug.s
GNU assembler version 2.37 (x86_64-redhat-linux) using BFD version version
2.37-27.fc36
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/12/:/usr/libexec/gcc/x86_64-redhat-linux/12/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/12/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/12/:/usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/12/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a.'
 /usr/libexec/gcc/x86_64-redhat-linux/12/collect2 -plugin
/usr/libexec/gcc/x86_64-redhat-linux/12/liblto_plugin.so
-plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/12/lto-wrapper

[Bug ipa/106627] Exception from multiversion function cannot be caught

2022-08-28 Thread gcc.gnu at vvalter dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106627

--- Comment #2 from Simon Rainer  ---
Created attachment 53518
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53518&action=edit
Proposed patch: Set TREE_NOTHROW correctly

I think I identified the issue and found a fix.

ix86_get_function_versions_dispatcher creates a new dispatch declaration that
has always TREE_NOTHROW set to 1, because it is created by build_fn_decl.

It seems like the original function declaration has TREE_NOTHROW set correctly,
so it's enough to set TREE_NOTHROW on the newly created dispatch declaration to
this value.

With the attached patch, I was able to catch exceptions from multiversioned
functions as expected. I also checked manually that if none of the function
versions raise an exception, TREE_NOTHROW is correctly set to 1.

The same code is used for RS/6000 and I'm pretty confident that the same patch
works there, but I'm unable to test this.

[Bug ipa/106816] New: noreturn/pure attributes are not set correctly on multiversioned functions

2022-09-02 Thread gcc.gnu at vvalter dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106816

Bug ID: 106816
   Summary: noreturn/pure attributes are not set correctly on
multiversioned functions
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ipa
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gcc.gnu at vvalter dot com
CC: marxin at gcc dot gnu.org
  Target Milestone: ---

During the investigation of PR106627, Richard noted (
https://gcc.gnu.org/pipermail/gcc-patches/2022-September/600777.html ) that
attributes like noreturn and pure on multiversioned functions are lost when the
function declaration is replaced by the dispatcher declaration in the same way
that the TREE_NOTHROW attribute got lost, which was fixed in PR106627.

Example:

__attribute__((noreturn,target("default")))
void f() {
for (;;) {}
}

__attribute__((noreturn,target("sse4.2,bmi")))
void f() {
for (;;) {}
}

int main()
{
f();
return 1;
}


Gcc should create no code after the call to f(), but the assembly output with
-O3 looks like the following:

call_Z5_Z1fvv@PLT
movl$1, %eax
addq$8, %rsp
.cfi_def_cfa_offset 8
ret

For a non-multiversioned function, no assembly instructions are generated after
the call instruction. Similar problems happen if the function is marked pure.
I reproduced this on 11.2.0 and 12.2, but this most likely affects all gcc
versions.

[Bug ipa/106816] noreturn/pure attributes are not set correctly on multiversioned functions

2022-09-02 Thread gcc.gnu at vvalter dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106816

--- Comment #2 from Simon Rainer  ---
(In reply to H.J. Lu from comment #1)
> Like this?
> 
> diff --git a/gcc/config/i386/i386-features.cc
> b/gcc/config/i386/i386-features.cc
> index fd212262f50..4904e4d71b3 100644
> --- a/gcc/config/i386/i386-features.cc
> +++ b/gcc/config/i386/i386-features.cc
> @@ -3269,6 +3269,9 @@ ix86_get_function_versions_dispatcher (void *decl)
>/* Right now, the dispatching is done via ifunc.  */
>dispatch_decl = make_dispatcher_decl (default_node->decl);
>TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn);
> +  TREE_THIS_VOLATILE (dispatch_decl) = TREE_THIS_VOLATILE (fn);
> +  TREE_READONLY (dispatch_decl) = TREE_READONLY (fn);
> +  DECL_PURE_P (dispatch_decl) = DECL_PURE_P (fn);
>  
>dispatcher_node = cgraph_node::get_create (dispatch_decl);
>gcc_assert (dispatcher_node != NULL);

I tried something like that, but I didn't see changes in the generated
assembly. I don't know if that is because something else is preventing
optimization or some other member needs to be set correctly.

[Bug ipa/106816] noreturn/pure attributes are not set correctly on multiversioned functions

2022-09-02 Thread gcc.gnu at vvalter dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106816

--- Comment #4 from Simon Rainer  ---
That's weird, I still get the following with your patch applied:

main:
.LFB2:
.cfi_startproc
subq$8, %rsp
.cfi_def_cfa_offset 16
call_Z5_Z1fvv@PLT
movl$1, %eax
addq$8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

I double checked that and reran a full bootstrap, but maybe I'm doing something
wrong. I would also be surprised if information about volatile, readonly, and
pure are enough to detect that the function is noreturn, wouldn't that need to
be a separate information?