mirror of git://gcc.gnu.org/git/gcc.git
Merge from trunk revision 3a39a31b8a.
This commit is contained in:
commit
aa1e672b5d
12
ChangeLog
12
ChangeLog
|
|
@ -1,3 +1,15 @@
|
||||||
|
2023-06-25 Lehua Ding <lehua.ding@rivai.ai>
|
||||||
|
|
||||||
|
* MAINTAINERS: Add Lehua Ding to write after approval
|
||||||
|
|
||||||
|
2023-06-25 Iain Sandoe <iain@sandoe.co.uk>
|
||||||
|
|
||||||
|
* Makefile.def: Pass the enable-host-pie value to GCC configure.
|
||||||
|
* Makefile.in: Regenerate.
|
||||||
|
* configure: Regenerate.
|
||||||
|
* configure.ac: Adjust the logic for shared and PIE host flags to
|
||||||
|
ensure that PIE is passed for hosts that require it.
|
||||||
|
|
||||||
2023-06-16 YunQiang Su <yunqiang.su@cipunited.com>
|
2023-06-16 YunQiang Su <yunqiang.su@cipunited.com>
|
||||||
|
|
||||||
* MAINTAINERS (Write After Approval): move Matthew Fortune
|
* MAINTAINERS (Write After Approval): move Matthew Fortune
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,7 @@ Chris Demetriou <cgd@google.com>
|
||||||
Sameera Deshpande <sameera.deshpande@linaro.org>
|
Sameera Deshpande <sameera.deshpande@linaro.org>
|
||||||
Wilco Dijkstra <wdijkstr@arm.com>
|
Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
Benoit Dupont de Dinechin <benoit.dupont-de-dinechin@st.com>
|
Benoit Dupont de Dinechin <benoit.dupont-de-dinechin@st.com>
|
||||||
|
Lehua Ding <lehua.ding@rivai.ai>
|
||||||
Jason Eckhardt <jle@rice.edu>
|
Jason Eckhardt <jle@rice.edu>
|
||||||
Bernd Edlinger <bernd.edlinger@hotmail.de>
|
Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
Phil Edwards <pme@gcc.gnu.org>
|
Phil Edwards <pme@gcc.gnu.org>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ host_modules= { module= fixincludes; bootstrap=true;
|
||||||
host_modules= { module= flex; no_check_cross= true; };
|
host_modules= { module= flex; no_check_cross= true; };
|
||||||
host_modules= { module= gas; bootstrap=true; };
|
host_modules= { module= gas; bootstrap=true; };
|
||||||
host_modules= { module= gcc; bootstrap=true;
|
host_modules= { module= gcc; bootstrap=true;
|
||||||
extra_make_flags="$(EXTRA_GCC_FLAGS)"; };
|
extra_make_flags="$(EXTRA_GCC_FLAGS)";
|
||||||
|
extra_configure_flags='@gcc_host_pie@'; };
|
||||||
host_modules= { module= gmp; lib_path=.libs; bootstrap=true;
|
host_modules= { module= gmp; lib_path=.libs; bootstrap=true;
|
||||||
// Work around in-tree gmp configure bug with missing flex.
|
// Work around in-tree gmp configure bug with missing flex.
|
||||||
extra_configure_flags='--disable-shared LEX="touch lex.yy.c" @host_libs_picflag@';
|
extra_configure_flags='--disable-shared LEX="touch lex.yy.c" @host_libs_picflag@';
|
||||||
|
|
|
||||||
29
Makefile.in
29
Makefile.in
|
|
@ -12021,7 +12021,7 @@ configure-gcc:
|
||||||
$$s/$$module_srcdir/configure \
|
$$s/$$module_srcdir/configure \
|
||||||
--srcdir=$${topdir}/$$module_srcdir \
|
--srcdir=$${topdir}/$$module_srcdir \
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} @gcc_host_pie@ \
|
||||||
|| exit 1
|
|| exit 1
|
||||||
@endif gcc
|
@endif gcc
|
||||||
|
|
||||||
|
|
@ -12056,7 +12056,8 @@ configure-stage1-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
\
|
\
|
||||||
$(STAGE1_CONFIGURE_FLAGS)
|
$(STAGE1_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stage2-gcc maybe-configure-stage2-gcc
|
.PHONY: configure-stage2-gcc maybe-configure-stage2-gcc
|
||||||
|
|
@ -12089,7 +12090,8 @@ configure-stage2-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGE2_CONFIGURE_FLAGS)
|
$(STAGE2_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stage3-gcc maybe-configure-stage3-gcc
|
.PHONY: configure-stage3-gcc maybe-configure-stage3-gcc
|
||||||
|
|
@ -12122,7 +12124,8 @@ configure-stage3-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGE3_CONFIGURE_FLAGS)
|
$(STAGE3_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stage4-gcc maybe-configure-stage4-gcc
|
.PHONY: configure-stage4-gcc maybe-configure-stage4-gcc
|
||||||
|
|
@ -12155,7 +12158,8 @@ configure-stage4-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGE4_CONFIGURE_FLAGS)
|
$(STAGE4_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stageprofile-gcc maybe-configure-stageprofile-gcc
|
.PHONY: configure-stageprofile-gcc maybe-configure-stageprofile-gcc
|
||||||
|
|
@ -12188,7 +12192,8 @@ configure-stageprofile-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGEprofile_CONFIGURE_FLAGS)
|
$(STAGEprofile_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stagetrain-gcc maybe-configure-stagetrain-gcc
|
.PHONY: configure-stagetrain-gcc maybe-configure-stagetrain-gcc
|
||||||
|
|
@ -12221,7 +12226,8 @@ configure-stagetrain-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGEtrain_CONFIGURE_FLAGS)
|
$(STAGEtrain_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stagefeedback-gcc maybe-configure-stagefeedback-gcc
|
.PHONY: configure-stagefeedback-gcc maybe-configure-stagefeedback-gcc
|
||||||
|
|
@ -12254,7 +12260,8 @@ configure-stagefeedback-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGEfeedback_CONFIGURE_FLAGS)
|
$(STAGEfeedback_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stageautoprofile-gcc maybe-configure-stageautoprofile-gcc
|
.PHONY: configure-stageautoprofile-gcc maybe-configure-stageautoprofile-gcc
|
||||||
|
|
@ -12287,7 +12294,8 @@ configure-stageautoprofile-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGEautoprofile_CONFIGURE_FLAGS)
|
$(STAGEautoprofile_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
.PHONY: configure-stageautofeedback-gcc maybe-configure-stageautofeedback-gcc
|
.PHONY: configure-stageautofeedback-gcc maybe-configure-stageautofeedback-gcc
|
||||||
|
|
@ -12320,7 +12328,8 @@ configure-stageautofeedback-gcc:
|
||||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||||
--target=${target_alias} \
|
--target=${target_alias} \
|
||||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||||
$(STAGEautofeedback_CONFIGURE_FLAGS)
|
$(STAGEautofeedback_CONFIGURE_FLAGS) \
|
||||||
|
@gcc_host_pie@
|
||||||
@endif gcc-bootstrap
|
@endif gcc-bootstrap
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2023-06-22 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
* configure.ac (--enable-host-bind-now): New check.
|
||||||
|
* configure: Regenerate.
|
||||||
|
|
||||||
2023-06-15 Marek Polacek <polacek@redhat.com>
|
2023-06-15 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
* Makefile.in: Rename PIEFLAG to PICFLAG. Set LD_PICFLAG. Use it.
|
* Makefile.in: Rename PIEFLAG to PICFLAG. Set LD_PICFLAG. Use it.
|
||||||
|
|
|
||||||
|
|
@ -628,6 +628,7 @@ EGREP
|
||||||
GREP
|
GREP
|
||||||
CXXCPP
|
CXXCPP
|
||||||
LD_PICFLAG
|
LD_PICFLAG
|
||||||
|
enable_host_bind_now
|
||||||
PICFLAG
|
PICFLAG
|
||||||
MAINTAINER
|
MAINTAINER
|
||||||
CXX_AUX_TOOLS
|
CXX_AUX_TOOLS
|
||||||
|
|
@ -702,6 +703,7 @@ enable_maintainer_mode
|
||||||
enable_checking
|
enable_checking
|
||||||
enable_default_pie
|
enable_default_pie
|
||||||
enable_host_pie
|
enable_host_pie
|
||||||
|
enable_host_bind_now
|
||||||
with_gcc_major_version_only
|
with_gcc_major_version_only
|
||||||
'
|
'
|
||||||
ac_precious_vars='build_alias
|
ac_precious_vars='build_alias
|
||||||
|
|
@ -1336,6 +1338,7 @@ Optional Features:
|
||||||
yes,no,all,none,release.
|
yes,no,all,none,release.
|
||||||
--enable-default-pie enable Position Independent Executable as default
|
--enable-default-pie enable Position Independent Executable as default
|
||||||
--enable-host-pie build host code as PIE
|
--enable-host-pie build host code as PIE
|
||||||
|
--enable-host-bind-now link host code as BIND_NOW
|
||||||
|
|
||||||
Optional Packages:
|
Optional Packages:
|
||||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||||
|
|
@ -3007,6 +3010,14 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Enable --enable-host-bind-now
|
||||||
|
# Check whether --enable-host-bind-now was given.
|
||||||
|
if test "${enable_host_bind_now+set}" = set; then :
|
||||||
|
enableval=$enable_host_bind_now; LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check if O_CLOEXEC is defined by fcntl
|
# Check if O_CLOEXEC is defined by fcntl
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,13 @@ AC_ARG_ENABLE(host-pie,
|
||||||
[build host code as PIE])],
|
[build host code as PIE])],
|
||||||
[PICFLAG=-fPIE; LD_PICFLAG=-pie], [])
|
[PICFLAG=-fPIE; LD_PICFLAG=-pie], [])
|
||||||
AC_SUBST(PICFLAG)
|
AC_SUBST(PICFLAG)
|
||||||
|
|
||||||
|
# Enable --enable-host-bind-now
|
||||||
|
AC_ARG_ENABLE(host-bind-now,
|
||||||
|
[AS_HELP_STRING([--enable-host-bind-now],
|
||||||
|
[link host code as BIND_NOW])],
|
||||||
|
[LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"], [])
|
||||||
|
AC_SUBST(enable_host_bind_now)
|
||||||
AC_SUBST(LD_PICFLAG)
|
AC_SUBST(LD_PICFLAG)
|
||||||
|
|
||||||
# Check if O_CLOEXEC is defined by fcntl
|
# Check if O_CLOEXEC is defined by fcntl
|
||||||
|
|
|
||||||
|
|
@ -689,6 +689,7 @@ stage1_languages
|
||||||
host_libs_picflag
|
host_libs_picflag
|
||||||
PICFLAG
|
PICFLAG
|
||||||
host_shared
|
host_shared
|
||||||
|
gcc_host_pie
|
||||||
host_pie
|
host_pie
|
||||||
extra_linker_plugin_flags
|
extra_linker_plugin_flags
|
||||||
extra_linker_plugin_configure_flags
|
extra_linker_plugin_configure_flags
|
||||||
|
|
@ -8649,23 +8650,31 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Enable --enable-host-pie.
|
# Handle --enable-host-pie
|
||||||
# Checked early to determine whether jit is an 'all' language
|
# If host PIE executables are the default (or must be forced on) for some host,
|
||||||
|
# we must pass that configuration to the gcc directory.
|
||||||
|
gcc_host_pie=
|
||||||
# Check whether --enable-host-pie was given.
|
# Check whether --enable-host-pie was given.
|
||||||
if test "${enable_host_pie+set}" = set; then :
|
if test "${enable_host_pie+set}" = set; then :
|
||||||
enableval=$enable_host_pie; host_pie=$enableval
|
enableval=$enable_host_pie; host_pie=$enableval
|
||||||
case $host in
|
case $host in
|
||||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
*-*-darwin2*)
|
||||||
if test x$host_pie != xyes ; then
|
if test x$host_pie != xyes ; then
|
||||||
# PIC is the default, and actually cannot be switched off.
|
# for Darwin20+ this is required.
|
||||||
echo configure.ac: warning: PIC code is required for the configured target, host-shared setting ignored. 1>&2
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PIE executables are required for the configured host, host-pie setting ignored." >&5
|
||||||
|
$as_echo "$as_me: WARNING: PIE executables are required for the configured host, host-pie setting ignored." >&2;}
|
||||||
host_pie=yes
|
host_pie=yes
|
||||||
|
gcc_host_pie=--enable-host-pie
|
||||||
fi ;;
|
fi ;;
|
||||||
*) ;;
|
*) ;;
|
||||||
esac
|
esac
|
||||||
else
|
else
|
||||||
case $host in
|
case $host in
|
||||||
*-*-darwin2*) host_pie=yes ;;
|
*-*-darwin2*)
|
||||||
|
# Default to PIE (mandatory for aarch64).
|
||||||
|
host_pie=yes
|
||||||
|
gcc_host_pie=--enable-host-pie
|
||||||
|
;;
|
||||||
*) host_pie=no ;;
|
*) host_pie=no ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
@ -8673,6 +8682,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Enable --enable-host-shared.
|
# Enable --enable-host-shared.
|
||||||
# Checked early to determine whether jit is an 'all' language
|
# Checked early to determine whether jit is an 'all' language
|
||||||
# Check whether --enable-host-shared was given.
|
# Check whether --enable-host-shared was given.
|
||||||
|
|
@ -8682,21 +8692,24 @@ if test "${enable_host_shared+set}" = set; then :
|
||||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
x86_64-*-darwin* | aarch64-*-darwin*)
|
||||||
if test x$host_shared != xyes ; then
|
if test x$host_shared != xyes ; then
|
||||||
# PIC is the default, and actually cannot be switched off.
|
# PIC is the default, and actually cannot be switched off.
|
||||||
echo configure.ac: warning: PIC code is required for the configured target, host-shared setting ignored. 1>&2
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PIC code is required for the configured host; host-shared setting ignored." >&5
|
||||||
|
$as_echo "$as_me: WARNING: PIC code is required for the configured host; host-shared setting ignored." >&2;}
|
||||||
host_shared=yes
|
host_shared=yes
|
||||||
fi ;;
|
fi ;;
|
||||||
*-*-darwin*)
|
*-*-darwin*)
|
||||||
if test x$host_pie == xyes ; then
|
if test x$host_pie = xyes -a x$host_shared != xyes ; then
|
||||||
echo configure.ac: warning: PIC code is required for PIE executables. 1>&2
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PIC code is required for PIE host executables host-shared setting ignored." >&5
|
||||||
|
$as_echo "$as_me: WARNING: PIC code is required for PIE host executables host-shared setting ignored." >&2;}
|
||||||
host_shared=yes
|
host_shared=yes
|
||||||
fi ;;
|
fi ;;
|
||||||
*) ;;
|
*) ;;
|
||||||
esac
|
esac
|
||||||
else
|
else
|
||||||
case $host in
|
case $host in
|
||||||
|
# 64B x86_64 and Aarch64 Darwin default to PIC.
|
||||||
x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;;
|
x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;;
|
||||||
# Darwin needs PIC objects to link PIE executables.
|
# 32B and powerpc64 Darwin must use PIC to link PIE exes.
|
||||||
*-*-darwin*) host_shared=host_pie ;;
|
*-*-darwin*) host_shared=$host_pie ;;
|
||||||
*) host_shared=no;;
|
*) host_shared=no;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
@ -8705,7 +8718,18 @@ fi
|
||||||
|
|
||||||
|
|
||||||
if test x$host_shared = xyes; then
|
if test x$host_shared = xyes; then
|
||||||
PICFLAG=-fPIC
|
case $host in
|
||||||
|
*-*-darwin*)
|
||||||
|
# Since host shared is the default for 64b Darwin, and also enabled for
|
||||||
|
# host_pie, ensure that we present the PIE flag when host_pie is active.
|
||||||
|
if test x$host_pie = xyes; then
|
||||||
|
PICFLAG=-fPIE
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
PICFLAG=-fPIC
|
||||||
|
;;
|
||||||
|
esac
|
||||||
elif test x$host_pie = xyes; then
|
elif test x$host_pie = xyes; then
|
||||||
PICFLAG=-fPIE
|
PICFLAG=-fPIE
|
||||||
else
|
else
|
||||||
|
|
|
||||||
44
configure.ac
44
configure.ac
|
|
@ -1891,27 +1891,35 @@ AC_ARG_ENABLE(linker-plugin-flags,
|
||||||
extra_linker_plugin_flags=)
|
extra_linker_plugin_flags=)
|
||||||
AC_SUBST(extra_linker_plugin_flags)
|
AC_SUBST(extra_linker_plugin_flags)
|
||||||
|
|
||||||
# Enable --enable-host-pie.
|
# Handle --enable-host-pie
|
||||||
# Checked early to determine whether jit is an 'all' language
|
# If host PIE executables are the default (or must be forced on) for some host,
|
||||||
|
# we must pass that configuration to the gcc directory.
|
||||||
|
gcc_host_pie=
|
||||||
AC_ARG_ENABLE(host-pie,
|
AC_ARG_ENABLE(host-pie,
|
||||||
[AS_HELP_STRING([--enable-host-pie],
|
[AS_HELP_STRING([--enable-host-pie],
|
||||||
[build position independent host executables])],
|
[build position independent host executables])],
|
||||||
[host_pie=$enableval
|
[host_pie=$enableval
|
||||||
case $host in
|
case $host in
|
||||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
*-*-darwin2*)
|
||||||
if test x$host_pie != xyes ; then
|
if test x$host_pie != xyes ; then
|
||||||
# PIC is the default, and actually cannot be switched off.
|
# for Darwin20+ this is required.
|
||||||
echo configure.ac: warning: PIC code is required for the configured target, host-shared setting ignored. 1>&2
|
AC_MSG_WARN([PIE executables are required for the configured host, host-pie setting ignored.])
|
||||||
host_pie=yes
|
host_pie=yes
|
||||||
|
gcc_host_pie=--enable-host-pie
|
||||||
fi ;;
|
fi ;;
|
||||||
*) ;;
|
*) ;;
|
||||||
esac],
|
esac],
|
||||||
[case $host in
|
[case $host in
|
||||||
*-*-darwin2*) host_pie=yes ;;
|
*-*-darwin2*)
|
||||||
|
# Default to PIE (mandatory for aarch64).
|
||||||
|
host_pie=yes
|
||||||
|
gcc_host_pie=--enable-host-pie
|
||||||
|
;;
|
||||||
*) host_pie=no ;;
|
*) host_pie=no ;;
|
||||||
esac])
|
esac])
|
||||||
|
|
||||||
AC_SUBST(host_pie)
|
AC_SUBST(host_pie)
|
||||||
|
AC_SUBST(gcc_host_pie)
|
||||||
|
|
||||||
# Enable --enable-host-shared.
|
# Enable --enable-host-shared.
|
||||||
# Checked early to determine whether jit is an 'all' language
|
# Checked early to determine whether jit is an 'all' language
|
||||||
|
|
@ -1923,27 +1931,39 @@ AC_ARG_ENABLE(host-shared,
|
||||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
x86_64-*-darwin* | aarch64-*-darwin*)
|
||||||
if test x$host_shared != xyes ; then
|
if test x$host_shared != xyes ; then
|
||||||
# PIC is the default, and actually cannot be switched off.
|
# PIC is the default, and actually cannot be switched off.
|
||||||
echo configure.ac: warning: PIC code is required for the configured target, host-shared setting ignored. 1>&2
|
AC_MSG_WARN([PIC code is required for the configured host; host-shared setting ignored.])
|
||||||
host_shared=yes
|
host_shared=yes
|
||||||
fi ;;
|
fi ;;
|
||||||
*-*-darwin*)
|
*-*-darwin*)
|
||||||
if test x$host_pie == xyes ; then
|
if test x$host_pie = xyes -a x$host_shared != xyes ; then
|
||||||
echo configure.ac: warning: PIC code is required for PIE executables. 1>&2
|
AC_MSG_WARN([PIC code is required for PIE host executables host-shared setting ignored.])
|
||||||
host_shared=yes
|
host_shared=yes
|
||||||
fi ;;
|
fi ;;
|
||||||
*) ;;
|
*) ;;
|
||||||
esac],
|
esac],
|
||||||
[case $host in
|
[case $host in
|
||||||
|
# 64B x86_64 and Aarch64 Darwin default to PIC.
|
||||||
x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;;
|
x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;;
|
||||||
# Darwin needs PIC objects to link PIE executables.
|
# 32B and powerpc64 Darwin must use PIC to link PIE exes.
|
||||||
*-*-darwin*) host_shared=host_pie ;;
|
*-*-darwin*) host_shared=$host_pie ;;
|
||||||
*) host_shared=no;;
|
*) host_shared=no;;
|
||||||
esac])
|
esac])
|
||||||
|
|
||||||
AC_SUBST(host_shared)
|
AC_SUBST(host_shared)
|
||||||
|
|
||||||
if test x$host_shared = xyes; then
|
if test x$host_shared = xyes; then
|
||||||
PICFLAG=-fPIC
|
case $host in
|
||||||
|
*-*-darwin*)
|
||||||
|
# Since host shared is the default for 64b Darwin, and also enabled for
|
||||||
|
# host_pie, ensure that we present the PIE flag when host_pie is active.
|
||||||
|
if test x$host_pie = xyes; then
|
||||||
|
PICFLAG=-fPIE
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
PICFLAG=-fPIC
|
||||||
|
;;
|
||||||
|
esac
|
||||||
elif test x$host_pie = xyes; then
|
elif test x$host_pie = xyes; then
|
||||||
PICFLAG=-fPIE
|
PICFLAG=-fPIE
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2023-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* unicode/gen-box-drawing-chars.py: New file.
|
||||||
|
* unicode/gen-combining-chars.py: New file.
|
||||||
|
* unicode/gen-printable-chars.py: New file.
|
||||||
|
|
||||||
2023-06-17 Thiago Jung Bauermann <thiago.bauermann@linaro.org>
|
2023-06-17 Thiago Jung Bauermann <thiago.bauermann@linaro.org>
|
||||||
|
|
||||||
* testsuite-management/validate_failures.py (IsInterestingResult):
|
* testsuite-management/validate_failures.py (IsInterestingResult):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Script to generate gcc/text-art/box-drawing-chars.inc
|
||||||
|
#
|
||||||
|
# This file is part of GCC.
|
||||||
|
#
|
||||||
|
# GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 3, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with GCC; see the file COPYING3. If not see
|
||||||
|
# <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
|
def get_box_drawing_char_name(up: bool,
|
||||||
|
down: bool,
|
||||||
|
left: bool,
|
||||||
|
right: bool) -> str:
|
||||||
|
if 0:
|
||||||
|
print(f'{locals()=}')
|
||||||
|
if up and down:
|
||||||
|
vertical = True
|
||||||
|
up = False
|
||||||
|
down = False
|
||||||
|
else:
|
||||||
|
vertical = False
|
||||||
|
|
||||||
|
if left and right:
|
||||||
|
horizontal = True
|
||||||
|
left = False
|
||||||
|
right = False
|
||||||
|
else:
|
||||||
|
horizontal = False
|
||||||
|
|
||||||
|
weights = []
|
||||||
|
heavy = []
|
||||||
|
light = []
|
||||||
|
dirs = []
|
||||||
|
for dir_name in ('up', 'down', 'vertical', 'left', 'right', 'horizontal'):
|
||||||
|
val = locals()[dir_name]
|
||||||
|
if val:
|
||||||
|
dirs.append(dir_name.upper())
|
||||||
|
|
||||||
|
if not dirs:
|
||||||
|
return 'SPACE'
|
||||||
|
|
||||||
|
name = 'BOX DRAWINGS'
|
||||||
|
#print(f'{light=} {heavy=}')
|
||||||
|
|
||||||
|
if 0:
|
||||||
|
print(dirs)
|
||||||
|
|
||||||
|
def weights_frag(weight: str, dirs: list, prefix: bool):
|
||||||
|
"""
|
||||||
|
Generate a fragment where all directions share the same weight, e.g.:
|
||||||
|
'HEAVY HORIZONTAL'
|
||||||
|
'DOWN LIGHT'
|
||||||
|
'LEFT DOWN HEAVY'
|
||||||
|
'HEAVY DOWN AND RIGHT'
|
||||||
|
"""
|
||||||
|
assert len(dirs) >= 1
|
||||||
|
assert len(dirs) <= 2
|
||||||
|
if prefix:
|
||||||
|
return f' {weight} ' + (' AND '.join(dirs))
|
||||||
|
else:
|
||||||
|
return ' ' + (' '.join(dirs)) + f' {weight}'
|
||||||
|
|
||||||
|
assert(len(dirs) >= 1 and len(dirs) <= 2)
|
||||||
|
name += weights_frag('LIGHT', dirs, True)
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
print('/* Generated by contrib/unicode/gen-box-drawing-chars.py. */')
|
||||||
|
print()
|
||||||
|
for i in range(16):
|
||||||
|
up = (i & 8)
|
||||||
|
down = (i & 4)
|
||||||
|
left = (i & 2)
|
||||||
|
right = (i & 1)
|
||||||
|
name = get_box_drawing_char_name(up, down, left, right)
|
||||||
|
if i < 15:
|
||||||
|
trailing_comma = ','
|
||||||
|
else:
|
||||||
|
trailing_comma = ' '
|
||||||
|
unichar = unicodedata.lookup(name)
|
||||||
|
print(f'0x{ord(unichar):04X}{trailing_comma} /* "{unichar}": U+{ord(unichar):04X}: {name} */')
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Script to generate libcpp/combining-chars.inc
|
||||||
|
#
|
||||||
|
# This file is part of GCC.
|
||||||
|
#
|
||||||
|
# GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 3, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with GCC; see the file COPYING3. If not see
|
||||||
|
# <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
|
def is_combining_char(code_point) -> bool:
|
||||||
|
return unicodedata.combining(chr(code_point)) != 0
|
||||||
|
|
||||||
|
class Range:
|
||||||
|
def __init__(self, start, end, value):
|
||||||
|
self.start = start
|
||||||
|
self.end = end
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'Range({self.start:x}, {self.end:x}, {self.value})'
|
||||||
|
|
||||||
|
def make_ranges(value_callback):
|
||||||
|
ranges = []
|
||||||
|
for code_point in range(0x10FFFF):
|
||||||
|
value = is_combining_char(code_point)
|
||||||
|
if 0:
|
||||||
|
print(f'{code_point=:x} {value=}')
|
||||||
|
if ranges and ranges[-1].value == value:
|
||||||
|
# Extend current range
|
||||||
|
ranges[-1].end = code_point
|
||||||
|
else:
|
||||||
|
# Start a new range
|
||||||
|
ranges.append(Range(code_point, code_point, value))
|
||||||
|
return ranges
|
||||||
|
|
||||||
|
ranges = make_ranges(is_combining_char)
|
||||||
|
if 0:
|
||||||
|
pprint(ranges)
|
||||||
|
|
||||||
|
print(f"/* Generated by contrib/unicode/gen-combining-chars.py")
|
||||||
|
print(f" using version {unicodedata.unidata_version}"
|
||||||
|
" of the Unicode standard. */")
|
||||||
|
print("\nstatic const cppchar_t combining_range_ends[] = {", end="")
|
||||||
|
for i, r in enumerate(ranges):
|
||||||
|
if i % 8:
|
||||||
|
print(" ", end="")
|
||||||
|
else:
|
||||||
|
print("\n ", end="")
|
||||||
|
print("0x%x," % r.end, end="")
|
||||||
|
print("\n};\n")
|
||||||
|
print("static const bool is_combining[] = {", end="")
|
||||||
|
for i, r in enumerate(ranges):
|
||||||
|
if i % 24:
|
||||||
|
print(" ", end="")
|
||||||
|
else:
|
||||||
|
print("\n ", end="")
|
||||||
|
if r.value:
|
||||||
|
print("1,", end="")
|
||||||
|
else:
|
||||||
|
print("0,", end="")
|
||||||
|
print("\n};")
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Script to generate libcpp/printable-chars.inc
|
||||||
|
#
|
||||||
|
# This file is part of GCC.
|
||||||
|
#
|
||||||
|
# GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 3, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with GCC; see the file COPYING3. If not see
|
||||||
|
# <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
|
def is_printable_char(code_point) -> bool:
|
||||||
|
category = unicodedata.category(chr(code_point))
|
||||||
|
# "Cc" is "control" and "Cf" is "format"
|
||||||
|
return category[0] != 'C'
|
||||||
|
|
||||||
|
class Range:
|
||||||
|
def __init__(self, start, end, value):
|
||||||
|
self.start = start
|
||||||
|
self.end = end
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'Range({self.start:x}, {self.end:x}, {self.value})'
|
||||||
|
|
||||||
|
def make_ranges(value_callback):
|
||||||
|
ranges = []
|
||||||
|
for code_point in range(0x10FFFF):
|
||||||
|
value = is_printable_char(code_point)
|
||||||
|
if 0:
|
||||||
|
print(f'{code_point=:x} {value=}')
|
||||||
|
if ranges and ranges[-1].value == value:
|
||||||
|
# Extend current range
|
||||||
|
ranges[-1].end = code_point
|
||||||
|
else:
|
||||||
|
# Start a new range
|
||||||
|
ranges.append(Range(code_point, code_point, value))
|
||||||
|
return ranges
|
||||||
|
|
||||||
|
ranges = make_ranges(is_printable_char)
|
||||||
|
if 0:
|
||||||
|
pprint(ranges)
|
||||||
|
|
||||||
|
print(f"/* Generated by contrib/unicode/gen-printable-chars.py")
|
||||||
|
print(f" using version {unicodedata.unidata_version}"
|
||||||
|
" of the Unicode standard. */")
|
||||||
|
print("\nstatic const cppchar_t printable_range_ends[] = {", end="")
|
||||||
|
for i, r in enumerate(ranges):
|
||||||
|
if i % 8:
|
||||||
|
print(" ", end="")
|
||||||
|
else:
|
||||||
|
print("\n ", end="")
|
||||||
|
print("0x%x," % r.end, end="")
|
||||||
|
print("\n};\n")
|
||||||
|
print("static const bool is_printable[] = {", end="")
|
||||||
|
for i, r in enumerate(ranges):
|
||||||
|
if i % 24:
|
||||||
|
print(" ", end="")
|
||||||
|
else:
|
||||||
|
print("\n ", end="")
|
||||||
|
if r.value:
|
||||||
|
print("1,", end="")
|
||||||
|
else:
|
||||||
|
print("0,", end="")
|
||||||
|
print("\n};")
|
||||||
643
gcc/ChangeLog
643
gcc/ChangeLog
|
|
@ -1,3 +1,646 @@
|
||||||
|
2023-06-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* config/riscv/riscv-vsetvl.cc (vector_insn_info::parse_insn): Ehance
|
||||||
|
AVL propagation.
|
||||||
|
* config/riscv/riscv-vsetvl.h: New function.
|
||||||
|
|
||||||
|
2023-06-25 Li Xu <xuli1@eswincomputing.com>
|
||||||
|
|
||||||
|
* config/riscv/riscv-vector-builtins-bases.cc: change emit_insn to
|
||||||
|
emit_move_insn
|
||||||
|
|
||||||
|
2023-06-25 Juzhe-Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* config/riscv/autovec.md (len_load_<mode>): Remove.
|
||||||
|
(len_maskload<mode><vm>): Remove.
|
||||||
|
(len_store_<mode>): New pattern.
|
||||||
|
(len_maskstore<mode><vm>): New pattern.
|
||||||
|
* config/riscv/predicates.md (autovec_length_operand): New predicate.
|
||||||
|
* config/riscv/riscv-protos.h (enum insn_type): New enum.
|
||||||
|
(expand_load_store): New function.
|
||||||
|
* config/riscv/riscv-v.cc (emit_vlmax_masked_insn): Ditto.
|
||||||
|
(emit_nonvlmax_masked_insn): Ditto.
|
||||||
|
(expand_load_store): Ditto.
|
||||||
|
* config/riscv/riscv-vector-builtins.cc
|
||||||
|
(function_expander::use_contiguous_store_insn): Add avl_type operand
|
||||||
|
into pred_store.
|
||||||
|
* config/riscv/vector.md: Ditto.
|
||||||
|
|
||||||
|
2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* internal-fn.cc (expand_partial_store_optab_fn): Fix bug of BIAS
|
||||||
|
argument index.
|
||||||
|
|
||||||
|
2023-06-25 Pan Li <pan2.li@intel.com>
|
||||||
|
|
||||||
|
* config/riscv/vector.md: Revert.
|
||||||
|
|
||||||
|
2023-06-25 Pan Li <pan2.li@intel.com>
|
||||||
|
|
||||||
|
* config/riscv/genrvv-type-indexer.cc (valid_type): Revert changes.
|
||||||
|
* config/riscv/riscv-modes.def (RVV_TUPLE_MODES): Ditto.
|
||||||
|
(ADJUST_ALIGNMENT): Ditto.
|
||||||
|
(RVV_TUPLE_PARTIAL_MODES): Ditto.
|
||||||
|
(ADJUST_NUNITS): Ditto.
|
||||||
|
* config/riscv/riscv-vector-builtins-types.def (vfloat16mf4x2_t): Ditto.
|
||||||
|
(vfloat16mf4x3_t): Ditto.
|
||||||
|
(vfloat16mf4x4_t): Ditto.
|
||||||
|
(vfloat16mf4x5_t): Ditto.
|
||||||
|
(vfloat16mf4x6_t): Ditto.
|
||||||
|
(vfloat16mf4x7_t): Ditto.
|
||||||
|
(vfloat16mf4x8_t): Ditto.
|
||||||
|
(vfloat16mf2x2_t): Ditto.
|
||||||
|
(vfloat16mf2x3_t): Ditto.
|
||||||
|
(vfloat16mf2x4_t): Ditto.
|
||||||
|
(vfloat16mf2x5_t): Ditto.
|
||||||
|
(vfloat16mf2x6_t): Ditto.
|
||||||
|
(vfloat16mf2x7_t): Ditto.
|
||||||
|
(vfloat16mf2x8_t): Ditto.
|
||||||
|
(vfloat16m1x2_t): Ditto.
|
||||||
|
(vfloat16m1x3_t): Ditto.
|
||||||
|
(vfloat16m1x4_t): Ditto.
|
||||||
|
(vfloat16m1x5_t): Ditto.
|
||||||
|
(vfloat16m1x6_t): Ditto.
|
||||||
|
(vfloat16m1x7_t): Ditto.
|
||||||
|
(vfloat16m1x8_t): Ditto.
|
||||||
|
(vfloat16m2x2_t): Ditto.
|
||||||
|
(vfloat16m2x3_t): Diito.
|
||||||
|
(vfloat16m2x4_t): Diito.
|
||||||
|
(vfloat16m4x2_t): Diito.
|
||||||
|
* config/riscv/riscv-vector-builtins.def (vfloat16mf4x2_t): Ditto.
|
||||||
|
(vfloat16mf4x3_t): Ditto.
|
||||||
|
(vfloat16mf4x4_t): Ditto.
|
||||||
|
(vfloat16mf4x5_t): Ditto.
|
||||||
|
(vfloat16mf4x6_t): Ditto.
|
||||||
|
(vfloat16mf4x7_t): Ditto.
|
||||||
|
(vfloat16mf4x8_t): Ditto.
|
||||||
|
(vfloat16mf2x2_t): Ditto.
|
||||||
|
(vfloat16mf2x3_t): Ditto.
|
||||||
|
(vfloat16mf2x4_t): Ditto.
|
||||||
|
(vfloat16mf2x5_t): Ditto.
|
||||||
|
(vfloat16mf2x6_t): Ditto.
|
||||||
|
(vfloat16mf2x7_t): Ditto.
|
||||||
|
(vfloat16mf2x8_t): Ditto.
|
||||||
|
(vfloat16m1x2_t): Ditto.
|
||||||
|
(vfloat16m1x3_t): Ditto.
|
||||||
|
(vfloat16m1x4_t): Ditto.
|
||||||
|
(vfloat16m1x5_t): Ditto.
|
||||||
|
(vfloat16m1x6_t): Ditto.
|
||||||
|
(vfloat16m1x7_t): Ditto.
|
||||||
|
(vfloat16m1x8_t): Ditto.
|
||||||
|
(vfloat16m2x2_t): Ditto.
|
||||||
|
(vfloat16m2x3_t): Ditto.
|
||||||
|
(vfloat16m2x4_t): Ditto.
|
||||||
|
(vfloat16m4x2_t): Ditto.
|
||||||
|
* config/riscv/riscv-vector-switch.def (TUPLE_ENTRY): Ditto.
|
||||||
|
* config/riscv/riscv.md: Ditto.
|
||||||
|
* config/riscv/vector-iterators.md: Ditto.
|
||||||
|
|
||||||
|
2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* gimple-fold.cc (arith_overflowed_p): Apply LEN_MASK_{LOAD,STORE}.
|
||||||
|
(gimple_fold_partial_load_store_mem_ref): Ditto.
|
||||||
|
(gimple_fold_partial_store): Ditto.
|
||||||
|
(gimple_fold_call): Ditto.
|
||||||
|
|
||||||
|
2023-06-25 liuhongt <hongtao.liu@intel.com>
|
||||||
|
|
||||||
|
PR target/110309
|
||||||
|
* config/i386/sse.md (maskload<mode><avx512fmaskmodelower>):
|
||||||
|
Refine pattern with UNSPEC_MASKLOAD.
|
||||||
|
(maskload<mode><avx512fmaskmodelower>): Ditto.
|
||||||
|
(*<avx512>_load<mode>_mask): Extend mode iterator to
|
||||||
|
VI12HFBF_AVX512VL.
|
||||||
|
(*<avx512>_load<mode>): Ditto.
|
||||||
|
|
||||||
|
2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* tree-ssa-alias.cc (call_may_clobber_ref_p_1): Add LEN_MASK_STORE.
|
||||||
|
|
||||||
|
2023-06-25 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* tree-ssa-alias.cc (ref_maybe_used_by_call_p_1): Apply
|
||||||
|
LEN_MASK_{LOAD,STORE}
|
||||||
|
|
||||||
|
2023-06-25 yulong <shiyulong@iscas.ac.cn>
|
||||||
|
|
||||||
|
* config/riscv/vector.md: Add float16 attr at sew、vlmul and ratio.
|
||||||
|
|
||||||
|
2023-06-24 Roger Sayle <roger@nextmovesoftware.com>
|
||||||
|
|
||||||
|
* config/i386/i386.md (*<code>qi_ext<mode>_3): New define_insn.
|
||||||
|
|
||||||
|
2023-06-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* config/riscv/autovec.md (*fma<mode>): set clobber to Pmode in expand stage.
|
||||||
|
(*fma<VI:mode><P:mode>): Ditto.
|
||||||
|
(*fnma<mode>): Ditto.
|
||||||
|
(*fnma<VI:mode><P:mode>): Ditto.
|
||||||
|
|
||||||
|
2023-06-24 Juzhe-Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* config/riscv/autovec.md (fma<mode>4): New pattern.
|
||||||
|
(*fma<mode>): Ditto.
|
||||||
|
(fnma<mode>4): Ditto.
|
||||||
|
(*fnma<mode>): Ditto.
|
||||||
|
(fms<mode>4): Ditto.
|
||||||
|
(*fms<mode>): Ditto.
|
||||||
|
(fnms<mode>4): Ditto.
|
||||||
|
(*fnms<mode>): Ditto.
|
||||||
|
* config/riscv/riscv-protos.h (emit_vlmax_fp_ternary_insn):
|
||||||
|
New function.
|
||||||
|
* config/riscv/riscv-v.cc (emit_vlmax_fp_ternary_insn): Ditto.
|
||||||
|
* config/riscv/vector.md: Fix attribute bug.
|
||||||
|
|
||||||
|
2023-06-24 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* tree-ssa-loop-ivopts.cc (get_mem_type_for_internal_fn):
|
||||||
|
Apply LEN_MASK_{LOAD,STORE}.
|
||||||
|
|
||||||
|
2023-06-24 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* tree-ssa-loop-ivopts.cc (get_alias_ptr_type_for_ptr_address):
|
||||||
|
Add LEN_MASK_{LOAD,STORE}.
|
||||||
|
|
||||||
|
2023-06-24 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* diagnostic-format-sarif.cc: Add #define INCLUDE_VECTOR.
|
||||||
|
* diagnostic.cc: Likewise.
|
||||||
|
* text-art/box-drawing.cc: Likewise.
|
||||||
|
* text-art/canvas.cc: Likewise.
|
||||||
|
* text-art/ruler.cc: Likewise.
|
||||||
|
* text-art/selftests.cc: Likewise.
|
||||||
|
* text-art/selftests.h (text_art::canvas): New forward decl.
|
||||||
|
* text-art/style.cc: Add #define INCLUDE_VECTOR.
|
||||||
|
* text-art/styled-string.cc: Likewise.
|
||||||
|
* text-art/table.cc: Likewise.
|
||||||
|
* text-art/table.h: Remove #include <vector>.
|
||||||
|
* text-art/theme.cc: Add #define INCLUDE_VECTOR.
|
||||||
|
* text-art/types.h: Check that INCLUDE_VECTOR is defined.
|
||||||
|
Remove #include of <vector> and <string>.
|
||||||
|
* text-art/widget.cc: Add #define INCLUDE_VECTOR.
|
||||||
|
* text-art/widget.h: Remove #include <vector>.
|
||||||
|
|
||||||
|
2023-06-24 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* internal-fn.cc (expand_partial_store_optab_fn): Adapt for LEN_MASK_STORE.
|
||||||
|
(internal_load_fn_p): Add LEN_MASK_LOAD.
|
||||||
|
(internal_store_fn_p): Add LEN_MASK_STORE.
|
||||||
|
(internal_fn_mask_index): Add LEN_MASK_{LOAD,STORE}.
|
||||||
|
(internal_fn_stored_value_index): Add LEN_MASK_STORE.
|
||||||
|
(internal_len_load_store_bias): Add LEN_MASK_{LOAD,STORE}.
|
||||||
|
* optabs-tree.cc (can_vec_mask_load_store_p): Adapt for LEN_MASK_{LOAD,STORE}.
|
||||||
|
(get_len_load_store_mode): Ditto.
|
||||||
|
* optabs-tree.h (can_vec_mask_load_store_p): Ditto.
|
||||||
|
(get_len_load_store_mode): Ditto.
|
||||||
|
* tree-vect-stmts.cc (check_load_store_for_partial_vectors): Ditto.
|
||||||
|
(get_all_ones_mask): New function.
|
||||||
|
(vectorizable_store): Apply LEN_MASK_{LOAD,STORE} into vectorizer.
|
||||||
|
(vectorizable_load): Ditto.
|
||||||
|
|
||||||
|
2023-06-23 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
* doc/cpp.texi (__cplusplus): Document value for -std=c++26 and
|
||||||
|
-std=gnu++26. Document that for C++23, its value is 202302L.
|
||||||
|
* doc/invoke.texi: Document -std=c++26 and -std=gnu++26.
|
||||||
|
* dwarf2out.cc (highest_c_language): Handle GNU C++26.
|
||||||
|
(gen_compile_unit_die): Likewise.
|
||||||
|
|
||||||
|
2023-06-23 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
* tree-ssa-phiprop.cc (propagate_with_phi): Compute post dominators on
|
||||||
|
demand.
|
||||||
|
(pass_phiprop::execute): Do not compute it here; return
|
||||||
|
update_ssa_only_virtuals if something changed.
|
||||||
|
(pass_data_phiprop): Remove TODO_update_ssa from todos.
|
||||||
|
|
||||||
|
2023-06-23 Michael Meissner <meissner@linux.ibm.com>
|
||||||
|
Aaron Sawdey <acsawdey@linux.ibm.com>
|
||||||
|
|
||||||
|
PR target/105325
|
||||||
|
* config/rs6000/genfusion.pl (gen_ld_cmpi_p10_one): Fix problems that
|
||||||
|
allowed prefixed lwa to be generated.
|
||||||
|
* config/rs6000/fusion.md: Regenerate.
|
||||||
|
* config/rs6000/predicates.md (ds_form_mem_operand): Delete.
|
||||||
|
* config/rs6000/rs6000.md (prefixed attribute): Add support for load
|
||||||
|
plus compare immediate fused insns.
|
||||||
|
(maybe_prefixed): Likewise.
|
||||||
|
|
||||||
|
2023-06-23 Roger Sayle <roger@nextmovesoftware.com>
|
||||||
|
|
||||||
|
* simplify-rtx.cc (simplify_subreg): Optimize lowpart SUBREGs
|
||||||
|
of ASHIFT to const0_rtx with sufficiently large shift count.
|
||||||
|
Optimize highpart SUBREGs of ASHIFT as the shift operand when
|
||||||
|
the shift count is the correct offset. Optimize SUBREGs of
|
||||||
|
multi-word logic operations if the SUBREGs of both operands
|
||||||
|
can be simplified.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* varasm.cc (initializer_constant_valid_p_1): Only
|
||||||
|
allow conversions between scalar floating point types.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-vect-stmts.cc (vectorizable_assignment):
|
||||||
|
Properly handle non-integral operands when analyzing
|
||||||
|
conversions.
|
||||||
|
|
||||||
|
2023-06-23 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||||
|
|
||||||
|
PR tree-optimization/110280
|
||||||
|
* match.pd (vec_perm_expr(v, v, mask) -> v): Explicitly build vector
|
||||||
|
using build_vector_from_val with the element of input operand, and
|
||||||
|
mask's type if operand and mask's types don't match.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* fold-const.cc (tree_simple_nonnegative_warnv_p): Guard
|
||||||
|
the truth_value_p case with !VECTOR_TYPE_P.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-vect-patterns.cc (vect_look_through_possible_promotion):
|
||||||
|
Exit early when the type isn't scalar integral.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* match.pd ((outertype)((innertype0)a+(innertype1)b)
|
||||||
|
-> ((newtype)a+(newtype)b)): Use element_precision
|
||||||
|
where appropriate.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* fold-const.cc (fold_binary_loc): Use element_precision
|
||||||
|
when trying (double)float1 CMP (double)float2 to
|
||||||
|
float1 CMP float2 simplification.
|
||||||
|
* match.pd: Likewise.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-vect-stmts.cc (vectorizable_load): Avoid useless
|
||||||
|
copies of VMAT_INVARIANT vectorized stmts, fix SLP support.
|
||||||
|
|
||||||
|
2023-06-23 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-vect-stmts.cc (vector_vector_composition_type):
|
||||||
|
Handle composition of a vector from a number of elements that
|
||||||
|
happens to match its number of lanes.
|
||||||
|
|
||||||
|
2023-06-22 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
* configure.ac (--enable-host-bind-now): New check. Add
|
||||||
|
-Wl,-z,now to LD_PICFLAG if --enable-host-bind-now.
|
||||||
|
* configure: Regenerate.
|
||||||
|
* doc/install.texi: Document --enable-host-bind-now.
|
||||||
|
|
||||||
|
2023-06-22 Di Zhao OS <dizhao@os.amperecomputing.com>
|
||||||
|
|
||||||
|
* config/aarch64/aarch64.cc: Change fma_reassoc_width for ampere1.
|
||||||
|
|
||||||
|
2023-06-22 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/110332
|
||||||
|
* tree-ssa-phiprop.cc (propagate_with_phi): Always
|
||||||
|
check aliasing with edge inserted loads.
|
||||||
|
|
||||||
|
2023-06-22 Roger Sayle <roger@nextmovesoftware.com>
|
||||||
|
Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
|
* config/i386/i386-expand.cc (ix86_expand_sse_ptest): Recognize
|
||||||
|
expansion of ptestc with equal operands as producing const1_rtx.
|
||||||
|
* config/i386/i386.cc (ix86_rtx_costs): Provide accurate cost
|
||||||
|
estimates of UNSPEC_PTEST, where the ptest performs the PAND
|
||||||
|
or PAND of its operands.
|
||||||
|
* config/i386/sse.md (define_split): Transform CCCmode UNSPEC_PTEST
|
||||||
|
of reg_equal_p operands into an x86_stc instruction.
|
||||||
|
(define_split): Split pandn/ptestz/set{n?}e into ptestc/set{n?}c.
|
||||||
|
(define_split): Similar to above for strict_low_part destinations.
|
||||||
|
(define_split): Split pandn/ptestz/j{n?}e into ptestc/j{n?}c.
|
||||||
|
|
||||||
|
2023-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
PR analyzer/106626
|
||||||
|
* Makefile.in (ANALYZER_OBJS): Add analyzer/access-diagram.o.
|
||||||
|
* doc/invoke.texi (Wanalyzer-out-of-bounds): Add description of
|
||||||
|
text art.
|
||||||
|
(fanalyzer-debug-text-art): New.
|
||||||
|
|
||||||
|
2023-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* Makefile.in (OBJS-libcommon): Add text-art/box-drawing.o,
|
||||||
|
text-art/canvas.o, text-art/ruler.o, text-art/selftests.o,
|
||||||
|
text-art/style.o, text-art/styled-string.o, text-art/table.o,
|
||||||
|
text-art/theme.o, and text-art/widget.o.
|
||||||
|
* color-macros.h (COLOR_FG_BRIGHT_BLACK): New.
|
||||||
|
(COLOR_FG_BRIGHT_RED): New.
|
||||||
|
(COLOR_FG_BRIGHT_GREEN): New.
|
||||||
|
(COLOR_FG_BRIGHT_YELLOW): New.
|
||||||
|
(COLOR_FG_BRIGHT_BLUE): New.
|
||||||
|
(COLOR_FG_BRIGHT_MAGENTA): New.
|
||||||
|
(COLOR_FG_BRIGHT_CYAN): New.
|
||||||
|
(COLOR_FG_BRIGHT_WHITE): New.
|
||||||
|
(COLOR_BG_BRIGHT_BLACK): New.
|
||||||
|
(COLOR_BG_BRIGHT_RED): New.
|
||||||
|
(COLOR_BG_BRIGHT_GREEN): New.
|
||||||
|
(COLOR_BG_BRIGHT_YELLOW): New.
|
||||||
|
(COLOR_BG_BRIGHT_BLUE): New.
|
||||||
|
(COLOR_BG_BRIGHT_MAGENTA): New.
|
||||||
|
(COLOR_BG_BRIGHT_CYAN): New.
|
||||||
|
(COLOR_BG_BRIGHT_WHITE): New.
|
||||||
|
* common.opt (fdiagnostics-text-art-charset=): New option.
|
||||||
|
(diagnostic-text-art.h): New SourceInclude.
|
||||||
|
(diagnostic_text_art_charset) New Enum and EnumValues.
|
||||||
|
* configure: Regenerate.
|
||||||
|
* configure.ac (gccdepdir): Add text-art to loop.
|
||||||
|
* diagnostic-diagram.h: New file.
|
||||||
|
* diagnostic-format-json.cc (json_emit_diagram): New.
|
||||||
|
(diagnostic_output_format_init_json): Wire it up to
|
||||||
|
context->m_diagrams.m_emission_cb.
|
||||||
|
* diagnostic-format-sarif.cc: Include "diagnostic-diagram.h" and
|
||||||
|
"text-art/canvas.h".
|
||||||
|
(sarif_result::on_nested_diagnostic): Move code to...
|
||||||
|
(sarif_result::add_related_location): ...this new function.
|
||||||
|
(sarif_result::on_diagram): New.
|
||||||
|
(sarif_builder::emit_diagram): New.
|
||||||
|
(sarif_builder::make_message_object_for_diagram): New.
|
||||||
|
(sarif_emit_diagram): New.
|
||||||
|
(diagnostic_output_format_init_sarif): Set
|
||||||
|
context->m_diagrams.m_emission_cb to sarif_emit_diagram.
|
||||||
|
* diagnostic-text-art.h: New file.
|
||||||
|
* diagnostic.cc: Include "diagnostic-text-art.h",
|
||||||
|
"diagnostic-diagram.h", and "text-art/theme.h".
|
||||||
|
(diagnostic_initialize): Initialize context->m_diagrams and
|
||||||
|
call diagnostics_text_art_charset_init.
|
||||||
|
(diagnostic_finish): Clean up context->m_diagrams.m_theme.
|
||||||
|
(diagnostic_emit_diagram): New.
|
||||||
|
(diagnostics_text_art_charset_init): New.
|
||||||
|
* diagnostic.h (text_art::theme): New forward decl.
|
||||||
|
(class diagnostic_diagram): Likewise.
|
||||||
|
(diagnostic_context::m_diagrams): New field.
|
||||||
|
(diagnostic_emit_diagram): New decl.
|
||||||
|
* doc/invoke.texi (Diagnostic Message Formatting Options): Add
|
||||||
|
-fdiagnostics-text-art-charset=.
|
||||||
|
(-fdiagnostics-plain-output): Add
|
||||||
|
-fdiagnostics-text-art-charset=none.
|
||||||
|
* gcc.cc: Include "diagnostic-text-art.h".
|
||||||
|
(driver_handle_option): Handle OPT_fdiagnostics_text_art_charset_.
|
||||||
|
* opts-common.cc (decode_cmdline_options_to_array): Add
|
||||||
|
"-fdiagnostics-text-art-charset=none" to expanded_args for
|
||||||
|
-fdiagnostics-plain-output.
|
||||||
|
* opts.cc: Include "diagnostic-text-art.h".
|
||||||
|
(common_handle_option): Handle OPT_fdiagnostics_text_art_charset_.
|
||||||
|
* pretty-print.cc (pp_unicode_character): New.
|
||||||
|
* pretty-print.h (pp_unicode_character): New decl.
|
||||||
|
* selftest-run-tests.cc: Include "text-art/selftests.h".
|
||||||
|
(selftest::run_tests): Call text_art_tests.
|
||||||
|
* text-art/box-drawing-chars.inc: New file, generated by
|
||||||
|
contrib/unicode/gen-box-drawing-chars.py.
|
||||||
|
* text-art/box-drawing.cc: New file.
|
||||||
|
* text-art/box-drawing.h: New file.
|
||||||
|
* text-art/canvas.cc: New file.
|
||||||
|
* text-art/canvas.h: New file.
|
||||||
|
* text-art/ruler.cc: New file.
|
||||||
|
* text-art/ruler.h: New file.
|
||||||
|
* text-art/selftests.cc: New file.
|
||||||
|
* text-art/selftests.h: New file.
|
||||||
|
* text-art/style.cc: New file.
|
||||||
|
* text-art/styled-string.cc: New file.
|
||||||
|
* text-art/table.cc: New file.
|
||||||
|
* text-art/table.h: New file.
|
||||||
|
* text-art/theme.cc: New file.
|
||||||
|
* text-art/theme.h: New file.
|
||||||
|
* text-art/types.h: New file.
|
||||||
|
* text-art/widget.cc: New file.
|
||||||
|
* text-art/widget.h: New file.
|
||||||
|
|
||||||
|
2023-06-21 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
|
* function.h (emit_initial_value_sets):
|
||||||
|
Change return type from int to void.
|
||||||
|
(aggregate_value_p): Change return type from int to bool.
|
||||||
|
(prologue_contains): Ditto.
|
||||||
|
(epilogue_contains): Ditto.
|
||||||
|
(prologue_epilogue_contains): Ditto.
|
||||||
|
* function.cc (temp_slot): Make "in_use" variable bool.
|
||||||
|
(make_slot_available): Update for changed "in_use" variable.
|
||||||
|
(assign_stack_temp_for_type): Ditto.
|
||||||
|
(emit_initial_value_sets): Change return type from int to void
|
||||||
|
and update function body accordingly.
|
||||||
|
(instantiate_virtual_regs): Ditto.
|
||||||
|
(rest_of_handle_thread_prologue_and_epilogue): Ditto.
|
||||||
|
(safe_insn_predicate): Change return type from int to bool.
|
||||||
|
(aggregate_value_p): Change return type from int to bool
|
||||||
|
and update function body accordingly.
|
||||||
|
(prologue_contains): Change return type from int to bool.
|
||||||
|
(prologue_epilogue_contains): Ditto.
|
||||||
|
|
||||||
|
2023-06-21 Alexander Monakov <amonakov@ispras.ru>
|
||||||
|
|
||||||
|
* common.opt (fp_contract_mode) [on]: Remove fallback.
|
||||||
|
* config/sh/sh.md (*fmasf4): Correct flag_fp_contract_mode test.
|
||||||
|
* doc/invoke.texi (-ffp-contract): Update.
|
||||||
|
* trans-mem.cc (diagnose_tm_1): Skip internal function calls.
|
||||||
|
|
||||||
|
2023-06-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
|
* config/aarch64/aarch64-sve.md (mask_gather_load<mode><v_int_container>):
|
||||||
|
Add alternatives to prefer to avoid same input and output Z register.
|
||||||
|
(mask_gather_load<mode><v_int_container>): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_<su>xtw_unpacked): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_sxtw): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_uxtw): Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_4HSI:mode><SVE_4BHI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_<ANY_EXTEND2:su>xtw_unpacked): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx4_WIDE:mode>
|
||||||
|
<VNx4_NARROW:mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_uxtw): Likewise.
|
||||||
|
* config/aarch64/aarch64-sve2.md (@aarch64_gather_ldnt<mode>): Likewise.
|
||||||
|
(@aarch64_gather_ldnt_<ANY_EXTEND:optab><SVE_FULL_SDI:mode>
|
||||||
|
<SVE_PARTIAL_I:mode>): Likewise.
|
||||||
|
|
||||||
|
2023-06-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
|
* config/aarch64/aarch64-sve.md (mask_gather_load<mode><v_int_container>):
|
||||||
|
Convert to compact alternatives syntax.
|
||||||
|
(mask_gather_load<mode><v_int_container>): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_<su>xtw_unpacked): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_sxtw): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_uxtw): Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_4HSI:mode><SVE_4BHI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_<ANY_EXTEND2:su>xtw_unpacked): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx4_WIDE:mode>
|
||||||
|
<VNx4_NARROW:mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_uxtw): Likewise.
|
||||||
|
* config/aarch64/aarch64-sve2.md (@aarch64_gather_ldnt<mode>): Likewise.
|
||||||
|
(@aarch64_gather_ldnt_<ANY_EXTEND:optab><SVE_FULL_SDI:mode>
|
||||||
|
<SVE_PARTIAL_I:mode>): Likewise.
|
||||||
|
|
||||||
|
2023-06-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
|
Revert:
|
||||||
|
2023-06-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
|
* config/aarch64/aarch64-sve.md (mask_gather_load<mode><v_int_container>):
|
||||||
|
Convert to compact alternatives syntax.
|
||||||
|
(mask_gather_load<mode><v_int_container>): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_<su>xtw_unpacked): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_sxtw): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_uxtw): Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_4HSI:mode><SVE_4BHI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_<ANY_EXTEND2:su>xtw_unpacked): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx4_WIDE:mode>
|
||||||
|
<VNx4_NARROW:mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_uxtw): Likewise.
|
||||||
|
* config/aarch64/aarch64-sve2.md (@aarch64_gather_ldnt<mode>): Likewise.
|
||||||
|
(@aarch64_gather_ldnt_<ANY_EXTEND:optab><SVE_FULL_SDI:mode>
|
||||||
|
<SVE_PARTIAL_I:mode>): Likewise.
|
||||||
|
|
||||||
|
2023-06-21 Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
|
||||||
|
|
||||||
|
* optabs-query.cc (can_vec_mask_load_store_p): Move to optabs-tree.cc.
|
||||||
|
(get_len_load_store_mode): Ditto.
|
||||||
|
* optabs-query.h (can_vec_mask_load_store_p): Move to optabs-tree.h.
|
||||||
|
(get_len_load_store_mode): Ditto.
|
||||||
|
* optabs-tree.cc (can_vec_mask_load_store_p): New function.
|
||||||
|
(get_len_load_store_mode): Ditto.
|
||||||
|
* optabs-tree.h (can_vec_mask_load_store_p): Ditto.
|
||||||
|
(get_len_load_store_mode): Ditto.
|
||||||
|
* tree-if-conv.cc: include optabs-tree instead of optabs-query
|
||||||
|
|
||||||
|
2023-06-21 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-ssa-loop-ivopts.cc (add_iv_candidate_for_use): Use
|
||||||
|
split_constant_offset for the POINTER_PLUS_EXPR case.
|
||||||
|
|
||||||
|
2023-06-21 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-ssa-loop-ivopts.cc (record_group_use): Use
|
||||||
|
split_constant_offset.
|
||||||
|
|
||||||
|
2023-06-21 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* tree-loop-distribution.cc (classify_builtin_st): Use
|
||||||
|
split_constant_offset.
|
||||||
|
* tree-ssa-loop-ivopts.h (strip_offset): Remove.
|
||||||
|
* tree-ssa-loop-ivopts.cc (strip_offset): Make static.
|
||||||
|
|
||||||
|
2023-06-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
|
* config/aarch64/aarch64-sve.md (mask_gather_load<mode><v_int_container>):
|
||||||
|
Convert to compact alternatives syntax.
|
||||||
|
(mask_gather_load<mode><v_int_container>): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_<su>xtw_unpacked): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_sxtw): Likewise.
|
||||||
|
(*mask_gather_load<mode><v_int_container>_uxtw): Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_4HSI:mode><SVE_4BHI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(@aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>):
|
||||||
|
Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_<ANY_EXTEND2:su>xtw_unpacked): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode>
|
||||||
|
<SVE_2BHSI:mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather<mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather<mode>_uxtw): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx4_WIDE:mode>
|
||||||
|
<VNx4_NARROW:mode>): Likewise.
|
||||||
|
(@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_sxtw): Likewise.
|
||||||
|
(*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode>
|
||||||
|
<VNx2_NARROW:mode>_uxtw): Likewise.
|
||||||
|
* config/aarch64/aarch64-sve2.md (@aarch64_gather_ldnt<mode>): Likewise.
|
||||||
|
(@aarch64_gather_ldnt_<ANY_EXTEND:optab><SVE_FULL_SDI:mode>
|
||||||
|
<SVE_PARTIAL_I:mode>): Likewise.
|
||||||
|
|
||||||
|
2023-06-21 Tamar Christina <tamar.christina@arm.com>
|
||||||
|
|
||||||
|
PR other/110329
|
||||||
|
* doc/md.texi: Replace backslashchar.
|
||||||
|
|
||||||
|
2023-06-21 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
* config/i386/i386.cc (ix86_vector_costs::finish_cost):
|
||||||
|
Overload. For masked main loops make sure the vectorization
|
||||||
|
factor isn't more than double the number of iterations.
|
||||||
|
|
||||||
|
2023-06-21 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
|
* config/i386/i386-expand.cc (ix86_expand_copysign): Request
|
||||||
|
value duplication by ix86_build_signbit_mask() when AVX512F and
|
||||||
|
not HFmode.
|
||||||
|
* config/i386/sse.md (*<avx512>_vternlog<mode>_all): Convert to
|
||||||
|
2-alternative form. Adjust "mode" attribute. Add "enabled"
|
||||||
|
attribute.
|
||||||
|
(*<avx512>_vpternlog<mode>_1): Also permit when TARGET_AVX512F
|
||||||
|
&& !TARGET_PREFER_AVX256.
|
||||||
|
(*<avx512>_vpternlog<mode>_2): Likewise.
|
||||||
|
(*<avx512>_vpternlog<mode>_3): Likewise.
|
||||||
|
|
||||||
|
2023-06-21 liuhongt <hongtao.liu@intel.com>
|
||||||
|
|
||||||
|
PR target/110018
|
||||||
|
* tree-vect-stmts.cc (vectorizable_conversion): Use
|
||||||
|
intermiediate integer type for float_expr/fix_trunc_expr when
|
||||||
|
direct optab is not existed.
|
||||||
|
|
||||||
2023-06-20 Tamar Christina <tamar.christina@arm.com>
|
2023-06-20 Tamar Christina <tamar.christina@arm.com>
|
||||||
|
|
||||||
PR bootstrap/110324
|
PR bootstrap/110324
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
20230621
|
20230626
|
||||||
|
|
|
||||||
|
|
@ -1281,6 +1281,7 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
|
||||||
|
|
||||||
# Analyzer object files
|
# Analyzer object files
|
||||||
ANALYZER_OBJS = \
|
ANALYZER_OBJS = \
|
||||||
|
analyzer/access-diagram.o \
|
||||||
analyzer/analysis-plan.o \
|
analyzer/analysis-plan.o \
|
||||||
analyzer/analyzer.o \
|
analyzer/analyzer.o \
|
||||||
analyzer/analyzer-language.o \
|
analyzer/analyzer-language.o \
|
||||||
|
|
@ -1788,7 +1789,16 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \
|
||||||
json.o \
|
json.o \
|
||||||
sbitmap.o \
|
sbitmap.o \
|
||||||
vec.o input.o hash-table.o ggc-none.o memory-block.o \
|
vec.o input.o hash-table.o ggc-none.o memory-block.o \
|
||||||
selftest.o selftest-diagnostic.o sort.o
|
selftest.o selftest-diagnostic.o sort.o \
|
||||||
|
text-art/box-drawing.o \
|
||||||
|
text-art/canvas.o \
|
||||||
|
text-art/ruler.o \
|
||||||
|
text-art/selftests.o \
|
||||||
|
text-art/style.o \
|
||||||
|
text-art/styled-string.o \
|
||||||
|
text-art/table.o \
|
||||||
|
text-art/theme.o \
|
||||||
|
text-art/widget.o
|
||||||
|
|
||||||
# Objects in libcommon-target.a, used by drivers and by the core
|
# Objects in libcommon-target.a, used by drivers and by the core
|
||||||
# compiler and containing target-dependent code.
|
# compiler and containing target-dependent code.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,151 @@
|
||||||
|
2023-06-24 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* access-diagram.cc: Add #define INCLUDE_VECTOR.
|
||||||
|
* bounds-checking.cc: Likewise.
|
||||||
|
|
||||||
|
2023-06-22 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
PR analyzer/106626
|
||||||
|
* access-diagram.cc: New file.
|
||||||
|
* access-diagram.h: New file.
|
||||||
|
* analyzer.h (class region_offset): Add default ctor.
|
||||||
|
(region_offset::make_byte_offset): New decl.
|
||||||
|
(region_offset::concrete_p): New.
|
||||||
|
(region_offset::get_concrete_byte_offset): New.
|
||||||
|
(region_offset::calc_symbolic_bit_offset): New decl.
|
||||||
|
(region_offset::calc_symbolic_byte_offset): New decl.
|
||||||
|
(region_offset::dump_to_pp): New decl.
|
||||||
|
(region_offset::dump): New decl.
|
||||||
|
(operator<, operator<=, operator>, operator>=): New decls for
|
||||||
|
region_offset.
|
||||||
|
* analyzer.opt
|
||||||
|
(-param=analyzer-text-art-string-ellipsis-threshold=): New.
|
||||||
|
(-param=analyzer-text-art-string-ellipsis-head-len=): New.
|
||||||
|
(-param=analyzer-text-art-string-ellipsis-tail-len=): New.
|
||||||
|
(-param=analyzer-text-art-ideal-canvas-width=): New.
|
||||||
|
(fanalyzer-debug-text-art): New.
|
||||||
|
* bounds-checking.cc: Include "intl.h", "diagnostic-diagram.h",
|
||||||
|
and "analyzer/access-diagram.h".
|
||||||
|
(class out_of_bounds::oob_region_creation_event_capacity): New.
|
||||||
|
(out_of_bounds::out_of_bounds): Add "model" and "sval_hint"
|
||||||
|
params.
|
||||||
|
(out_of_bounds::mark_interesting_stuff): Use the base region.
|
||||||
|
(out_of_bounds::add_region_creation_events): Use
|
||||||
|
oob_region_creation_event_capacity.
|
||||||
|
(out_of_bounds::get_dir): New pure vfunc.
|
||||||
|
(out_of_bounds::maybe_show_notes): New.
|
||||||
|
(out_of_bounds::maybe_show_diagram): New.
|
||||||
|
(out_of_bounds::make_access_diagram): New.
|
||||||
|
(out_of_bounds::m_model): New field.
|
||||||
|
(out_of_bounds::m_sval_hint): New field.
|
||||||
|
(out_of_bounds::m_region_creation_event_id): New field.
|
||||||
|
(concrete_out_of_bounds::concrete_out_of_bounds): Update for new
|
||||||
|
fields.
|
||||||
|
(concrete_past_the_end::concrete_past_the_end): Likewise.
|
||||||
|
(concrete_past_the_end::add_region_creation_events): Use
|
||||||
|
oob_region_creation_event_capacity.
|
||||||
|
(concrete_buffer_overflow::concrete_buffer_overflow): Update for
|
||||||
|
new fields.
|
||||||
|
(concrete_buffer_overflow::emit): Replace call to
|
||||||
|
maybe_describe_array_bounds with maybe_show_notes.
|
||||||
|
(concrete_buffer_overflow::get_dir): New.
|
||||||
|
(concrete_buffer_over_read::concrete_buffer_over_read): Update for
|
||||||
|
new fields.
|
||||||
|
(concrete_buffer_over_read::emit): Replace call to
|
||||||
|
maybe_describe_array_bounds with maybe_show_notes.
|
||||||
|
(concrete_buffer_overflow::get_dir): New.
|
||||||
|
(concrete_buffer_underwrite::concrete_buffer_underwrite): Update
|
||||||
|
for new fields.
|
||||||
|
(concrete_buffer_underwrite::emit): Replace call to
|
||||||
|
maybe_describe_array_bounds with maybe_show_notes.
|
||||||
|
(concrete_buffer_underwrite::get_dir): New.
|
||||||
|
(concrete_buffer_under_read::concrete_buffer_under_read): Update
|
||||||
|
for new fields.
|
||||||
|
(concrete_buffer_under_read::emit): Replace call to
|
||||||
|
maybe_describe_array_bounds with maybe_show_notes.
|
||||||
|
(concrete_buffer_under_read::get_dir): New.
|
||||||
|
(symbolic_past_the_end::symbolic_past_the_end): Update for new
|
||||||
|
fields.
|
||||||
|
(symbolic_buffer_overflow::symbolic_buffer_overflow): Likewise.
|
||||||
|
(symbolic_buffer_overflow::emit): Call maybe_show_notes.
|
||||||
|
(symbolic_buffer_overflow::get_dir): New.
|
||||||
|
(symbolic_buffer_over_read::symbolic_buffer_over_read): Update for
|
||||||
|
new fields.
|
||||||
|
(symbolic_buffer_over_read::emit): Call maybe_show_notes.
|
||||||
|
(symbolic_buffer_over_read::get_dir): New.
|
||||||
|
(region_model::check_symbolic_bounds): Add "sval_hint" param. Pass
|
||||||
|
it and sized_offset_reg to diagnostics.
|
||||||
|
(region_model::check_region_bounds): Add "sval_hint" param, passing
|
||||||
|
it to diagnostics.
|
||||||
|
* diagnostic-manager.cc
|
||||||
|
(diagnostic_manager::emit_saved_diagnostic): Pass logger to
|
||||||
|
pending_diagnostic::emit.
|
||||||
|
* engine.cc: Add logger param to pending_diagnostic::emit
|
||||||
|
implementations.
|
||||||
|
* infinite-recursion.cc: Likewise.
|
||||||
|
* kf-analyzer.cc: Likewise.
|
||||||
|
* kf.cc: Likewise. Add nullptr for new param of
|
||||||
|
check_region_for_write.
|
||||||
|
* pending-diagnostic.h: Likewise in decl.
|
||||||
|
* region-model-manager.cc
|
||||||
|
(region_model_manager::get_or_create_int_cst): Convert param from
|
||||||
|
poly_int64 to const poly_wide_int_ref &.
|
||||||
|
(region_model_manager::maybe_fold_binop): Support type being NULL
|
||||||
|
when checking for floating-point types.
|
||||||
|
Check for (X + Y) - X => Y. Be less strict about types when folding
|
||||||
|
associative ops. Check for (X + Y) * CST => (X * CST) + (Y * CST).
|
||||||
|
* region-model-manager.h
|
||||||
|
(region_model_manager::get_or_create_int_cst): Convert param from
|
||||||
|
poly_int64 to const poly_wide_int_ref &.
|
||||||
|
* region-model.cc: Add logger param to pending_diagnostic::emit
|
||||||
|
implementations.
|
||||||
|
(region_model::check_external_function_for_access_attr): Update
|
||||||
|
for new param of check_region_for_write.
|
||||||
|
(region_model::deref_rvalue): Use nullptr rather than NULL.
|
||||||
|
(region_model::get_capacity): Handle RK_STRING.
|
||||||
|
(region_model::check_region_access): Add "sval_hint" param; pass it to
|
||||||
|
check_region_bounds.
|
||||||
|
(region_model::check_region_for_write): Add "sval_hint" param;
|
||||||
|
pass it to check_region_access.
|
||||||
|
(region_model::check_region_for_read): Add NULL for new param to
|
||||||
|
check_region_access.
|
||||||
|
(region_model::set_value): Pass rhs_sval to
|
||||||
|
check_region_for_write.
|
||||||
|
(region_model::get_representative_path_var_1): Handle SK_CONSTANT
|
||||||
|
in the check for infinite recursion.
|
||||||
|
* region-model.h (region_model::check_region_for_write): Add
|
||||||
|
"sval_hint" param.
|
||||||
|
(region_model::check_region_access): Likewise.
|
||||||
|
(region_model::check_symbolic_bounds): Likewise.
|
||||||
|
(region_model::check_region_bounds): Likewise.
|
||||||
|
* region.cc (region_offset::make_byte_offset): New.
|
||||||
|
(region_offset::calc_symbolic_bit_offset): New.
|
||||||
|
(region_offset::calc_symbolic_byte_offset): New.
|
||||||
|
(region_offset::dump_to_pp): New.
|
||||||
|
(region_offset::dump): New.
|
||||||
|
(struct linear_op): New.
|
||||||
|
(operator<, operator<=, operator>, operator>=): New, for
|
||||||
|
region_offset.
|
||||||
|
(region::get_next_offset): New.
|
||||||
|
(region::get_relative_symbolic_offset): Use ptrdiff_type_node.
|
||||||
|
(field_region::get_relative_symbolic_offset): Likewise.
|
||||||
|
(element_region::get_relative_symbolic_offset): Likewise.
|
||||||
|
(bit_range_region::get_relative_symbolic_offset): Likewise.
|
||||||
|
* region.h (region::get_next_offset): New decl.
|
||||||
|
* sm-fd.cc: Add logger param to pending_diagnostic::emit
|
||||||
|
implementations.
|
||||||
|
* sm-file.cc: Likewise.
|
||||||
|
* sm-malloc.cc: Likewise.
|
||||||
|
* sm-pattern-test.cc: Likewise.
|
||||||
|
* sm-sensitive.cc: Likewise.
|
||||||
|
* sm-signal.cc: Likewise.
|
||||||
|
* sm-taint.cc: Likewise.
|
||||||
|
* store.cc (bit_range::contains_p): Allow "out" to be null.
|
||||||
|
* store.h (byte_range::get_start_bit_offset): New.
|
||||||
|
(byte_range::get_next_bit_offset): New.
|
||||||
|
* varargs.cc: Add logger param to pending_diagnostic::emit
|
||||||
|
implementations.
|
||||||
|
|
||||||
2023-06-10 Tim Lange <mail@tim-lange.me>
|
2023-06-10 Tim Lange <mail@tim-lange.me>
|
||||||
|
|
||||||
PR analyzer/109577
|
PR analyzer/109577
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,165 @@
|
||||||
|
/* Text art visualizations within -fanalyzer.
|
||||||
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||||
|
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_ANALYZER_ACCESS_DIAGRAM_H
|
||||||
|
#define GCC_ANALYZER_ACCESS_DIAGRAM_H
|
||||||
|
|
||||||
|
#include "text-art/canvas.h"
|
||||||
|
#include "text-art/theme.h"
|
||||||
|
#include "text-art/widget.h"
|
||||||
|
#include "analyzer/analyzer.h"
|
||||||
|
#include "analyzer/store.h"
|
||||||
|
|
||||||
|
namespace ana {
|
||||||
|
|
||||||
|
class bit_size_expr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bit_size_expr () : m_num_bits (NULL) {}
|
||||||
|
bit_size_expr (tree num_bits) : m_num_bits (num_bits) {}
|
||||||
|
|
||||||
|
text_art::styled_string
|
||||||
|
get_formatted_str (text_art::style_manager &sm,
|
||||||
|
const char *concrete_single_bit_fmt,
|
||||||
|
const char *concrete_plural_bits_fmt,
|
||||||
|
const char *concrete_single_byte_fmt,
|
||||||
|
const char *concrete_plural_bytes_fmt,
|
||||||
|
const char *symbolic_bits_fmt,
|
||||||
|
const char *symbolic_bytes_fmt) const;
|
||||||
|
void print (pretty_printer *pp) const;
|
||||||
|
|
||||||
|
tree maybe_get_as_bytes () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tree m_num_bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A range of bits within a base region, where each endpoint
|
||||||
|
could be concrete or symbolic (not necessarily the same). */
|
||||||
|
|
||||||
|
struct access_range
|
||||||
|
{
|
||||||
|
access_range ()
|
||||||
|
: m_start (), m_next ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
access_range (region_offset start, region_offset next)
|
||||||
|
: m_start (start), m_next (next)
|
||||||
|
{}
|
||||||
|
access_range (const region *base_region, const bit_range &bits);
|
||||||
|
access_range (const region *base_region, const byte_range &bytes);
|
||||||
|
access_range (const region ®, region_model_manager *);
|
||||||
|
|
||||||
|
bool concrete_p () const
|
||||||
|
{
|
||||||
|
return m_start.concrete_p () && m_next.concrete_p ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty_p () const;
|
||||||
|
|
||||||
|
bool get_size (const region_model &model, bit_size_expr *out) const;
|
||||||
|
|
||||||
|
bool get_size_in_bits (bit_size_t *out) const
|
||||||
|
{
|
||||||
|
if (concrete_p ())
|
||||||
|
{
|
||||||
|
*out = m_next.get_bit_offset () - m_start.get_bit_offset ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool as_concrete_bit_range (bit_range *out) const
|
||||||
|
{
|
||||||
|
if (!concrete_p ())
|
||||||
|
return false;
|
||||||
|
bit_size_t size = m_next.get_bit_offset () - m_start.get_bit_offset ();
|
||||||
|
*out = bit_range (m_start.get_bit_offset (), size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool as_concrete_byte_range (byte_range *out) const
|
||||||
|
{
|
||||||
|
bit_range bits (0, 0);
|
||||||
|
if (!as_concrete_bit_range (&bits))
|
||||||
|
return false;
|
||||||
|
return bits.as_byte_range (out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains_p (const access_range &other) const;
|
||||||
|
|
||||||
|
void dump_to_pp (pretty_printer *pp, bool) const;
|
||||||
|
void dump (bool) const;
|
||||||
|
void log (const char *title, logger &) const;
|
||||||
|
|
||||||
|
region_offset m_start;
|
||||||
|
region_offset m_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct access_operation
|
||||||
|
{
|
||||||
|
access_operation (const region_model &model,
|
||||||
|
enum access_direction dir,
|
||||||
|
const region ®,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: m_model (model),
|
||||||
|
m_dir (dir),
|
||||||
|
m_reg (reg),
|
||||||
|
m_sval_hint (sval_hint),
|
||||||
|
m_base_region (reg.get_base_region ())
|
||||||
|
{}
|
||||||
|
|
||||||
|
region_model_manager *get_manager () const
|
||||||
|
{
|
||||||
|
return m_model.get_manager ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the valid bits to access within the base region. */
|
||||||
|
access_range get_valid_bits () const;
|
||||||
|
|
||||||
|
/* Get the actual bits accessed within the base region. */
|
||||||
|
access_range get_actual_bits () const;
|
||||||
|
|
||||||
|
bool maybe_get_invalid_before_bits (access_range *out) const;
|
||||||
|
bool maybe_get_invalid_after_bits (access_range *out) const;
|
||||||
|
|
||||||
|
const region_model &m_model;
|
||||||
|
enum access_direction m_dir;
|
||||||
|
const region &m_reg;
|
||||||
|
const svalue *m_sval_hint;
|
||||||
|
const region *m_base_region;
|
||||||
|
};
|
||||||
|
|
||||||
|
class access_diagram : public text_art::wrapper_widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
access_diagram (const access_operation &op,
|
||||||
|
diagnostic_event_id_t region_creation_event_id,
|
||||||
|
text_art::style_manager &sm,
|
||||||
|
const text_art::theme &theme,
|
||||||
|
logger *logger);
|
||||||
|
const char *get_desc () const override
|
||||||
|
{
|
||||||
|
return "access_diagram";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ana
|
||||||
|
|
||||||
|
#endif /* GCC_ANALYZER_ACCESS_DIAGRAM_H */
|
||||||
|
|
@ -183,6 +183,11 @@ extern tree get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset);
|
||||||
class region_offset
|
class region_offset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
region_offset ()
|
||||||
|
: m_base_region (NULL), m_offset (0), m_sym_offset (NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static region_offset make_concrete (const region *base_region,
|
static region_offset make_concrete (const region *base_region,
|
||||||
bit_offset_t offset)
|
bit_offset_t offset)
|
||||||
{
|
{
|
||||||
|
|
@ -193,9 +198,12 @@ public:
|
||||||
{
|
{
|
||||||
return region_offset (base_region, 0, sym_offset);
|
return region_offset (base_region, 0, sym_offset);
|
||||||
}
|
}
|
||||||
|
static region_offset make_byte_offset (const region *base_region,
|
||||||
|
const svalue *num_bytes_sval);
|
||||||
|
|
||||||
const region *get_base_region () const { return m_base_region; }
|
const region *get_base_region () const { return m_base_region; }
|
||||||
|
|
||||||
|
bool concrete_p () const { return m_sym_offset == NULL; }
|
||||||
bool symbolic_p () const { return m_sym_offset != NULL; }
|
bool symbolic_p () const { return m_sym_offset != NULL; }
|
||||||
|
|
||||||
bit_offset_t get_bit_offset () const
|
bit_offset_t get_bit_offset () const
|
||||||
|
|
@ -204,12 +212,26 @@ public:
|
||||||
return m_offset;
|
return m_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_concrete_byte_offset (byte_offset_t *out) const
|
||||||
|
{
|
||||||
|
gcc_assert (!symbolic_p ());
|
||||||
|
if (m_offset % BITS_PER_UNIT == 0)
|
||||||
|
{
|
||||||
|
*out = m_offset / BITS_PER_UNIT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const svalue *get_symbolic_byte_offset () const
|
const svalue *get_symbolic_byte_offset () const
|
||||||
{
|
{
|
||||||
gcc_assert (symbolic_p ());
|
gcc_assert (symbolic_p ());
|
||||||
return m_sym_offset;
|
return m_sym_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree calc_symbolic_bit_offset (const region_model &model) const;
|
||||||
|
const svalue *calc_symbolic_byte_offset (region_model_manager *mgr) const;
|
||||||
|
|
||||||
bool operator== (const region_offset &other) const
|
bool operator== (const region_offset &other) const
|
||||||
{
|
{
|
||||||
return (m_base_region == other.m_base_region
|
return (m_base_region == other.m_base_region
|
||||||
|
|
@ -217,6 +239,9 @@ public:
|
||||||
&& m_sym_offset == other.m_sym_offset);
|
&& m_sym_offset == other.m_sym_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump_to_pp (pretty_printer *pp, bool) const;
|
||||||
|
void dump (bool) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
region_offset (const region *base_region, bit_offset_t offset,
|
region_offset (const region *base_region, bit_offset_t offset,
|
||||||
const svalue *sym_offset)
|
const svalue *sym_offset)
|
||||||
|
|
@ -228,6 +253,11 @@ private:
|
||||||
const svalue *m_sym_offset;
|
const svalue *m_sym_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern bool operator< (const region_offset &, const region_offset &);
|
||||||
|
extern bool operator<= (const region_offset &, const region_offset &);
|
||||||
|
extern bool operator> (const region_offset &, const region_offset &);
|
||||||
|
extern bool operator>= (const region_offset &, const region_offset &);
|
||||||
|
|
||||||
extern location_t get_stmt_location (const gimple *stmt, function *fun);
|
extern location_t get_stmt_location (const gimple *stmt, function *fun);
|
||||||
|
|
||||||
extern bool compat_types_p (tree src_type, tree dst_type);
|
extern bool compat_types_p (tree src_type, tree dst_type);
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,22 @@ The minimum number of supernodes within a function for the analyzer to consider
|
||||||
Common Joined UInteger Var(param_analyzer_max_enodes_for_full_dump) Init(200) Param
|
Common Joined UInteger Var(param_analyzer_max_enodes_for_full_dump) Init(200) Param
|
||||||
The maximum depth of exploded nodes that should appear in a dot dump before switching to a less verbose format.
|
The maximum depth of exploded nodes that should appear in a dot dump before switching to a less verbose format.
|
||||||
|
|
||||||
|
-param=analyzer-text-art-string-ellipsis-threshold=
|
||||||
|
Common Joined UInteger Var(param_analyzer_text_art_string_ellipsis_threshold) Init(15) Param
|
||||||
|
The number of bytes at which to ellipsize string literals in analyzer text art diagrams.
|
||||||
|
|
||||||
|
-param=analyzer-text-art-string-ellipsis-head-len=
|
||||||
|
Common Joined UInteger Var(param_analyzer_text_art_string_ellipsis_head_len) Init(6) Param
|
||||||
|
The number of literal bytes to show at the head of a string literal in text art when ellipsizing it.
|
||||||
|
|
||||||
|
-param=analyzer-text-art-string-ellipsis-tail-len=
|
||||||
|
Common Joined UInteger Var(param_analyzer_text_art_string_ellipsis_tail_len) Init(6) Param
|
||||||
|
The number of literal bytes to show at the tail of a string literal in text art when ellipsizing it.
|
||||||
|
|
||||||
|
-param=analyzer-text-art-ideal-canvas-width=
|
||||||
|
Common Joined UInteger Var(param_analyzer_text_art_ideal_canvas_width) Init(72) Param
|
||||||
|
The ideal width in characters of text art diagrams generated by the analyzer.
|
||||||
|
|
||||||
Wanalyzer-allocation-size
|
Wanalyzer-allocation-size
|
||||||
Common Var(warn_analyzer_allocation_size) Init(1) Warning
|
Common Var(warn_analyzer_allocation_size) Init(1) Warning
|
||||||
Warn about code paths in which a pointer to a buffer is assigned to an incompatible type.
|
Warn about code paths in which a pointer to a buffer is assigned to an incompatible type.
|
||||||
|
|
@ -242,6 +258,10 @@ fanalyzer-checker=
|
||||||
Common Joined RejectNegative Var(flag_analyzer_checker)
|
Common Joined RejectNegative Var(flag_analyzer_checker)
|
||||||
Restrict the analyzer to run just the named checker.
|
Restrict the analyzer to run just the named checker.
|
||||||
|
|
||||||
|
fanalyzer-debug-text-art
|
||||||
|
Common Var(flag_analyzer_debug_text_art) Init(0)
|
||||||
|
Add extra annotations to diagrams.
|
||||||
|
|
||||||
fanalyzer-fine-grained
|
fanalyzer-fine-grained
|
||||||
Common Var(flag_analyzer_fine_grained) Init(0)
|
Common Var(flag_analyzer_fine_grained) Init(0)
|
||||||
Avoid combining multiple statements into one exploded edge.
|
Avoid combining multiple statements into one exploded edge.
|
||||||
|
|
|
||||||
|
|
@ -19,21 +19,25 @@ along with GCC; see the file COPYING3. If not see
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#define INCLUDE_MEMORY
|
#define INCLUDE_MEMORY
|
||||||
|
#define INCLUDE_VECTOR
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "coretypes.h"
|
#include "coretypes.h"
|
||||||
#include "make-unique.h"
|
#include "make-unique.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
|
#include "intl.h"
|
||||||
#include "gimple.h"
|
#include "gimple.h"
|
||||||
#include "gimple-iterator.h"
|
#include "gimple-iterator.h"
|
||||||
#include "diagnostic-core.h"
|
#include "diagnostic-core.h"
|
||||||
#include "diagnostic-metadata.h"
|
#include "diagnostic-metadata.h"
|
||||||
|
#include "diagnostic-diagram.h"
|
||||||
#include "analyzer/analyzer.h"
|
#include "analyzer/analyzer.h"
|
||||||
#include "analyzer/analyzer-logging.h"
|
#include "analyzer/analyzer-logging.h"
|
||||||
#include "analyzer/region-model.h"
|
#include "analyzer/region-model.h"
|
||||||
#include "analyzer/checker-event.h"
|
#include "analyzer/checker-event.h"
|
||||||
#include "analyzer/checker-path.h"
|
#include "analyzer/checker-path.h"
|
||||||
|
#include "analyzer/access-diagram.h"
|
||||||
|
|
||||||
#if ENABLE_ANALYZER
|
#if ENABLE_ANALYZER
|
||||||
|
|
||||||
|
|
@ -44,8 +48,35 @@ namespace ana {
|
||||||
class out_of_bounds : public pending_diagnostic
|
class out_of_bounds : public pending_diagnostic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
out_of_bounds (const region *reg, tree diag_arg)
|
class oob_region_creation_event_capacity : public region_creation_event_capacity
|
||||||
: m_reg (reg), m_diag_arg (diag_arg)
|
{
|
||||||
|
public:
|
||||||
|
oob_region_creation_event_capacity (tree capacity,
|
||||||
|
const event_loc_info &loc_info,
|
||||||
|
out_of_bounds &oob)
|
||||||
|
: region_creation_event_capacity (capacity,
|
||||||
|
loc_info),
|
||||||
|
m_oob (oob)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void prepare_for_emission (checker_path *path,
|
||||||
|
pending_diagnostic *pd,
|
||||||
|
diagnostic_event_id_t emission_id) override
|
||||||
|
{
|
||||||
|
region_creation_event_capacity::prepare_for_emission (path,
|
||||||
|
pd,
|
||||||
|
emission_id);
|
||||||
|
m_oob.m_region_creation_event_id = emission_id;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
out_of_bounds &m_oob;
|
||||||
|
};
|
||||||
|
|
||||||
|
out_of_bounds (const region_model &model,
|
||||||
|
const region *reg,
|
||||||
|
tree diag_arg,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: m_model (model), m_reg (reg), m_diag_arg (diag_arg), m_sval_hint (sval_hint)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool subclass_equal_p (const pending_diagnostic &base_other) const override
|
bool subclass_equal_p (const pending_diagnostic &base_other) const override
|
||||||
|
|
@ -63,7 +94,7 @@ public:
|
||||||
|
|
||||||
void mark_interesting_stuff (interesting_t *interest) final override
|
void mark_interesting_stuff (interesting_t *interest) final override
|
||||||
{
|
{
|
||||||
interest->add_region_creation (m_reg);
|
interest->add_region_creation (m_reg->get_base_region ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_region_creation_events (const region *,
|
void add_region_creation_events (const region *,
|
||||||
|
|
@ -75,15 +106,25 @@ public:
|
||||||
so we don't need an event for that. */
|
so we don't need an event for that. */
|
||||||
if (capacity)
|
if (capacity)
|
||||||
emission_path.add_event
|
emission_path.add_event
|
||||||
(make_unique<region_creation_event_capacity> (capacity, loc_info));
|
(make_unique<oob_region_creation_event_capacity> (capacity, loc_info,
|
||||||
|
*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual enum access_direction get_dir () const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum memory_space get_memory_space () const
|
enum memory_space get_memory_space () const
|
||||||
{
|
{
|
||||||
return m_reg->get_memory_space ();
|
return m_reg->get_memory_space ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
maybe_show_notes (location_t loc, logger *logger) const
|
||||||
|
{
|
||||||
|
maybe_describe_array_bounds (loc);
|
||||||
|
maybe_show_diagram (logger);
|
||||||
|
}
|
||||||
|
|
||||||
/* Potentially add a note about valid ways to index this array, such
|
/* Potentially add a note about valid ways to index this array, such
|
||||||
as (given "int arr[10];"):
|
as (given "int arr[10];"):
|
||||||
note: valid subscripts for 'arr' are '[0]' to '[9]'
|
note: valid subscripts for 'arr' are '[0]' to '[9]'
|
||||||
|
|
@ -112,8 +153,49 @@ protected:
|
||||||
m_diag_arg, min_idx, max_idx);
|
m_diag_arg, min_idx, max_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
maybe_show_diagram (logger *logger) const
|
||||||
|
{
|
||||||
|
access_operation op (m_model, get_dir (), *m_reg, m_sval_hint);
|
||||||
|
|
||||||
|
/* Don't attempt to make a diagram if there's no valid way of
|
||||||
|
accessing the base region (e.g. a 0-element array). */
|
||||||
|
if (op.get_valid_bits ().empty_p ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (const text_art::theme *theme = global_dc->m_diagrams.m_theme)
|
||||||
|
{
|
||||||
|
text_art::style_manager sm;
|
||||||
|
text_art::canvas canvas (make_access_diagram (op, sm, *theme, logger));
|
||||||
|
if (canvas.get_size ().w == 0 && canvas.get_size ().h == 0)
|
||||||
|
{
|
||||||
|
/* In lieu of exceptions, return a zero-sized diagram if there's
|
||||||
|
a problem. Give up if that's happened. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
diagnostic_diagram diagram
|
||||||
|
(canvas,
|
||||||
|
/* Alt text. */
|
||||||
|
_("Diagram visualizing the predicted out-of-bounds access"));
|
||||||
|
diagnostic_emit_diagram (global_dc, diagram);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text_art::canvas
|
||||||
|
make_access_diagram (const access_operation &op,
|
||||||
|
text_art::style_manager &sm,
|
||||||
|
const text_art::theme &theme,
|
||||||
|
logger *logger) const
|
||||||
|
{
|
||||||
|
access_diagram d (op, m_region_creation_event_id, sm, theme, logger);
|
||||||
|
return d.to_canvas (sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
region_model m_model;
|
||||||
const region *m_reg;
|
const region *m_reg;
|
||||||
tree m_diag_arg;
|
tree m_diag_arg;
|
||||||
|
const svalue *m_sval_hint;
|
||||||
|
diagnostic_event_id_t m_region_creation_event_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Abstract base class for all out-of-bounds warnings where the
|
/* Abstract base class for all out-of-bounds warnings where the
|
||||||
|
|
@ -122,9 +204,11 @@ protected:
|
||||||
class concrete_out_of_bounds : public out_of_bounds
|
class concrete_out_of_bounds : public out_of_bounds
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
concrete_out_of_bounds (const region *reg, tree diag_arg,
|
concrete_out_of_bounds (const region_model &model,
|
||||||
byte_range out_of_bounds_range)
|
const region *reg, tree diag_arg,
|
||||||
: out_of_bounds (reg, diag_arg),
|
byte_range out_of_bounds_range,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: out_of_bounds (model, reg, diag_arg, sval_hint),
|
||||||
m_out_of_bounds_range (out_of_bounds_range)
|
m_out_of_bounds_range (out_of_bounds_range)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -146,9 +230,12 @@ protected:
|
||||||
class concrete_past_the_end : public concrete_out_of_bounds
|
class concrete_past_the_end : public concrete_out_of_bounds
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
concrete_past_the_end (const region *reg, tree diag_arg, byte_range range,
|
concrete_past_the_end (const region_model &model,
|
||||||
tree byte_bound)
|
const region *reg, tree diag_arg, byte_range range,
|
||||||
: concrete_out_of_bounds (reg, diag_arg, range), m_byte_bound (byte_bound)
|
tree byte_bound,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: concrete_out_of_bounds (model, reg, diag_arg, range, sval_hint),
|
||||||
|
m_byte_bound (byte_bound)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -168,7 +255,9 @@ public:
|
||||||
{
|
{
|
||||||
if (m_byte_bound && TREE_CODE (m_byte_bound) == INTEGER_CST)
|
if (m_byte_bound && TREE_CODE (m_byte_bound) == INTEGER_CST)
|
||||||
emission_path.add_event
|
emission_path.add_event
|
||||||
(make_unique<region_creation_event_capacity> (m_byte_bound, loc_info));
|
(make_unique<oob_region_creation_event_capacity> (m_byte_bound,
|
||||||
|
loc_info,
|
||||||
|
*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -180,9 +269,11 @@ protected:
|
||||||
class concrete_buffer_overflow : public concrete_past_the_end
|
class concrete_buffer_overflow : public concrete_past_the_end
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
concrete_buffer_overflow (const region *reg, tree diag_arg,
|
concrete_buffer_overflow (const region_model &model,
|
||||||
byte_range range, tree byte_bound)
|
const region *reg, tree diag_arg,
|
||||||
: concrete_past_the_end (reg, diag_arg, range, byte_bound)
|
byte_range range, tree byte_bound,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: concrete_past_the_end (model, reg, diag_arg, range, byte_bound, sval_hint)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char *get_kind () const final override
|
const char *get_kind () const final override
|
||||||
|
|
@ -190,7 +281,8 @@ public:
|
||||||
return "concrete_buffer_overflow";
|
return "concrete_buffer_overflow";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc,
|
||||||
|
logger *logger) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
bool warned;
|
bool warned;
|
||||||
|
|
@ -238,7 +330,7 @@ public:
|
||||||
"write to beyond the end of %qE",
|
"write to beyond the end of %qE",
|
||||||
m_diag_arg);
|
m_diag_arg);
|
||||||
|
|
||||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
return warned;
|
return warned;
|
||||||
|
|
@ -276,6 +368,8 @@ public:
|
||||||
start_buf, end_buf, m_byte_bound);
|
start_buf, end_buf, m_byte_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum access_direction get_dir () const final override { return DIR_WRITE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Concrete subclass to complain about buffer over-reads. */
|
/* Concrete subclass to complain about buffer over-reads. */
|
||||||
|
|
@ -283,9 +377,10 @@ public:
|
||||||
class concrete_buffer_over_read : public concrete_past_the_end
|
class concrete_buffer_over_read : public concrete_past_the_end
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
concrete_buffer_over_read (const region *reg, tree diag_arg,
|
concrete_buffer_over_read (const region_model &model,
|
||||||
|
const region *reg, tree diag_arg,
|
||||||
byte_range range, tree byte_bound)
|
byte_range range, tree byte_bound)
|
||||||
: concrete_past_the_end (reg, diag_arg, range, byte_bound)
|
: concrete_past_the_end (model, reg, diag_arg, range, byte_bound, NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char *get_kind () const final override
|
const char *get_kind () const final override
|
||||||
|
|
@ -293,7 +388,7 @@ public:
|
||||||
return "concrete_buffer_over_read";
|
return "concrete_buffer_over_read";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
bool warned;
|
bool warned;
|
||||||
|
|
@ -339,7 +434,7 @@ public:
|
||||||
"read from after the end of %qE",
|
"read from after the end of %qE",
|
||||||
m_diag_arg);
|
m_diag_arg);
|
||||||
|
|
||||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
return warned;
|
return warned;
|
||||||
|
|
@ -377,6 +472,8 @@ public:
|
||||||
start_buf, end_buf, m_byte_bound);
|
start_buf, end_buf, m_byte_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum access_direction get_dir () const final override { return DIR_READ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Concrete subclass to complain about buffer underwrites. */
|
/* Concrete subclass to complain about buffer underwrites. */
|
||||||
|
|
@ -384,9 +481,11 @@ public:
|
||||||
class concrete_buffer_underwrite : public concrete_out_of_bounds
|
class concrete_buffer_underwrite : public concrete_out_of_bounds
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
concrete_buffer_underwrite (const region *reg, tree diag_arg,
|
concrete_buffer_underwrite (const region_model &model,
|
||||||
byte_range range)
|
const region *reg, tree diag_arg,
|
||||||
: concrete_out_of_bounds (reg, diag_arg, range)
|
byte_range range,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: concrete_out_of_bounds (model, reg, diag_arg, range, sval_hint)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char *get_kind () const final override
|
const char *get_kind () const final override
|
||||||
|
|
@ -394,7 +493,7 @@ public:
|
||||||
return "concrete_buffer_underwrite";
|
return "concrete_buffer_underwrite";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
bool warned;
|
bool warned;
|
||||||
|
|
@ -415,7 +514,7 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (warned)
|
if (warned)
|
||||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||||
return warned;
|
return warned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,6 +548,8 @@ public:
|
||||||
start_buf, end_buf);;
|
start_buf, end_buf);;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum access_direction get_dir () const final override { return DIR_WRITE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Concrete subclass to complain about buffer under-reads. */
|
/* Concrete subclass to complain about buffer under-reads. */
|
||||||
|
|
@ -456,9 +557,10 @@ public:
|
||||||
class concrete_buffer_under_read : public concrete_out_of_bounds
|
class concrete_buffer_under_read : public concrete_out_of_bounds
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
concrete_buffer_under_read (const region *reg, tree diag_arg,
|
concrete_buffer_under_read (const region_model &model,
|
||||||
|
const region *reg, tree diag_arg,
|
||||||
byte_range range)
|
byte_range range)
|
||||||
: concrete_out_of_bounds (reg, diag_arg, range)
|
: concrete_out_of_bounds (model, reg, diag_arg, range, NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char *get_kind () const final override
|
const char *get_kind () const final override
|
||||||
|
|
@ -466,7 +568,7 @@ public:
|
||||||
return "concrete_buffer_under_read";
|
return "concrete_buffer_under_read";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
bool warned;
|
bool warned;
|
||||||
|
|
@ -487,7 +589,7 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (warned)
|
if (warned)
|
||||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||||
return warned;
|
return warned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,6 +623,8 @@ public:
|
||||||
start_buf, end_buf);;
|
start_buf, end_buf);;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum access_direction get_dir () const final override { return DIR_READ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Abstract class to complain about out-of-bounds read/writes where
|
/* Abstract class to complain about out-of-bounds read/writes where
|
||||||
|
|
@ -529,9 +633,11 @@ public:
|
||||||
class symbolic_past_the_end : public out_of_bounds
|
class symbolic_past_the_end : public out_of_bounds
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
symbolic_past_the_end (const region *reg, tree diag_arg, tree offset,
|
symbolic_past_the_end (const region_model &model,
|
||||||
tree num_bytes, tree capacity)
|
const region *reg, tree diag_arg, tree offset,
|
||||||
: out_of_bounds (reg, diag_arg),
|
tree num_bytes, tree capacity,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: out_of_bounds (model, reg, diag_arg, sval_hint),
|
||||||
m_offset (offset),
|
m_offset (offset),
|
||||||
m_num_bytes (num_bytes),
|
m_num_bytes (num_bytes),
|
||||||
m_capacity (capacity)
|
m_capacity (capacity)
|
||||||
|
|
@ -559,9 +665,12 @@ protected:
|
||||||
class symbolic_buffer_overflow : public symbolic_past_the_end
|
class symbolic_buffer_overflow : public symbolic_past_the_end
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
symbolic_buffer_overflow (const region *reg, tree diag_arg, tree offset,
|
symbolic_buffer_overflow (const region_model &model,
|
||||||
tree num_bytes, tree capacity)
|
const region *reg, tree diag_arg, tree offset,
|
||||||
: symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
|
tree num_bytes, tree capacity,
|
||||||
|
const svalue *sval_hint)
|
||||||
|
: symbolic_past_the_end (model, reg, diag_arg, offset, num_bytes, capacity,
|
||||||
|
sval_hint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -570,24 +679,31 @@ public:
|
||||||
return "symbolic_buffer_overflow";
|
return "symbolic_buffer_overflow";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
bool warned;
|
||||||
switch (get_memory_space ())
|
switch (get_memory_space ())
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
m.add_cwe (787);
|
m.add_cwe (787);
|
||||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
"buffer overflow");
|
"buffer overflow");
|
||||||
|
break;
|
||||||
case MEMSPACE_STACK:
|
case MEMSPACE_STACK:
|
||||||
m.add_cwe (121);
|
m.add_cwe (121);
|
||||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
"stack-based buffer overflow");
|
"stack-based buffer overflow");
|
||||||
|
break;
|
||||||
case MEMSPACE_HEAP:
|
case MEMSPACE_HEAP:
|
||||||
m.add_cwe (122);
|
m.add_cwe (122);
|
||||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
"heap-based buffer overflow");
|
"heap-based buffer overflow");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (warned)
|
||||||
|
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||||
|
return warned;
|
||||||
}
|
}
|
||||||
|
|
||||||
label_text
|
label_text
|
||||||
|
|
@ -658,6 +774,8 @@ public:
|
||||||
m_diag_arg);
|
m_diag_arg);
|
||||||
return ev.formatted_print ("out-of-bounds write");
|
return ev.formatted_print ("out-of-bounds write");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum access_direction get_dir () const final override { return DIR_WRITE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Concrete subclass to complain about over-reads with symbolic values. */
|
/* Concrete subclass to complain about over-reads with symbolic values. */
|
||||||
|
|
@ -665,9 +783,11 @@ public:
|
||||||
class symbolic_buffer_over_read : public symbolic_past_the_end
|
class symbolic_buffer_over_read : public symbolic_past_the_end
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
symbolic_buffer_over_read (const region *reg, tree diag_arg, tree offset,
|
symbolic_buffer_over_read (const region_model &model,
|
||||||
|
const region *reg, tree diag_arg, tree offset,
|
||||||
tree num_bytes, tree capacity)
|
tree num_bytes, tree capacity)
|
||||||
: symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
|
: symbolic_past_the_end (model, reg, diag_arg, offset, num_bytes, capacity,
|
||||||
|
NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -676,25 +796,32 @@ public:
|
||||||
return "symbolic_buffer_over_read";
|
return "symbolic_buffer_over_read";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
m.add_cwe (126);
|
m.add_cwe (126);
|
||||||
|
bool warned;
|
||||||
switch (get_memory_space ())
|
switch (get_memory_space ())
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
m.add_cwe (787);
|
m.add_cwe (787);
|
||||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
"buffer over-read");
|
"buffer over-read");
|
||||||
|
break;
|
||||||
case MEMSPACE_STACK:
|
case MEMSPACE_STACK:
|
||||||
m.add_cwe (121);
|
m.add_cwe (121);
|
||||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
"stack-based buffer over-read");
|
"stack-based buffer over-read");
|
||||||
|
break;
|
||||||
case MEMSPACE_HEAP:
|
case MEMSPACE_HEAP:
|
||||||
m.add_cwe (122);
|
m.add_cwe (122);
|
||||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
"heap-based buffer over-read");
|
"heap-based buffer over-read");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (warned)
|
||||||
|
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||||
|
return warned;
|
||||||
}
|
}
|
||||||
|
|
||||||
label_text
|
label_text
|
||||||
|
|
@ -765,6 +892,8 @@ public:
|
||||||
m_diag_arg);
|
m_diag_arg);
|
||||||
return ev.formatted_print ("out-of-bounds read");
|
return ev.formatted_print ("out-of-bounds read");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum access_direction get_dir () const final override { return DIR_READ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Check whether an access is past the end of the BASE_REG.
|
/* Check whether an access is past the end of the BASE_REG.
|
||||||
|
|
@ -776,6 +905,7 @@ region_model::check_symbolic_bounds (const region *base_reg,
|
||||||
const svalue *num_bytes_sval,
|
const svalue *num_bytes_sval,
|
||||||
const svalue *capacity,
|
const svalue *capacity,
|
||||||
enum access_direction dir,
|
enum access_direction dir,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const
|
region_model_context *ctxt) const
|
||||||
{
|
{
|
||||||
gcc_assert (ctxt);
|
gcc_assert (ctxt);
|
||||||
|
|
@ -790,13 +920,21 @@ region_model::check_symbolic_bounds (const region *base_reg,
|
||||||
tree offset_tree = get_representative_tree (sym_byte_offset);
|
tree offset_tree = get_representative_tree (sym_byte_offset);
|
||||||
tree num_bytes_tree = get_representative_tree (num_bytes_sval);
|
tree num_bytes_tree = get_representative_tree (num_bytes_sval);
|
||||||
tree capacity_tree = get_representative_tree (capacity);
|
tree capacity_tree = get_representative_tree (capacity);
|
||||||
|
const region *offset_reg = m_mgr->get_offset_region (base_reg,
|
||||||
|
NULL_TREE,
|
||||||
|
sym_byte_offset);
|
||||||
|
const region *sized_offset_reg = m_mgr->get_sized_region (offset_reg,
|
||||||
|
NULL_TREE,
|
||||||
|
num_bytes_sval);
|
||||||
switch (dir)
|
switch (dir)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
break;
|
break;
|
||||||
case DIR_READ:
|
case DIR_READ:
|
||||||
ctxt->warn (make_unique<symbolic_buffer_over_read> (base_reg,
|
gcc_assert (sval_hint == nullptr);
|
||||||
|
ctxt->warn (make_unique<symbolic_buffer_over_read> (*this,
|
||||||
|
sized_offset_reg,
|
||||||
diag_arg,
|
diag_arg,
|
||||||
offset_tree,
|
offset_tree,
|
||||||
num_bytes_tree,
|
num_bytes_tree,
|
||||||
|
|
@ -804,11 +942,13 @@ region_model::check_symbolic_bounds (const region *base_reg,
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
case DIR_WRITE:
|
case DIR_WRITE:
|
||||||
ctxt->warn (make_unique<symbolic_buffer_overflow> (base_reg,
|
ctxt->warn (make_unique<symbolic_buffer_overflow> (*this,
|
||||||
|
sized_offset_reg,
|
||||||
diag_arg,
|
diag_arg,
|
||||||
offset_tree,
|
offset_tree,
|
||||||
num_bytes_tree,
|
num_bytes_tree,
|
||||||
capacity_tree));
|
capacity_tree,
|
||||||
|
sval_hint));
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -832,6 +972,7 @@ maybe_get_integer_cst_tree (const svalue *sval)
|
||||||
bool
|
bool
|
||||||
region_model::check_region_bounds (const region *reg,
|
region_model::check_region_bounds (const region *reg,
|
||||||
enum access_direction dir,
|
enum access_direction dir,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const
|
region_model_context *ctxt) const
|
||||||
{
|
{
|
||||||
gcc_assert (ctxt);
|
gcc_assert (ctxt);
|
||||||
|
|
@ -882,8 +1023,8 @@ region_model::check_region_bounds (const region *reg,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
|
byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
|
||||||
return check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
|
return check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
|
||||||
capacity, dir, ctxt);
|
capacity, dir, sval_hint, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise continue to check with concrete values. */
|
/* Otherwise continue to check with concrete values. */
|
||||||
|
|
@ -902,13 +1043,17 @@ region_model::check_region_bounds (const region *reg,
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
break;
|
break;
|
||||||
case DIR_READ:
|
case DIR_READ:
|
||||||
ctxt->warn (make_unique<concrete_buffer_under_read> (reg, diag_arg,
|
gcc_assert (sval_hint == nullptr);
|
||||||
|
ctxt->warn (make_unique<concrete_buffer_under_read> (*this, reg,
|
||||||
|
diag_arg,
|
||||||
out));
|
out));
|
||||||
oob_safe = false;
|
oob_safe = false;
|
||||||
break;
|
break;
|
||||||
case DIR_WRITE:
|
case DIR_WRITE:
|
||||||
ctxt->warn (make_unique<concrete_buffer_underwrite> (reg, diag_arg,
|
ctxt->warn (make_unique<concrete_buffer_underwrite> (*this,
|
||||||
out));
|
reg, diag_arg,
|
||||||
|
out,
|
||||||
|
sval_hint));
|
||||||
oob_safe = false;
|
oob_safe = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -934,13 +1079,17 @@ region_model::check_region_bounds (const region *reg,
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
break;
|
break;
|
||||||
case DIR_READ:
|
case DIR_READ:
|
||||||
ctxt->warn (make_unique<concrete_buffer_over_read> (reg, diag_arg,
|
gcc_assert (sval_hint == nullptr);
|
||||||
|
ctxt->warn (make_unique<concrete_buffer_over_read> (*this,
|
||||||
|
reg, diag_arg,
|
||||||
out, byte_bound));
|
out, byte_bound));
|
||||||
oob_safe = false;
|
oob_safe = false;
|
||||||
break;
|
break;
|
||||||
case DIR_WRITE:
|
case DIR_WRITE:
|
||||||
ctxt->warn (make_unique<concrete_buffer_overflow> (reg, diag_arg,
|
ctxt->warn (make_unique<concrete_buffer_overflow> (*this,
|
||||||
out, byte_bound));
|
reg, diag_arg,
|
||||||
|
out, byte_bound,
|
||||||
|
sval_hint));
|
||||||
oob_safe = false;
|
oob_safe = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1421,7 +1421,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
|
||||||
|
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
auto_cfun sentinel (sd.m_snode->m_fun);
|
auto_cfun sentinel (sd.m_snode->m_fun);
|
||||||
if (sd.m_d->emit (&rich_loc))
|
if (sd.m_d->emit (&rich_loc, get_logger ()))
|
||||||
{
|
{
|
||||||
sd.emit_any_notes ();
|
sd.emit_any_notes ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1771,7 +1771,7 @@ public:
|
||||||
return OPT_Wanalyzer_stale_setjmp_buffer;
|
return OPT_Wanalyzer_stale_setjmp_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *richloc) final override
|
bool emit (rich_location *richloc, logger *) final override
|
||||||
{
|
{
|
||||||
return warning_at
|
return warning_at
|
||||||
(richloc, get_controlling_option (),
|
(richloc, get_controlling_option (),
|
||||||
|
|
@ -3925,7 +3925,7 @@ public:
|
||||||
return OPT_Wanalyzer_jump_through_null;
|
return OPT_Wanalyzer_jump_through_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
"jump through null pointer");
|
"jump through null pointer");
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ public:
|
||||||
return OPT_Wanalyzer_infinite_recursion;
|
return OPT_Wanalyzer_infinite_recursion;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* "CWE-674: Uncontrolled Recursion". */
|
/* "CWE-674: Uncontrolled Recursion". */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *richloc) final override
|
bool emit (rich_location *richloc, logger *) final override
|
||||||
{
|
{
|
||||||
inform (richloc, "path");
|
inform (richloc, "path");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -553,7 +553,9 @@ kf_memset::impl_call_pre (const call_details &cd) const
|
||||||
const region *sized_dest_reg = mgr->get_sized_region (dest_reg,
|
const region *sized_dest_reg = mgr->get_sized_region (dest_reg,
|
||||||
NULL_TREE,
|
NULL_TREE,
|
||||||
num_bytes_sval);
|
num_bytes_sval);
|
||||||
model->check_region_for_write (sized_dest_reg, cd.get_ctxt ());
|
model->check_region_for_write (sized_dest_reg,
|
||||||
|
nullptr,
|
||||||
|
cd.get_ctxt ());
|
||||||
model->fill_region (sized_dest_reg, fill_value_u8);
|
model->fill_region (sized_dest_reg, fill_value_u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -587,7 +589,7 @@ public:
|
||||||
return OPT_Wanalyzer_putenv_of_auto_var;
|
return OPT_Wanalyzer_putenv_of_auto_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ class pending_diagnostic
|
||||||
/* Vfunc for emitting the diagnostic. The rich_location will have been
|
/* Vfunc for emitting the diagnostic. The rich_location will have been
|
||||||
populated with a diagnostic_path.
|
populated with a diagnostic_path.
|
||||||
Return true if a diagnostic is actually emitted. */
|
Return true if a diagnostic is actually emitted. */
|
||||||
virtual bool emit (rich_location *) = 0;
|
virtual bool emit (rich_location *, logger *) = 0;
|
||||||
|
|
||||||
/* Hand-coded RTTI: get an ID for the subclass. */
|
/* Hand-coded RTTI: get an ID for the subclass. */
|
||||||
virtual const char *get_kind () const = 0;
|
virtual const char *get_kind () const = 0;
|
||||||
|
|
|
||||||
|
|
@ -230,10 +230,11 @@ region_model_manager::get_or_create_constant_svalue (tree cst_expr)
|
||||||
for VAL of type TYPE, creating it if necessary. */
|
for VAL of type TYPE, creating it if necessary. */
|
||||||
|
|
||||||
const svalue *
|
const svalue *
|
||||||
region_model_manager::get_or_create_int_cst (tree type, poly_int64 val)
|
region_model_manager::get_or_create_int_cst (tree type,
|
||||||
|
const poly_wide_int_ref &cst)
|
||||||
{
|
{
|
||||||
gcc_assert (type);
|
gcc_assert (type);
|
||||||
tree tree_cst = build_int_cst (type, val);
|
tree tree_cst = wide_int_to_tree (type, cst);
|
||||||
return get_or_create_constant_svalue (tree_cst);
|
return get_or_create_constant_svalue (tree_cst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -612,7 +613,7 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
|
||||||
return get_or_create_constant_svalue (result);
|
return get_or_create_constant_svalue (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLOAT_TYPE_P (type)
|
if ((type && FLOAT_TYPE_P (type))
|
||||||
|| (arg0->get_type () && FLOAT_TYPE_P (arg0->get_type ()))
|
|| (arg0->get_type () && FLOAT_TYPE_P (arg0->get_type ()))
|
||||||
|| (arg1->get_type () && FLOAT_TYPE_P (arg1->get_type ())))
|
|| (arg1->get_type () && FLOAT_TYPE_P (arg1->get_type ())))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -634,6 +635,11 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
|
||||||
/* (0 - VAL) -> -VAL. */
|
/* (0 - VAL) -> -VAL. */
|
||||||
if (cst0 && zerop (cst0))
|
if (cst0 && zerop (cst0))
|
||||||
return get_or_create_unaryop (type, NEGATE_EXPR, arg1);
|
return get_or_create_unaryop (type, NEGATE_EXPR, arg1);
|
||||||
|
/* (X + Y) - X -> Y. */
|
||||||
|
if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
|
||||||
|
if (binop->get_op () == PLUS_EXPR)
|
||||||
|
if (binop->get_arg0 () == arg1)
|
||||||
|
return get_or_create_cast (type, binop->get_arg1 ());
|
||||||
break;
|
break;
|
||||||
case MULT_EXPR:
|
case MULT_EXPR:
|
||||||
/* (VAL * 0). */
|
/* (VAL * 0). */
|
||||||
|
|
@ -726,10 +732,7 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
|
||||||
if (cst1 && associative_tree_code (op))
|
if (cst1 && associative_tree_code (op))
|
||||||
if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
|
if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
|
||||||
if (binop->get_op () == op
|
if (binop->get_op () == op
|
||||||
&& binop->get_arg1 ()->maybe_get_constant ()
|
&& binop->get_arg1 ()->maybe_get_constant ())
|
||||||
&& type == binop->get_type ()
|
|
||||||
&& type == binop->get_arg0 ()->get_type ()
|
|
||||||
&& type == binop->get_arg1 ()->get_type ())
|
|
||||||
return get_or_create_binop
|
return get_or_create_binop
|
||||||
(type, op, binop->get_arg0 (),
|
(type, op, binop->get_arg0 (),
|
||||||
get_or_create_binop (type, op,
|
get_or_create_binop (type, op,
|
||||||
|
|
@ -748,6 +751,21 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
|
||||||
get_or_create_binop (size_type_node, op,
|
get_or_create_binop (size_type_node, op,
|
||||||
binop->get_arg1 (), arg1));
|
binop->get_arg1 (), arg1));
|
||||||
|
|
||||||
|
/* Distribute multiplication by a constant through addition/subtraction:
|
||||||
|
(X + Y) * CST => (X * CST) + (Y * CST). */
|
||||||
|
if (cst1 && op == MULT_EXPR)
|
||||||
|
if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
|
||||||
|
if (binop->get_op () == PLUS_EXPR
|
||||||
|
|| binop->get_op () == MINUS_EXPR)
|
||||||
|
{
|
||||||
|
return get_or_create_binop
|
||||||
|
(type, binop->get_op (),
|
||||||
|
get_or_create_binop (type, op,
|
||||||
|
binop->get_arg0 (), arg1),
|
||||||
|
get_or_create_binop (type, op,
|
||||||
|
binop->get_arg1 (), arg1));
|
||||||
|
}
|
||||||
|
|
||||||
/* etc. */
|
/* etc. */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public:
|
||||||
|
|
||||||
/* svalue consolidation. */
|
/* svalue consolidation. */
|
||||||
const svalue *get_or_create_constant_svalue (tree cst_expr);
|
const svalue *get_or_create_constant_svalue (tree cst_expr);
|
||||||
const svalue *get_or_create_int_cst (tree type, poly_int64);
|
const svalue *get_or_create_int_cst (tree type, const poly_wide_int_ref &cst);
|
||||||
const svalue *get_or_create_null_ptr (tree pointer_type);
|
const svalue *get_or_create_null_ptr (tree pointer_type);
|
||||||
const svalue *get_or_create_unknown_svalue (tree type);
|
const svalue *get_or_create_unknown_svalue (tree type);
|
||||||
const svalue *get_or_create_setjmp_svalue (const setjmp_record &r,
|
const svalue *get_or_create_setjmp_svalue (const setjmp_record &r,
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,7 @@ public:
|
||||||
|
|
||||||
bool terminate_path_p () const final override { return true; }
|
bool terminate_path_p () const final override { return true; }
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
switch (m_pkind)
|
switch (m_pkind)
|
||||||
{
|
{
|
||||||
|
|
@ -638,7 +638,7 @@ public:
|
||||||
return OPT_Wanalyzer_shift_count_negative;
|
return OPT_Wanalyzer_shift_count_negative;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
"shift by negative count (%qE)", m_count_cst);
|
"shift by negative count (%qE)", m_count_cst);
|
||||||
|
|
@ -685,7 +685,7 @@ public:
|
||||||
return OPT_Wanalyzer_shift_count_overflow;
|
return OPT_Wanalyzer_shift_count_overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
"shift by count (%qE) >= precision of type (%qi)",
|
"shift by count (%qE) >= precision of type (%qi)",
|
||||||
|
|
@ -1736,7 +1736,7 @@ check_external_function_for_access_attr (const gcall *call,
|
||||||
tree ptr_tree = gimple_call_arg (call, access->ptrarg);
|
tree ptr_tree = gimple_call_arg (call, access->ptrarg);
|
||||||
const svalue *ptr_sval = get_rvalue (ptr_tree, &my_ctxt);
|
const svalue *ptr_sval = get_rvalue (ptr_tree, &my_ctxt);
|
||||||
const region *reg = deref_rvalue (ptr_sval, ptr_tree, &my_ctxt);
|
const region *reg = deref_rvalue (ptr_sval, ptr_tree, &my_ctxt);
|
||||||
check_region_for_write (reg, &my_ctxt);
|
check_region_for_write (reg, nullptr, &my_ctxt);
|
||||||
/* We don't use the size arg for now. */
|
/* We don't use the size arg for now. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2522,8 +2522,8 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
|
||||||
const poisoned_svalue *poisoned_sval
|
const poisoned_svalue *poisoned_sval
|
||||||
= as_a <const poisoned_svalue *> (ptr_sval);
|
= as_a <const poisoned_svalue *> (ptr_sval);
|
||||||
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
|
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
|
||||||
ctxt->warn (make_unique<poisoned_value_diagnostic>
|
ctxt->warn (::make_unique<poisoned_value_diagnostic>
|
||||||
(ptr, pkind, NULL, NULL));
|
(ptr, pkind, nullptr, nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2576,7 +2576,7 @@ public:
|
||||||
return OPT_Wanalyzer_write_to_const;
|
return OPT_Wanalyzer_write_to_const;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
bool warned;
|
bool warned;
|
||||||
|
|
@ -2644,7 +2644,7 @@ public:
|
||||||
return OPT_Wanalyzer_write_to_string_literal;
|
return OPT_Wanalyzer_write_to_string_literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
"write to string literal");
|
"write to string literal");
|
||||||
|
|
@ -2742,6 +2742,15 @@ region_model::get_capacity (const region *reg) const
|
||||||
/* Look through sized regions to get at the capacity
|
/* Look through sized regions to get at the capacity
|
||||||
of the underlying regions. */
|
of the underlying regions. */
|
||||||
return get_capacity (reg->get_parent_region ());
|
return get_capacity (reg->get_parent_region ());
|
||||||
|
case RK_STRING:
|
||||||
|
{
|
||||||
|
/* "Capacity" here means "size". */
|
||||||
|
const string_region *string_reg = as_a <const string_region *> (reg);
|
||||||
|
tree string_cst = string_reg->get_string_cst ();
|
||||||
|
return m_mgr->get_or_create_int_cst (size_type_node,
|
||||||
|
TREE_STRING_LENGTH (string_cst));
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const svalue *recorded = get_dynamic_extents (reg))
|
if (const svalue *recorded = get_dynamic_extents (reg))
|
||||||
|
|
@ -2781,11 +2790,14 @@ region_model::get_string_size (const region *reg) const
|
||||||
|
|
||||||
/* If CTXT is non-NULL, use it to warn about any problems accessing REG,
|
/* If CTXT is non-NULL, use it to warn about any problems accessing REG,
|
||||||
using DIR to determine if this access is a read or write.
|
using DIR to determine if this access is a read or write.
|
||||||
Return TRUE if an UNKNOWN_SVALUE needs be created. */
|
Return TRUE if an UNKNOWN_SVALUE needs be created.
|
||||||
|
If SVAL_HINT is non-NULL, use it as a hint in diagnostics
|
||||||
|
about the value that would be written to REG. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
region_model::check_region_access (const region *reg,
|
region_model::check_region_access (const region *reg,
|
||||||
enum access_direction dir,
|
enum access_direction dir,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const
|
region_model_context *ctxt) const
|
||||||
{
|
{
|
||||||
/* Fail gracefully if CTXT is NULL. */
|
/* Fail gracefully if CTXT is NULL. */
|
||||||
|
|
@ -2794,7 +2806,7 @@ region_model::check_region_access (const region *reg,
|
||||||
|
|
||||||
bool need_unknown_sval = false;
|
bool need_unknown_sval = false;
|
||||||
check_region_for_taint (reg, dir, ctxt);
|
check_region_for_taint (reg, dir, ctxt);
|
||||||
if (!check_region_bounds (reg, dir, ctxt))
|
if (!check_region_bounds (reg, dir, sval_hint, ctxt))
|
||||||
need_unknown_sval = true;
|
need_unknown_sval = true;
|
||||||
|
|
||||||
switch (dir)
|
switch (dir)
|
||||||
|
|
@ -2815,9 +2827,10 @@ region_model::check_region_access (const region *reg,
|
||||||
|
|
||||||
void
|
void
|
||||||
region_model::check_region_for_write (const region *dest_reg,
|
region_model::check_region_for_write (const region *dest_reg,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const
|
region_model_context *ctxt) const
|
||||||
{
|
{
|
||||||
check_region_access (dest_reg, DIR_WRITE, ctxt);
|
check_region_access (dest_reg, DIR_WRITE, sval_hint, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If CTXT is non-NULL, use it to warn about any problems reading from REG.
|
/* If CTXT is non-NULL, use it to warn about any problems reading from REG.
|
||||||
|
|
@ -2827,7 +2840,7 @@ bool
|
||||||
region_model::check_region_for_read (const region *src_reg,
|
region_model::check_region_for_read (const region *src_reg,
|
||||||
region_model_context *ctxt) const
|
region_model_context *ctxt) const
|
||||||
{
|
{
|
||||||
return check_region_access (src_reg, DIR_READ, ctxt);
|
return check_region_access (src_reg, DIR_READ, NULL, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Concrete subclass for casts of pointers that lead to trailing bytes. */
|
/* Concrete subclass for casts of pointers that lead to trailing bytes. */
|
||||||
|
|
@ -2863,7 +2876,7 @@ public:
|
||||||
return OPT_Wanalyzer_allocation_size;
|
return OPT_Wanalyzer_allocation_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
m.add_cwe (131);
|
m.add_cwe (131);
|
||||||
|
|
@ -3203,7 +3216,7 @@ region_model::set_value (const region *lhs_reg, const svalue *rhs_sval,
|
||||||
|
|
||||||
check_region_size (lhs_reg, rhs_sval, ctxt);
|
check_region_size (lhs_reg, rhs_sval, ctxt);
|
||||||
|
|
||||||
check_region_for_write (lhs_reg, ctxt);
|
check_region_for_write (lhs_reg, rhs_sval, ctxt);
|
||||||
|
|
||||||
m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval,
|
m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval,
|
||||||
ctxt ? ctxt->get_uncertainty () : NULL);
|
ctxt ? ctxt->get_uncertainty () : NULL);
|
||||||
|
|
@ -3836,7 +3849,12 @@ region_model::get_representative_path_var_1 (const svalue *sval,
|
||||||
|
|
||||||
/* Prevent infinite recursion. */
|
/* Prevent infinite recursion. */
|
||||||
if (visited->contains (sval))
|
if (visited->contains (sval))
|
||||||
return path_var (NULL_TREE, 0);
|
{
|
||||||
|
if (sval->get_kind () == SK_CONSTANT)
|
||||||
|
return path_var (sval->maybe_get_constant (), 0);
|
||||||
|
else
|
||||||
|
return path_var (NULL_TREE, 0);
|
||||||
|
}
|
||||||
visited->add (sval);
|
visited->add (sval);
|
||||||
|
|
||||||
/* Handle casts by recursion into get_representative_path_var. */
|
/* Handle casts by recursion into get_representative_path_var. */
|
||||||
|
|
@ -4941,7 +4959,7 @@ public:
|
||||||
return same_tree_p (m_arg, ((const float_as_size_arg &) other).m_arg);
|
return same_tree_p (m_arg, ((const float_as_size_arg &) other).m_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
bool warned = warning_meta (rich_loc, m, get_controlling_option (),
|
bool warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||||
|
|
@ -5303,7 +5321,7 @@ public:
|
||||||
return OPT_Wanalyzer_exposure_through_uninit_copy;
|
return OPT_Wanalyzer_exposure_through_uninit_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-200: Exposure of Sensitive Information to an Unauthorized Actor. */
|
/* CWE-200: Exposure of Sensitive Information to an Unauthorized Actor. */
|
||||||
|
|
|
||||||
|
|
@ -490,6 +490,7 @@ class region_model
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
|
|
||||||
void check_region_for_write (const region *dest_reg,
|
void check_region_for_write (const region *dest_reg,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -555,6 +556,7 @@ private:
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
bool check_region_access (const region *reg,
|
bool check_region_access (const region *reg,
|
||||||
enum access_direction dir,
|
enum access_direction dir,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
bool check_region_for_read (const region *src_reg,
|
bool check_region_for_read (const region *src_reg,
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
|
|
@ -567,8 +569,10 @@ private:
|
||||||
const svalue *num_bytes_sval,
|
const svalue *num_bytes_sval,
|
||||||
const svalue *capacity,
|
const svalue *capacity,
|
||||||
enum access_direction dir,
|
enum access_direction dir,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
bool check_region_bounds (const region *reg, enum access_direction dir,
|
bool check_region_bounds (const region *reg, enum access_direction dir,
|
||||||
|
const svalue *sval_hint,
|
||||||
region_model_context *ctxt) const;
|
region_model_context *ctxt) const;
|
||||||
|
|
||||||
void check_call_args (const call_details &cd) const;
|
void check_call_args (const call_details &cd) const;
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,332 @@ along with GCC; see the file COPYING3. If not see
|
||||||
|
|
||||||
namespace ana {
|
namespace ana {
|
||||||
|
|
||||||
|
region_offset
|
||||||
|
region_offset::make_byte_offset (const region *base_region,
|
||||||
|
const svalue *num_bytes_sval)
|
||||||
|
{
|
||||||
|
if (tree num_bytes_cst = num_bytes_sval->maybe_get_constant ())
|
||||||
|
{
|
||||||
|
gcc_assert (TREE_CODE (num_bytes_cst) == INTEGER_CST);
|
||||||
|
bit_offset_t num_bits = wi::to_offset (num_bytes_cst) * BITS_PER_UNIT;
|
||||||
|
return make_concrete (base_region, num_bits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return make_symbolic (base_region, num_bytes_sval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree
|
||||||
|
region_offset::calc_symbolic_bit_offset (const region_model &model) const
|
||||||
|
{
|
||||||
|
if (symbolic_p ())
|
||||||
|
{
|
||||||
|
tree num_bytes_expr = model.get_representative_tree (m_sym_offset);
|
||||||
|
if (!num_bytes_expr)
|
||||||
|
return NULL_TREE;
|
||||||
|
tree bytes_to_bits_scale = build_int_cst (size_type_node, BITS_PER_UNIT);
|
||||||
|
return fold_build2 (MULT_EXPR, size_type_node,
|
||||||
|
num_bytes_expr, bytes_to_bits_scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tree cst = wide_int_to_tree (size_type_node, m_offset);
|
||||||
|
return cst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const svalue *
|
||||||
|
region_offset::calc_symbolic_byte_offset (region_model_manager *mgr) const
|
||||||
|
{
|
||||||
|
if (symbolic_p ())
|
||||||
|
return m_sym_offset;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte_offset_t concrete_byte_offset;
|
||||||
|
if (get_concrete_byte_offset (&concrete_byte_offset))
|
||||||
|
return mgr->get_or_create_int_cst (size_type_node,
|
||||||
|
concrete_byte_offset);
|
||||||
|
else
|
||||||
|
/* Can't handle bitfields; return UNKNOWN. */
|
||||||
|
return mgr->get_or_create_unknown_svalue (size_type_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
region_offset::dump_to_pp (pretty_printer *pp, bool simple) const
|
||||||
|
{
|
||||||
|
if (symbolic_p ())
|
||||||
|
{
|
||||||
|
/* We don't bother showing the base region. */
|
||||||
|
pp_string (pp, "byte ");
|
||||||
|
m_sym_offset->dump_to_pp (pp, simple);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_offset % BITS_PER_UNIT == 0)
|
||||||
|
{
|
||||||
|
pp_string (pp, "byte ");
|
||||||
|
pp_wide_int (pp, m_offset / BITS_PER_UNIT, SIGNED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pp_string (pp, "bit ");
|
||||||
|
pp_wide_int (pp, m_offset, SIGNED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_FUNCTION void
|
||||||
|
region_offset::dump (bool simple) const
|
||||||
|
{
|
||||||
|
pretty_printer pp;
|
||||||
|
pp_format_decoder (&pp) = default_tree_printer;
|
||||||
|
pp_show_color (&pp) = pp_show_color (global_dc->printer);
|
||||||
|
pp.buffer->stream = stderr;
|
||||||
|
dump_to_pp (&pp, simple);
|
||||||
|
pp_newline (&pp);
|
||||||
|
pp_flush (&pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An svalue that matches the pattern (BASE * FACTOR) + OFFSET
|
||||||
|
where FACTOR or OFFSET could be the identity (represented as NULL). */
|
||||||
|
|
||||||
|
struct linear_op
|
||||||
|
{
|
||||||
|
linear_op (const svalue *base,
|
||||||
|
const svalue *factor,
|
||||||
|
const svalue *offset)
|
||||||
|
: m_base (base), m_factor (factor), m_offset (offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool maybe_get_cst_factor (bit_offset_t *out) const
|
||||||
|
{
|
||||||
|
if (m_factor == nullptr)
|
||||||
|
{
|
||||||
|
*out = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (tree cst_factor = m_factor->maybe_get_constant ())
|
||||||
|
{
|
||||||
|
*out = wi::to_offset (cst_factor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool maybe_get_cst_offset (bit_offset_t *out) const
|
||||||
|
{
|
||||||
|
if (m_offset == nullptr)
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (tree cst_offset = m_offset->maybe_get_constant ())
|
||||||
|
{
|
||||||
|
*out = wi::to_offset (cst_offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tristate
|
||||||
|
less (const linear_op &a, const linear_op &b)
|
||||||
|
{
|
||||||
|
/* Same base. */
|
||||||
|
if (a.m_base == b.m_base)
|
||||||
|
{
|
||||||
|
bit_offset_t a_wi_factor;
|
||||||
|
bit_offset_t b_wi_factor;
|
||||||
|
if (a.maybe_get_cst_factor (&a_wi_factor)
|
||||||
|
&& b.maybe_get_cst_factor (&b_wi_factor))
|
||||||
|
{
|
||||||
|
if (a_wi_factor != b_wi_factor)
|
||||||
|
return tristate (a_wi_factor < b_wi_factor);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bit_offset_t a_wi_offset;
|
||||||
|
bit_offset_t b_wi_offset;
|
||||||
|
if (a.maybe_get_cst_offset (&a_wi_offset)
|
||||||
|
&& b.maybe_get_cst_offset (&b_wi_offset))
|
||||||
|
return tristate (a_wi_offset < b_wi_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tristate::unknown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static tristate
|
||||||
|
le (const linear_op &a, const linear_op &b)
|
||||||
|
{
|
||||||
|
/* Same base. */
|
||||||
|
if (a.m_base == b.m_base)
|
||||||
|
{
|
||||||
|
bit_offset_t a_wi_factor;
|
||||||
|
bit_offset_t b_wi_factor;
|
||||||
|
if (a.maybe_get_cst_factor (&a_wi_factor)
|
||||||
|
&& b.maybe_get_cst_factor (&b_wi_factor))
|
||||||
|
{
|
||||||
|
if (a_wi_factor != b_wi_factor)
|
||||||
|
return tristate (a_wi_factor <= b_wi_factor);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bit_offset_t a_wi_offset;
|
||||||
|
bit_offset_t b_wi_offset;
|
||||||
|
if (a.maybe_get_cst_offset (&a_wi_offset)
|
||||||
|
&& b.maybe_get_cst_offset (&b_wi_offset))
|
||||||
|
return tristate (a_wi_offset <= b_wi_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tristate::unknown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
from_svalue (const svalue &sval, linear_op *out)
|
||||||
|
{
|
||||||
|
switch (sval.get_kind ())
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case SK_BINOP:
|
||||||
|
{
|
||||||
|
const binop_svalue &binop_sval ((const binop_svalue &)sval);
|
||||||
|
if (binop_sval.get_op () == MULT_EXPR)
|
||||||
|
{
|
||||||
|
*out = linear_op (binop_sval.get_arg0 (),
|
||||||
|
binop_sval.get_arg1 (),
|
||||||
|
NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (binop_sval.get_op () == PLUS_EXPR)
|
||||||
|
{
|
||||||
|
if (binop_sval.get_arg0 ()->get_kind () == SK_BINOP)
|
||||||
|
{
|
||||||
|
const binop_svalue &inner_binop_sval
|
||||||
|
((const binop_svalue &)*binop_sval.get_arg0 ());
|
||||||
|
if (inner_binop_sval.get_op () == MULT_EXPR)
|
||||||
|
{
|
||||||
|
*out = linear_op (inner_binop_sval.get_arg0 (),
|
||||||
|
inner_binop_sval.get_arg1 (),
|
||||||
|
binop_sval.get_arg1 ());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = linear_op (binop_sval.get_arg0 (),
|
||||||
|
NULL,
|
||||||
|
binop_sval.get_arg1 ());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const svalue *m_base;
|
||||||
|
const svalue *m_factor;
|
||||||
|
const svalue *m_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
operator< (const region_offset &a, const region_offset &b)
|
||||||
|
{
|
||||||
|
if (a.symbolic_p ())
|
||||||
|
{
|
||||||
|
if (b.symbolic_p ())
|
||||||
|
{
|
||||||
|
/* Symbolic vs symbolic. */
|
||||||
|
const svalue &a_sval = *a.get_symbolic_byte_offset ();
|
||||||
|
const svalue &b_sval = *b.get_symbolic_byte_offset ();
|
||||||
|
|
||||||
|
linear_op op_a (NULL, NULL, NULL);
|
||||||
|
linear_op op_b (NULL, NULL, NULL);
|
||||||
|
if (linear_op::from_svalue (a_sval, &op_a)
|
||||||
|
&& linear_op::from_svalue (b_sval, &op_b))
|
||||||
|
{
|
||||||
|
tristate ts = linear_op::less (op_a, op_b);
|
||||||
|
if (ts.is_true ())
|
||||||
|
return true;
|
||||||
|
else if (ts.is_false ())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Use svalue's deterministic order, for now. */
|
||||||
|
return (svalue::cmp_ptr (a.get_symbolic_byte_offset (),
|
||||||
|
b.get_symbolic_byte_offset ())
|
||||||
|
< 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Symbolic vs concrete: put all symbolic after all concrete. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (b.symbolic_p ())
|
||||||
|
/* Concrete vs symbolic: put all concrete before all symbolic. */
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
/* Concrete vs concrete. */
|
||||||
|
return a.get_bit_offset () < b.get_bit_offset ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
operator<= (const region_offset &a, const region_offset &b)
|
||||||
|
{
|
||||||
|
if (a.symbolic_p ())
|
||||||
|
{
|
||||||
|
if (b.symbolic_p ())
|
||||||
|
{
|
||||||
|
/* Symbolic vs symbolic. */
|
||||||
|
const svalue &a_sval = *a.get_symbolic_byte_offset ();
|
||||||
|
const svalue &b_sval = *b.get_symbolic_byte_offset ();
|
||||||
|
|
||||||
|
linear_op op_a (NULL, NULL, NULL);
|
||||||
|
linear_op op_b (NULL, NULL, NULL);
|
||||||
|
if (linear_op::from_svalue (a_sval, &op_a)
|
||||||
|
&& linear_op::from_svalue (b_sval, &op_b))
|
||||||
|
{
|
||||||
|
tristate ts = linear_op::le (op_a, op_b);
|
||||||
|
if (ts.is_true ())
|
||||||
|
return true;
|
||||||
|
else if (ts.is_false ())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Use svalue's deterministic order, for now. */
|
||||||
|
return (svalue::cmp_ptr (a.get_symbolic_byte_offset (),
|
||||||
|
b.get_symbolic_byte_offset ())
|
||||||
|
<= 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Symbolic vs concrete: put all symbolic after all concrete. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (b.symbolic_p ())
|
||||||
|
/* Concrete vs symbolic: put all concrete before all symbolic. */
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
/* Concrete vs concrete. */
|
||||||
|
return a.get_bit_offset () <= b.get_bit_offset ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
operator> (const region_offset &a, const region_offset &b)
|
||||||
|
{
|
||||||
|
return b < a;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
operator>= (const region_offset &a, const region_offset &b)
|
||||||
|
{
|
||||||
|
return b <= a;
|
||||||
|
}
|
||||||
|
|
||||||
/* class region and its various subclasses. */
|
/* class region and its various subclasses. */
|
||||||
|
|
||||||
/* class region. */
|
/* class region. */
|
||||||
|
|
@ -339,6 +665,35 @@ region::get_offset (region_model_manager *mgr) const
|
||||||
return *m_cached_offset;
|
return *m_cached_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the region_offset for immediately beyond this region. */
|
||||||
|
|
||||||
|
region_offset
|
||||||
|
region::get_next_offset (region_model_manager *mgr) const
|
||||||
|
{
|
||||||
|
region_offset start = get_offset (mgr);
|
||||||
|
|
||||||
|
bit_size_t bit_size;
|
||||||
|
if (get_bit_size (&bit_size))
|
||||||
|
{
|
||||||
|
if (start.concrete_p ())
|
||||||
|
{
|
||||||
|
bit_offset_t next_bit_offset = start.get_bit_offset () + bit_size;
|
||||||
|
return region_offset::make_concrete (start.get_base_region (),
|
||||||
|
next_bit_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const svalue *start_byte_offset_sval = start.calc_symbolic_byte_offset (mgr);
|
||||||
|
const svalue *byte_size_sval = get_byte_size_sval (mgr);
|
||||||
|
const svalue *sum_sval
|
||||||
|
= mgr->get_or_create_binop (size_type_node,
|
||||||
|
PLUS_EXPR,
|
||||||
|
start_byte_offset_sval,
|
||||||
|
byte_size_sval);
|
||||||
|
return region_offset::make_symbolic (start.get_base_region (),
|
||||||
|
sum_sval);
|
||||||
|
}
|
||||||
|
|
||||||
/* Base class implementation of region::get_byte_size vfunc.
|
/* Base class implementation of region::get_byte_size vfunc.
|
||||||
If the size of this region (in bytes) is known statically, write it to *OUT
|
If the size of this region (in bytes) is known statically, write it to *OUT
|
||||||
and return true.
|
and return true.
|
||||||
|
|
@ -617,7 +972,7 @@ region::get_relative_concrete_offset (bit_offset_t *) const
|
||||||
const svalue *
|
const svalue *
|
||||||
region::get_relative_symbolic_offset (region_model_manager *mgr) const
|
region::get_relative_symbolic_offset (region_model_manager *mgr) const
|
||||||
{
|
{
|
||||||
return mgr->get_or_create_unknown_svalue (integer_type_node);
|
return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to get the position and size of this region expressed as a
|
/* Attempt to get the position and size of this region expressed as a
|
||||||
|
|
@ -1448,10 +1803,10 @@ field_region::get_relative_symbolic_offset (region_model_manager *mgr) const
|
||||||
if (get_relative_concrete_offset (&out))
|
if (get_relative_concrete_offset (&out))
|
||||||
{
|
{
|
||||||
tree cst_tree
|
tree cst_tree
|
||||||
= wide_int_to_tree (integer_type_node, out / BITS_PER_UNIT);
|
= wide_int_to_tree (ptrdiff_type_node, out / BITS_PER_UNIT);
|
||||||
return mgr->get_or_create_constant_svalue (cst_tree);
|
return mgr->get_or_create_constant_svalue (cst_tree);
|
||||||
}
|
}
|
||||||
return mgr->get_or_create_unknown_svalue (integer_type_node);
|
return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* class element_region : public region. */
|
/* class element_region : public region. */
|
||||||
|
|
@ -1533,14 +1888,14 @@ element_region::get_relative_symbolic_offset (region_model_manager *mgr) const
|
||||||
HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
|
HOST_WIDE_INT hwi_byte_size = int_size_in_bytes (elem_type);
|
||||||
if (hwi_byte_size > 0)
|
if (hwi_byte_size > 0)
|
||||||
{
|
{
|
||||||
tree byte_size_tree = wide_int_to_tree (integer_type_node,
|
tree byte_size_tree = wide_int_to_tree (ptrdiff_type_node,
|
||||||
hwi_byte_size);
|
hwi_byte_size);
|
||||||
const svalue *byte_size_sval
|
const svalue *byte_size_sval
|
||||||
= mgr->get_or_create_constant_svalue (byte_size_tree);
|
= mgr->get_or_create_constant_svalue (byte_size_tree);
|
||||||
return mgr->get_or_create_binop (integer_type_node, MULT_EXPR,
|
return mgr->get_or_create_binop (ptrdiff_type_node, MULT_EXPR,
|
||||||
m_index, byte_size_sval);
|
m_index, byte_size_sval);
|
||||||
}
|
}
|
||||||
return mgr->get_or_create_unknown_svalue (integer_type_node);
|
return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* class offset_region : public region. */
|
/* class offset_region : public region. */
|
||||||
|
|
@ -1864,7 +2219,7 @@ bit_range_region::get_relative_symbolic_offset (region_model_manager *mgr)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
byte_offset_t start_byte = m_bits.get_start_bit_offset () / BITS_PER_UNIT;
|
byte_offset_t start_byte = m_bits.get_start_bit_offset () / BITS_PER_UNIT;
|
||||||
tree start_bit_tree = wide_int_to_tree (integer_type_node, start_byte);
|
tree start_bit_tree = wide_int_to_tree (ptrdiff_type_node, start_byte);
|
||||||
return mgr->get_or_create_constant_svalue (start_bit_tree);
|
return mgr->get_or_create_constant_svalue (start_bit_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,7 @@ public:
|
||||||
bool involves_p (const svalue *sval) const;
|
bool involves_p (const svalue *sval) const;
|
||||||
|
|
||||||
region_offset get_offset (region_model_manager *mgr) const;
|
region_offset get_offset (region_model_manager *mgr) const;
|
||||||
|
region_offset get_next_offset (region_model_manager *mgr) const;
|
||||||
|
|
||||||
/* Attempt to get the size of this region as a concrete number of bytes.
|
/* Attempt to get the size of this region as a concrete number of bytes.
|
||||||
If successful, return true and write the size to *OUT.
|
If successful, return true and write the size to *OUT.
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/*CWE-775: Missing Release of File Descriptor or Handle after Effective
|
/*CWE-775: Missing Release of File Descriptor or Handle after Effective
|
||||||
Lifetime
|
Lifetime
|
||||||
|
|
@ -550,7 +550,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
bool warned;
|
bool warned;
|
||||||
switch (m_fd_dir)
|
switch (m_fd_dir)
|
||||||
|
|
@ -612,7 +612,7 @@ public:
|
||||||
return OPT_Wanalyzer_fd_double_close;
|
return OPT_Wanalyzer_fd_double_close;
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
// CWE-1341: Multiple Releases of Same Resource or Handle
|
// CWE-1341: Multiple Releases of Same Resource or Handle
|
||||||
|
|
@ -677,7 +677,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
bool warned;
|
bool warned;
|
||||||
warned = warning_at (rich_loc, get_controlling_option (),
|
warned = warning_at (rich_loc, get_controlling_option (),
|
||||||
|
|
@ -748,7 +748,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
bool warned;
|
bool warned;
|
||||||
warned = warning_at (rich_loc, get_controlling_option (),
|
warned = warning_at (rich_loc, get_controlling_option (),
|
||||||
|
|
@ -859,7 +859,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* CWE-666: Operation on Resource in Wrong Phase of Lifetime. */
|
/* CWE-666: Operation on Resource in Wrong Phase of Lifetime. */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1019,7 +1019,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
emit (rich_location *rich_loc) final override
|
emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
switch (m_expected_type)
|
switch (m_expected_type)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ public:
|
||||||
return OPT_Wanalyzer_double_fclose;
|
return OPT_Wanalyzer_double_fclose;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-1341: Multiple Releases of Same Resource or Handle. */
|
/* CWE-1341: Multiple Releases of Same Resource or Handle. */
|
||||||
|
|
@ -224,7 +224,7 @@ public:
|
||||||
return OPT_Wanalyzer_file_leak;
|
return OPT_Wanalyzer_file_leak;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-775: "Missing Release of File Descriptor or Handle after
|
/* CWE-775: "Missing Release of File Descriptor or Handle after
|
||||||
|
|
|
||||||
|
|
@ -835,7 +835,7 @@ public:
|
||||||
return OPT_Wanalyzer_mismatching_deallocation;
|
return OPT_Wanalyzer_mismatching_deallocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -914,7 +914,7 @@ public:
|
||||||
return OPT_Wanalyzer_double_free;
|
return OPT_Wanalyzer_double_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1010,7 +1010,7 @@ public:
|
||||||
return OPT_Wanalyzer_possible_null_dereference;
|
return OPT_Wanalyzer_possible_null_dereference;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
|
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1099,7 +1099,7 @@ public:
|
||||||
return OPT_Wanalyzer_possible_null_argument;
|
return OPT_Wanalyzer_possible_null_argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
|
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
|
|
@ -1152,7 +1152,7 @@ public:
|
||||||
|
|
||||||
bool terminate_path_p () const final override { return true; }
|
bool terminate_path_p () const final override { return true; }
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* CWE-476: NULL Pointer Dereference. */
|
/* CWE-476: NULL Pointer Dereference. */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1207,7 +1207,7 @@ public:
|
||||||
|
|
||||||
bool terminate_path_p () const final override { return true; }
|
bool terminate_path_p () const final override { return true; }
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* CWE-476: NULL Pointer Dereference. */
|
/* CWE-476: NULL Pointer Dereference. */
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
|
|
@ -1264,7 +1264,7 @@ public:
|
||||||
return OPT_Wanalyzer_use_after_free;
|
return OPT_Wanalyzer_use_after_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* CWE-416: Use After Free. */
|
/* CWE-416: Use After Free. */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1358,7 +1358,7 @@ public:
|
||||||
return OPT_Wanalyzer_malloc_leak;
|
return OPT_Wanalyzer_malloc_leak;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* "CWE-401: Missing Release of Memory after Effective Lifetime". */
|
/* "CWE-401: Missing Release of Memory after Effective Lifetime". */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1432,7 +1432,7 @@ public:
|
||||||
return OPT_Wanalyzer_free_of_non_heap;
|
return OPT_Wanalyzer_free_of_non_heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -1511,7 +1511,7 @@ public:
|
||||||
return OPT_Wanalyzer_deref_before_check;
|
return OPT_Wanalyzer_deref_before_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
/* Don't emit the warning if we can't show where the deref
|
/* Don't emit the warning if we can't show where the deref
|
||||||
and the check occur. */
|
and the check occur. */
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
"pattern match on %<%E %s %E%>",
|
"pattern match on %<%E %s %E%>",
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,8 @@ public:
|
||||||
return OPT_Wanalyzer_exposure_through_output_file;
|
return OPT_Wanalyzer_exposure_through_output_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc,
|
||||||
|
logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-532: Information Exposure Through Log Files */
|
/* CWE-532: Information Exposure Through Log Files */
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ public:
|
||||||
return OPT_Wanalyzer_unsafe_call_within_signal_handler;
|
return OPT_Wanalyzer_unsafe_call_within_signal_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ public:
|
||||||
return OPT_Wanalyzer_tainted_array_index;
|
return OPT_Wanalyzer_tainted_array_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-129: "Improper Validation of Array Index". */
|
/* CWE-129: "Improper Validation of Array Index". */
|
||||||
|
|
@ -327,7 +327,7 @@ public:
|
||||||
return OPT_Wanalyzer_tainted_offset;
|
return OPT_Wanalyzer_tainted_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-823: "Use of Out-of-range Pointer Offset". */
|
/* CWE-823: "Use of Out-of-range Pointer Offset". */
|
||||||
|
|
@ -437,7 +437,7 @@ public:
|
||||||
return OPT_Wanalyzer_tainted_size;
|
return OPT_Wanalyzer_tainted_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) override
|
bool emit (rich_location *rich_loc, logger *) override
|
||||||
{
|
{
|
||||||
/* "CWE-129: Improper Validation of Array Index". */
|
/* "CWE-129: Improper Validation of Array Index". */
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -547,9 +547,9 @@ public:
|
||||||
return "tainted_access_attrib_size";
|
return "tainted_access_attrib_size";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||||
{
|
{
|
||||||
bool warned = tainted_size::emit (rich_loc);
|
bool warned = tainted_size::emit (rich_loc, logger);
|
||||||
if (warned)
|
if (warned)
|
||||||
{
|
{
|
||||||
inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
|
inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
|
||||||
|
|
@ -583,7 +583,7 @@ public:
|
||||||
return OPT_Wanalyzer_tainted_divisor;
|
return OPT_Wanalyzer_tainted_divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* CWE-369: "Divide By Zero". */
|
/* CWE-369: "Divide By Zero". */
|
||||||
|
|
@ -645,7 +645,7 @@ public:
|
||||||
return OPT_Wanalyzer_tainted_allocation_size;
|
return OPT_Wanalyzer_tainted_allocation_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* "CWE-789: Memory Allocation with Excessive Size Value". */
|
/* "CWE-789: Memory Allocation with Excessive Size Value". */
|
||||||
|
|
@ -800,7 +800,7 @@ public:
|
||||||
return OPT_Wanalyzer_tainted_assertion;
|
return OPT_Wanalyzer_tainted_assertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
/* "CWE-617: Reachable Assertion". */
|
/* "CWE-617: Reachable Assertion". */
|
||||||
|
|
|
||||||
|
|
@ -236,8 +236,8 @@ bit_range::dump () const
|
||||||
pp_flush (&pp);
|
pp_flush (&pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If OTHER is a subset of this, return true and write
|
/* If OTHER is a subset of this, return true and, if OUT is
|
||||||
to *OUT the relative range of OTHER within this.
|
non-null, write to *OUT the relative range of OTHER within this.
|
||||||
Otherwise return false. */
|
Otherwise return false. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -246,8 +246,11 @@ bit_range::contains_p (const bit_range &other, bit_range *out) const
|
||||||
if (contains_p (other.get_start_bit_offset ())
|
if (contains_p (other.get_start_bit_offset ())
|
||||||
&& contains_p (other.get_last_bit_offset ()))
|
&& contains_p (other.get_last_bit_offset ()))
|
||||||
{
|
{
|
||||||
out->m_start_bit_offset = other.m_start_bit_offset - m_start_bit_offset;
|
if (out)
|
||||||
out->m_size_in_bits = other.m_size_in_bits;
|
{
|
||||||
|
out->m_start_bit_offset = other.m_start_bit_offset - m_start_bit_offset;
|
||||||
|
out->m_size_in_bits = other.m_size_in_bits;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -350,6 +350,15 @@ struct byte_range
|
||||||
m_size_in_bytes * BITS_PER_UNIT);
|
m_size_in_bytes * BITS_PER_UNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bit_offset_t get_start_bit_offset () const
|
||||||
|
{
|
||||||
|
return m_start_byte_offset * BITS_PER_UNIT;
|
||||||
|
}
|
||||||
|
bit_offset_t get_next_bit_offset () const
|
||||||
|
{
|
||||||
|
return get_next_byte_offset () * BITS_PER_UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmp (const byte_range &br1, const byte_range &br2);
|
static int cmp (const byte_range &br1, const byte_range &br2);
|
||||||
|
|
||||||
byte_offset_t m_start_byte_offset;
|
byte_offset_t m_start_byte_offset;
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,7 @@ public:
|
||||||
&& 0 == strcmp (m_usage_fnname, other.m_usage_fnname));
|
&& 0 == strcmp (m_usage_fnname, other.m_usage_fnname));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
|
|
@ -478,7 +478,7 @@ public:
|
||||||
return va_list_sm_diagnostic::subclass_equal_p (other);
|
return va_list_sm_diagnostic::subclass_equal_p (other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
return warning_at (rich_loc, get_controlling_option (),
|
return warning_at (rich_loc, get_controlling_option (),
|
||||||
|
|
@ -892,7 +892,7 @@ public:
|
||||||
return OPT_Wanalyzer_va_arg_type_mismatch;
|
return OPT_Wanalyzer_va_arg_type_mismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
@ -942,7 +942,7 @@ public:
|
||||||
return OPT_Wanalyzer_va_list_exhausted;
|
return OPT_Wanalyzer_va_list_exhausted;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emit (rich_location *rich_loc) final override
|
bool emit (rich_location *rich_loc, logger *) final override
|
||||||
{
|
{
|
||||||
auto_diagnostic_group d;
|
auto_diagnostic_group d;
|
||||||
diagnostic_metadata m;
|
diagnostic_metadata m;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,21 @@
|
||||||
|
2023-06-23 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
|
* c-common.h (cxx_dialect): Add cxx26 as a dialect.
|
||||||
|
* c-opts.cc (set_std_cxx26): New.
|
||||||
|
(c_common_handle_option): Set options when -std={c,gnu}++2{c,6} is
|
||||||
|
enabled.
|
||||||
|
(c_common_post_options): Adjust comments.
|
||||||
|
* c.opt: Add options for -std=c++26, std=c++2c, -std=gnu++26,
|
||||||
|
and -std=gnu++2c.
|
||||||
|
(std=c++2b): Mark as Undocumented.
|
||||||
|
(std=c++23): No longer Undocumented.
|
||||||
|
|
||||||
|
2023-06-21 Alexander Monakov <amonakov@ispras.ru>
|
||||||
|
|
||||||
|
* c-gimplify.cc (fma_supported_p): New helper.
|
||||||
|
(c_gimplify_expr) [PLUS_EXPR, MINUS_EXPR]: Implement FMA
|
||||||
|
contraction.
|
||||||
|
|
||||||
2023-06-16 Alex Coplan <alex.coplan@arm.com>
|
2023-06-16 Alex Coplan <alex.coplan@arm.com>
|
||||||
|
|
||||||
* c.opt (Welaborated-enum-base): New.
|
* c.opt (Welaborated-enum-base): New.
|
||||||
|
|
|
||||||
|
|
@ -1338,6 +1338,10 @@ shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
|
||||||
int uns;
|
int uns;
|
||||||
tree type;
|
tree type;
|
||||||
|
|
||||||
|
/* Do not shorten vector operations. */
|
||||||
|
if (VECTOR_TYPE_P (result_type))
|
||||||
|
return result_type;
|
||||||
|
|
||||||
/* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
|
/* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents
|
||||||
excessive narrowing when we call get_narrower below. For
|
excessive narrowing when we call get_narrower below. For
|
||||||
example, suppose that OP0 is of unsigned int extended
|
example, suppose that OP0 is of unsigned int extended
|
||||||
|
|
|
||||||
|
|
@ -740,7 +740,9 @@ enum cxx_dialect {
|
||||||
/* C++20 */
|
/* C++20 */
|
||||||
cxx20,
|
cxx20,
|
||||||
/* C++23 */
|
/* C++23 */
|
||||||
cxx23
|
cxx23,
|
||||||
|
/* C++26 */
|
||||||
|
cxx26
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The C++ dialect being used. C++98 is the default. */
|
/* The C++ dialect being used. C++98 is the default. */
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "c-ubsan.h"
|
#include "c-ubsan.h"
|
||||||
#include "tree-nested.h"
|
#include "tree-nested.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
#include "tree-pass.h"
|
||||||
|
#include "internal-fn.h"
|
||||||
|
|
||||||
/* The gimplification pass converts the language-dependent trees
|
/* The gimplification pass converts the language-dependent trees
|
||||||
(ld-trees) emitted by the parser into language-independent trees
|
(ld-trees) emitted by the parser into language-independent trees
|
||||||
|
|
@ -686,6 +688,14 @@ c_build_bind_expr (location_t loc, tree block, tree body)
|
||||||
return bind;
|
return bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper for c_gimplify_expr: test if target supports fma-like FN. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
fma_supported_p (enum internal_fn fn, tree type)
|
||||||
|
{
|
||||||
|
return direct_internal_fn_supported_p (fn, type, OPTIMIZE_FOR_BOTH);
|
||||||
|
}
|
||||||
|
|
||||||
/* Gimplification of expression trees. */
|
/* Gimplification of expression trees. */
|
||||||
|
|
||||||
/* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in
|
/* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in
|
||||||
|
|
@ -739,6 +749,75 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PLUS_EXPR:
|
||||||
|
case MINUS_EXPR:
|
||||||
|
{
|
||||||
|
tree type = TREE_TYPE (*expr_p);
|
||||||
|
/* For -ffp-contract=on we need to attempt FMA contraction only
|
||||||
|
during initial gimplification. Late contraction across statement
|
||||||
|
boundaries would violate language semantics. */
|
||||||
|
if (SCALAR_FLOAT_TYPE_P (type)
|
||||||
|
&& flag_fp_contract_mode == FP_CONTRACT_ON
|
||||||
|
&& cfun && !(cfun->curr_properties & PROP_gimple_any)
|
||||||
|
&& fma_supported_p (IFN_FMA, type))
|
||||||
|
{
|
||||||
|
bool neg_mul = false, neg_add = code == MINUS_EXPR;
|
||||||
|
|
||||||
|
tree *op0_p = &TREE_OPERAND (*expr_p, 0);
|
||||||
|
tree *op1_p = &TREE_OPERAND (*expr_p, 1);
|
||||||
|
|
||||||
|
/* Look for ±(x * y) ± z, swapping operands if necessary. */
|
||||||
|
if (TREE_CODE (*op0_p) == NEGATE_EXPR
|
||||||
|
&& TREE_CODE (TREE_OPERAND (*op0_p, 0)) == MULT_EXPR)
|
||||||
|
/* '*EXPR_P' is '-(x * y) ± z'. This is fine. */;
|
||||||
|
else if (TREE_CODE (*op0_p) != MULT_EXPR)
|
||||||
|
{
|
||||||
|
std::swap (op0_p, op1_p);
|
||||||
|
std::swap (neg_mul, neg_add);
|
||||||
|
}
|
||||||
|
if (TREE_CODE (*op0_p) == NEGATE_EXPR)
|
||||||
|
{
|
||||||
|
op0_p = &TREE_OPERAND (*op0_p, 0);
|
||||||
|
neg_mul = !neg_mul;
|
||||||
|
}
|
||||||
|
if (TREE_CODE (*op0_p) != MULT_EXPR)
|
||||||
|
break;
|
||||||
|
auto_vec<tree, 3> ops (3);
|
||||||
|
ops.quick_push (TREE_OPERAND (*op0_p, 0));
|
||||||
|
ops.quick_push (TREE_OPERAND (*op0_p, 1));
|
||||||
|
ops.quick_push (*op1_p);
|
||||||
|
|
||||||
|
enum internal_fn ifn = IFN_FMA;
|
||||||
|
if (neg_mul)
|
||||||
|
{
|
||||||
|
if (fma_supported_p (IFN_FNMA, type))
|
||||||
|
ifn = IFN_FNMA;
|
||||||
|
else
|
||||||
|
ops[0] = build1 (NEGATE_EXPR, type, ops[0]);
|
||||||
|
}
|
||||||
|
if (neg_add)
|
||||||
|
{
|
||||||
|
enum internal_fn ifn2 = ifn == IFN_FMA ? IFN_FMS : IFN_FNMS;
|
||||||
|
if (fma_supported_p (ifn2, type))
|
||||||
|
ifn = ifn2;
|
||||||
|
else
|
||||||
|
ops[2] = build1 (NEGATE_EXPR, type, ops[2]);
|
||||||
|
}
|
||||||
|
/* Avoid gimplify_arg: it emits all side effects into *PRE_P. */
|
||||||
|
for (auto &&op : ops)
|
||||||
|
if (gimplify_expr (&op, pre_p, post_p, is_gimple_val, fb_rvalue)
|
||||||
|
== GS_ERROR)
|
||||||
|
return GS_ERROR;
|
||||||
|
|
||||||
|
gcall *call = gimple_build_call_internal_vec (ifn, ops);
|
||||||
|
gimple_seq_add_stmt_without_update (pre_p, call);
|
||||||
|
*expr_p = create_tmp_var (type);
|
||||||
|
gimple_call_set_lhs (call, *expr_p);
|
||||||
|
return GS_ALL_DONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ static void set_std_cxx14 (int);
|
||||||
static void set_std_cxx17 (int);
|
static void set_std_cxx17 (int);
|
||||||
static void set_std_cxx20 (int);
|
static void set_std_cxx20 (int);
|
||||||
static void set_std_cxx23 (int);
|
static void set_std_cxx23 (int);
|
||||||
|
static void set_std_cxx26 (int);
|
||||||
static void set_std_c89 (int, int);
|
static void set_std_c89 (int, int);
|
||||||
static void set_std_c99 (int);
|
static void set_std_c99 (int);
|
||||||
static void set_std_c11 (int);
|
static void set_std_c11 (int);
|
||||||
|
|
@ -663,6 +664,12 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
|
||||||
set_std_cxx23 (code == OPT_std_c__23 /* ISO */);
|
set_std_cxx23 (code == OPT_std_c__23 /* ISO */);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_std_c__26:
|
||||||
|
case OPT_std_gnu__26:
|
||||||
|
if (!preprocessing_asm_p)
|
||||||
|
set_std_cxx26 (code == OPT_std_c__26 /* ISO */);
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_std_c90:
|
case OPT_std_c90:
|
||||||
case OPT_std_iso9899_199409:
|
case OPT_std_iso9899_199409:
|
||||||
if (!preprocessing_asm_p)
|
if (!preprocessing_asm_p)
|
||||||
|
|
@ -1032,7 +1039,8 @@ c_common_post_options (const char **pfilename)
|
||||||
warn_narrowing = 1;
|
warn_narrowing = 1;
|
||||||
|
|
||||||
/* Unless -f{,no-}ext-numeric-literals has been used explicitly,
|
/* Unless -f{,no-}ext-numeric-literals has been used explicitly,
|
||||||
for -std=c++{11,14,17,20,23} default to -fno-ext-numeric-literals. */
|
for -std=c++{11,14,17,20,23,26} default to
|
||||||
|
-fno-ext-numeric-literals. */
|
||||||
if (flag_iso && !OPTION_SET_P (flag_ext_numeric_literals))
|
if (flag_iso && !OPTION_SET_P (flag_ext_numeric_literals))
|
||||||
cpp_opts->ext_numeric_literals = 0;
|
cpp_opts->ext_numeric_literals = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1820,6 +1828,24 @@ set_std_cxx23 (int iso)
|
||||||
lang_hooks.name = "GNU C++23";
|
lang_hooks.name = "GNU C++23";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the C++ 2026 standard (without GNU extensions if ISO). */
|
||||||
|
static void
|
||||||
|
set_std_cxx26 (int iso)
|
||||||
|
{
|
||||||
|
cpp_set_lang (parse_in, iso ? CLK_CXX26: CLK_GNUCXX26);
|
||||||
|
flag_no_gnu_keywords = iso;
|
||||||
|
flag_no_nonansi_builtin = iso;
|
||||||
|
flag_iso = iso;
|
||||||
|
/* C++26 includes the C11 standard library. */
|
||||||
|
flag_isoc94 = 1;
|
||||||
|
flag_isoc99 = 1;
|
||||||
|
flag_isoc11 = 1;
|
||||||
|
/* C++26 includes coroutines. */
|
||||||
|
flag_coroutines = true;
|
||||||
|
cxx_dialect = cxx26;
|
||||||
|
lang_hooks.name = "GNU C++26";
|
||||||
|
}
|
||||||
|
|
||||||
/* Args to -d specify what to dump. Silently ignore
|
/* Args to -d specify what to dump. Silently ignore
|
||||||
unrecognized options; they may be aimed at toplev.cc. */
|
unrecognized options; they may be aimed at toplev.cc. */
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -2403,13 +2403,21 @@ C++ ObjC++
|
||||||
Conform to the ISO 2020 C++ standard (experimental and incomplete support).
|
Conform to the ISO 2020 C++ standard (experimental and incomplete support).
|
||||||
|
|
||||||
std=c++2b
|
std=c++2b
|
||||||
C++ ObjC++ Alias(std=c++23)
|
C++ ObjC++ Alias(std=c++23) Undocumented
|
||||||
Conform to the ISO 2023 C++ draft standard (experimental and incomplete support).
|
Conform to the ISO 2023 C++ draft standard (experimental and incomplete support).
|
||||||
|
|
||||||
std=c++23
|
std=c++23
|
||||||
C++ ObjC++ Undocumented
|
C++ ObjC++
|
||||||
Conform to the ISO 2023 C++ draft standard (experimental and incomplete support).
|
Conform to the ISO 2023 C++ draft standard (experimental and incomplete support).
|
||||||
|
|
||||||
|
std=c++2c
|
||||||
|
C++ ObjC++ Alias(std=c++26)
|
||||||
|
Conform to the ISO 2026 C++ draft standard (experimental and incomplete support).
|
||||||
|
|
||||||
|
std=c++26
|
||||||
|
C++ ObjC++ Undocumented
|
||||||
|
Conform to the ISO 2026 C++ draft standard (experimental and incomplete support).
|
||||||
|
|
||||||
std=c11
|
std=c11
|
||||||
C ObjC
|
C ObjC
|
||||||
Conform to the ISO 2011 C standard.
|
Conform to the ISO 2011 C standard.
|
||||||
|
|
@ -2489,13 +2497,21 @@ C++ ObjC++
|
||||||
Conform to the ISO 2020 C++ standard with GNU extensions (experimental and incomplete support).
|
Conform to the ISO 2020 C++ standard with GNU extensions (experimental and incomplete support).
|
||||||
|
|
||||||
std=gnu++2b
|
std=gnu++2b
|
||||||
C++ ObjC++ Alias(std=gnu++23)
|
C++ ObjC++ Alias(std=gnu++23) Undocumented
|
||||||
Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support).
|
Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support).
|
||||||
|
|
||||||
std=gnu++23
|
std=gnu++23
|
||||||
C++ ObjC++ Undocumented
|
C++ ObjC++
|
||||||
Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support).
|
Conform to the ISO 2023 C++ draft standard with GNU extensions (experimental and incomplete support).
|
||||||
|
|
||||||
|
std=gnu++2c
|
||||||
|
C++ ObjC++ Alias(std=gnu++26)
|
||||||
|
Conform to the ISO 2026 C++ draft standard with GNU extensions (experimental and incomplete support).
|
||||||
|
|
||||||
|
std=gnu++26
|
||||||
|
C++ ObjC++ Undocumented
|
||||||
|
Conform to the ISO 2026 C++ draft standard with GNU extensions (experimental and incomplete support).
|
||||||
|
|
||||||
std=gnu11
|
std=gnu11
|
||||||
C ObjC
|
C ObjC
|
||||||
Conform to the ISO 2011 C standard with GNU extensions.
|
Conform to the ISO 2011 C standard with GNU extensions.
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,14 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#define COLOR_FG_MAGENTA "35"
|
#define COLOR_FG_MAGENTA "35"
|
||||||
#define COLOR_FG_CYAN "36"
|
#define COLOR_FG_CYAN "36"
|
||||||
#define COLOR_FG_WHITE "37"
|
#define COLOR_FG_WHITE "37"
|
||||||
|
#define COLOR_FG_BRIGHT_BLACK "90"
|
||||||
|
#define COLOR_FG_BRIGHT_RED "91"
|
||||||
|
#define COLOR_FG_BRIGHT_GREEN "92"
|
||||||
|
#define COLOR_FG_BRIGHT_YELLOW "93"
|
||||||
|
#define COLOR_FG_BRIGHT_BLUE "94"
|
||||||
|
#define COLOR_FG_BRIGHT_MAGENTA "95"
|
||||||
|
#define COLOR_FG_BRIGHT_CYAN "96"
|
||||||
|
#define COLOR_FG_BRIGHT_WHITE "97"
|
||||||
#define COLOR_BG_BLACK "40"
|
#define COLOR_BG_BLACK "40"
|
||||||
#define COLOR_BG_RED "41"
|
#define COLOR_BG_RED "41"
|
||||||
#define COLOR_BG_GREEN "42"
|
#define COLOR_BG_GREEN "42"
|
||||||
|
|
@ -100,6 +108,14 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#define COLOR_BG_MAGENTA "45"
|
#define COLOR_BG_MAGENTA "45"
|
||||||
#define COLOR_BG_CYAN "46"
|
#define COLOR_BG_CYAN "46"
|
||||||
#define COLOR_BG_WHITE "47"
|
#define COLOR_BG_WHITE "47"
|
||||||
|
#define COLOR_BG_BRIGHT_BLACK "100"
|
||||||
|
#define COLOR_BG_BRIGHT_RED "101"
|
||||||
|
#define COLOR_BG_BRIGHT_GREEN "102"
|
||||||
|
#define COLOR_BG_BRIGHT_YELLOW "103"
|
||||||
|
#define COLOR_BG_BRIGHT_BLUE "104"
|
||||||
|
#define COLOR_BG_BRIGHT_MAGENTA "105"
|
||||||
|
#define COLOR_BG_BRIGHT_CYAN "106"
|
||||||
|
#define COLOR_BG_BRIGHT_WHITE "107"
|
||||||
#define SGR_START "\33["
|
#define SGR_START "\33["
|
||||||
#define SGR_END "m\33[K"
|
#define SGR_END "m\33[K"
|
||||||
#define SGR_SEQ(str) SGR_START str SGR_END
|
#define SGR_SEQ(str) SGR_START str SGR_END
|
||||||
|
|
|
||||||
|
|
@ -1502,6 +1502,29 @@ fdiagnostics-show-path-depths
|
||||||
Common Var(flag_diagnostics_show_path_depths) Init(0)
|
Common Var(flag_diagnostics_show_path_depths) Init(0)
|
||||||
Show stack depths of events in paths.
|
Show stack depths of events in paths.
|
||||||
|
|
||||||
|
fdiagnostics-text-art-charset=
|
||||||
|
Driver Common Joined RejectNegative Var(flag_diagnostics_text_art_charset) Enum(diagnostic_text_art_charset) Init(DIAGNOSTICS_TEXT_ART_CHARSET_EMOJI)
|
||||||
|
-fdiagnostics-text-art-charset=[none|ascii|unicode|emoji] Determine which characters to use in text arg diagrams.
|
||||||
|
|
||||||
|
; Required for these enum values.
|
||||||
|
SourceInclude
|
||||||
|
diagnostic-text-art.h
|
||||||
|
|
||||||
|
Enum
|
||||||
|
Name(diagnostic_text_art_charset) Type(int)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(diagnostic_text_art_charset) String(none) Value(DIAGNOSTICS_TEXT_ART_CHARSET_NONE)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(diagnostic_text_art_charset) String(ascii) Value(DIAGNOSTICS_TEXT_ART_CHARSET_ASCII)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(diagnostic_text_art_charset) String(unicode) Value(DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE)
|
||||||
|
|
||||||
|
EnumValue
|
||||||
|
Enum(diagnostic_text_art_charset) String(emoji) Value(DIAGNOSTICS_TEXT_ART_CHARSET_EMOJI)
|
||||||
|
|
||||||
fdiagnostics-minimum-margin-width=
|
fdiagnostics-minimum-margin-width=
|
||||||
Common Joined UInteger Var(diagnostics_minimum_margin_width) Init(6)
|
Common Joined UInteger Var(diagnostics_minimum_margin_width) Init(6)
|
||||||
Set minimum width of left margin of source code when showing source.
|
Set minimum width of left margin of source code when showing source.
|
||||||
|
|
@ -1662,9 +1685,8 @@ Name(fp_contract_mode) Type(enum fp_contract_mode) UnknownError(unknown floating
|
||||||
EnumValue
|
EnumValue
|
||||||
Enum(fp_contract_mode) String(off) Value(FP_CONTRACT_OFF)
|
Enum(fp_contract_mode) String(off) Value(FP_CONTRACT_OFF)
|
||||||
|
|
||||||
; Not implemented, fall back to conservative FP_CONTRACT_OFF.
|
|
||||||
EnumValue
|
EnumValue
|
||||||
Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_OFF)
|
Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_ON)
|
||||||
|
|
||||||
EnumValue
|
EnumValue
|
||||||
Enum(fp_contract_mode) String(fast) Value(FP_CONTRACT_FAST)
|
Enum(fp_contract_mode) String(fast) Value(FP_CONTRACT_FAST)
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,7 @@ bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
|
||||||
bool aarch64_const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT,
|
bool aarch64_const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT,
|
||||||
HOST_WIDE_INT);
|
HOST_WIDE_INT);
|
||||||
bool aarch64_const_vec_rnd_cst_p (rtx, rtx);
|
bool aarch64_const_vec_rnd_cst_p (rtx, rtx);
|
||||||
bool aarch64_const_vec_rsra_rnd_imm_p (rtx);
|
bool aarch64_rnd_imm_p (rtx);
|
||||||
bool aarch64_constant_address_p (rtx);
|
bool aarch64_constant_address_p (rtx);
|
||||||
bool aarch64_emit_approx_div (rtx, rtx, rtx);
|
bool aarch64_emit_approx_div (rtx, rtx, rtx);
|
||||||
bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
|
bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
|
||||||
|
|
|
||||||
|
|
@ -1323,7 +1323,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(<SHIFTEXTEND>:<V2XWIDE>
|
(<SHIFTEXTEND>:<V2XWIDE>
|
||||||
(match_operand:VSDQ_I_DI 2 "register_operand" "w"))
|
(match_operand:VSDQ_I_DI 2 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VSDQ_I_DI 3 "aarch64_simd_shift_imm_<vec_or_offset>_<Vel>")))
|
(match_operand:VSDQ_I_DI 3 "aarch64_simd_shift_imm_<vec_or_offset>_<Vel>")))
|
||||||
(match_operand:VSDQ_I_DI 1 "register_operand" "0")))]
|
(match_operand:VSDQ_I_DI 1 "register_operand" "0")))]
|
||||||
"TARGET_SIMD
|
"TARGET_SIMD
|
||||||
|
|
@ -6437,7 +6437,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(<SHIFTEXTEND>:<V2XWIDE>
|
(<SHIFTEXTEND>:<V2XWIDE>
|
||||||
(match_operand:VSDQ_I_DI 1 "register_operand" "w"))
|
(match_operand:VSDQ_I_DI 1 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VSDQ_I_DI 2 "aarch64_simd_shift_imm_<vec_or_offset>_<Vel>"))))]
|
(match_operand:VSDQ_I_DI 2 "aarch64_simd_shift_imm_<vec_or_offset>_<Vel>"))))]
|
||||||
"TARGET_SIMD
|
"TARGET_SIMD
|
||||||
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
||||||
|
|
@ -6557,7 +6557,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(<TRUNCEXTEND>:<V2XWIDE>
|
(<TRUNCEXTEND>:<V2XWIDE>
|
||||||
(match_operand:VQN 1 "register_operand" "w"))
|
(match_operand:VQN 1 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))))]
|
(match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))))]
|
||||||
"TARGET_SIMD
|
"TARGET_SIMD
|
||||||
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
||||||
|
|
@ -6572,7 +6572,7 @@
|
||||||
(plus:<DWI>
|
(plus:<DWI>
|
||||||
(<TRUNCEXTEND>:<DWI>
|
(<TRUNCEXTEND>:<DWI>
|
||||||
(match_operand:SD_HSDI 1 "register_operand" "w"))
|
(match_operand:SD_HSDI 1 "register_operand" "w"))
|
||||||
(match_operand:<DWI> 3 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<DWI> 3 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>"))))]
|
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>"))))]
|
||||||
"TARGET_SIMD
|
"TARGET_SIMD
|
||||||
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
||||||
|
|
@ -6702,7 +6702,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(sign_extend:<V2XWIDE>
|
(sign_extend:<V2XWIDE>
|
||||||
(match_operand:VQN 1 "register_operand" "w"))
|
(match_operand:VQN 1 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 3 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
|
(match_operand:VQN 2 "aarch64_simd_shift_imm_vec_<vn_mode>"))
|
||||||
(match_operand:<V2XWIDE> 4 "aarch64_simd_imm_zero"))
|
(match_operand:<V2XWIDE> 4 "aarch64_simd_imm_zero"))
|
||||||
(match_operand:<V2XWIDE> 5 "aarch64_simd_umax_quarter_mode"))))]
|
(match_operand:<V2XWIDE> 5 "aarch64_simd_umax_quarter_mode"))))]
|
||||||
|
|
@ -6713,14 +6713,14 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
(define_insn "aarch64_sqrshrun_n<mode>_insn"
|
(define_insn "aarch64_sqrshrun_n<mode>_insn"
|
||||||
[(set (match_operand:<V2XWIDE> 0 "register_operand" "=w")
|
[(set (match_operand:<DWI> 0 "register_operand" "=w")
|
||||||
(smin:<V2XWIDE>
|
(smin:<DWI>
|
||||||
(smax:<V2XWIDE>
|
(smax:<DWI>
|
||||||
(ashiftrt:<V2XWIDE>
|
(ashiftrt:<DWI>
|
||||||
(plus:<V2XWIDE>
|
(plus:<DWI>
|
||||||
(sign_extend:<V2XWIDE>
|
(sign_extend:<DWI>
|
||||||
(match_operand:SD_HSDI 1 "register_operand" "w"))
|
(match_operand:SD_HSDI 1 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 3 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<DWI> 3 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>"))
|
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>"))
|
||||||
(const_int 0))
|
(const_int 0))
|
||||||
(const_int <half_mask>)))]
|
(const_int <half_mask>)))]
|
||||||
|
|
@ -6736,10 +6736,10 @@
|
||||||
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>")]
|
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>")]
|
||||||
"TARGET_SIMD"
|
"TARGET_SIMD"
|
||||||
{
|
{
|
||||||
int prec = GET_MODE_UNIT_PRECISION (<V2XWIDE>mode);
|
int prec = GET_MODE_UNIT_PRECISION (<DWI>mode);
|
||||||
wide_int rnd_wi = wi::set_bit_in_zero (INTVAL (operands[2]) - 1, prec);
|
wide_int rnd_wi = wi::set_bit_in_zero (INTVAL (operands[2]) - 1, prec);
|
||||||
rtx rnd = immed_wide_int_const (rnd_wi, <V2XWIDE>mode);
|
rtx rnd = immed_wide_int_const (rnd_wi, <DWI>mode);
|
||||||
rtx dst = gen_reg_rtx (<V2XWIDE>mode);
|
rtx dst = gen_reg_rtx (<DWI>mode);
|
||||||
emit_insn (gen_aarch64_sqrshrun_n<mode>_insn (dst, operands[1], operands[2], rnd));
|
emit_insn (gen_aarch64_sqrshrun_n<mode>_insn (dst, operands[1], operands[2], rnd));
|
||||||
emit_move_insn (operands[0], gen_lowpart (<VNARROWQ>mode, dst));
|
emit_move_insn (operands[0], gen_lowpart (<VNARROWQ>mode, dst));
|
||||||
DONE;
|
DONE;
|
||||||
|
|
@ -6831,7 +6831,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(<TRUNCEXTEND>:<V2XWIDE>
|
(<TRUNCEXTEND>:<V2XWIDE>
|
||||||
(match_operand:VQN 2 "register_operand" "w"))
|
(match_operand:VQN 2 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")))))]
|
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")))))]
|
||||||
"TARGET_SIMD && !BYTES_BIG_ENDIAN
|
"TARGET_SIMD && !BYTES_BIG_ENDIAN
|
||||||
&& aarch64_const_vec_rnd_cst_p (operands[4], operands[3])"
|
&& aarch64_const_vec_rnd_cst_p (operands[4], operands[3])"
|
||||||
|
|
@ -6847,7 +6847,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(<TRUNCEXTEND>:<V2XWIDE>
|
(<TRUNCEXTEND>:<V2XWIDE>
|
||||||
(match_operand:VQN 2 "register_operand" "w"))
|
(match_operand:VQN 2 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")))
|
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>")))
|
||||||
(match_operand:<VNARROWQ> 1 "register_operand" "0")))]
|
(match_operand:<VNARROWQ> 1 "register_operand" "0")))]
|
||||||
"TARGET_SIMD && BYTES_BIG_ENDIAN
|
"TARGET_SIMD && BYTES_BIG_ENDIAN
|
||||||
|
|
@ -6965,7 +6965,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(sign_extend:<V2XWIDE>
|
(sign_extend:<V2XWIDE>
|
||||||
(match_operand:VQN 2 "register_operand" "w"))
|
(match_operand:VQN 2 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
|
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
|
||||||
(match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
|
(match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
|
||||||
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))))]
|
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))))]
|
||||||
|
|
@ -6985,7 +6985,7 @@
|
||||||
(plus:<V2XWIDE>
|
(plus:<V2XWIDE>
|
||||||
(sign_extend:<V2XWIDE>
|
(sign_extend:<V2XWIDE>
|
||||||
(match_operand:VQN 2 "register_operand" "w"))
|
(match_operand:VQN 2 "register_operand" "w"))
|
||||||
(match_operand:<V2XWIDE> 4 "aarch64_simd_rsra_rnd_imm_vec"))
|
(match_operand:<V2XWIDE> 4 "aarch64_int_rnd_operand"))
|
||||||
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
|
(match_operand:VQN 3 "aarch64_simd_shift_imm_vec_<vn_mode>"))
|
||||||
(match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
|
(match_operand:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
|
||||||
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))
|
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))
|
||||||
|
|
|
||||||
|
|
@ -1929,7 +1929,7 @@ static const struct tune_params ampere1_tunings =
|
||||||
"32:16", /* loop_align. */
|
"32:16", /* loop_align. */
|
||||||
2, /* int_reassoc_width. */
|
2, /* int_reassoc_width. */
|
||||||
4, /* fp_reassoc_width. */
|
4, /* fp_reassoc_width. */
|
||||||
1, /* fma_reassoc_width. */
|
4, /* fma_reassoc_width. */
|
||||||
2, /* vec_reassoc_width. */
|
2, /* vec_reassoc_width. */
|
||||||
2, /* min_div_recip_mul_sf. */
|
2, /* min_div_recip_mul_sf. */
|
||||||
2, /* min_div_recip_mul_df. */
|
2, /* min_div_recip_mul_df. */
|
||||||
|
|
@ -11761,14 +11761,14 @@ aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if X is a TImode constant or a constant vector of integer
|
/* Return true if X is a scalar or a constant vector of integer
|
||||||
immediates that represent the rounding constant used in the RSRA
|
immediates that represent the rounding constant used in the fixed-point
|
||||||
instructions.
|
arithmetic instructions.
|
||||||
The accepted form of the constant is (1 << (C - 1)) where C is within
|
The accepted form of the constant is (1 << (C - 1)) where C is in the range
|
||||||
[1, MODE_WIDTH/2]. */
|
[1, MODE_WIDTH/2]. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aarch64_const_vec_rsra_rnd_imm_p (rtx x)
|
aarch64_rnd_imm_p (rtx x)
|
||||||
{
|
{
|
||||||
wide_int rnd_cst;
|
wide_int rnd_cst;
|
||||||
if (!aarch64_extract_vec_duplicate_wide_int (x, &rnd_cst))
|
if (!aarch64_extract_vec_duplicate_wide_int (x, &rnd_cst))
|
||||||
|
|
|
||||||
|
|
@ -626,15 +626,11 @@
|
||||||
(and (match_code "const_vector")
|
(and (match_code "const_vector")
|
||||||
(match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 64)")))
|
(match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 64)")))
|
||||||
|
|
||||||
(define_predicate "aarch64_simd_rsra_rnd_imm_vec"
|
;; A constant or vector of constants that represents an integer rounding
|
||||||
|
;; constant added during fixed-point arithmetic calculations
|
||||||
|
(define_predicate "aarch64_int_rnd_operand"
|
||||||
(and (match_code "const_vector,const_int,const_wide_int")
|
(and (match_code "const_vector,const_int,const_wide_int")
|
||||||
(match_test "aarch64_const_vec_rsra_rnd_imm_p (op)")))
|
(match_test "aarch64_rnd_imm_p (op)")))
|
||||||
|
|
||||||
(define_predicate "aarch64_simd_rshrn_imm_vec"
|
|
||||||
(and (match_code "const_vector")
|
|
||||||
(match_test "aarch64_const_vec_all_same_in_range_p (op, 1,
|
|
||||||
HOST_WIDE_INT_1U
|
|
||||||
<< (GET_MODE_UNIT_BITSIZE (mode) - 1))")))
|
|
||||||
|
|
||||||
(define_predicate "aarch64_simd_raddsubhn_imm_vec"
|
(define_predicate "aarch64_simd_raddsubhn_imm_vec"
|
||||||
(and (match_code "const_vector")
|
(and (match_code "const_vector")
|
||||||
|
|
|
||||||
|
|
@ -10234,6 +10234,18 @@ ix86_expand_sse_ptest (const struct builtin_description *d, tree exp,
|
||||||
machine_mode mode1 = insn_data[d->icode].operand[1].mode;
|
machine_mode mode1 = insn_data[d->icode].operand[1].mode;
|
||||||
enum rtx_code comparison = d->comparison;
|
enum rtx_code comparison = d->comparison;
|
||||||
|
|
||||||
|
/* ptest reg, reg sets the carry flag. */
|
||||||
|
if (comparison == LTU
|
||||||
|
&& (d->code == IX86_BUILTIN_PTESTC
|
||||||
|
|| d->code == IX86_BUILTIN_PTESTC256)
|
||||||
|
&& rtx_equal_p (op0, op1))
|
||||||
|
{
|
||||||
|
if (!target)
|
||||||
|
target = gen_reg_rtx (SImode);
|
||||||
|
emit_move_insn (target, const1_rtx);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
if (VECTOR_MODE_P (mode0))
|
if (VECTOR_MODE_P (mode0))
|
||||||
op0 = safe_vector_operand (op0, mode0);
|
op0 = safe_vector_operand (op0, mode0);
|
||||||
if (VECTOR_MODE_P (mode1))
|
if (VECTOR_MODE_P (mode1))
|
||||||
|
|
|
||||||
|
|
@ -1400,7 +1400,11 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args,
|
||||||
if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
|
if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
|
||||||
opts->x_ix86_tune_string
|
opts->x_ix86_tune_string
|
||||||
= ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]);
|
= ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]);
|
||||||
else if (orig_tune_defaulted)
|
/* If we have explicit arch string and no tune string specified, set
|
||||||
|
tune_string to NULL and later it will be overriden by arch_string
|
||||||
|
so target clones can get proper optimization. */
|
||||||
|
else if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
|
||||||
|
|| orig_tune_defaulted)
|
||||||
opts->x_ix86_tune_string = NULL;
|
opts->x_ix86_tune_string = NULL;
|
||||||
|
|
||||||
/* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
|
/* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
|
||||||
|
|
|
||||||
|
|
@ -21423,16 +21423,23 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
|
||||||
else if (XINT (x, 1) == UNSPEC_PTEST)
|
else if (XINT (x, 1) == UNSPEC_PTEST)
|
||||||
{
|
{
|
||||||
*total = cost->sse_op;
|
*total = cost->sse_op;
|
||||||
if (XVECLEN (x, 0) == 2
|
rtx test_op0 = XVECEXP (x, 0, 0);
|
||||||
&& GET_CODE (XVECEXP (x, 0, 0)) == AND)
|
if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
|
||||||
|
return false;
|
||||||
|
if (GET_CODE (test_op0) == AND)
|
||||||
{
|
{
|
||||||
rtx andop = XVECEXP (x, 0, 0);
|
rtx and_op0 = XEXP (test_op0, 0);
|
||||||
*total += rtx_cost (XEXP (andop, 0), GET_MODE (andop),
|
if (GET_CODE (and_op0) == NOT)
|
||||||
AND, opno, speed)
|
and_op0 = XEXP (and_op0, 0);
|
||||||
+ rtx_cost (XEXP (andop, 1), GET_MODE (andop),
|
*total += rtx_cost (and_op0, GET_MODE (and_op0),
|
||||||
AND, opno, speed);
|
AND, 0, speed)
|
||||||
return true;
|
+ rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
|
||||||
|
AND, 1, speed);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*total = rtx_cost (test_op0, GET_MODE (test_op0),
|
||||||
|
UNSPEC, 0, speed);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11380,6 +11380,8 @@
|
||||||
[(set_attr "type" "alu")
|
[(set_attr "type" "alu")
|
||||||
(set_attr "mode" "QI")])
|
(set_attr "mode" "QI")])
|
||||||
|
|
||||||
|
;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
|
||||||
|
|
||||||
;; Convert wide AND instructions with immediate operand to shorter QImode
|
;; Convert wide AND instructions with immediate operand to shorter QImode
|
||||||
;; equivalents when possible.
|
;; equivalents when possible.
|
||||||
;; Don't do the splitting with memory operands, since it introduces risk
|
;; Don't do the splitting with memory operands, since it introduces risk
|
||||||
|
|
@ -12092,6 +12094,26 @@
|
||||||
[(set_attr "type" "alu")
|
[(set_attr "type" "alu")
|
||||||
(set_attr "mode" "QI")])
|
(set_attr "mode" "QI")])
|
||||||
|
|
||||||
|
(define_insn "*<code>qi_ext<mode>_3"
|
||||||
|
[(set (zero_extract:SWI248
|
||||||
|
(match_operand 0 "int248_register_operand" "+Q")
|
||||||
|
(const_int 8)
|
||||||
|
(const_int 8))
|
||||||
|
(zero_extract:SWI248
|
||||||
|
(any_logic:SWI248
|
||||||
|
(match_operand 1 "int248_register_operand" "%0")
|
||||||
|
(match_operand 2 "int248_register_operand" "Q"))
|
||||||
|
(const_int 8)
|
||||||
|
(const_int 8)))
|
||||||
|
(clobber (reg:CC FLAGS_REG))]
|
||||||
|
"(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
|
||||||
|
/* FIXME: without this LRA can't reload this pattern, see PR82524. */
|
||||||
|
&& (rtx_equal_p (operands[0], operands[1])
|
||||||
|
|| rtx_equal_p (operands[0], operands[2]))"
|
||||||
|
"<logic>{b}\t{%h2, %h0|%h0, %h2}"
|
||||||
|
[(set_attr "type" "alu")
|
||||||
|
(set_attr "mode" "QI")])
|
||||||
|
|
||||||
;; Convert wide OR instructions with immediate operand to shorter QImode
|
;; Convert wide OR instructions with immediate operand to shorter QImode
|
||||||
;; equivalents when possible.
|
;; equivalents when possible.
|
||||||
;; Don't do the splitting with memory operands, since it introduces risk
|
;; Don't do the splitting with memory operands, since it introduces risk
|
||||||
|
|
@ -12206,6 +12228,18 @@
|
||||||
(set_attr "type" "alu")
|
(set_attr "type" "alu")
|
||||||
(set_attr "mode" "QI")])
|
(set_attr "mode" "QI")])
|
||||||
|
|
||||||
|
;; Peephole2 rega = 0; rega op= regb into rega = regb.
|
||||||
|
(define_peephole2
|
||||||
|
[(parallel [(set (match_operand:SWI 0 "general_reg_operand")
|
||||||
|
(const_int 0))
|
||||||
|
(clobber (reg:CC FLAGS_REG))])
|
||||||
|
(parallel [(set (match_dup 0)
|
||||||
|
(any_or_plus:SWI (match_dup 0)
|
||||||
|
(match_operand:SWI 1 "<general_operand>")))
|
||||||
|
(clobber (reg:CC FLAGS_REG))])]
|
||||||
|
""
|
||||||
|
[(set (match_dup 0) (match_dup 1))])
|
||||||
|
|
||||||
;; Split DST = (HI<<32)|LO early to minimize register usage.
|
;; Split DST = (HI<<32)|LO early to minimize register usage.
|
||||||
(define_insn_and_split "*concat<mode><dwi>3_1"
|
(define_insn_and_split "*concat<mode><dwi>3_1"
|
||||||
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
|
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
|
||||||
|
|
@ -13365,6 +13399,28 @@
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
"ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
|
"ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
|
||||||
|
|
||||||
|
(define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
|
||||||
|
[(set (match_operand:<DWI> 0 "register_operand" "=r")
|
||||||
|
(ashift:<DWI>
|
||||||
|
(any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
|
||||||
|
(match_operand:QI 2 "const_int_operand")))
|
||||||
|
(clobber (reg:CC FLAGS_REG))]
|
||||||
|
"INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
|
||||||
|
&& INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
|
||||||
|
int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
|
||||||
|
if (!rtx_equal_p (operands[3], operands[1]))
|
||||||
|
emit_move_insn (operands[3], operands[1]);
|
||||||
|
if (bits > 0)
|
||||||
|
emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
|
||||||
|
ix86_expand_clear (operands[0]);
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn "x86_64_shld"
|
(define_insn "x86_64_shld"
|
||||||
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
|
||||||
(ior:DI (ashift:DI (match_dup 0)
|
(ior:DI (ashift:DI (match_dup 0)
|
||||||
|
|
|
||||||
|
|
@ -1465,12 +1465,12 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn "*<avx512>_load<mode>_mask"
|
(define_insn "*<avx512>_load<mode>_mask"
|
||||||
[(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
|
[(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand" "=v")
|
||||||
(vec_merge:VI12_AVX512VL
|
(vec_merge:VI12HFBF_AVX512VL
|
||||||
(unspec:VI12_AVX512VL
|
(unspec:VI12HFBF_AVX512VL
|
||||||
[(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
|
[(match_operand:VI12HFBF_AVX512VL 1 "memory_operand" "m")]
|
||||||
UNSPEC_MASKLOAD)
|
UNSPEC_MASKLOAD)
|
||||||
(match_operand:VI12_AVX512VL 2 "nonimm_or_0_operand" "0C")
|
(match_operand:VI12HFBF_AVX512VL 2 "nonimm_or_0_operand" "0C")
|
||||||
(match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
|
(match_operand:<avx512fmaskmode> 3 "register_operand" "Yk")))]
|
||||||
"TARGET_AVX512BW"
|
"TARGET_AVX512BW"
|
||||||
"vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
|
"vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
|
||||||
|
|
@ -1479,9 +1479,9 @@
|
||||||
(set_attr "mode" "<sseinsnmode>")])
|
(set_attr "mode" "<sseinsnmode>")])
|
||||||
|
|
||||||
(define_insn_and_split "*<avx512>_load<mode>"
|
(define_insn_and_split "*<avx512>_load<mode>"
|
||||||
[(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
|
[(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand" "=v")
|
||||||
(unspec:VI12_AVX512VL
|
(unspec:VI12HFBF_AVX512VL
|
||||||
[(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
|
[(match_operand:VI12HFBF_AVX512VL 1 "memory_operand" "m")]
|
||||||
UNSPEC_MASKLOAD))]
|
UNSPEC_MASKLOAD))]
|
||||||
"TARGET_AVX512BW"
|
"TARGET_AVX512BW"
|
||||||
"#"
|
"#"
|
||||||
|
|
@ -23490,6 +23490,70 @@
|
||||||
[(set (reg:CCZ FLAGS_REG)
|
[(set (reg:CCZ FLAGS_REG)
|
||||||
(unspec:CCZ [(match_dup 0) (match_dup 1)] UNSPEC_PTEST))])
|
(unspec:CCZ [(match_dup 0) (match_dup 1)] UNSPEC_PTEST))])
|
||||||
|
|
||||||
|
;; ptest reg,reg sets the carry flag.
|
||||||
|
(define_split
|
||||||
|
[(set (reg:CCC FLAGS_REG)
|
||||||
|
(unspec:CCC [(match_operand:V_AVX 0 "register_operand")
|
||||||
|
(match_operand:V_AVX 1 "register_operand")]
|
||||||
|
UNSPEC_PTEST))]
|
||||||
|
"TARGET_SSE4_1
|
||||||
|
&& rtx_equal_p (operands[0], operands[1])"
|
||||||
|
[(set (reg:CCC FLAGS_REG)
|
||||||
|
(unspec:CCC [(const_int 0)] UNSPEC_STC))])
|
||||||
|
|
||||||
|
;; Changing the CCmode of FLAGS_REG requires updating both def and use.
|
||||||
|
;; pandn/ptestz/set{n?}e -> ptestc/set{n?}c
|
||||||
|
(define_split
|
||||||
|
[(set (match_operand:SWI 0 "register_operand")
|
||||||
|
(match_operator:SWI 3 "bt_comparison_operator"
|
||||||
|
[(unspec:CCZ [
|
||||||
|
(and:V_AVX (not:V_AVX (match_operand:V_AVX 1 "register_operand"))
|
||||||
|
(match_operand:V_AVX 2 "register_operand"))
|
||||||
|
(and:V_AVX (not:V_AVX (match_dup 1)) (match_dup 2))]
|
||||||
|
UNSPEC_PTEST)
|
||||||
|
(const_int 0)]))]
|
||||||
|
"TARGET_SSE4_1"
|
||||||
|
[(set (reg:CCC FLAGS_REG)
|
||||||
|
(unspec:CCC [(match_dup 1) (match_dup 2)] UNSPEC_PTEST))
|
||||||
|
(set (match_dup 0)
|
||||||
|
(match_op_dup 3 [(reg:CCC FLAGS_REG) (const_int 0)]))])
|
||||||
|
|
||||||
|
(define_split
|
||||||
|
[(set (strict_low_part (match_operand:QI 0 "register_operand"))
|
||||||
|
(match_operator:QI 3 "bt_comparison_operator"
|
||||||
|
[(unspec:CCZ [
|
||||||
|
(and:V_AVX (not:V_AVX (match_operand:V_AVX 1 "register_operand"))
|
||||||
|
(match_operand:V_AVX 2 "register_operand"))
|
||||||
|
(and:V_AVX (not:V_AVX (match_dup 1)) (match_dup 2))]
|
||||||
|
UNSPEC_PTEST)
|
||||||
|
(const_int 0)]))]
|
||||||
|
"TARGET_SSE4_1"
|
||||||
|
[(set (reg:CCC FLAGS_REG)
|
||||||
|
(unspec:CCC [(match_dup 1) (match_dup 2)] UNSPEC_PTEST))
|
||||||
|
(set (strict_low_part (match_dup 0))
|
||||||
|
(match_op_dup 3 [(reg:CCC FLAGS_REG) (const_int 0)]))])
|
||||||
|
|
||||||
|
;; pandn/ptestz/j{n?}e -> ptestc/j{n?}c
|
||||||
|
(define_split
|
||||||
|
[(set (pc)
|
||||||
|
(if_then_else
|
||||||
|
(match_operator 3 "bt_comparison_operator"
|
||||||
|
[(unspec:CCZ [
|
||||||
|
(and:V_AVX
|
||||||
|
(not:V_AVX (match_operand:V_AVX 1 "register_operand"))
|
||||||
|
(match_operand:V_AVX 2 "register_operand"))
|
||||||
|
(and:V_AVX (not:V_AVX (match_dup 1)) (match_dup 2))]
|
||||||
|
UNSPEC_PTEST)
|
||||||
|
(const_int 0)])
|
||||||
|
(match_operand 0)
|
||||||
|
(pc)))]
|
||||||
|
"TARGET_SSE4_1"
|
||||||
|
[(set (reg:CCC FLAGS_REG)
|
||||||
|
(unspec:CCC [(match_dup 1) (match_dup 2)] UNSPEC_PTEST))
|
||||||
|
(set (pc) (if_then_else (match_op_dup 3 [(reg:CCC FLAGS_REG) (const_int 0)])
|
||||||
|
(match_dup 0)
|
||||||
|
(pc)))])
|
||||||
|
|
||||||
(define_expand "nearbyint<mode>2"
|
(define_expand "nearbyint<mode>2"
|
||||||
[(set (match_operand:VFH 0 "register_operand")
|
[(set (match_operand:VFH 0 "register_operand")
|
||||||
(unspec:VFH
|
(unspec:VFH
|
||||||
|
|
@ -26915,17 +26979,21 @@
|
||||||
"TARGET_AVX")
|
"TARGET_AVX")
|
||||||
|
|
||||||
(define_expand "maskload<mode><avx512fmaskmodelower>"
|
(define_expand "maskload<mode><avx512fmaskmodelower>"
|
||||||
[(set (match_operand:V48H_AVX512VL 0 "register_operand")
|
[(set (match_operand:V48_AVX512VL 0 "register_operand")
|
||||||
(vec_merge:V48H_AVX512VL
|
(vec_merge:V48_AVX512VL
|
||||||
(match_operand:V48H_AVX512VL 1 "memory_operand")
|
(unspec:V48_AVX512VL
|
||||||
|
[(match_operand:V48_AVX512VL 1 "memory_operand")]
|
||||||
|
UNSPEC_MASKLOAD)
|
||||||
(match_dup 0)
|
(match_dup 0)
|
||||||
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
|
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
|
||||||
"TARGET_AVX512F")
|
"TARGET_AVX512F")
|
||||||
|
|
||||||
(define_expand "maskload<mode><avx512fmaskmodelower>"
|
(define_expand "maskload<mode><avx512fmaskmodelower>"
|
||||||
[(set (match_operand:VI12_AVX512VL 0 "register_operand")
|
[(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand")
|
||||||
(vec_merge:VI12_AVX512VL
|
(vec_merge:VI12HFBF_AVX512VL
|
||||||
(match_operand:VI12_AVX512VL 1 "memory_operand")
|
(unspec:VI12HFBF_AVX512VL
|
||||||
|
[(match_operand:VI12HFBF_AVX512VL 1 "memory_operand")]
|
||||||
|
UNSPEC_MASKLOAD)
|
||||||
(match_dup 0)
|
(match_dup 0)
|
||||||
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
|
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
|
||||||
"TARGET_AVX512BW")
|
"TARGET_AVX512BW")
|
||||||
|
|
|
||||||
|
|
@ -22,29 +22,27 @@
|
||||||
;; == Loads/Stores
|
;; == Loads/Stores
|
||||||
;; =========================================================================
|
;; =========================================================================
|
||||||
|
|
||||||
;; len_load/len_store is a sub-optimal pattern for RVV auto-vectorization support.
|
(define_expand "len_maskload<mode><vm>"
|
||||||
;; We will replace them when len_maskload/len_maskstore is supported in loop vectorizer.
|
|
||||||
(define_expand "len_load_<mode>"
|
|
||||||
[(match_operand:V 0 "register_operand")
|
[(match_operand:V 0 "register_operand")
|
||||||
(match_operand:V 1 "memory_operand")
|
(match_operand:V 1 "memory_operand")
|
||||||
(match_operand 2 "vector_length_operand")
|
(match_operand 2 "autovec_length_operand")
|
||||||
(match_operand 3 "const_0_operand")]
|
(match_operand:<VM> 3 "vector_mask_operand")
|
||||||
|
(match_operand 4 "const_0_operand")]
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
{
|
{
|
||||||
riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
|
riscv_vector::expand_load_store (operands, true);
|
||||||
riscv_vector::RVV_UNOP, operands, operands[2]);
|
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_expand "len_store_<mode>"
|
(define_expand "len_maskstore<mode><vm>"
|
||||||
[(match_operand:V 0 "memory_operand")
|
[(match_operand:V 0 "memory_operand")
|
||||||
(match_operand:V 1 "register_operand")
|
(match_operand:V 1 "register_operand")
|
||||||
(match_operand 2 "vector_length_operand")
|
(match_operand 2 "autovec_length_operand")
|
||||||
(match_operand 3 "const_0_operand")]
|
(match_operand:<VM> 3 "vector_mask_operand")
|
||||||
|
(match_operand 4 "const_0_operand")]
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
{
|
{
|
||||||
riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
|
riscv_vector::expand_load_store (operands, false);
|
||||||
riscv_vector::RVV_UNOP, operands, operands[2]);
|
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -313,44 +311,6 @@
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
;; -------------------------------------------------------------------------
|
|
||||||
;; ---- [INT,FP] Compare and select
|
|
||||||
;; -------------------------------------------------------------------------
|
|
||||||
;; The patterns in this section are synthetic.
|
|
||||||
;; -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(define_expand "vcond<V:mode><VI:mode>"
|
|
||||||
[(set (match_operand:V 0 "register_operand")
|
|
||||||
(if_then_else:V
|
|
||||||
(match_operator 3 "comparison_operator"
|
|
||||||
[(match_operand:VI 4 "register_operand")
|
|
||||||
(match_operand:VI 5 "register_operand")])
|
|
||||||
(match_operand:V 1 "register_operand")
|
|
||||||
(match_operand:V 2 "register_operand")))]
|
|
||||||
"TARGET_VECTOR && known_eq (GET_MODE_NUNITS (<V:MODE>mode),
|
|
||||||
GET_MODE_NUNITS (<VI:MODE>mode))"
|
|
||||||
{
|
|
||||||
riscv_vector::expand_vcond (operands);
|
|
||||||
DONE;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
(define_expand "vcondu<V:mode><VI:mode>"
|
|
||||||
[(set (match_operand:V 0 "register_operand")
|
|
||||||
(if_then_else:V
|
|
||||||
(match_operator 3 "comparison_operator"
|
|
||||||
[(match_operand:VI 4 "register_operand")
|
|
||||||
(match_operand:VI 5 "register_operand")])
|
|
||||||
(match_operand:V 1 "register_operand")
|
|
||||||
(match_operand:V 2 "register_operand")))]
|
|
||||||
"TARGET_VECTOR && known_eq (GET_MODE_NUNITS (<V:MODE>mode),
|
|
||||||
GET_MODE_NUNITS (<VI:MODE>mode))"
|
|
||||||
{
|
|
||||||
riscv_vector::expand_vcond (operands);
|
|
||||||
DONE;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
||||||
;; ---- [INT] Sign and zero extension
|
;; ---- [INT] Sign and zero extension
|
||||||
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
||||||
|
|
@ -596,40 +556,41 @@
|
||||||
;; result after reload_completed.
|
;; result after reload_completed.
|
||||||
(define_expand "fma<mode>4"
|
(define_expand "fma<mode>4"
|
||||||
[(parallel
|
[(parallel
|
||||||
[(set (match_operand:VI 0 "register_operand" "=vr")
|
[(set (match_operand:VI 0 "register_operand")
|
||||||
(plus:VI
|
(plus:VI
|
||||||
(mult:VI
|
(mult:VI
|
||||||
(match_operand:VI 1 "register_operand" " vr")
|
(match_operand:VI 1 "register_operand")
|
||||||
(match_operand:VI 2 "register_operand" " vr"))
|
(match_operand:VI 2 "register_operand"))
|
||||||
(match_operand:VI 3 "register_operand" " vr")))
|
(match_operand:VI 3 "register_operand")))
|
||||||
(clobber (match_scratch:SI 4))])]
|
(clobber (match_dup 4))])]
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
{})
|
{
|
||||||
|
operands[4] = gen_reg_rtx (Pmode);
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*fma<mode>"
|
(define_insn_and_split "*fma<VI:mode><P:mode>"
|
||||||
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
|
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
|
||||||
(plus:VI
|
(plus:VI
|
||||||
(mult:VI
|
(mult:VI
|
||||||
(match_operand:VI 1 "register_operand" " %0, vr, vr")
|
(match_operand:VI 1 "register_operand" " %0, vr, vr")
|
||||||
(match_operand:VI 2 "register_operand" " vr, vr, vr"))
|
(match_operand:VI 2 "register_operand" " vr, vr, vr"))
|
||||||
(match_operand:VI 3 "register_operand" " vr, 0, vr")))
|
(match_operand:VI 3 "register_operand" " vr, 0, vr")))
|
||||||
(clobber (match_scratch:SI 4 "=r,r,r"))]
|
(clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
"#"
|
"#"
|
||||||
"&& reload_completed"
|
"&& reload_completed"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
PUT_MODE (operands[4], Pmode);
|
riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
|
||||||
riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
|
|
||||||
if (which_alternative == 2)
|
if (which_alternative == 2)
|
||||||
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
||||||
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
||||||
riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<MODE>mode),
|
riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<VI:MODE>mode),
|
||||||
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||||
DONE;
|
DONE;
|
||||||
}
|
}
|
||||||
[(set_attr "type" "vimuladd")
|
[(set_attr "type" "vimuladd")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<VI:MODE>")])
|
||||||
|
|
||||||
;; -------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------
|
||||||
;; ---- [INT] VNMSAC and VNMSUB
|
;; ---- [INT] VNMSAC and VNMSUB
|
||||||
|
|
@ -641,40 +602,225 @@
|
||||||
|
|
||||||
(define_expand "fnma<mode>4"
|
(define_expand "fnma<mode>4"
|
||||||
[(parallel
|
[(parallel
|
||||||
[(set (match_operand:VI 0 "register_operand" "=vr")
|
[(set (match_operand:VI 0 "register_operand")
|
||||||
(minus:VI
|
(minus:VI
|
||||||
(match_operand:VI 3 "register_operand" " vr")
|
(match_operand:VI 3 "register_operand")
|
||||||
(mult:VI
|
(mult:VI
|
||||||
(match_operand:VI 1 "register_operand" " vr")
|
(match_operand:VI 1 "register_operand")
|
||||||
(match_operand:VI 2 "register_operand" " vr"))))
|
(match_operand:VI 2 "register_operand"))))
|
||||||
(clobber (match_scratch:SI 4))])]
|
(clobber (match_dup 4))])]
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
{})
|
{
|
||||||
|
operands[4] = gen_reg_rtx (Pmode);
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*fnma<mode>"
|
(define_insn_and_split "*fnma<VI:mode><P:mode>"
|
||||||
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
|
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
|
||||||
(minus:VI
|
(minus:VI
|
||||||
(match_operand:VI 3 "register_operand" " vr, 0, vr")
|
(match_operand:VI 3 "register_operand" " vr, 0, vr")
|
||||||
(mult:VI
|
(mult:VI
|
||||||
(match_operand:VI 1 "register_operand" " %0, vr, vr")
|
(match_operand:VI 1 "register_operand" " %0, vr, vr")
|
||||||
(match_operand:VI 2 "register_operand" " vr, vr, vr"))))
|
(match_operand:VI 2 "register_operand" " vr, vr, vr"))))
|
||||||
(clobber (match_scratch:SI 4 "=r,r,r"))]
|
(clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
"#"
|
"#"
|
||||||
"&& reload_completed"
|
"&& reload_completed"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
PUT_MODE (operands[4], Pmode);
|
riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
|
||||||
riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
|
|
||||||
if (which_alternative == 2)
|
if (which_alternative == 2)
|
||||||
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
||||||
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
||||||
riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<MODE>mode),
|
riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<VI:MODE>mode),
|
||||||
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||||
DONE;
|
DONE;
|
||||||
}
|
}
|
||||||
[(set_attr "type" "vimuladd")
|
[(set_attr "type" "vimuladd")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<VI:MODE>")])
|
||||||
|
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; ---- [FP] VFMACC and VFMADD
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; Includes:
|
||||||
|
;; - vfmacc
|
||||||
|
;; - vfmadd
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(define_expand "fma<mode>4"
|
||||||
|
[(parallel
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand")
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand")
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand")))
|
||||||
|
(clobber (match_dup 4))])]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
{
|
||||||
|
operands[4] = gen_reg_rtx (Pmode);
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn_and_split "*fma<VF_AUTO:mode><P:mode>"
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr")
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr")))
|
||||||
|
(clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
|
||||||
|
if (which_alternative == 2)
|
||||||
|
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
||||||
|
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
||||||
|
riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (PLUS, <VF_AUTO:MODE>mode),
|
||||||
|
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
[(set_attr "type" "vfmuladd")
|
||||||
|
(set_attr "mode" "<VF_AUTO:MODE>")])
|
||||||
|
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; ---- [FP] VFNMSAC and VFNMSUB
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; Includes:
|
||||||
|
;; - vfnmsac
|
||||||
|
;; - vfnmsub
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(define_expand "fnma<mode>4"
|
||||||
|
[(parallel
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand"))
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand")
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand")))
|
||||||
|
(clobber (match_dup 4))])]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
{
|
||||||
|
operands[4] = gen_reg_rtx (Pmode);
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn_and_split "*fnma<VF_AUTO:mode><P:mode>"
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr"))
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr")))
|
||||||
|
(clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
|
||||||
|
if (which_alternative == 2)
|
||||||
|
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
||||||
|
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
||||||
|
riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (PLUS, <VF_AUTO:MODE>mode),
|
||||||
|
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
[(set_attr "type" "vfmuladd")
|
||||||
|
(set_attr "mode" "<VF_AUTO:MODE>")])
|
||||||
|
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; ---- [FP] VFMSAC and VFMSUB
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; Includes:
|
||||||
|
;; - vfmsac
|
||||||
|
;; - vfmsub
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(define_expand "fms<mode>4"
|
||||||
|
[(parallel
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand")
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand")
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand"))))
|
||||||
|
(clobber (match_dup 4))])]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
{
|
||||||
|
operands[4] = gen_reg_rtx (Pmode);
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn_and_split "*fms<VF_AUTO:mode><P:mode>"
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr")
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr"))))
|
||||||
|
(clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
|
||||||
|
if (which_alternative == 2)
|
||||||
|
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
||||||
|
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
||||||
|
riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (MINUS, <VF_AUTO:MODE>mode),
|
||||||
|
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
[(set_attr "type" "vfmuladd")
|
||||||
|
(set_attr "mode" "<VF_AUTO:MODE>")])
|
||||||
|
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; ---- [FP] VFMSAC and VFMSUB
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
;; Includes:
|
||||||
|
;; - vfmsac
|
||||||
|
;; - vfmsub
|
||||||
|
;; -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(define_expand "fnms<mode>4"
|
||||||
|
[(parallel
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand"))
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand")
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand"))))
|
||||||
|
(clobber (match_dup 4))])]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
{
|
||||||
|
operands[4] = gen_reg_rtx (Pmode);
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn_and_split "*fnms<VF_AUTO:mode><P:mode>"
|
||||||
|
[(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
|
||||||
|
(fma:VF_AUTO
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr"))
|
||||||
|
(match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
|
||||||
|
(neg:VF_AUTO
|
||||||
|
(match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr"))))
|
||||||
|
(clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
|
||||||
|
"TARGET_VECTOR"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
|
||||||
|
if (which_alternative == 2)
|
||||||
|
emit_insn (gen_rtx_SET (operands[0], operands[3]));
|
||||||
|
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
|
||||||
|
riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (MINUS, <VF_AUTO:MODE>mode),
|
||||||
|
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
[(set_attr "type" "vfmuladd")
|
||||||
|
(set_attr "mode" "<VF_AUTO:MODE>")])
|
||||||
|
|
||||||
;; =========================================================================
|
;; =========================================================================
|
||||||
;; == SELECT_VL
|
;; == SELECT_VL
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,9 @@ valid_type (unsigned sew, int lmul_log2, unsigned nf, bool float_p)
|
||||||
if (nf > 8 || nf < 1)
|
if (nf > 8 || nf < 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (sew == 16 && nf != 1 && float_p) // Disable FP16 tuple in temporarily.
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (lmul_log2)
|
switch (lmul_log2)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,13 @@
|
||||||
(ior (match_operand 0 "pmode_register_operand")
|
(ior (match_operand 0 "pmode_register_operand")
|
||||||
(match_operand 0 "const_csr_operand")))
|
(match_operand 0 "const_csr_operand")))
|
||||||
|
|
||||||
|
(define_special_predicate "autovec_length_operand"
|
||||||
|
(ior (match_operand 0 "pmode_register_operand")
|
||||||
|
(ior (match_operand 0 "const_csr_operand")
|
||||||
|
(match_test "rtx_equal_p (op, gen_int_mode
|
||||||
|
(GET_MODE_NUNITS (GET_MODE (op)),
|
||||||
|
Pmode))"))))
|
||||||
|
|
||||||
(define_predicate "reg_or_mem_operand"
|
(define_predicate "reg_or_mem_operand"
|
||||||
(ior (match_operand 0 "register_operand")
|
(ior (match_operand 0 "register_operand")
|
||||||
(match_operand 0 "memory_operand")))
|
(match_operand 0 "memory_operand")))
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,6 @@ ADJUST_ALIGNMENT (VNx1QI, 1);
|
||||||
#define RVV_TUPLE_MODES(NBYTES, NSUBPARTS, VB, VH, VS, VD) \
|
#define RVV_TUPLE_MODES(NBYTES, NSUBPARTS, VB, VH, VS, VD) \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, NBYTES, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, NBYTES, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, NBYTES / 2, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, NBYTES / 2, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, HF, NBYTES / 2, 1); \
|
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, SI, NBYTES / 4, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, SI, NBYTES / 4, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, SF, NBYTES / 4, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, SF, NBYTES / 4, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, DI, NBYTES / 8, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, DI, NBYTES / 8, 1); \
|
||||||
|
|
@ -237,9 +236,6 @@ ADJUST_ALIGNMENT (VNx1QI, 1);
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x##VD##DI, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x##VD##DI, \
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VD##DI##mode, \
|
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VD##DI##mode, \
|
||||||
VD * NSUBPARTS)); \
|
VD * NSUBPARTS)); \
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x##VH##HF, \
|
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VH##HF##mode, \
|
|
||||||
VH * NSUBPARTS)); \
|
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x##VS##SF, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x##VS##SF, \
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VS##SF##mode, \
|
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VS##SF##mode, \
|
||||||
VS * NSUBPARTS)); \
|
VS * NSUBPARTS)); \
|
||||||
|
|
@ -251,7 +247,6 @@ ADJUST_ALIGNMENT (VNx1QI, 1);
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VH##HI, 2); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VH##HI, 2); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SI, 4); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SI, 4); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VD##DI, 8); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VD##DI, 8); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VH##HF, 2); \
|
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SF, 4); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SF, 4); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VD##DF, 8);
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VD##DF, 8);
|
||||||
|
|
||||||
|
|
@ -280,12 +275,10 @@ RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8)
|
||||||
#define RVV_TUPLE_PARTIAL_MODES(NSUBPARTS) \
|
#define RVV_TUPLE_PARTIAL_MODES(NSUBPARTS) \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 1, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 1, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, 1, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, 1, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, HF, 1, 1); \
|
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, SI, 1, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, SI, 1, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, SF, 1, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, SF, 1, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 2, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 2, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, 2, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, HI, 2, 1); \
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, FLOAT, HF, 2, 1); \
|
|
||||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 4, 1); \
|
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 4, 1); \
|
||||||
\
|
\
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1QI, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x1QI, \
|
||||||
|
|
@ -294,9 +287,6 @@ RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8)
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1HI, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x1HI, \
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HI##mode, \
|
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HI##mode, \
|
||||||
NSUBPARTS)); \
|
NSUBPARTS)); \
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1HF, \
|
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HF##mode, \
|
|
||||||
NSUBPARTS)); \
|
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1SI, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x1SI, \
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1SI##mode, \
|
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1SI##mode, \
|
||||||
NSUBPARTS)); \
|
NSUBPARTS)); \
|
||||||
|
|
@ -309,20 +299,15 @@ RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8)
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x2HI, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x2HI, \
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HI##mode, \
|
riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HI##mode, \
|
||||||
2 * NSUBPARTS)); \
|
2 * NSUBPARTS)); \
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x2HF, \
|
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HF##mode, \
|
|
||||||
2 * NSUBPARTS)); \
|
|
||||||
ADJUST_NUNITS (VNx##NSUBPARTS##x4QI, \
|
ADJUST_NUNITS (VNx##NSUBPARTS##x4QI, \
|
||||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x4QI##mode, \
|
riscv_v_adjust_nunits (VNx##NSUBPARTS##x4QI##mode, \
|
||||||
4 * NSUBPARTS)); \
|
4 * NSUBPARTS)); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1QI, 1); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1QI, 1); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HI, 2); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HI, 2); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HF, 2); \
|
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SI, 4); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SI, 4); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SF, 4); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SF, 4); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2QI, 1); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2QI, 1); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HI, 2); \
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HI, 2); \
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HF, 2); \
|
|
||||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x4QI, 1);
|
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x4QI, 1);
|
||||||
|
|
||||||
RVV_TUPLE_PARTIAL_MODES (2)
|
RVV_TUPLE_PARTIAL_MODES (2)
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ enum insn_type
|
||||||
RVV_CMP_OP = 4,
|
RVV_CMP_OP = 4,
|
||||||
RVV_CMP_MU_OP = RVV_CMP_OP + 2, /* +2 means mask and maskoff operand. */
|
RVV_CMP_MU_OP = RVV_CMP_OP + 2, /* +2 means mask and maskoff operand. */
|
||||||
RVV_UNOP_MU = RVV_UNOP + 2, /* Likewise. */
|
RVV_UNOP_MU = RVV_UNOP + 2, /* Likewise. */
|
||||||
|
RVV_UNOP_M = RVV_UNOP + 2, /* Likewise. */
|
||||||
RVV_TERNOP = 5,
|
RVV_TERNOP = 5,
|
||||||
RVV_WIDEN_TERNOP = 4,
|
RVV_WIDEN_TERNOP = 4,
|
||||||
RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md. */
|
RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md. */
|
||||||
|
|
@ -187,6 +188,7 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
|
||||||
void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
|
void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
|
||||||
void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
|
void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
|
||||||
void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
|
void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
|
||||||
|
void emit_vlmax_fp_ternary_insn (unsigned, int, rtx *, rtx = 0);
|
||||||
void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
|
void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
|
||||||
void emit_vlmax_slide_insn (unsigned, rtx *);
|
void emit_vlmax_slide_insn (unsigned, rtx *);
|
||||||
void emit_nonvlmax_slide_tu_insn (unsigned, rtx *, rtx);
|
void emit_nonvlmax_slide_tu_insn (unsigned, rtx *, rtx);
|
||||||
|
|
@ -250,9 +252,9 @@ machine_mode preferred_simd_mode (scalar_mode);
|
||||||
opt_machine_mode get_mask_mode (machine_mode);
|
opt_machine_mode get_mask_mode (machine_mode);
|
||||||
void expand_vec_series (rtx, rtx, rtx);
|
void expand_vec_series (rtx, rtx, rtx);
|
||||||
void expand_vec_init (rtx, rtx);
|
void expand_vec_init (rtx, rtx);
|
||||||
void expand_vcond (rtx *);
|
|
||||||
void expand_vec_perm (rtx, rtx, rtx, rtx);
|
void expand_vec_perm (rtx, rtx, rtx, rtx);
|
||||||
void expand_select_vl (rtx *);
|
void expand_select_vl (rtx *);
|
||||||
|
void expand_load_store (rtx *, bool);
|
||||||
|
|
||||||
/* Rounding mode bitfield for fixed point VXRM. */
|
/* Rounding mode bitfield for fixed point VXRM. */
|
||||||
enum fixed_point_rounding_mode
|
enum fixed_point_rounding_mode
|
||||||
|
|
|
||||||
|
|
@ -705,19 +705,42 @@ emit_vlmax_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
|
||||||
{
|
{
|
||||||
machine_mode dest_mode = GET_MODE (ops[0]);
|
machine_mode dest_mode = GET_MODE (ops[0]);
|
||||||
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
||||||
/* We have a maximum of 11 operands for RVV instruction patterns according to
|
insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
|
||||||
* vector.md. */
|
/*HAS_DEST_P*/ true,
|
||||||
insn_expander<11> e (/*OP_NUM*/ op_num, /*HAS_DEST_P*/ true,
|
/*FULLY_UNMASKED_P*/ true,
|
||||||
/*FULLY_UNMASKED_P*/ true,
|
/*USE_REAL_MERGE_P*/ true,
|
||||||
/*USE_REAL_MERGE_P*/ true, /*HAS_AVL_P*/ true,
|
/*HAS_AVL_P*/ true,
|
||||||
/*VLMAX_P*/ true,
|
/*VLMAX_P*/ true,
|
||||||
/*DEST_MODE*/ dest_mode, /*MASK_MODE*/ mask_mode);
|
/*DEST_MODE*/ dest_mode,
|
||||||
|
/*MASK_MODE*/ mask_mode);
|
||||||
e.set_policy (TAIL_ANY);
|
e.set_policy (TAIL_ANY);
|
||||||
e.set_policy (MASK_ANY);
|
e.set_policy (MASK_ANY);
|
||||||
e.set_vl (vl);
|
e.set_vl (vl);
|
||||||
e.emit_insn ((enum insn_code) icode, ops);
|
e.emit_insn ((enum insn_code) icode, ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function emits a {VLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
|
||||||
|
* ternary operation which always has a real merge operand. */
|
||||||
|
void
|
||||||
|
emit_vlmax_fp_ternary_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
|
||||||
|
{
|
||||||
|
machine_mode dest_mode = GET_MODE (ops[0]);
|
||||||
|
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
||||||
|
insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
|
||||||
|
/*HAS_DEST_P*/ true,
|
||||||
|
/*FULLY_UNMASKED_P*/ true,
|
||||||
|
/*USE_REAL_MERGE_P*/ true,
|
||||||
|
/*HAS_AVL_P*/ true,
|
||||||
|
/*VLMAX_P*/ true,
|
||||||
|
/*DEST_MODE*/ dest_mode,
|
||||||
|
/*MASK_MODE*/ mask_mode);
|
||||||
|
e.set_policy (TAIL_ANY);
|
||||||
|
e.set_policy (MASK_ANY);
|
||||||
|
e.set_rounding_mode (FRM_DYN);
|
||||||
|
e.set_vl (vl);
|
||||||
|
e.emit_insn ((enum insn_code) icode, ops);
|
||||||
|
}
|
||||||
|
|
||||||
/* This function emits a {NONVLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
|
/* This function emits a {NONVLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
|
||||||
* actual operation. */
|
* actual operation. */
|
||||||
void
|
void
|
||||||
|
|
@ -841,17 +864,56 @@ emit_vlmax_cmp_mu_insn (unsigned icode, rtx *ops)
|
||||||
e.emit_insn ((enum insn_code) icode, ops);
|
e.emit_insn ((enum insn_code) icode, ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function emits a masked instruction. */
|
||||||
|
static void
|
||||||
|
emit_vlmax_masked_insn (unsigned icode, int op_num, rtx *ops)
|
||||||
|
{
|
||||||
|
machine_mode dest_mode = GET_MODE (ops[0]);
|
||||||
|
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
||||||
|
insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
|
||||||
|
/*HAS_DEST_P*/ true,
|
||||||
|
/*FULLY_UNMASKED_P*/ false,
|
||||||
|
/*USE_REAL_MERGE_P*/ true,
|
||||||
|
/*HAS_AVL_P*/ true,
|
||||||
|
/*VLMAX_P*/ true, dest_mode,
|
||||||
|
mask_mode);
|
||||||
|
e.set_policy (TAIL_ANY);
|
||||||
|
e.set_policy (MASK_ANY);
|
||||||
|
e.emit_insn ((enum insn_code) icode, ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function emits a masked instruction. */
|
||||||
|
static void
|
||||||
|
emit_nonvlmax_masked_insn (unsigned icode, int op_num, rtx *ops, rtx avl)
|
||||||
|
{
|
||||||
|
machine_mode dest_mode = GET_MODE (ops[0]);
|
||||||
|
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
||||||
|
insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
|
||||||
|
/*HAS_DEST_P*/ true,
|
||||||
|
/*FULLY_UNMASKED_P*/ false,
|
||||||
|
/*USE_REAL_MERGE_P*/ true,
|
||||||
|
/*HAS_AVL_P*/ true,
|
||||||
|
/*VLMAX_P*/ false, dest_mode,
|
||||||
|
mask_mode);
|
||||||
|
e.set_policy (TAIL_ANY);
|
||||||
|
e.set_policy (MASK_ANY);
|
||||||
|
e.set_vl (avl);
|
||||||
|
e.emit_insn ((enum insn_code) icode, ops);
|
||||||
|
}
|
||||||
|
|
||||||
/* This function emits a masked instruction. */
|
/* This function emits a masked instruction. */
|
||||||
void
|
void
|
||||||
emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops)
|
emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops)
|
||||||
{
|
{
|
||||||
machine_mode dest_mode = GET_MODE (ops[0]);
|
machine_mode dest_mode = GET_MODE (ops[0]);
|
||||||
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
machine_mode mask_mode = get_mask_mode (dest_mode).require ();
|
||||||
insn_expander<11> e (/*OP_NUM*/ op_num, /*HAS_DEST_P*/ true,
|
insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
|
||||||
/*FULLY_UNMASKED_P*/ false,
|
/*HAS_DEST_P*/ true,
|
||||||
/*USE_REAL_MERGE_P*/ true,
|
/*FULLY_UNMASKED_P*/ false,
|
||||||
/*HAS_AVL_P*/ true,
|
/*USE_REAL_MERGE_P*/ true,
|
||||||
/*VLMAX_P*/ true, dest_mode, mask_mode);
|
/*HAS_AVL_P*/ true,
|
||||||
|
/*VLMAX_P*/ true, dest_mode,
|
||||||
|
mask_mode);
|
||||||
e.set_policy (TAIL_ANY);
|
e.set_policy (TAIL_ANY);
|
||||||
e.set_policy (MASK_UNDISTURBED);
|
e.set_policy (MASK_UNDISTURBED);
|
||||||
e.emit_insn ((enum insn_code) icode, ops);
|
e.emit_insn ((enum insn_code) icode, ops);
|
||||||
|
|
@ -2359,28 +2421,6 @@ expand_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand an RVV vcond pattern with operands OPS. DATA_MODE is the mode
|
|
||||||
of the data being merged and CMP_MODE is the mode of the values being
|
|
||||||
compared. */
|
|
||||||
|
|
||||||
void
|
|
||||||
expand_vcond (rtx *ops)
|
|
||||||
{
|
|
||||||
machine_mode cmp_mode = GET_MODE (ops[4]);
|
|
||||||
machine_mode data_mode = GET_MODE (ops[1]);
|
|
||||||
machine_mode mask_mode = get_mask_mode (cmp_mode).require ();
|
|
||||||
rtx mask = gen_reg_rtx (mask_mode);
|
|
||||||
if (FLOAT_MODE_P (cmp_mode))
|
|
||||||
{
|
|
||||||
if (expand_vec_cmp_float (mask, GET_CODE (ops[3]), ops[4], ops[5], true))
|
|
||||||
std::swap (ops[1], ops[2]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
expand_vec_cmp (mask, GET_CODE (ops[3]), ops[4], ops[5]);
|
|
||||||
emit_insn (
|
|
||||||
gen_vcond_mask (data_mode, data_mode, ops[0], ops[1], ops[2], mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implement vec_perm<mode>. */
|
/* Implement vec_perm<mode>. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2721,4 +2761,45 @@ expand_select_vl (rtx *ops)
|
||||||
emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1]));
|
emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expand LEN_MASK_{LOAD,STORE}. */
|
||||||
|
void
|
||||||
|
expand_load_store (rtx *ops, bool is_load)
|
||||||
|
{
|
||||||
|
poly_int64 value;
|
||||||
|
rtx len = ops[2];
|
||||||
|
rtx mask = ops[3];
|
||||||
|
machine_mode mode = GET_MODE (ops[0]);
|
||||||
|
|
||||||
|
if (poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode)))
|
||||||
|
{
|
||||||
|
/* If the length operand is equal to VF, it is VLMAX load/store. */
|
||||||
|
if (is_load)
|
||||||
|
{
|
||||||
|
rtx m_ops[] = {ops[0], mask, RVV_VUNDEF (mode), ops[1]};
|
||||||
|
emit_vlmax_masked_insn (code_for_pred_mov (mode), RVV_UNOP_M, m_ops);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = gen_reg_rtx (Pmode);
|
||||||
|
emit_vlmax_vsetvl (mode, len);
|
||||||
|
emit_insn (gen_pred_store (mode, ops[0], mask, ops[1], len,
|
||||||
|
get_avl_type_rtx (VLMAX)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!satisfies_constraint_K (len))
|
||||||
|
len = force_reg (Pmode, len);
|
||||||
|
if (is_load)
|
||||||
|
{
|
||||||
|
rtx m_ops[] = {ops[0], mask, RVV_VUNDEF (mode), ops[1]};
|
||||||
|
emit_nonvlmax_masked_insn (code_for_pred_mov (mode), RVV_UNOP_M,
|
||||||
|
m_ops, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emit_insn (gen_pred_store (mode, ops[0], mask, ops[1], len,
|
||||||
|
get_avl_type_rtx (NONVLMAX)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace riscv_vector
|
} // namespace riscv_vector
|
||||||
|
|
|
||||||
|
|
@ -1567,7 +1567,7 @@ public:
|
||||||
{
|
{
|
||||||
tree arg = CALL_EXPR_ARG (e.exp, 0);
|
tree arg = CALL_EXPR_ARG (e.exp, 0);
|
||||||
rtx src = expand_normal (arg);
|
rtx src = expand_normal (arg);
|
||||||
emit_insn (gen_rtx_SET (gen_lowpart (e.vector_mode (), e.target), src));
|
emit_move_insn (gen_lowpart (e.vector_mode (), e.target), src);
|
||||||
return e.target;
|
return e.target;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,6 @@ extern const function_base *const vsmul;
|
||||||
extern const function_base *const vssra;
|
extern const function_base *const vssra;
|
||||||
extern const function_base *const vssrl;
|
extern const function_base *const vssrl;
|
||||||
extern const function_base *const vnclip;
|
extern const function_base *const vnclip;
|
||||||
extern const function_base *const vnclip;
|
|
||||||
extern const function_base *const vnclipu;
|
|
||||||
extern const function_base *const vnclipu;
|
extern const function_base *const vnclipu;
|
||||||
extern const function_base *const vmand;
|
extern const function_base *const vmand;
|
||||||
extern const function_base *const vmnand;
|
extern const function_base *const vmnand;
|
||||||
|
|
@ -144,8 +142,6 @@ extern const function_base *const vmsof;
|
||||||
extern const function_base *const viota;
|
extern const function_base *const viota;
|
||||||
extern const function_base *const vid;
|
extern const function_base *const vid;
|
||||||
extern const function_base *const vfadd;
|
extern const function_base *const vfadd;
|
||||||
extern const function_base *const vfadd;
|
|
||||||
extern const function_base *const vfsub;
|
|
||||||
extern const function_base *const vfsub;
|
extern const function_base *const vfsub;
|
||||||
extern const function_base *const vfrsub;
|
extern const function_base *const vfrsub;
|
||||||
extern const function_base *const vfwadd;
|
extern const function_base *const vfwadd;
|
||||||
|
|
@ -153,7 +149,6 @@ extern const function_base *const vfwsub;
|
||||||
extern const function_base *const vfmul;
|
extern const function_base *const vfmul;
|
||||||
extern const function_base *const vfmul;
|
extern const function_base *const vfmul;
|
||||||
extern const function_base *const vfdiv;
|
extern const function_base *const vfdiv;
|
||||||
extern const function_base *const vfdiv;
|
|
||||||
extern const function_base *const vfrdiv;
|
extern const function_base *const vfrdiv;
|
||||||
extern const function_base *const vfwmul;
|
extern const function_base *const vfwmul;
|
||||||
extern const function_base *const vfmacc;
|
extern const function_base *const vfmacc;
|
||||||
|
|
|
||||||
|
|
@ -1291,31 +1291,6 @@ DEF_RVV_TUPLE_OPS (vint64m2x4_t, RVV_REQUIRE_ELEN_64)
|
||||||
DEF_RVV_TUPLE_OPS (vuint64m2x4_t, RVV_REQUIRE_ELEN_64)
|
DEF_RVV_TUPLE_OPS (vuint64m2x4_t, RVV_REQUIRE_ELEN_64)
|
||||||
DEF_RVV_TUPLE_OPS (vint64m4x2_t, RVV_REQUIRE_ELEN_64)
|
DEF_RVV_TUPLE_OPS (vint64m4x2_t, RVV_REQUIRE_ELEN_64)
|
||||||
DEF_RVV_TUPLE_OPS (vuint64m4x2_t, RVV_REQUIRE_ELEN_64)
|
DEF_RVV_TUPLE_OPS (vuint64m4x2_t, RVV_REQUIRE_ELEN_64)
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x2_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x3_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x4_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x5_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x6_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x7_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf4x8_t, RVV_REQUIRE_ELEN_FP_16 | RVV_REQUIRE_MIN_VLEN_64)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x2_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x3_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x4_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x5_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x6_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x7_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16mf2x8_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x2_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x3_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x4_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x5_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x6_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x7_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m1x8_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m2x2_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m2x3_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m2x4_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat16m4x2_t, RVV_REQUIRE_ELEN_FP_16)
|
|
||||||
DEF_RVV_TUPLE_OPS (vfloat32mf2x2_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64)
|
DEF_RVV_TUPLE_OPS (vfloat32mf2x2_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64)
|
||||||
DEF_RVV_TUPLE_OPS (vfloat32mf2x3_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64)
|
DEF_RVV_TUPLE_OPS (vfloat32mf2x3_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64)
|
||||||
DEF_RVV_TUPLE_OPS (vfloat32mf2x4_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64)
|
DEF_RVV_TUPLE_OPS (vfloat32mf2x4_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64)
|
||||||
|
|
|
||||||
|
|
@ -3636,6 +3636,7 @@ function_expander::use_contiguous_store_insn (insn_code icode)
|
||||||
for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++)
|
for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++)
|
||||||
add_input_operand (argno);
|
add_input_operand (argno);
|
||||||
|
|
||||||
|
add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
|
||||||
return generate_insn (icode);
|
return generate_insn (icode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -494,48 +494,18 @@ DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, uint64, VNx16DI, VNx8DI, VOID,
|
||||||
/* LMUL = 1/4. */
|
/* LMUL = 1/4. */
|
||||||
DEF_RVV_TYPE (vfloat16mf4_t, 18, __rvv_float16mf4_t, float16, VNx2HF, VNx1HF, VOID,
|
DEF_RVV_TYPE (vfloat16mf4_t, 18, __rvv_float16mf4_t, float16, VNx2HF, VNx1HF, VOID,
|
||||||
_f16mf4, _f16, _e16mf4)
|
_f16mf4, _f16, _e16mf4)
|
||||||
/* Define tuple types for SEW = 16, LMUL = MF4. */
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x2_t, 20, __rvv_float16mf4x2_t, vfloat16mf4_t, float, 2, _f16mf4x2)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x3_t, 20, __rvv_float16mf4x3_t, vfloat16mf4_t, float, 3, _f16mf4x3)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x4_t, 20, __rvv_float16mf4x4_t, vfloat16mf4_t, float, 4, _f16mf4x4)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x5_t, 20, __rvv_float16mf4x5_t, vfloat16mf4_t, float, 5, _f16mf4x5)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x6_t, 20, __rvv_float16mf4x6_t, vfloat16mf4_t, float, 6, _f16mf4x6)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x7_t, 20, __rvv_float16mf4x7_t, vfloat16mf4_t, float, 7, _f16mf4x7)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf4x8_t, 20, __rvv_float16mf4x8_t, vfloat16mf4_t, float, 8, _f16mf4x8)
|
|
||||||
/* LMUL = 1/2. */
|
/* LMUL = 1/2. */
|
||||||
DEF_RVV_TYPE (vfloat16mf2_t, 18, __rvv_float16mf2_t, float16, VNx4HF, VNx2HF, VNx1HF,
|
DEF_RVV_TYPE (vfloat16mf2_t, 18, __rvv_float16mf2_t, float16, VNx4HF, VNx2HF, VNx1HF,
|
||||||
_f16mf2, _f16, _e16mf2)
|
_f16mf2, _f16, _e16mf2)
|
||||||
/* Define tuple types for SEW = 16, LMUL = MF2. */
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x2_t, 20, __rvv_float16mf2x2_t, vfloat16mf2_t, float, 2, _f16mf2x2)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x3_t, 20, __rvv_float16mf2x3_t, vfloat16mf2_t, float, 3, _f16mf2x3)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x4_t, 20, __rvv_float16mf2x4_t, vfloat16mf2_t, float, 4, _f16mf2x4)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x5_t, 20, __rvv_float16mf2x5_t, vfloat16mf2_t, float, 5, _f16mf2x5)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x6_t, 20, __rvv_float16mf2x6_t, vfloat16mf2_t, float, 6, _f16mf2x6)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x7_t, 20, __rvv_float16mf2x7_t, vfloat16mf2_t, float, 7, _f16mf2x7)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16mf2x8_t, 20, __rvv_float16mf2x8_t, vfloat16mf2_t, float, 8, _f16mf2x8)
|
|
||||||
/* LMUL = 1. */
|
/* LMUL = 1. */
|
||||||
DEF_RVV_TYPE (vfloat16m1_t, 17, __rvv_float16m1_t, float16, VNx8HF, VNx4HF, VNx2HF,
|
DEF_RVV_TYPE (vfloat16m1_t, 17, __rvv_float16m1_t, float16, VNx8HF, VNx4HF, VNx2HF,
|
||||||
_f16m1, _f16, _e16m1)
|
_f16m1, _f16, _e16m1)
|
||||||
/* Define tuple types for SEW = 16, LMUL = M1. */
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x2_t, 19, __rvv_float16m1x2_t, vfloat16m1_t, float, 2, _f16m1x2)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x3_t, 19, __rvv_float16m1x3_t, vfloat16m1_t, float, 3, _f16m1x3)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x4_t, 19, __rvv_float16m1x4_t, vfloat16m1_t, float, 4, _f16m1x4)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x5_t, 19, __rvv_float16m1x5_t, vfloat16m1_t, float, 5, _f16m1x5)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x6_t, 19, __rvv_float16m1x6_t, vfloat16m1_t, float, 6, _f16m1x6)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x7_t, 19, __rvv_float16m1x7_t, vfloat16m1_t, float, 7, _f16m1x7)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m1x8_t, 19, __rvv_float16m1x8_t, vfloat16m1_t, float, 8, _f16m1x8)
|
|
||||||
/* LMUL = 2. */
|
/* LMUL = 2. */
|
||||||
DEF_RVV_TYPE (vfloat16m2_t, 17, __rvv_float16m2_t, float16, VNx16HF, VNx8HF, VNx4HF,
|
DEF_RVV_TYPE (vfloat16m2_t, 17, __rvv_float16m2_t, float16, VNx16HF, VNx8HF, VNx4HF,
|
||||||
_f16m2, _f16, _e16m2)
|
_f16m2, _f16, _e16m2)
|
||||||
/* Define tuple types for SEW = 16, LMUL = M2. */
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m2x2_t, 19, __rvv_float16m2x2_t, vfloat16m2_t, float, 2, _f16m2x2)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m2x3_t, 19, __rvv_float16m2x3_t, vfloat16m2_t, float, 3, _f16m2x3)
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m2x4_t, 19, __rvv_float16m2x4_t, vfloat16m2_t, float, 4, _f16m2x4)
|
|
||||||
/* LMUL = 4. */
|
/* LMUL = 4. */
|
||||||
DEF_RVV_TYPE (vfloat16m4_t, 17, __rvv_float16m4_t, float16, VNx32HF, VNx16HF, VNx8HF,
|
DEF_RVV_TYPE (vfloat16m4_t, 17, __rvv_float16m4_t, float16, VNx32HF, VNx16HF, VNx8HF,
|
||||||
_f16m4, _f16, _e16m4)
|
_f16m4, _f16, _e16m4)
|
||||||
/* Define tuple types for SEW = 16, LMUL = M4. */
|
|
||||||
DEF_RVV_TUPLE_TYPE (vfloat16m4x2_t, 19, __rvv_float16m4x2_t, vfloat16m4_t, float, 2, _f16m4x2)
|
|
||||||
/* LMUL = 8. */
|
/* LMUL = 8. */
|
||||||
DEF_RVV_TYPE (vfloat16m8_t, 16, __rvv_float16m8_t, float16, VNx64HF, VNx32HF, VNx16HF,
|
DEF_RVV_TYPE (vfloat16m8_t, 16, __rvv_float16m8_t, float16, VNx64HF, VNx32HF, VNx16HF,
|
||||||
_f16m8, _f16, _e16m8)
|
_f16m8, _f16, _e16m8)
|
||||||
|
|
|
||||||
|
|
@ -248,38 +248,6 @@ TUPLE_ENTRY (VNx5x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 5, LMUL_F2, 32, LMUL_F4, 6
|
||||||
TUPLE_ENTRY (VNx6x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 6, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
TUPLE_ENTRY (VNx6x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 6, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
||||||
TUPLE_ENTRY (VNx7x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 7, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
TUPLE_ENTRY (VNx7x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 7, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
||||||
TUPLE_ENTRY (VNx8x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 8, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
TUPLE_ENTRY (VNx8x1HI, TARGET_MIN_VLEN < 128, VNx1HI, 8, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
||||||
TUPLE_ENTRY (VNx2x32HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx32HF, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 4)
|
|
||||||
TUPLE_ENTRY (VNx2x16HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx16HF, 2, LMUL_RESERVED, 0, LMUL_4, 4, LMUL_2, 8)
|
|
||||||
TUPLE_ENTRY (VNx3x16HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx16HF, 3, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 8)
|
|
||||||
TUPLE_ENTRY (VNx4x16HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx16HF, 4, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_2, 8)
|
|
||||||
TUPLE_ENTRY (VNx2x8HF, TARGET_VECTOR_ELEN_FP_16, VNx8HF, 2, LMUL_4, 4, LMUL_2, 8, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx3x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx8HF, 3, LMUL_RESERVED, 0, LMUL_2, 8, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx4x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx8HF, 4, LMUL_RESERVED, 0, LMUL_2, 8, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx5x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 5, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx6x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 6, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx7x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 7, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx8x8HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128, VNx8HF, 8, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_1, 16)
|
|
||||||
TUPLE_ENTRY (VNx2x4HF, TARGET_VECTOR_ELEN_FP_16, VNx4HF, 2, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx3x4HF, TARGET_VECTOR_ELEN_FP_16, VNx4HF, 3, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx4x4HF, TARGET_VECTOR_ELEN_FP_16, VNx4HF, 4, LMUL_2, 8, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx5x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 5, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx6x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 6, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx7x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 7, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx8x4HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64, VNx4HF, 8, LMUL_RESERVED, 0, LMUL_1, 16, LMUL_F2, 32)
|
|
||||||
TUPLE_ENTRY (VNx2x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 2, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx3x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 3, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx4x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 4, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx5x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 5, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx6x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 6, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx7x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 7, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx8x2HF, TARGET_VECTOR_ELEN_FP_16, VNx2HF, 8, LMUL_1, 16, LMUL_F2, 32, LMUL_F4, 64)
|
|
||||||
TUPLE_ENTRY (VNx2x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 2, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
TUPLE_ENTRY (VNx3x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 3, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
TUPLE_ENTRY (VNx4x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 4, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
TUPLE_ENTRY (VNx5x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 5, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
TUPLE_ENTRY (VNx6x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 6, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
TUPLE_ENTRY (VNx7x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 7, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
TUPLE_ENTRY (VNx8x1HF, TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128, VNx1HF, 8, LMUL_F2, 32, LMUL_F4, 64, LMUL_RESERVED, 0)
|
|
||||||
|
|
||||||
/* Tuple modes for EEW = 32. */
|
/* Tuple modes for EEW = 32. */
|
||||||
TUPLE_ENTRY (VNx2x16SI, TARGET_MIN_VLEN >= 128, VNx16SI, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 8)
|
TUPLE_ENTRY (VNx2x16SI, TARGET_MIN_VLEN >= 128, VNx16SI, 2, LMUL_RESERVED, 0, LMUL_RESERVED, 0, LMUL_4, 8)
|
||||||
|
|
|
||||||
|
|
@ -2003,9 +2003,51 @@ vector_insn_info::parse_insn (insn_info *insn)
|
||||||
new_info.parse_insn (def_insn);
|
new_info.parse_insn (def_insn);
|
||||||
if (!same_vlmax_p (new_info) && !scalar_move_insn_p (insn->rtl ()))
|
if (!same_vlmax_p (new_info) && !scalar_move_insn_p (insn->rtl ()))
|
||||||
return;
|
return;
|
||||||
/* TODO: Currently, we don't forward AVL for non-VLMAX vsetvl. */
|
|
||||||
if (vlmax_avl_p (new_info.get_avl ()))
|
if (new_info.has_avl ())
|
||||||
set_avl_info (avl_info (new_info.get_avl (), get_avl_source ()));
|
{
|
||||||
|
if (new_info.has_avl_imm ())
|
||||||
|
set_avl_info (avl_info (new_info.get_avl (), nullptr));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (vlmax_avl_p (new_info.get_avl ()))
|
||||||
|
set_avl_info (avl_info (new_info.get_avl (), get_avl_source ()));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Conservatively propagate non-VLMAX AVL of user vsetvl:
|
||||||
|
1. The user vsetvl should be same block with the rvv insn.
|
||||||
|
2. The user vsetvl is the only def insn of rvv insn.
|
||||||
|
3. The AVL is not modified between def-use chain.
|
||||||
|
4. The VL is only used by insn within EBB.
|
||||||
|
*/
|
||||||
|
bool modified_p = false;
|
||||||
|
for (insn_info *i = def_insn->next_nondebug_insn ();
|
||||||
|
real_insn_and_same_bb_p (i, get_insn ()->bb ());
|
||||||
|
i = i->next_nondebug_insn ())
|
||||||
|
{
|
||||||
|
if (find_access (i->defs (), REGNO (new_info.get_avl ())))
|
||||||
|
{
|
||||||
|
modified_p = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_live_out_use = false;
|
||||||
|
for (use_info *use : m_avl.get_source ()->all_uses ())
|
||||||
|
{
|
||||||
|
if (use->is_live_out_use ())
|
||||||
|
{
|
||||||
|
has_live_out_use = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!modified_p && !has_live_out_use
|
||||||
|
&& def_insn == m_avl.get_source ()->insn ()
|
||||||
|
&& m_insn->bb () == def_insn->bb ())
|
||||||
|
set_avl_info (new_info.get_avl_info ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (scalar_move_insn_p (insn->rtl ()) && m_avl.has_non_zero_avl ())
|
if (scalar_move_insn_p (insn->rtl ()) && m_avl.has_non_zero_avl ())
|
||||||
m_demands[DEMAND_NONZERO_AVL] = true;
|
m_demands[DEMAND_NONZERO_AVL] = true;
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ public:
|
||||||
bool has_avl_reg () const { return get_value () && REG_P (get_value ()); }
|
bool has_avl_reg () const { return get_value () && REG_P (get_value ()); }
|
||||||
bool has_avl_no_reg () const { return !get_value (); }
|
bool has_avl_no_reg () const { return !get_value (); }
|
||||||
bool has_non_zero_avl () const;
|
bool has_non_zero_avl () const;
|
||||||
|
bool has_avl () const { return get_value (); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Basic structure to save VL/VTYPE information. */
|
/* Basic structure to save VL/VTYPE information. */
|
||||||
|
|
@ -219,6 +220,7 @@ public:
|
||||||
bool has_avl_reg () const { return m_avl.has_avl_reg (); }
|
bool has_avl_reg () const { return m_avl.has_avl_reg (); }
|
||||||
bool has_avl_no_reg () const { return m_avl.has_avl_no_reg (); }
|
bool has_avl_no_reg () const { return m_avl.has_avl_no_reg (); }
|
||||||
bool has_non_zero_avl () const { return m_avl.has_non_zero_avl (); };
|
bool has_non_zero_avl () const { return m_avl.has_non_zero_avl (); };
|
||||||
|
bool has_avl () const { return m_avl.has_avl (); }
|
||||||
|
|
||||||
rtx get_avl () const { return m_avl.get_value (); }
|
rtx get_avl () const { return m_avl.get_value (); }
|
||||||
const avl_info &get_avl_info () const { return m_avl; }
|
const avl_info &get_avl_info () const { return m_avl; }
|
||||||
|
|
|
||||||
|
|
@ -191,11 +191,6 @@
|
||||||
VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI,
|
VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI,
|
||||||
VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI,
|
VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI,
|
||||||
VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI,
|
VNx2x1HI,VNx3x1HI,VNx4x1HI,VNx5x1HI,VNx6x1HI,VNx7x1HI,VNx8x1HI,
|
||||||
VNx2x32HF,VNx2x16HF,VNx3x16HF,VNx4x16HF,
|
|
||||||
VNx2x8HF,VNx3x8HF,VNx4x8HF,VNx5x8HF,VNx6x8HF,VNx7x8HF,VNx8x8HF,
|
|
||||||
VNx2x4HF,VNx3x4HF,VNx4x4HF,VNx5x4HF,VNx6x4HF,VNx7x4HF,VNx8x4HF,
|
|
||||||
VNx2x2HF,VNx3x2HF,VNx4x2HF,VNx5x2HF,VNx6x2HF,VNx7x2HF,VNx8x2HF,
|
|
||||||
VNx2x1HF,VNx3x1HF,VNx4x1HF,VNx5x1HF,VNx6x1HF,VNx7x1HF,VNx8x1HF,
|
|
||||||
VNx2x16SI,VNx2x8SI,VNx3x8SI,VNx4x8SI,
|
VNx2x16SI,VNx2x8SI,VNx3x8SI,VNx4x8SI,
|
||||||
VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI,
|
VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI,
|
||||||
VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI,
|
VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI,
|
||||||
|
|
|
||||||
|
|
@ -652,38 +652,6 @@
|
||||||
(VNx6x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128")
|
(VNx6x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128")
|
||||||
(VNx7x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128")
|
(VNx7x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128")
|
||||||
(VNx8x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128")
|
(VNx8x1DI "TARGET_VECTOR_ELEN_64 && TARGET_MIN_VLEN < 128")
|
||||||
(VNx2x32HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx2x16HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx3x16HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx4x16HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx2x8HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx3x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx4x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx5x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx6x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx7x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx8x8HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 128")
|
|
||||||
(VNx2x4HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx3x4HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx4x4HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx5x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx6x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx7x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx8x4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN >= 64")
|
|
||||||
(VNx2x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx3x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx4x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx5x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx6x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx7x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx8x2HF "TARGET_VECTOR_ELEN_FP_16")
|
|
||||||
(VNx2x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx3x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx4x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx5x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx6x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx7x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx8x1HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_MIN_VLEN < 128")
|
|
||||||
(VNx2x16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
|
(VNx2x16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
|
||||||
(VNx2x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64")
|
(VNx2x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64")
|
||||||
(VNx3x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
|
(VNx3x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
|
||||||
|
|
@ -1154,11 +1122,6 @@
|
||||||
(VNx2x8DI "VNx8BI") (VNx2x4DI "VNx4BI") (VNx3x4DI "VNx4BI") (VNx4x4DI "VNx4BI")
|
(VNx2x8DI "VNx8BI") (VNx2x4DI "VNx4BI") (VNx3x4DI "VNx4BI") (VNx4x4DI "VNx4BI")
|
||||||
(VNx2x2DI "VNx2BI") (VNx3x2DI "VNx2BI") (VNx4x2DI "VNx2BI") (VNx5x2DI "VNx2BI") (VNx6x2DI "VNx2BI") (VNx7x2DI "VNx2BI") (VNx8x2DI "VNx2BI")
|
(VNx2x2DI "VNx2BI") (VNx3x2DI "VNx2BI") (VNx4x2DI "VNx2BI") (VNx5x2DI "VNx2BI") (VNx6x2DI "VNx2BI") (VNx7x2DI "VNx2BI") (VNx8x2DI "VNx2BI")
|
||||||
(VNx2x1DI "VNx1BI") (VNx3x1DI "VNx1BI") (VNx4x1DI "VNx1BI") (VNx5x1DI "VNx1BI") (VNx6x1DI "VNx1BI") (VNx7x1DI "VNx1BI") (VNx8x1DI "VNx1BI")
|
(VNx2x1DI "VNx1BI") (VNx3x1DI "VNx1BI") (VNx4x1DI "VNx1BI") (VNx5x1DI "VNx1BI") (VNx6x1DI "VNx1BI") (VNx7x1DI "VNx1BI") (VNx8x1DI "VNx1BI")
|
||||||
(VNx2x32HF "VNx32BI") (VNx2x16HF "VNx16BI") (VNx3x16HF "VNx16BI") (VNx4x16HF "VNx16BI")
|
|
||||||
(VNx2x8HF "VNx8BI") (VNx3x8HF "VNx8BI") (VNx4x8HF "VNx8BI") (VNx5x8HF "VNx8BI") (VNx6x8HF "VNx8BI") (VNx7x8HF "VNx8BI") (VNx8x8HF "VNx8BI")
|
|
||||||
(VNx2x4HF "VNx4BI") (VNx3x4HF "VNx4BI") (VNx4x4HF "VNx4BI") (VNx5x4HF "VNx4BI") (VNx6x4HF "VNx4BI") (VNx7x4HF "VNx4BI") (VNx8x4HF "VNx4BI")
|
|
||||||
(VNx2x2HF "VNx2BI") (VNx3x2HF "VNx2BI") (VNx4x2HF "VNx2BI") (VNx5x2HF "VNx2BI") (VNx6x2HF "VNx2BI") (VNx7x2HF "VNx2BI") (VNx8x2HF "VNx2BI")
|
|
||||||
(VNx2x1HF "VNx1BI") (VNx3x1HF "VNx1BI") (VNx4x1HF "VNx1BI") (VNx5x1HF "VNx1BI") (VNx6x1HF "VNx1BI") (VNx7x1HF "VNx1BI") (VNx8x1HF "VNx1BI")
|
|
||||||
(VNx2x16SF "VNx16BI") (VNx2x8SF "VNx8BI") (VNx3x8SF "VNx8BI") (VNx4x8SF "VNx8BI")
|
(VNx2x16SF "VNx16BI") (VNx2x8SF "VNx8BI") (VNx3x8SF "VNx8BI") (VNx4x8SF "VNx8BI")
|
||||||
(VNx2x4SF "VNx4BI") (VNx3x4SF "VNx4BI") (VNx4x4SF "VNx4BI") (VNx5x4SF "VNx4BI") (VNx6x4SF "VNx4BI") (VNx7x4SF "VNx4BI") (VNx8x4SF "VNx4BI")
|
(VNx2x4SF "VNx4BI") (VNx3x4SF "VNx4BI") (VNx4x4SF "VNx4BI") (VNx5x4SF "VNx4BI") (VNx6x4SF "VNx4BI") (VNx7x4SF "VNx4BI") (VNx8x4SF "VNx4BI")
|
||||||
(VNx2x2SF "VNx2BI") (VNx3x2SF "VNx2BI") (VNx4x2SF "VNx2BI") (VNx5x2SF "VNx2BI") (VNx6x2SF "VNx2BI") (VNx7x2SF "VNx2BI") (VNx8x2SF "VNx2BI")
|
(VNx2x2SF "VNx2BI") (VNx3x2SF "VNx2BI") (VNx4x2SF "VNx2BI") (VNx5x2SF "VNx2BI") (VNx6x2SF "VNx2BI") (VNx7x2SF "VNx2BI") (VNx8x2SF "VNx2BI")
|
||||||
|
|
|
||||||
|
|
@ -425,14 +425,14 @@
|
||||||
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
|
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
|
||||||
viwalu,viwmul,vnshift,vaalu,vsmul,vsshift,\
|
viwalu,viwmul,vnshift,vaalu,vsmul,vsshift,\
|
||||||
vnclip,vicmp,vfalu,vfmul,vfminmax,vfdiv,vfwalu,vfwmul,\
|
vnclip,vicmp,vfalu,vfmul,vfminmax,vfdiv,vfwalu,vfwmul,\
|
||||||
vfsgnj,vfcmp,vfmuladd,vslideup,vslidedown,vislide1up,\
|
vfsgnj,vfcmp,vslideup,vslidedown,vislide1up,\
|
||||||
vislide1down,vfslide1up,vfslide1down,vgather,viwmuladd,vfwmuladd,\
|
vislide1down,vfslide1up,vfslide1down,vgather,viwmuladd,vfwmuladd,\
|
||||||
vlsegds,vlsegdux,vlsegdox")
|
vlsegds,vlsegdux,vlsegdox")
|
||||||
(symbol_ref "INTVAL (operands[8])")
|
(symbol_ref "INTVAL (operands[8])")
|
||||||
(eq_attr "type" "vstux,vstox,vssegts,vssegtux,vssegtox")
|
(eq_attr "type" "vstux,vstox,vssegts,vssegtux,vssegtox")
|
||||||
(symbol_ref "INTVAL (operands[5])")
|
(symbol_ref "INTVAL (operands[5])")
|
||||||
|
|
||||||
(eq_attr "type" "vimuladd")
|
(eq_attr "type" "vimuladd,vfmuladd")
|
||||||
(symbol_ref "INTVAL (operands[9])")
|
(symbol_ref "INTVAL (operands[9])")
|
||||||
|
|
||||||
(eq_attr "type" "vmsfs,vmidx,vcompress")
|
(eq_attr "type" "vmsfs,vmidx,vcompress")
|
||||||
|
|
@ -1063,6 +1063,7 @@
|
||||||
(unspec:<VM>
|
(unspec:<VM>
|
||||||
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
|
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
|
||||||
(match_operand 3 "vector_length_operand" " rK")
|
(match_operand 3 "vector_length_operand" " rK")
|
||||||
|
(match_operand 4 "const_int_operand" " i")
|
||||||
(reg:SI VL_REGNUM)
|
(reg:SI VL_REGNUM)
|
||||||
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
||||||
(match_operand:V 2 "register_operand" " vr")
|
(match_operand:V 2 "register_operand" " vr")
|
||||||
|
|
@ -1071,7 +1072,7 @@
|
||||||
"vse<sew>.v\t%2,%0%p1"
|
"vse<sew>.v\t%2,%0%p1"
|
||||||
[(set_attr "type" "vste")
|
[(set_attr "type" "vste")
|
||||||
(set_attr "mode" "<MODE>")
|
(set_attr "mode" "<MODE>")
|
||||||
(set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
|
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))
|
||||||
(set_attr "vl_op_idx" "3")])
|
(set_attr "vl_op_idx" "3")])
|
||||||
|
|
||||||
;; vlm.v/vsm.v/vmclr.m/vmset.m.
|
;; vlm.v/vsm.v/vmclr.m/vmset.m.
|
||||||
|
|
@ -1113,6 +1114,7 @@
|
||||||
(unspec:VB
|
(unspec:VB
|
||||||
[(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1")
|
[(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1")
|
||||||
(match_operand 3 "vector_length_operand" " rK")
|
(match_operand 3 "vector_length_operand" " rK")
|
||||||
|
(match_operand 4 "const_int_operand" " i")
|
||||||
(reg:SI VL_REGNUM)
|
(reg:SI VL_REGNUM)
|
||||||
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
||||||
(match_operand:VB 2 "register_operand" " vr")
|
(match_operand:VB 2 "register_operand" " vr")
|
||||||
|
|
@ -1121,7 +1123,7 @@
|
||||||
"vsm.v\t%2,%0"
|
"vsm.v\t%2,%0"
|
||||||
[(set_attr "type" "vstm")
|
[(set_attr "type" "vstm")
|
||||||
(set_attr "mode" "<MODE>")
|
(set_attr "mode" "<MODE>")
|
||||||
(set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
|
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))
|
||||||
(set_attr "vl_op_idx" "3")])
|
(set_attr "vl_op_idx" "3")])
|
||||||
|
|
||||||
(define_insn "@pred_merge<mode>"
|
(define_insn "@pred_merge<mode>"
|
||||||
|
|
@ -1433,6 +1435,7 @@
|
||||||
(unspec:<VM>
|
(unspec:<VM>
|
||||||
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
|
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
|
||||||
(match_operand 4 "vector_length_operand" " rK")
|
(match_operand 4 "vector_length_operand" " rK")
|
||||||
|
(match_operand 5 "const_int_operand" " i")
|
||||||
(reg:SI VL_REGNUM)
|
(reg:SI VL_REGNUM)
|
||||||
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
||||||
(unspec:V
|
(unspec:V
|
||||||
|
|
@ -1442,7 +1445,8 @@
|
||||||
"TARGET_VECTOR"
|
"TARGET_VECTOR"
|
||||||
"vsse<sew>.v\t%3,%0,%z2%p1"
|
"vsse<sew>.v\t%3,%0,%z2%p1"
|
||||||
[(set_attr "type" "vsts")
|
[(set_attr "type" "vsts")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")
|
||||||
|
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
|
||||||
|
|
||||||
;; -------------------------------------------------------------------------------
|
;; -------------------------------------------------------------------------------
|
||||||
;; ---- Predicated indexed loads/stores
|
;; ---- Predicated indexed loads/stores
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
;; load mode is DI result mode is clobber compare mode is CC extend is none
|
;; load mode is DI result mode is clobber compare mode is CC extend is none
|
||||||
(define_insn_and_split "*ld_cmpdi_cr0_DI_clobber_CC_none"
|
(define_insn_and_split "*ld_cmpdi_cr0_DI_clobber_CC_none"
|
||||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
||||||
(compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m")
|
(compare:CC (match_operand:DI 1 "non_update_memory_operand" "YZ")
|
||||||
(match_operand:DI 3 "const_m1_to_1_operand" "n")))
|
(match_operand:DI 3 "const_m1_to_1_operand" "n")))
|
||||||
(clobber (match_scratch:DI 0 "=r"))]
|
(clobber (match_scratch:DI 0 "=r"))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
;; load mode is DI result mode is clobber compare mode is CCUNS extend is none
|
;; load mode is DI result mode is clobber compare mode is CCUNS extend is none
|
||||||
(define_insn_and_split "*ld_cmpldi_cr0_DI_clobber_CCUNS_none"
|
(define_insn_and_split "*ld_cmpldi_cr0_DI_clobber_CCUNS_none"
|
||||||
[(set (match_operand:CCUNS 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CCUNS 2 "cc_reg_operand" "=x")
|
||||||
(compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m")
|
(compare:CCUNS (match_operand:DI 1 "non_update_memory_operand" "YZ")
|
||||||
(match_operand:DI 3 "const_0_to_1_operand" "n")))
|
(match_operand:DI 3 "const_0_to_1_operand" "n")))
|
||||||
(clobber (match_scratch:DI 0 "=r"))]
|
(clobber (match_scratch:DI 0 "=r"))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
;; load mode is DI result mode is DI compare mode is CC extend is none
|
;; load mode is DI result mode is DI compare mode is CC extend is none
|
||||||
(define_insn_and_split "*ld_cmpdi_cr0_DI_DI_CC_none"
|
(define_insn_and_split "*ld_cmpdi_cr0_DI_DI_CC_none"
|
||||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
||||||
(compare:CC (match_operand:DI 1 "ds_form_mem_operand" "m")
|
(compare:CC (match_operand:DI 1 "non_update_memory_operand" "YZ")
|
||||||
(match_operand:DI 3 "const_m1_to_1_operand" "n")))
|
(match_operand:DI 3 "const_m1_to_1_operand" "n")))
|
||||||
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
;; load mode is DI result mode is DI compare mode is CCUNS extend is none
|
;; load mode is DI result mode is DI compare mode is CCUNS extend is none
|
||||||
(define_insn_and_split "*ld_cmpldi_cr0_DI_DI_CCUNS_none"
|
(define_insn_and_split "*ld_cmpldi_cr0_DI_DI_CCUNS_none"
|
||||||
[(set (match_operand:CCUNS 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CCUNS 2 "cc_reg_operand" "=x")
|
||||||
(compare:CCUNS (match_operand:DI 1 "ds_form_mem_operand" "m")
|
(compare:CCUNS (match_operand:DI 1 "non_update_memory_operand" "YZ")
|
||||||
(match_operand:DI 3 "const_0_to_1_operand" "n")))
|
(match_operand:DI 3 "const_0_to_1_operand" "n")))
|
||||||
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
|
|
@ -104,17 +104,17 @@
|
||||||
|
|
||||||
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
||||||
;; load mode is SI result mode is clobber compare mode is CC extend is none
|
;; load mode is SI result mode is clobber compare mode is CC extend is none
|
||||||
(define_insn_and_split "*lwa_cmpdi_cr0_SI_clobber_CC_none"
|
(define_insn_and_split "*lwz_cmpwi_cr0_SI_clobber_CC_none"
|
||||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
||||||
(compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m")
|
(compare:CC (match_operand:SI 1 "non_update_memory_operand" "m")
|
||||||
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
|
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
|
||||||
(clobber (match_scratch:SI 0 "=r"))]
|
(clobber (match_scratch:SI 0 "=r"))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
"lwa%X1 %0,%1\;cmpdi %2,%0,%3"
|
"lwz%X1 %0,%1\;cmpwi %2,%0,%3"
|
||||||
"&& reload_completed
|
"&& reload_completed
|
||||||
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
||||||
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
||||||
SImode, NON_PREFIXED_DS))"
|
SImode, NON_PREFIXED_D))"
|
||||||
[(set (match_dup 0) (match_dup 1))
|
[(set (match_dup 0) (match_dup 1))
|
||||||
(set (match_dup 2)
|
(set (match_dup 2)
|
||||||
(compare:CC (match_dup 0) (match_dup 3)))]
|
(compare:CC (match_dup 0) (match_dup 3)))]
|
||||||
|
|
@ -146,17 +146,17 @@
|
||||||
|
|
||||||
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
||||||
;; load mode is SI result mode is SI compare mode is CC extend is none
|
;; load mode is SI result mode is SI compare mode is CC extend is none
|
||||||
(define_insn_and_split "*lwa_cmpdi_cr0_SI_SI_CC_none"
|
(define_insn_and_split "*lwz_cmpwi_cr0_SI_SI_CC_none"
|
||||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
||||||
(compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m")
|
(compare:CC (match_operand:SI 1 "non_update_memory_operand" "m")
|
||||||
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
|
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
(set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
"lwa%X1 %0,%1\;cmpdi %2,%0,%3"
|
"lwz%X1 %0,%1\;cmpwi %2,%0,%3"
|
||||||
"&& reload_completed
|
"&& reload_completed
|
||||||
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
||||||
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
||||||
SImode, NON_PREFIXED_DS))"
|
SImode, NON_PREFIXED_D))"
|
||||||
[(set (match_dup 0) (match_dup 1))
|
[(set (match_dup 0) (match_dup 1))
|
||||||
(set (match_dup 2)
|
(set (match_dup 2)
|
||||||
(compare:CC (match_dup 0) (match_dup 3)))]
|
(compare:CC (match_dup 0) (match_dup 3)))]
|
||||||
|
|
@ -190,7 +190,7 @@
|
||||||
;; load mode is SI result mode is EXTSI compare mode is CC extend is sign
|
;; load mode is SI result mode is EXTSI compare mode is CC extend is sign
|
||||||
(define_insn_and_split "*lwa_cmpdi_cr0_SI_EXTSI_CC_sign"
|
(define_insn_and_split "*lwa_cmpdi_cr0_SI_EXTSI_CC_sign"
|
||||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 2 "cc_reg_operand" "=x")
|
||||||
(compare:CC (match_operand:SI 1 "ds_form_mem_operand" "m")
|
(compare:CC (match_operand:SI 1 "non_update_memory_operand" "YZ")
|
||||||
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
|
(match_operand:SI 3 "const_m1_to_1_operand" "n")))
|
||||||
(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") (sign_extend:EXTSI (match_dup 1)))]
|
(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") (sign_extend:EXTSI (match_dup 1)))]
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
|
|
@ -205,6 +205,7 @@
|
||||||
""
|
""
|
||||||
[(set_attr "type" "fused_load_cmpi")
|
[(set_attr "type" "fused_load_cmpi")
|
||||||
(set_attr "cost" "8")
|
(set_attr "cost" "8")
|
||||||
|
(set_attr "sign_extend" "yes")
|
||||||
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
||||||
|
|
||||||
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
||||||
|
|
|
||||||
|
|
@ -61,20 +61,31 @@ sub gen_ld_cmpi_p10_one
|
||||||
my $mempred = "non_update_memory_operand";
|
my $mempred = "non_update_memory_operand";
|
||||||
my $extend;
|
my $extend;
|
||||||
|
|
||||||
|
# We need to special case lwa. The prefixed_load_p function in rs6000.cc
|
||||||
|
# (which determines if a load instruction is prefixed) uses the fact that the
|
||||||
|
# register mode is different from the memory mode, and that the sign_extend
|
||||||
|
# attribute is set to use DS-form rules for the address instead of D-form.
|
||||||
|
# If the register size is the same, prefixed_load_p assumes we are doing a
|
||||||
|
# lwz. We change to use an lwz and word compare if we don't need to sign
|
||||||
|
# extend the SImode value. Otherwise if we need the value, we need to
|
||||||
|
# make sure the insn is marked as ds-form.
|
||||||
|
my $cmp_size_char = ($lmode eq "SI"
|
||||||
|
&& $ccmode eq "CC"
|
||||||
|
&& $result !~ /^EXT|^DI$/) ? "w" : "d";
|
||||||
|
|
||||||
if ($ccmode eq "CC") {
|
if ($ccmode eq "CC") {
|
||||||
# ld and lwa are both DS-FORM.
|
# ld and lwa are both DS-FORM.
|
||||||
($lmode =~ /^[SD]I$/) and $np = "NON_PREFIXED_DS";
|
($lmode eq "DI") and $np = "NON_PREFIXED_DS";
|
||||||
($lmode =~ /^[SD]I$/) and $mempred = "ds_form_mem_operand";
|
($lmode eq "SI" && $cmp_size_char eq "d") and $np = "NON_PREFIXED_DS";
|
||||||
} else {
|
} else {
|
||||||
if ($lmode eq "DI") {
|
if ($lmode eq "DI") {
|
||||||
# ld is DS-form, but lwz is not.
|
# ld is DS-form, but lwz is not.
|
||||||
$np = "NON_PREFIXED_DS";
|
$np = "NON_PREFIXED_DS";
|
||||||
$mempred = "ds_form_mem_operand";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $cmpl = ($ccmode eq "CC") ? "" : "l";
|
my $cmpl = ($ccmode eq "CC") ? "" : "l";
|
||||||
my $echr = ($ccmode eq "CC") ? "a" : "z";
|
my $echr = ($ccmode eq "CC" && $cmp_size_char eq "d") ? "a" : "z";
|
||||||
if ($lmode eq "DI") { $echr = ""; }
|
if ($lmode eq "DI") { $echr = ""; }
|
||||||
my $constpred = ($ccmode eq "CC") ? "const_m1_to_1_operand"
|
my $constpred = ($ccmode eq "CC") ? "const_m1_to_1_operand"
|
||||||
: "const_0_to_1_operand";
|
: "const_0_to_1_operand";
|
||||||
|
|
@ -91,12 +102,15 @@ sub gen_ld_cmpi_p10_one
|
||||||
}
|
}
|
||||||
|
|
||||||
my $ldst = mode_to_ldst_char($lmode);
|
my $ldst = mode_to_ldst_char($lmode);
|
||||||
|
|
||||||
|
# DS-form addresses need YZ, and not m.
|
||||||
|
my $constraint = ($np eq "NON_PREFIXED_DS") ? "YZ" : "m";
|
||||||
print <<HERE;
|
print <<HERE;
|
||||||
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
|
||||||
;; load mode is $lmode result mode is $result compare mode is $ccmode extend is $extend
|
;; load mode is $lmode result mode is $result compare mode is $ccmode extend is $extend
|
||||||
(define_insn_and_split "*l${ldst}${echr}_cmp${cmpl}di_cr0_${lmode}_${result}_${ccmode}_${extend}"
|
(define_insn_and_split "*l${ldst}${echr}_cmp${cmpl}${cmp_size_char}i_cr0_${lmode}_${result}_${ccmode}_${extend}"
|
||||||
[(set (match_operand:${ccmode} 2 "cc_reg_operand" "=x")
|
[(set (match_operand:${ccmode} 2 "cc_reg_operand" "=x")
|
||||||
(compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "m")
|
(compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "${constraint}")
|
||||||
HERE
|
HERE
|
||||||
print " " if $ccmode eq "CCUNS";
|
print " " if $ccmode eq "CCUNS";
|
||||||
print <<HERE;
|
print <<HERE;
|
||||||
|
|
@ -119,7 +133,7 @@ HERE
|
||||||
|
|
||||||
print <<HERE;
|
print <<HERE;
|
||||||
"(TARGET_P10_FUSION)"
|
"(TARGET_P10_FUSION)"
|
||||||
"l${ldst}${echr}%X1 %0,%1\\;cmp${cmpl}di %2,%0,%3"
|
"l${ldst}${echr}%X1 %0,%1\\;cmp${cmpl}${cmp_size_char}i %2,%0,%3"
|
||||||
"&& reload_completed
|
"&& reload_completed
|
||||||
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
||||||
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
||||||
|
|
@ -140,6 +154,15 @@ HERE
|
||||||
""
|
""
|
||||||
[(set_attr "type" "fused_load_cmpi")
|
[(set_attr "type" "fused_load_cmpi")
|
||||||
(set_attr "cost" "8")
|
(set_attr "cost" "8")
|
||||||
|
HERE
|
||||||
|
|
||||||
|
if ($lmode eq "SI" && $ccmode eq "CC" && $cmp_size_char eq "d") {
|
||||||
|
# prefixed_load_p needs the sign_extend attribute to validate lwa as a
|
||||||
|
# DS-form instruction instead of D-form.
|
||||||
|
print " (set_attr \"sign_extend\" \"yes\")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
print <<HERE
|
||||||
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
||||||
|
|
||||||
HERE
|
HERE
|
||||||
|
|
|
||||||
|
|
@ -1125,20 +1125,6 @@
|
||||||
return INTVAL (offset) % 4 == 0;
|
return INTVAL (offset) % 4 == 0;
|
||||||
})
|
})
|
||||||
|
|
||||||
;; Return 1 if the operand is a memory operand that has a valid address for
|
|
||||||
;; a DS-form instruction. I.e. the address has to be either just a register,
|
|
||||||
;; or register + const where the two low order bits of const are zero.
|
|
||||||
(define_predicate "ds_form_mem_operand"
|
|
||||||
(match_code "subreg,mem")
|
|
||||||
{
|
|
||||||
if (!any_memory_operand (op, mode))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
rtx addr = XEXP (op, 0);
|
|
||||||
|
|
||||||
return address_to_insn_form (addr, mode, NON_PREFIXED_DS) == INSN_FORM_DS;
|
|
||||||
})
|
|
||||||
|
|
||||||
;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
|
;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
|
||||||
(define_predicate "symbol_ref_operand"
|
(define_predicate "symbol_ref_operand"
|
||||||
(and (match_code "symbol_ref")
|
(and (match_code "symbol_ref")
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@
|
||||||
;; Whether this insn has a prefixed form and a non-prefixed form.
|
;; Whether this insn has a prefixed form and a non-prefixed form.
|
||||||
(define_attr "maybe_prefixed" "no,yes"
|
(define_attr "maybe_prefixed" "no,yes"
|
||||||
(if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
|
(if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
|
||||||
integer,add")
|
integer,add,fused_load_cmpi")
|
||||||
(const_string "yes")
|
(const_string "yes")
|
||||||
(const_string "no")))
|
(const_string "no")))
|
||||||
|
|
||||||
|
|
@ -302,7 +302,7 @@
|
||||||
(eq_attr "maybe_prefixed" "no"))
|
(eq_attr "maybe_prefixed" "no"))
|
||||||
(const_string "no")
|
(const_string "no")
|
||||||
|
|
||||||
(eq_attr "type" "load,fpload,vecload")
|
(eq_attr "type" "load,fpload,vecload,fused_load_cmpi")
|
||||||
(if_then_else (match_test "prefixed_load_p (insn)")
|
(if_then_else (match_test "prefixed_load_p (insn)")
|
||||||
(const_string "yes")
|
(const_string "yes")
|
||||||
(const_string "no"))
|
(const_string "no"))
|
||||||
|
|
|
||||||
|
|
@ -13706,8 +13706,10 @@ s390_encode_section_info (tree decl, rtx rtl, int first)
|
||||||
{
|
{
|
||||||
/* Store the alignment to be able to check if we can use
|
/* Store the alignment to be able to check if we can use
|
||||||
a larl/load-relative instruction. We only handle the cases
|
a larl/load-relative instruction. We only handle the cases
|
||||||
that can go wrong (i.e. no FUNC_DECLs). */
|
that can go wrong (i.e. no FUNC_DECLs).
|
||||||
if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
|
All symbols without an explicit alignment are assumed to be 2
|
||||||
|
byte aligned as mandated by our ABI. */
|
||||||
|
if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) % 16)
|
||||||
SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
|
SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
|
||||||
else if (DECL_ALIGN (decl) % 32)
|
else if (DECL_ALIGN (decl) % 32)
|
||||||
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
|
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
|
||||||
|
|
|
||||||
|
|
@ -9269,7 +9269,7 @@
|
||||||
(match_operand:SF 3 "arith_reg_operand" "0")))
|
(match_operand:SF 3 "arith_reg_operand" "0")))
|
||||||
(clobber (reg:SI FPSCR_STAT_REG))
|
(clobber (reg:SI FPSCR_STAT_REG))
|
||||||
(use (reg:SI FPSCR_MODES_REG))]
|
(use (reg:SI FPSCR_MODES_REG))]
|
||||||
"TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF"
|
"TARGET_SH2E && flag_fp_contract_mode == FP_CONTRACT_FAST"
|
||||||
"fmac %1,%2,%0"
|
"fmac %1,%2,%0"
|
||||||
"&& can_create_pseudo_p ()"
|
"&& can_create_pseudo_p ()"
|
||||||
[(parallel [(set (match_dup 0)
|
[(parallel [(set (match_dup 0)
|
||||||
|
|
|
||||||
|
|
@ -635,6 +635,7 @@ CET_HOST_FLAGS
|
||||||
LD_PICFLAG
|
LD_PICFLAG
|
||||||
PICFLAG
|
PICFLAG
|
||||||
enable_default_pie
|
enable_default_pie
|
||||||
|
enable_host_bind_now
|
||||||
enable_host_pie
|
enable_host_pie
|
||||||
enable_host_shared
|
enable_host_shared
|
||||||
enable_plugin
|
enable_plugin
|
||||||
|
|
@ -1031,6 +1032,7 @@ enable_version_specific_runtime_libs
|
||||||
enable_plugin
|
enable_plugin
|
||||||
enable_host_shared
|
enable_host_shared
|
||||||
enable_host_pie
|
enable_host_pie
|
||||||
|
enable_host_bind_now
|
||||||
enable_libquadmath_support
|
enable_libquadmath_support
|
||||||
with_linker_hash_style
|
with_linker_hash_style
|
||||||
with_diagnostics_color
|
with_diagnostics_color
|
||||||
|
|
@ -1794,6 +1796,7 @@ Optional Features:
|
||||||
--enable-plugin enable plugin support
|
--enable-plugin enable plugin support
|
||||||
--enable-host-shared build host code as shared libraries
|
--enable-host-shared build host code as shared libraries
|
||||||
--enable-host-pie build host code as PIE
|
--enable-host-pie build host code as PIE
|
||||||
|
--enable-host-bind-now link host code as BIND_NOW
|
||||||
--disable-libquadmath-support
|
--disable-libquadmath-support
|
||||||
disable libquadmath support for Fortran
|
disable libquadmath support for Fortran
|
||||||
--enable-default-pie enable Position Independent Executable as default
|
--enable-default-pie enable Position Independent Executable as default
|
||||||
|
|
@ -19847,7 +19850,7 @@ else
|
||||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||||
lt_status=$lt_dlunknown
|
lt_status=$lt_dlunknown
|
||||||
cat > conftest.$ac_ext <<_LT_EOF
|
cat > conftest.$ac_ext <<_LT_EOF
|
||||||
#line 19850 "configure"
|
#line 19853 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#if HAVE_DLFCN_H
|
#if HAVE_DLFCN_H
|
||||||
|
|
@ -19953,7 +19956,7 @@ else
|
||||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||||
lt_status=$lt_dlunknown
|
lt_status=$lt_dlunknown
|
||||||
cat > conftest.$ac_ext <<_LT_EOF
|
cat > conftest.$ac_ext <<_LT_EOF
|
||||||
#line 19956 "configure"
|
#line 19959 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#if HAVE_DLFCN_H
|
#if HAVE_DLFCN_H
|
||||||
|
|
@ -32100,6 +32103,14 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Enable --enable-host-bind-now
|
||||||
|
# Check whether --enable-host-bind-now was given.
|
||||||
|
if test "${enable_host_bind_now+set}" = set; then :
|
||||||
|
enableval=$enable_host_bind_now;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --enable-libquadmath-support was given.
|
# Check whether --enable-libquadmath-support was given.
|
||||||
if test "${enable_libquadmath_support+set}" = set; then :
|
if test "${enable_libquadmath_support+set}" = set; then :
|
||||||
enableval=$enable_libquadmath_support; ENABLE_LIBQUADMATH_SUPPORT=$enableval
|
enableval=$enable_libquadmath_support; ENABLE_LIBQUADMATH_SUPPORT=$enableval
|
||||||
|
|
@ -32286,6 +32297,8 @@ else
|
||||||
PICFLAG=
|
PICFLAG=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test x$enable_host_pie = xyes; then
|
if test x$enable_host_pie = xyes; then
|
||||||
LD_PICFLAG=-pie
|
LD_PICFLAG=-pie
|
||||||
elif test x$gcc_cv_no_pie = xyes; then
|
elif test x$gcc_cv_no_pie = xyes; then
|
||||||
|
|
@ -32294,6 +32307,9 @@ else
|
||||||
LD_PICFLAG=
|
LD_PICFLAG=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x$enable_host_bind_now = xyes; then
|
||||||
|
LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -34009,7 +34025,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
|
||||||
"depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;;
|
"depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;;
|
||||||
"gccdepdir":C)
|
"gccdepdir":C)
|
||||||
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR
|
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR
|
||||||
for lang in $subdirs c-family common analyzer rtl-ssa
|
for lang in $subdirs c-family common analyzer text-art rtl-ssa
|
||||||
do
|
do
|
||||||
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
|
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
|
||||||
done ;;
|
done ;;
|
||||||
|
|
|
||||||
|
|
@ -1382,7 +1382,7 @@ AC_CHECK_HEADERS(ext/hash_map)
|
||||||
ZW_CREATE_DEPDIR
|
ZW_CREATE_DEPDIR
|
||||||
AC_CONFIG_COMMANDS([gccdepdir],[
|
AC_CONFIG_COMMANDS([gccdepdir],[
|
||||||
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR
|
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR
|
||||||
for lang in $subdirs c-family common analyzer rtl-ssa
|
for lang in $subdirs c-family common analyzer text-art rtl-ssa
|
||||||
do
|
do
|
||||||
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
|
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
|
||||||
done], [subdirs="$subdirs" ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR])
|
done], [subdirs="$subdirs" ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR])
|
||||||
|
|
@ -7425,6 +7425,12 @@ AC_ARG_ENABLE(host-pie,
|
||||||
[build host code as PIE])])
|
[build host code as PIE])])
|
||||||
AC_SUBST(enable_host_pie)
|
AC_SUBST(enable_host_pie)
|
||||||
|
|
||||||
|
# Enable --enable-host-bind-now
|
||||||
|
AC_ARG_ENABLE(host-bind-now,
|
||||||
|
[AS_HELP_STRING([--enable-host-bind-now],
|
||||||
|
[link host code as BIND_NOW])])
|
||||||
|
AC_SUBST(enable_host_bind_now)
|
||||||
|
|
||||||
AC_ARG_ENABLE(libquadmath-support,
|
AC_ARG_ENABLE(libquadmath-support,
|
||||||
[AS_HELP_STRING([--disable-libquadmath-support],
|
[AS_HELP_STRING([--disable-libquadmath-support],
|
||||||
[disable libquadmath support for Fortran])],
|
[disable libquadmath support for Fortran])],
|
||||||
|
|
@ -7566,6 +7572,8 @@ else
|
||||||
PICFLAG=
|
PICFLAG=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_SUBST([PICFLAG])
|
||||||
|
|
||||||
if test x$enable_host_pie = xyes; then
|
if test x$enable_host_pie = xyes; then
|
||||||
LD_PICFLAG=-pie
|
LD_PICFLAG=-pie
|
||||||
elif test x$gcc_cv_no_pie = xyes; then
|
elif test x$gcc_cv_no_pie = xyes; then
|
||||||
|
|
@ -7574,7 +7582,10 @@ else
|
||||||
LD_PICFLAG=
|
LD_PICFLAG=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST([PICFLAG])
|
if test x$enable_host_bind_now = xyes; then
|
||||||
|
LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST([LD_PICFLAG])
|
AC_SUBST([LD_PICFLAG])
|
||||||
|
|
||||||
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,12 @@
|
||||||
|
2023-06-23 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
PR c++/110164
|
||||||
|
* cp-name-hint.h (maybe_suggest_missing_header): New decl.
|
||||||
|
* decl.cc: Define INCLUDE_MEMORY. Add include of
|
||||||
|
"cp/cp-name-hint.h".
|
||||||
|
(start_decl_1): Call maybe_suggest_missing_header.
|
||||||
|
* name-lookup.cc (maybe_suggest_missing_header): Remove "static".
|
||||||
|
|
||||||
2023-06-16 Alex Coplan <alex.coplan@arm.com>
|
2023-06-16 Alex Coplan <alex.coplan@arm.com>
|
||||||
|
|
||||||
* parser.cc (cp_parser_enum_specifier): Don't reject
|
* parser.cc (cp_parser_enum_specifier): Don't reject
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
|
|
||||||
extern name_hint suggest_alternatives_for (location_t, tree, bool);
|
extern name_hint suggest_alternatives_for (location_t, tree, bool);
|
||||||
extern name_hint suggest_alternatives_in_other_namespaces (location_t, tree);
|
extern name_hint suggest_alternatives_in_other_namespaces (location_t, tree);
|
||||||
|
extern name_hint maybe_suggest_missing_header (location_t, tree, tree);
|
||||||
extern name_hint suggest_alternative_in_explicit_scope (location_t, tree, tree);
|
extern name_hint suggest_alternative_in_explicit_scope (location_t, tree, tree);
|
||||||
extern name_hint suggest_alternative_in_scoped_enum (tree, tree);
|
extern name_hint suggest_alternative_in_scoped_enum (tree, tree);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
line numbers. For example, the CONST_DECLs for enum values. */
|
line numbers. For example, the CONST_DECLs for enum values. */
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#define INCLUDE_MEMORY
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "coretypes.h"
|
#include "coretypes.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
@ -46,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "c-family/c-objc.h"
|
#include "c-family/c-objc.h"
|
||||||
#include "c-family/c-pragma.h"
|
#include "c-family/c-pragma.h"
|
||||||
#include "c-family/c-ubsan.h"
|
#include "c-family/c-ubsan.h"
|
||||||
|
#include "cp/cp-name-hint.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
|
|
@ -5995,7 +5997,11 @@ start_decl_1 (tree decl, bool initialized)
|
||||||
; /* An auto type is ok. */
|
; /* An auto type is ok. */
|
||||||
else if (TREE_CODE (type) != ARRAY_TYPE)
|
else if (TREE_CODE (type) != ARRAY_TYPE)
|
||||||
{
|
{
|
||||||
|
auto_diagnostic_group d;
|
||||||
error ("variable %q#D has initializer but incomplete type", decl);
|
error ("variable %q#D has initializer but incomplete type", decl);
|
||||||
|
maybe_suggest_missing_header (input_location,
|
||||||
|
TYPE_IDENTIFIER (type),
|
||||||
|
CP_TYPE_CONTEXT (type));
|
||||||
type = TREE_TYPE (decl) = error_mark_node;
|
type = TREE_TYPE (decl) = error_mark_node;
|
||||||
}
|
}
|
||||||
else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
|
else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
|
||||||
|
|
@ -6011,8 +6017,12 @@ start_decl_1 (tree decl, bool initialized)
|
||||||
gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (type));
|
gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (type));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto_diagnostic_group d;
|
||||||
error ("aggregate %q#D has incomplete type and cannot be defined",
|
error ("aggregate %q#D has incomplete type and cannot be defined",
|
||||||
decl);
|
decl);
|
||||||
|
maybe_suggest_missing_header (input_location,
|
||||||
|
TYPE_IDENTIFIER (type),
|
||||||
|
CP_TYPE_CONTEXT (type));
|
||||||
/* Change the type so that assemble_variable will give
|
/* Change the type so that assemble_variable will give
|
||||||
DECL an rtl we can live with: (mem (const_int 0)). */
|
DECL an rtl we can live with: (mem (const_int 0)). */
|
||||||
type = TREE_TYPE (decl) = error_mark_node;
|
type = TREE_TYPE (decl) = error_mark_node;
|
||||||
|
|
|
||||||
|
|
@ -6796,7 +6796,7 @@ maybe_suggest_missing_std_header (location_t location, tree name)
|
||||||
for NAME within SCOPE at LOCATION, or an empty name_hint if this isn't
|
for NAME within SCOPE at LOCATION, or an empty name_hint if this isn't
|
||||||
applicable. */
|
applicable. */
|
||||||
|
|
||||||
static name_hint
|
name_hint
|
||||||
maybe_suggest_missing_header (location_t location, tree name, tree scope)
|
maybe_suggest_missing_header (location_t location, tree name, tree scope)
|
||||||
{
|
{
|
||||||
if (scope == NULL_TREE)
|
if (scope == NULL_TREE)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2023-06-25 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||||
|
|
||||||
|
* dmd/MERGE: Merge upstream dmd a45f4e9f43.
|
||||||
|
* dmd/VERSION: Bump version to v2.103.1.
|
||||||
|
|
||||||
2023-06-15 Marek Polacek <polacek@redhat.com>
|
2023-06-15 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
* Make-lang.in: Remove NO_PIE_CFLAGS.
|
* Make-lang.in: Remove NO_PIE_CFLAGS.
|
||||||
|
|
|
||||||
|
|
@ -619,7 +619,7 @@ convert_expr (tree exp, Type *etype, Type *totype)
|
||||||
return result ? result : convert (build_ctype (totype), exp);
|
return result ? result : convert (build_ctype (totype), exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a TREE represenwation of EXPR, whose type has been converted from
|
/* Return a TREE representation of EXPR, whose type has been converted from
|
||||||
* ETYPE to TOTYPE, and is being used in an rvalue context. */
|
* ETYPE to TOTYPE, and is being used in an rvalue context. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
|
|
@ -634,20 +634,27 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
|
||||||
{
|
{
|
||||||
/* If casting from bool, the result is either 0 or 1, any other value
|
/* If casting from bool, the result is either 0 or 1, any other value
|
||||||
violates @safe code, so enforce that it is never invalid. */
|
violates @safe code, so enforce that it is never invalid. */
|
||||||
if (CONSTANT_CLASS_P (expr))
|
for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
|
||||||
result = d_truthvalue_conversion (expr);
|
ref = TREE_OPERAND (ref, 0))
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* Reinterpret the boolean as an integer and test the first bit.
|
/* If the expression is a field that's part of a union, reinterpret
|
||||||
The generated code should end up being equivalent to:
|
the boolean as an integer and test the first bit. The generated
|
||||||
|
code should end up being equivalent to:
|
||||||
*cast(ubyte *)&expr & 1; */
|
*cast(ubyte *)&expr & 1; */
|
||||||
machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
|
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
|
||||||
tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
|
{
|
||||||
result = fold_build2 (BIT_AND_EXPR, mtype,
|
machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
|
||||||
build_vconvert (mtype, expr),
|
tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
|
||||||
build_one_cst (mtype));
|
result = fold_build2 (BIT_AND_EXPR, mtype,
|
||||||
|
build_vconvert (mtype, expr),
|
||||||
|
build_one_cst (mtype));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result == NULL_TREE)
|
||||||
|
result = d_truthvalue_conversion (expr);
|
||||||
|
|
||||||
result = convert (build_ctype (tbtype), result);
|
result = convert (build_ctype (tbtype), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -844,7 +851,7 @@ convert_for_condition (tree expr, Type *type)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
result = expr;
|
result = convert_for_rvalue (expr, type, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
5f7552bb2829b75d5e36cc767a476e1ab35147b7
|
a45f4e9f43e9fdbf0b666175e5e66b1ce4f561f6
|
||||||
|
|
||||||
The first line of this file holds the git revision number of the last
|
The first line of this file holds the git revision number of the last
|
||||||
merge done from the dlang/dmd repository.
|
merge done from the dlang/dmd repository.
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
v2.103.0-rc.1
|
v2.103.1
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,8 @@ public:
|
||||||
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
|
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
|
||||||
|
|
||||||
Visibility visibility;
|
Visibility visibility;
|
||||||
bool noDefaultCtor; // no default construction
|
d_bool noDefaultCtor; // no default construction
|
||||||
bool disableNew; // disallow allocations using `new`
|
d_bool disableNew; // disallow allocations using `new`
|
||||||
Sizeok sizeok; // set when structsize contains valid data
|
Sizeok sizeok; // set when structsize contains valid data
|
||||||
|
|
||||||
virtual Scope *newScope(Scope *sc);
|
virtual Scope *newScope(Scope *sc);
|
||||||
|
|
@ -269,10 +269,10 @@ public:
|
||||||
// their own vtbl[]
|
// their own vtbl[]
|
||||||
|
|
||||||
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||||
bool com; // true if this is a COM class (meaning it derives from IUnknown)
|
d_bool com; // true if this is a COM class (meaning it derives from IUnknown)
|
||||||
bool stack; // true if this is a scope class
|
d_bool stack; // true if this is a scope class
|
||||||
int cppDtorVtblIndex; // slot reserved for the virtual destructor [extern(C++)]
|
int cppDtorVtblIndex; // slot reserved for the virtual destructor [extern(C++)]
|
||||||
bool inuse; // to prevent recursive attempts
|
d_bool inuse; // to prevent recursive attempts
|
||||||
|
|
||||||
ThreeState isabstract; // if abstract class
|
ThreeState isabstract; // if abstract class
|
||||||
Baseok baseok; // set the progress of base classes resolving
|
Baseok baseok; // set the progress of base classes resolving
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ public:
|
||||||
class AnonDeclaration final : public AttribDeclaration
|
class AnonDeclaration final : public AttribDeclaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isunion;
|
d_bool isunion;
|
||||||
int sem; // 1 if successful semantic()
|
int sem; // 1 if successful semantic()
|
||||||
unsigned anonoffset; // offset of anonymous struct
|
unsigned anonoffset; // offset of anonymous struct
|
||||||
unsigned anonstructsize; // size of anonymous struct
|
unsigned anonstructsize; // size of anonymous struct
|
||||||
|
|
@ -175,8 +175,8 @@ class StaticIfDeclaration final : public ConditionalDeclaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScopeDsymbol *scopesym;
|
ScopeDsymbol *scopesym;
|
||||||
bool addisdone;
|
d_bool addisdone;
|
||||||
bool onStack;
|
d_bool onStack;
|
||||||
|
|
||||||
StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
|
StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||||
Dsymbols *include(Scope *sc) override;
|
Dsymbols *include(Scope *sc) override;
|
||||||
|
|
@ -193,8 +193,8 @@ class StaticForeachDeclaration final : public AttribDeclaration
|
||||||
public:
|
public:
|
||||||
StaticForeach *sfe;
|
StaticForeach *sfe;
|
||||||
ScopeDsymbol *scopesym;
|
ScopeDsymbol *scopesym;
|
||||||
bool onStack;
|
d_bool onStack;
|
||||||
bool cached;
|
d_bool cached;
|
||||||
Dsymbols *cache;
|
Dsymbols *cache;
|
||||||
|
|
||||||
StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
|
StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||||
|
|
@ -227,7 +227,7 @@ public:
|
||||||
Expressions *exps;
|
Expressions *exps;
|
||||||
|
|
||||||
ScopeDsymbol *scopesym;
|
ScopeDsymbol *scopesym;
|
||||||
bool compiled;
|
d_bool compiled;
|
||||||
|
|
||||||
CompileDeclaration *syntaxCopy(Dsymbol *s) override;
|
CompileDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||||
void addMember(Scope *sc, ScopeDsymbol *sds) override;
|
void addMember(Scope *sc, ScopeDsymbol *sds) override;
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ struct OutBuffer
|
||||||
private:
|
private:
|
||||||
DArray<unsigned char> data;
|
DArray<unsigned char> data;
|
||||||
d_size_t offset;
|
d_size_t offset;
|
||||||
bool notlinehead;
|
d_bool notlinehead;
|
||||||
void *fileMapping; // pointer to a file mapping object not used on the C++ side
|
void *fileMapping; // pointer to a file mapping object not used on the C++ side
|
||||||
public:
|
public:
|
||||||
bool doindent;
|
d_bool doindent;
|
||||||
bool spaces;
|
d_bool spaces;
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
OutBuffer()
|
OutBuffer()
|
||||||
|
|
|
||||||
|
|
@ -935,9 +935,6 @@ extern (C++) final class StaticIfCondition : Condition
|
||||||
import dmd.staticcond;
|
import dmd.staticcond;
|
||||||
bool errors;
|
bool errors;
|
||||||
|
|
||||||
if (!exp)
|
|
||||||
return errorReturn();
|
|
||||||
|
|
||||||
bool result = evalStaticCondition(sc, exp, exp, errors);
|
bool result = evalStaticCondition(sc, exp, exp, errors);
|
||||||
|
|
||||||
// Prevent repeated condition evaluation.
|
// Prevent repeated condition evaluation.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ public:
|
||||||
ForeachStatement *aggrfe;
|
ForeachStatement *aggrfe;
|
||||||
ForeachRangeStatement *rangefe;
|
ForeachRangeStatement *rangefe;
|
||||||
|
|
||||||
bool needExpansion;
|
d_bool needExpansion;
|
||||||
|
|
||||||
StaticForeach *syntaxCopy();
|
StaticForeach *syntaxCopy();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,11 @@ private final class CppMangleVisitor : Visitor
|
||||||
{
|
{
|
||||||
auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;
|
auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;
|
||||||
Type rt = preSemantic.nextOf();
|
Type rt = preSemantic.nextOf();
|
||||||
|
// https://issues.dlang.org/show_bug.cgi?id=22739
|
||||||
|
// auto return type means that rt is null.
|
||||||
|
// if so, just pick up the type from the instance
|
||||||
|
if (!rt)
|
||||||
|
rt = tf.nextOf();
|
||||||
if (tf.isref)
|
if (tf.isref)
|
||||||
rt = rt.referenceTo();
|
rt = rt.referenceTo();
|
||||||
auto prev = this.context.push(tf.nextOf());
|
auto prev = this.context.push(tf.nextOf());
|
||||||
|
|
@ -560,7 +565,11 @@ private final class CppMangleVisitor : Visitor
|
||||||
foreach (j; i .. (*ti.tiargs).length)
|
foreach (j; i .. (*ti.tiargs).length)
|
||||||
{
|
{
|
||||||
Type t = isType((*ti.tiargs)[j]);
|
Type t = isType((*ti.tiargs)[j]);
|
||||||
assert(t);
|
if (t is null)
|
||||||
|
{
|
||||||
|
ti.error("internal compiler error: C++ `%s` template value parameter is not supported", (*ti.tiargs)[j].toChars());
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
t.accept(this);
|
t.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue