mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-26 21:15:01 +08:00
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>
|
||||
|
||||
* MAINTAINERS (Write After Approval): move Matthew Fortune
|
||||
|
@ -394,6 +394,7 @@ Chris Demetriou <cgd@google.com>
|
||||
Sameera Deshpande <sameera.deshpande@linaro.org>
|
||||
Wilco Dijkstra <wdijkstr@arm.com>
|
||||
Benoit Dupont de Dinechin <benoit.dupont-de-dinechin@st.com>
|
||||
Lehua Ding <lehua.ding@rivai.ai>
|
||||
Jason Eckhardt <jle@rice.edu>
|
||||
Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
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= gas; 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;
|
||||
// Work around in-tree gmp configure bug with missing flex.
|
||||
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 \
|
||||
--srcdir=$${topdir}/$$module_srcdir \
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--target=${target_alias} @gcc_host_pie@ \
|
||||
|| exit 1
|
||||
@endif gcc
|
||||
|
||||
@ -12056,7 +12056,8 @@ configure-stage1-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
\
|
||||
$(STAGE1_CONFIGURE_FLAGS)
|
||||
$(STAGE1_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stage2-gcc maybe-configure-stage2-gcc
|
||||
@ -12089,7 +12090,8 @@ configure-stage2-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGE2_CONFIGURE_FLAGS)
|
||||
$(STAGE2_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stage3-gcc maybe-configure-stage3-gcc
|
||||
@ -12122,7 +12124,8 @@ configure-stage3-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGE3_CONFIGURE_FLAGS)
|
||||
$(STAGE3_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stage4-gcc maybe-configure-stage4-gcc
|
||||
@ -12155,7 +12158,8 @@ configure-stage4-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGE4_CONFIGURE_FLAGS)
|
||||
$(STAGE4_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stageprofile-gcc maybe-configure-stageprofile-gcc
|
||||
@ -12188,7 +12192,8 @@ configure-stageprofile-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGEprofile_CONFIGURE_FLAGS)
|
||||
$(STAGEprofile_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stagetrain-gcc maybe-configure-stagetrain-gcc
|
||||
@ -12221,7 +12226,8 @@ configure-stagetrain-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGEtrain_CONFIGURE_FLAGS)
|
||||
$(STAGEtrain_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stagefeedback-gcc maybe-configure-stagefeedback-gcc
|
||||
@ -12254,7 +12260,8 @@ configure-stagefeedback-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGEfeedback_CONFIGURE_FLAGS)
|
||||
$(STAGEfeedback_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stageautoprofile-gcc maybe-configure-stageautoprofile-gcc
|
||||
@ -12287,7 +12294,8 @@ configure-stageautoprofile-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGEautoprofile_CONFIGURE_FLAGS)
|
||||
$(STAGEautoprofile_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@endif gcc-bootstrap
|
||||
|
||||
.PHONY: configure-stageautofeedback-gcc maybe-configure-stageautofeedback-gcc
|
||||
@ -12320,7 +12328,8 @@ configure-stageautofeedback-gcc:
|
||||
$(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
|
||||
--target=${target_alias} \
|
||||
--with-build-libsubdir=$(HOST_SUBDIR) \
|
||||
$(STAGEautofeedback_CONFIGURE_FLAGS)
|
||||
$(STAGEautofeedback_CONFIGURE_FLAGS) \
|
||||
@gcc_host_pie@
|
||||
@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>
|
||||
|
||||
* Makefile.in: Rename PIEFLAG to PICFLAG. Set LD_PICFLAG. Use it.
|
||||
|
11
c++tools/configure
vendored
11
c++tools/configure
vendored
@ -628,6 +628,7 @@ EGREP
|
||||
GREP
|
||||
CXXCPP
|
||||
LD_PICFLAG
|
||||
enable_host_bind_now
|
||||
PICFLAG
|
||||
MAINTAINER
|
||||
CXX_AUX_TOOLS
|
||||
@ -702,6 +703,7 @@ enable_maintainer_mode
|
||||
enable_checking
|
||||
enable_default_pie
|
||||
enable_host_pie
|
||||
enable_host_bind_now
|
||||
with_gcc_major_version_only
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@ -1336,6 +1338,7 @@ Optional Features:
|
||||
yes,no,all,none,release.
|
||||
--enable-default-pie enable Position Independent Executable as default
|
||||
--enable-host-pie build host code as PIE
|
||||
--enable-host-bind-now link host code as BIND_NOW
|
||||
|
||||
Optional Packages:
|
||||
--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
|
||||
|
||||
|
@ -110,6 +110,13 @@ AC_ARG_ENABLE(host-pie,
|
||||
[build host code as PIE])],
|
||||
[PICFLAG=-fPIE; LD_PICFLAG=-pie], [])
|
||||
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)
|
||||
|
||||
# Check if O_CLOEXEC is defined by fcntl
|
||||
|
48
configure
vendored
48
configure
vendored
@ -689,6 +689,7 @@ stage1_languages
|
||||
host_libs_picflag
|
||||
PICFLAG
|
||||
host_shared
|
||||
gcc_host_pie
|
||||
host_pie
|
||||
extra_linker_plugin_flags
|
||||
extra_linker_plugin_configure_flags
|
||||
@ -8649,23 +8650,31 @@ fi
|
||||
|
||||
|
||||
|
||||
# Enable --enable-host-pie.
|
||||
# Checked early to determine whether jit is an 'all' language
|
||||
# Handle --enable-host-pie
|
||||
# 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.
|
||||
if test "${enable_host_pie+set}" = set; then :
|
||||
enableval=$enable_host_pie; host_pie=$enableval
|
||||
case $host in
|
||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
||||
*-*-darwin2*)
|
||||
if test x$host_pie != xyes ; then
|
||||
# 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
|
||||
# for Darwin20+ this is required.
|
||||
{ $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
|
||||
gcc_host_pie=--enable-host-pie
|
||||
fi ;;
|
||||
*) ;;
|
||||
esac
|
||||
else
|
||||
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 ;;
|
||||
esac
|
||||
fi
|
||||
@ -8673,6 +8682,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
# Enable --enable-host-shared.
|
||||
# Checked early to determine whether jit is an 'all' language
|
||||
# Check whether --enable-host-shared was given.
|
||||
@ -8682,21 +8692,24 @@ if test "${enable_host_shared+set}" = set; then :
|
||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
||||
if test x$host_shared != xyes ; then
|
||||
# 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
|
||||
fi ;;
|
||||
*-*-darwin*)
|
||||
if test x$host_pie == xyes ; then
|
||||
echo configure.ac: warning: PIC code is required for PIE executables. 1>&2
|
||||
if test x$host_pie = xyes -a x$host_shared != xyes ; then
|
||||
{ $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
|
||||
fi ;;
|
||||
*) ;;
|
||||
esac
|
||||
else
|
||||
case $host in
|
||||
# 64B x86_64 and Aarch64 Darwin default to PIC.
|
||||
x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;;
|
||||
# Darwin needs PIC objects to link PIE executables.
|
||||
*-*-darwin*) host_shared=host_pie ;;
|
||||
# 32B and powerpc64 Darwin must use PIC to link PIE exes.
|
||||
*-*-darwin*) host_shared=$host_pie ;;
|
||||
*) host_shared=no;;
|
||||
esac
|
||||
fi
|
||||
@ -8705,7 +8718,18 @@ fi
|
||||
|
||||
|
||||
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
|
||||
PICFLAG=-fPIE
|
||||
else
|
||||
|
44
configure.ac
44
configure.ac
@ -1891,27 +1891,35 @@ AC_ARG_ENABLE(linker-plugin-flags,
|
||||
extra_linker_plugin_flags=)
|
||||
AC_SUBST(extra_linker_plugin_flags)
|
||||
|
||||
# Enable --enable-host-pie.
|
||||
# Checked early to determine whether jit is an 'all' language
|
||||
# Handle --enable-host-pie
|
||||
# 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,
|
||||
[AS_HELP_STRING([--enable-host-pie],
|
||||
[build position independent host executables])],
|
||||
[host_pie=$enableval
|
||||
case $host in
|
||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
||||
*-*-darwin2*)
|
||||
if test x$host_pie != xyes ; then
|
||||
# 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
|
||||
# for Darwin20+ this is required.
|
||||
AC_MSG_WARN([PIE executables are required for the configured host, host-pie setting ignored.])
|
||||
host_pie=yes
|
||||
gcc_host_pie=--enable-host-pie
|
||||
fi ;;
|
||||
*) ;;
|
||||
esac],
|
||||
[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 ;;
|
||||
esac])
|
||||
|
||||
AC_SUBST(host_pie)
|
||||
AC_SUBST(gcc_host_pie)
|
||||
|
||||
# Enable --enable-host-shared.
|
||||
# Checked early to determine whether jit is an 'all' language
|
||||
@ -1923,27 +1931,39 @@ AC_ARG_ENABLE(host-shared,
|
||||
x86_64-*-darwin* | aarch64-*-darwin*)
|
||||
if test x$host_shared != xyes ; then
|
||||
# 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
|
||||
fi ;;
|
||||
*-*-darwin*)
|
||||
if test x$host_pie == xyes ; then
|
||||
echo configure.ac: warning: PIC code is required for PIE executables. 1>&2
|
||||
if test x$host_pie = xyes -a x$host_shared != xyes ; then
|
||||
AC_MSG_WARN([PIC code is required for PIE host executables host-shared setting ignored.])
|
||||
host_shared=yes
|
||||
fi ;;
|
||||
*) ;;
|
||||
esac],
|
||||
[case $host in
|
||||
# 64B x86_64 and Aarch64 Darwin default to PIC.
|
||||
x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;;
|
||||
# Darwin needs PIC objects to link PIE executables.
|
||||
*-*-darwin*) host_shared=host_pie ;;
|
||||
# 32B and powerpc64 Darwin must use PIC to link PIE exes.
|
||||
*-*-darwin*) host_shared=$host_pie ;;
|
||||
*) host_shared=no;;
|
||||
esac])
|
||||
|
||||
AC_SUBST(host_shared)
|
||||
|
||||
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
|
||||
PICFLAG=-fPIE
|
||||
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>
|
||||
|
||||
* testsuite-management/validate_failures.py (IsInterestingResult):
|
||||
|
94
contrib/unicode/gen-box-drawing-chars.py
Executable file
94
contrib/unicode/gen-box-drawing-chars.py
Executable file
@ -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} */')
|
75
contrib/unicode/gen-combining-chars.py
Executable file
75
contrib/unicode/gen-combining-chars.py
Executable file
@ -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};")
|
77
contrib/unicode/gen-printable-chars.py
Executable file
77
contrib/unicode/gen-printable-chars.py
Executable file
@ -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>
|
||||
|
||||
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_OBJS = \
|
||||
analyzer/access-diagram.o \
|
||||
analyzer/analysis-plan.o \
|
||||
analyzer/analyzer.o \
|
||||
analyzer/analyzer-language.o \
|
||||
@ -1788,7 +1789,16 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \
|
||||
json.o \
|
||||
sbitmap.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
|
||||
# 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>
|
||||
|
||||
PR analyzer/109577
|
||||
|
2406
gcc/analyzer/access-diagram.cc
Normal file
2406
gcc/analyzer/access-diagram.cc
Normal file
File diff suppressed because it is too large
Load Diff
165
gcc/analyzer/access-diagram.h
Normal file
165
gcc/analyzer/access-diagram.h
Normal file
@ -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
|
||||
{
|
||||
public:
|
||||
region_offset ()
|
||||
: m_base_region (NULL), m_offset (0), m_sym_offset (NULL)
|
||||
{
|
||||
}
|
||||
|
||||
static region_offset make_concrete (const region *base_region,
|
||||
bit_offset_t offset)
|
||||
{
|
||||
@ -193,9 +198,12 @@ public:
|
||||
{
|
||||
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; }
|
||||
|
||||
bool concrete_p () const { return m_sym_offset == NULL; }
|
||||
bool symbolic_p () const { return m_sym_offset != NULL; }
|
||||
|
||||
bit_offset_t get_bit_offset () const
|
||||
@ -204,12 +212,26 @@ public:
|
||||
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
|
||||
{
|
||||
gcc_assert (symbolic_p ());
|
||||
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
|
||||
{
|
||||
return (m_base_region == other.m_base_region
|
||||
@ -217,6 +239,9 @@ public:
|
||||
&& m_sym_offset == other.m_sym_offset);
|
||||
}
|
||||
|
||||
void dump_to_pp (pretty_printer *pp, bool) const;
|
||||
void dump (bool) const;
|
||||
|
||||
private:
|
||||
region_offset (const region *base_region, bit_offset_t offset,
|
||||
const svalue *sym_offset)
|
||||
@ -228,6 +253,11 @@ private:
|
||||
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 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
|
||||
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
|
||||
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.
|
||||
@ -242,6 +258,10 @@ fanalyzer-checker=
|
||||
Common Joined RejectNegative Var(flag_analyzer_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
|
||||
Common Var(flag_analyzer_fine_grained) Init(0)
|
||||
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"
|
||||
#define INCLUDE_MEMORY
|
||||
#define INCLUDE_VECTOR
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "make-unique.h"
|
||||
#include "tree.h"
|
||||
#include "function.h"
|
||||
#include "basic-block.h"
|
||||
#include "intl.h"
|
||||
#include "gimple.h"
|
||||
#include "gimple-iterator.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "diagnostic-metadata.h"
|
||||
#include "diagnostic-diagram.h"
|
||||
#include "analyzer/analyzer.h"
|
||||
#include "analyzer/analyzer-logging.h"
|
||||
#include "analyzer/region-model.h"
|
||||
#include "analyzer/checker-event.h"
|
||||
#include "analyzer/checker-path.h"
|
||||
#include "analyzer/access-diagram.h"
|
||||
|
||||
#if ENABLE_ANALYZER
|
||||
|
||||
@ -44,8 +48,35 @@ namespace ana {
|
||||
class out_of_bounds : public pending_diagnostic
|
||||
{
|
||||
public:
|
||||
out_of_bounds (const region *reg, tree diag_arg)
|
||||
: m_reg (reg), m_diag_arg (diag_arg)
|
||||
class oob_region_creation_event_capacity : public region_creation_event_capacity
|
||||
{
|
||||
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
|
||||
@ -63,7 +94,7 @@ public:
|
||||
|
||||
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 *,
|
||||
@ -75,15 +106,25 @@ public:
|
||||
so we don't need an event for that. */
|
||||
if (capacity)
|
||||
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:
|
||||
enum memory_space get_memory_space () const
|
||||
{
|
||||
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
|
||||
as (given "int arr[10];"):
|
||||
note: valid subscripts for 'arr' are '[0]' to '[9]'
|
||||
@ -112,8 +153,49 @@ protected:
|
||||
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;
|
||||
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
|
||||
@ -122,9 +204,11 @@ protected:
|
||||
class concrete_out_of_bounds : public out_of_bounds
|
||||
{
|
||||
public:
|
||||
concrete_out_of_bounds (const region *reg, tree diag_arg,
|
||||
byte_range out_of_bounds_range)
|
||||
: out_of_bounds (reg, diag_arg),
|
||||
concrete_out_of_bounds (const region_model &model,
|
||||
const region *reg, tree 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)
|
||||
{}
|
||||
|
||||
@ -146,9 +230,12 @@ protected:
|
||||
class concrete_past_the_end : public concrete_out_of_bounds
|
||||
{
|
||||
public:
|
||||
concrete_past_the_end (const region *reg, tree diag_arg, byte_range range,
|
||||
tree byte_bound)
|
||||
: concrete_out_of_bounds (reg, diag_arg, range), m_byte_bound (byte_bound)
|
||||
concrete_past_the_end (const region_model &model,
|
||||
const region *reg, tree diag_arg, byte_range range,
|
||||
tree byte_bound,
|
||||
const svalue *sval_hint)
|
||||
: concrete_out_of_bounds (model, reg, diag_arg, range, sval_hint),
|
||||
m_byte_bound (byte_bound)
|
||||
{}
|
||||
|
||||
bool
|
||||
@ -168,7 +255,9 @@ public:
|
||||
{
|
||||
if (m_byte_bound && TREE_CODE (m_byte_bound) == INTEGER_CST)
|
||||
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:
|
||||
@ -180,9 +269,11 @@ protected:
|
||||
class concrete_buffer_overflow : public concrete_past_the_end
|
||||
{
|
||||
public:
|
||||
concrete_buffer_overflow (const region *reg, tree diag_arg,
|
||||
byte_range range, tree byte_bound)
|
||||
: concrete_past_the_end (reg, diag_arg, range, byte_bound)
|
||||
concrete_buffer_overflow (const region_model &model,
|
||||
const region *reg, tree diag_arg,
|
||||
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
|
||||
@ -190,7 +281,8 @@ public:
|
||||
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;
|
||||
bool warned;
|
||||
@ -238,7 +330,7 @@ public:
|
||||
"write to beyond the end of %qE",
|
||||
m_diag_arg);
|
||||
|
||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
||||
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||
}
|
||||
|
||||
return warned;
|
||||
@ -276,6 +368,8 @@ public:
|
||||
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. */
|
||||
@ -283,9 +377,10 @@ public:
|
||||
class concrete_buffer_over_read : public concrete_past_the_end
|
||||
{
|
||||
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)
|
||||
: 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
|
||||
@ -293,7 +388,7 @@ public:
|
||||
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;
|
||||
bool warned;
|
||||
@ -339,7 +434,7 @@ public:
|
||||
"read from after the end of %qE",
|
||||
m_diag_arg);
|
||||
|
||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
||||
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||
}
|
||||
|
||||
return warned;
|
||||
@ -377,6 +472,8 @@ public:
|
||||
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. */
|
||||
@ -384,9 +481,11 @@ public:
|
||||
class concrete_buffer_underwrite : public concrete_out_of_bounds
|
||||
{
|
||||
public:
|
||||
concrete_buffer_underwrite (const region *reg, tree diag_arg,
|
||||
byte_range range)
|
||||
: concrete_out_of_bounds (reg, diag_arg, range)
|
||||
concrete_buffer_underwrite (const region_model &model,
|
||||
const region *reg, tree diag_arg,
|
||||
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
|
||||
@ -394,7 +493,7 @@ public:
|
||||
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;
|
||||
bool warned;
|
||||
@ -415,7 +514,7 @@ public:
|
||||
break;
|
||||
}
|
||||
if (warned)
|
||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
||||
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||
return warned;
|
||||
}
|
||||
|
||||
@ -449,6 +548,8 @@ public:
|
||||
start_buf, end_buf);;
|
||||
}
|
||||
}
|
||||
|
||||
enum access_direction get_dir () const final override { return DIR_WRITE; }
|
||||
};
|
||||
|
||||
/* Concrete subclass to complain about buffer under-reads. */
|
||||
@ -456,9 +557,10 @@ public:
|
||||
class concrete_buffer_under_read : public concrete_out_of_bounds
|
||||
{
|
||||
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)
|
||||
: 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
|
||||
@ -466,7 +568,7 @@ public:
|
||||
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;
|
||||
bool warned;
|
||||
@ -487,7 +589,7 @@ public:
|
||||
break;
|
||||
}
|
||||
if (warned)
|
||||
maybe_describe_array_bounds (rich_loc->get_loc ());
|
||||
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||
return warned;
|
||||
}
|
||||
|
||||
@ -521,6 +623,8 @@ public:
|
||||
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
|
||||
@ -529,9 +633,11 @@ public:
|
||||
class symbolic_past_the_end : public out_of_bounds
|
||||
{
|
||||
public:
|
||||
symbolic_past_the_end (const region *reg, tree diag_arg, tree offset,
|
||||
tree num_bytes, tree capacity)
|
||||
: out_of_bounds (reg, diag_arg),
|
||||
symbolic_past_the_end (const region_model &model,
|
||||
const region *reg, tree diag_arg, tree offset,
|
||||
tree num_bytes, tree capacity,
|
||||
const svalue *sval_hint)
|
||||
: out_of_bounds (model, reg, diag_arg, sval_hint),
|
||||
m_offset (offset),
|
||||
m_num_bytes (num_bytes),
|
||||
m_capacity (capacity)
|
||||
@ -559,9 +665,12 @@ protected:
|
||||
class symbolic_buffer_overflow : public symbolic_past_the_end
|
||||
{
|
||||
public:
|
||||
symbolic_buffer_overflow (const region *reg, tree diag_arg, tree offset,
|
||||
tree num_bytes, tree capacity)
|
||||
: symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
|
||||
symbolic_buffer_overflow (const region_model &model,
|
||||
const region *reg, tree diag_arg, tree offset,
|
||||
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";
|
||||
}
|
||||
|
||||
bool emit (rich_location *rich_loc) final override
|
||||
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||
{
|
||||
diagnostic_metadata m;
|
||||
bool warned;
|
||||
switch (get_memory_space ())
|
||||
{
|
||||
default:
|
||||
m.add_cwe (787);
|
||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"buffer overflow");
|
||||
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"buffer overflow");
|
||||
break;
|
||||
case MEMSPACE_STACK:
|
||||
m.add_cwe (121);
|
||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"stack-based buffer overflow");
|
||||
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"stack-based buffer overflow");
|
||||
break;
|
||||
case MEMSPACE_HEAP:
|
||||
m.add_cwe (122);
|
||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"heap-based buffer overflow");
|
||||
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"heap-based buffer overflow");
|
||||
break;
|
||||
}
|
||||
if (warned)
|
||||
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||
return warned;
|
||||
}
|
||||
|
||||
label_text
|
||||
@ -658,6 +774,8 @@ public:
|
||||
m_diag_arg);
|
||||
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. */
|
||||
@ -665,9 +783,11 @@ public:
|
||||
class symbolic_buffer_over_read : public symbolic_past_the_end
|
||||
{
|
||||
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)
|
||||
: 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";
|
||||
}
|
||||
|
||||
bool emit (rich_location *rich_loc) final override
|
||||
bool emit (rich_location *rich_loc, logger *logger) final override
|
||||
{
|
||||
diagnostic_metadata m;
|
||||
m.add_cwe (126);
|
||||
bool warned;
|
||||
switch (get_memory_space ())
|
||||
{
|
||||
default:
|
||||
m.add_cwe (787);
|
||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"buffer over-read");
|
||||
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"buffer over-read");
|
||||
break;
|
||||
case MEMSPACE_STACK:
|
||||
m.add_cwe (121);
|
||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"stack-based buffer over-read");
|
||||
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"stack-based buffer over-read");
|
||||
break;
|
||||
case MEMSPACE_HEAP:
|
||||
m.add_cwe (122);
|
||||
return warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"heap-based buffer over-read");
|
||||
warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
"heap-based buffer over-read");
|
||||
break;
|
||||
}
|
||||
if (warned)
|
||||
maybe_show_notes (rich_loc->get_loc (), logger);
|
||||
return warned;
|
||||
}
|
||||
|
||||
label_text
|
||||
@ -765,6 +892,8 @@ public:
|
||||
m_diag_arg);
|
||||
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.
|
||||
@ -776,6 +905,7 @@ region_model::check_symbolic_bounds (const region *base_reg,
|
||||
const svalue *num_bytes_sval,
|
||||
const svalue *capacity,
|
||||
enum access_direction dir,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) const
|
||||
{
|
||||
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 num_bytes_tree = get_representative_tree (num_bytes_sval);
|
||||
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)
|
||||
{
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
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,
|
||||
offset_tree,
|
||||
num_bytes_tree,
|
||||
@ -804,11 +942,13 @@ region_model::check_symbolic_bounds (const region *base_reg,
|
||||
return false;
|
||||
break;
|
||||
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,
|
||||
offset_tree,
|
||||
num_bytes_tree,
|
||||
capacity_tree));
|
||||
capacity_tree,
|
||||
sval_hint));
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@ -832,6 +972,7 @@ maybe_get_integer_cst_tree (const svalue *sval)
|
||||
bool
|
||||
region_model::check_region_bounds (const region *reg,
|
||||
enum access_direction dir,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) const
|
||||
{
|
||||
gcc_assert (ctxt);
|
||||
@ -882,8 +1023,8 @@ region_model::check_region_bounds (const region *reg,
|
||||
}
|
||||
else
|
||||
byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
|
||||
return check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
|
||||
capacity, dir, ctxt);
|
||||
return check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
|
||||
capacity, dir, sval_hint, ctxt);
|
||||
}
|
||||
|
||||
/* Otherwise continue to check with concrete values. */
|
||||
@ -902,13 +1043,17 @@ region_model::check_region_bounds (const region *reg,
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
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));
|
||||
oob_safe = false;
|
||||
break;
|
||||
case DIR_WRITE:
|
||||
ctxt->warn (make_unique<concrete_buffer_underwrite> (reg, diag_arg,
|
||||
out));
|
||||
ctxt->warn (make_unique<concrete_buffer_underwrite> (*this,
|
||||
reg, diag_arg,
|
||||
out,
|
||||
sval_hint));
|
||||
oob_safe = false;
|
||||
break;
|
||||
}
|
||||
@ -934,13 +1079,17 @@ region_model::check_region_bounds (const region *reg,
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
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));
|
||||
oob_safe = false;
|
||||
break;
|
||||
case DIR_WRITE:
|
||||
ctxt->warn (make_unique<concrete_buffer_overflow> (reg, diag_arg,
|
||||
out, byte_bound));
|
||||
ctxt->warn (make_unique<concrete_buffer_overflow> (*this,
|
||||
reg, diag_arg,
|
||||
out, byte_bound,
|
||||
sval_hint));
|
||||
oob_safe = false;
|
||||
break;
|
||||
}
|
||||
|
@ -1421,7 +1421,7 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
|
||||
|
||||
auto_diagnostic_group d;
|
||||
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 ();
|
||||
|
||||
|
@ -1771,7 +1771,7 @@ public:
|
||||
return OPT_Wanalyzer_stale_setjmp_buffer;
|
||||
}
|
||||
|
||||
bool emit (rich_location *richloc) final override
|
||||
bool emit (rich_location *richloc, logger *) final override
|
||||
{
|
||||
return warning_at
|
||||
(richloc, get_controlling_option (),
|
||||
@ -3925,7 +3925,7 @@ public:
|
||||
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 (),
|
||||
"jump through null pointer");
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
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". */
|
||||
diagnostic_metadata m;
|
||||
|
@ -255,7 +255,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool emit (rich_location *richloc) final override
|
||||
bool emit (rich_location *richloc, logger *) final override
|
||||
{
|
||||
inform (richloc, "path");
|
||||
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,
|
||||
NULL_TREE,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -587,7 +589,7 @@ public:
|
||||
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;
|
||||
diagnostic_metadata m;
|
||||
|
@ -180,7 +180,7 @@ class pending_diagnostic
|
||||
/* Vfunc for emitting the diagnostic. The rich_location will have been
|
||||
populated with a diagnostic_path.
|
||||
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. */
|
||||
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. */
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -612,7 +613,7 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
|
||||
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 ()))
|
||||
|| (arg1->get_type () && FLOAT_TYPE_P (arg1->get_type ())))
|
||||
return NULL;
|
||||
@ -634,6 +635,11 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
|
||||
/* (0 - VAL) -> -VAL. */
|
||||
if (cst0 && zerop (cst0))
|
||||
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;
|
||||
case MULT_EXPR:
|
||||
/* (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 (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
|
||||
if (binop->get_op () == op
|
||||
&& binop->get_arg1 ()->maybe_get_constant ()
|
||||
&& type == binop->get_type ()
|
||||
&& type == binop->get_arg0 ()->get_type ()
|
||||
&& type == binop->get_arg1 ()->get_type ())
|
||||
&& binop->get_arg1 ()->maybe_get_constant ())
|
||||
return get_or_create_binop
|
||||
(type, op, binop->get_arg0 (),
|
||||
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,
|
||||
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. */
|
||||
|
||||
return NULL;
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
/* svalue consolidation. */
|
||||
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_unknown_svalue (tree type);
|
||||
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 emit (rich_location *rich_loc) final override
|
||||
bool emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
switch (m_pkind)
|
||||
{
|
||||
@ -638,7 +638,7 @@ public:
|
||||
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 (),
|
||||
"shift by negative count (%qE)", m_count_cst);
|
||||
@ -685,7 +685,7 @@ public:
|
||||
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 (),
|
||||
"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);
|
||||
const svalue *ptr_sval = get_rvalue (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. */
|
||||
}
|
||||
}
|
||||
@ -2522,8 +2522,8 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
|
||||
const poisoned_svalue *poisoned_sval
|
||||
= as_a <const poisoned_svalue *> (ptr_sval);
|
||||
enum poison_kind pkind = poisoned_sval->get_poison_kind ();
|
||||
ctxt->warn (make_unique<poisoned_value_diagnostic>
|
||||
(ptr, pkind, NULL, NULL));
|
||||
ctxt->warn (::make_unique<poisoned_value_diagnostic>
|
||||
(ptr, pkind, nullptr, nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2576,7 +2576,7 @@ public:
|
||||
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;
|
||||
bool warned;
|
||||
@ -2644,7 +2644,7 @@ public:
|
||||
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 (),
|
||||
"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
|
||||
of the underlying regions. */
|
||||
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))
|
||||
@ -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,
|
||||
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
|
||||
region_model::check_region_access (const region *reg,
|
||||
enum access_direction dir,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) const
|
||||
{
|
||||
/* Fail gracefully if CTXT is NULL. */
|
||||
@ -2794,7 +2806,7 @@ region_model::check_region_access (const region *reg,
|
||||
|
||||
bool need_unknown_sval = false;
|
||||
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;
|
||||
|
||||
switch (dir)
|
||||
@ -2815,9 +2827,10 @@ region_model::check_region_access (const region *reg,
|
||||
|
||||
void
|
||||
region_model::check_region_for_write (const region *dest_reg,
|
||||
const svalue *sval_hint,
|
||||
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.
|
||||
@ -2827,7 +2840,7 @@ bool
|
||||
region_model::check_region_for_read (const region *src_reg,
|
||||
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. */
|
||||
@ -2863,7 +2876,7 @@ public:
|
||||
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;
|
||||
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_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,
|
||||
ctxt ? ctxt->get_uncertainty () : NULL);
|
||||
@ -3836,7 +3849,12 @@ region_model::get_representative_path_var_1 (const svalue *sval,
|
||||
|
||||
/* Prevent infinite recursion. */
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
bool emit (rich_location *rich_loc) final override
|
||||
bool emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
diagnostic_metadata m;
|
||||
bool warned = warning_meta (rich_loc, m, get_controlling_option (),
|
||||
@ -5303,7 +5321,7 @@ public:
|
||||
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;
|
||||
/* CWE-200: Exposure of Sensitive Information to an Unauthorized Actor. */
|
||||
|
@ -490,6 +490,7 @@ class region_model
|
||||
region_model_context *ctxt) const;
|
||||
|
||||
void check_region_for_write (const region *dest_reg,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) const;
|
||||
|
||||
private:
|
||||
@ -555,6 +556,7 @@ private:
|
||||
region_model_context *ctxt) const;
|
||||
bool check_region_access (const region *reg,
|
||||
enum access_direction dir,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) const;
|
||||
bool check_region_for_read (const region *src_reg,
|
||||
region_model_context *ctxt) const;
|
||||
@ -567,8 +569,10 @@ private:
|
||||
const svalue *num_bytes_sval,
|
||||
const svalue *capacity,
|
||||
enum access_direction dir,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) const;
|
||||
bool check_region_bounds (const region *reg, enum access_direction dir,
|
||||
const svalue *sval_hint,
|
||||
region_model_context *ctxt) 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 {
|
||||
|
||||
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. */
|
||||
@ -339,6 +665,35 @@ region::get_offset (region_model_manager *mgr) const
|
||||
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.
|
||||
If the size of this region (in bytes) is known statically, write it to *OUT
|
||||
and return true.
|
||||
@ -617,7 +972,7 @@ region::get_relative_concrete_offset (bit_offset_t *) const
|
||||
const svalue *
|
||||
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
|
||||
@ -1448,10 +1803,10 @@ field_region::get_relative_symbolic_offset (region_model_manager *mgr) const
|
||||
if (get_relative_concrete_offset (&out))
|
||||
{
|
||||
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_unknown_svalue (integer_type_node);
|
||||
return mgr->get_or_create_unknown_svalue (ptrdiff_type_node);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
const svalue *byte_size_sval
|
||||
= 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);
|
||||
}
|
||||
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. */
|
||||
@ -1864,7 +2219,7 @@ bit_range_region::get_relative_symbolic_offset (region_model_manager *mgr)
|
||||
const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -183,6 +183,7 @@ public:
|
||||
bool involves_p (const svalue *sval) 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.
|
||||
If successful, return true and write the size to *OUT.
|
||||
|
@ -465,7 +465,7 @@ public:
|
||||
}
|
||||
|
||||
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
|
||||
Lifetime
|
||||
@ -550,7 +550,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
emit (rich_location *rich_loc) final override
|
||||
emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
bool warned;
|
||||
switch (m_fd_dir)
|
||||
@ -612,7 +612,7 @@ public:
|
||||
return OPT_Wanalyzer_fd_double_close;
|
||||
}
|
||||
bool
|
||||
emit (rich_location *rich_loc) final override
|
||||
emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
diagnostic_metadata m;
|
||||
// CWE-1341: Multiple Releases of Same Resource or Handle
|
||||
@ -677,7 +677,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
emit (rich_location *rich_loc) final override
|
||||
emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
bool warned;
|
||||
warned = warning_at (rich_loc, get_controlling_option (),
|
||||
@ -748,7 +748,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
emit (rich_location *rich_loc) final override
|
||||
emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
bool warned;
|
||||
warned = warning_at (rich_loc, get_controlling_option (),
|
||||
@ -859,7 +859,7 @@ public:
|
||||
}
|
||||
|
||||
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. */
|
||||
diagnostic_metadata m;
|
||||
@ -1019,7 +1019,7 @@ public:
|
||||
}
|
||||
|
||||
bool
|
||||
emit (rich_location *rich_loc) final override
|
||||
emit (rich_location *rich_loc, logger *) final override
|
||||
{
|
||||
switch (m_expected_type)
|
||||
{
|
||||
|
@ -176,7 +176,7 @@ public:
|
||||
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;
|
||||
/* CWE-1341: Multiple Releases of Same Resource or Handle. */
|
||||
@ -224,7 +224,7 @@ public:
|
||||
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;
|
||||
/* CWE-775: "Missing Release of File Descriptor or Handle after
|
||||
|
@ -835,7 +835,7 @@ public:
|
||||
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;
|
||||
diagnostic_metadata m;
|
||||
@ -914,7 +914,7 @@ public:
|
||||
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;
|
||||
diagnostic_metadata m;
|
||||
@ -1010,7 +1010,7 @@ public:
|
||||
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. */
|
||||
diagnostic_metadata m;
|
||||
@ -1099,7 +1099,7 @@ public:
|
||||
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. */
|
||||
auto_diagnostic_group d;
|
||||
@ -1152,7 +1152,7 @@ public:
|
||||
|
||||
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. */
|
||||
diagnostic_metadata m;
|
||||
@ -1207,7 +1207,7 @@ public:
|
||||
|
||||
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. */
|
||||
auto_diagnostic_group d;
|
||||
@ -1264,7 +1264,7 @@ public:
|
||||
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. */
|
||||
diagnostic_metadata m;
|
||||
@ -1358,7 +1358,7 @@ public:
|
||||
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". */
|
||||
diagnostic_metadata m;
|
||||
@ -1432,7 +1432,7 @@ public:
|
||||
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;
|
||||
diagnostic_metadata m;
|
||||
@ -1511,7 +1511,7 @@ public:
|
||||
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
|
||||
and the check occur. */
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
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 (),
|
||||
"pattern match on %<%E %s %E%>",
|
||||
|
@ -95,7 +95,8 @@ public:
|
||||
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;
|
||||
/* CWE-532: Information Exposure Through Log Files */
|
||||
|
@ -114,7 +114,7 @@ public:
|
||||
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;
|
||||
diagnostic_metadata m;
|
||||
|
@ -211,7 +211,7 @@ public:
|
||||
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;
|
||||
/* CWE-129: "Improper Validation of Array Index". */
|
||||
@ -327,7 +327,7 @@ public:
|
||||
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;
|
||||
/* CWE-823: "Use of Out-of-range Pointer Offset". */
|
||||
@ -437,7 +437,7 @@ public:
|
||||
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". */
|
||||
diagnostic_metadata m;
|
||||
@ -547,9 +547,9 @@ public:
|
||||
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)
|
||||
{
|
||||
inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
|
||||
@ -583,7 +583,7 @@ public:
|
||||
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;
|
||||
/* CWE-369: "Divide By Zero". */
|
||||
@ -645,7 +645,7 @@ public:
|
||||
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;
|
||||
/* "CWE-789: Memory Allocation with Excessive Size Value". */
|
||||
@ -800,7 +800,7 @@ public:
|
||||
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;
|
||||
/* "CWE-617: Reachable Assertion". */
|
||||
|
@ -236,8 +236,8 @@ bit_range::dump () const
|
||||
pp_flush (&pp);
|
||||
}
|
||||
|
||||
/* If OTHER is a subset of this, return true and write
|
||||
to *OUT the relative range of OTHER within this.
|
||||
/* If OTHER is a subset of this, return true and, if OUT is
|
||||
non-null, write to *OUT the relative range of OTHER within this.
|
||||
Otherwise return false. */
|
||||
|
||||
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 ())
|
||||
&& contains_p (other.get_last_bit_offset ()))
|
||||
{
|
||||
out->m_start_bit_offset = other.m_start_bit_offset - m_start_bit_offset;
|
||||
out->m_size_in_bits = other.m_size_in_bits;
|
||||
if (out)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -350,6 +350,15 @@ struct byte_range
|
||||
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);
|
||||
|
||||
byte_offset_t m_start_byte_offset;
|
||||
|
@ -403,7 +403,7 @@ public:
|
||||
&& 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;
|
||||
return warning_at (rich_loc, get_controlling_option (),
|
||||
@ -478,7 +478,7 @@ public:
|
||||
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;
|
||||
return warning_at (rich_loc, get_controlling_option (),
|
||||
@ -892,7 +892,7 @@ public:
|
||||
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;
|
||||
diagnostic_metadata m;
|
||||
@ -942,7 +942,7 @@ public:
|
||||
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;
|
||||
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>
|
||||
|
||||
* c.opt (Welaborated-enum-base): New.
|
||||
|
@ -1338,6 +1338,10 @@ shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
|
||||
int uns;
|
||||
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
|
||||
excessive narrowing when we call get_narrower below. For
|
||||
example, suppose that OP0 is of unsigned int extended
|
||||
|
@ -740,7 +740,9 @@ enum cxx_dialect {
|
||||
/* C++20 */
|
||||
cxx20,
|
||||
/* C++23 */
|
||||
cxx23
|
||||
cxx23,
|
||||
/* C++26 */
|
||||
cxx26
|
||||
};
|
||||
|
||||
/* 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 "tree-nested.h"
|
||||
#include "context.h"
|
||||
#include "tree-pass.h"
|
||||
#include "internal-fn.h"
|
||||
|
||||
/* The gimplification pass converts the language-dependent 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;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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:;
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,7 @@ static void set_std_cxx14 (int);
|
||||
static void set_std_cxx17 (int);
|
||||
static void set_std_cxx20 (int);
|
||||
static void set_std_cxx23 (int);
|
||||
static void set_std_cxx26 (int);
|
||||
static void set_std_c89 (int, int);
|
||||
static void set_std_c99 (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 */);
|
||||
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_iso9899_199409:
|
||||
if (!preprocessing_asm_p)
|
||||
@ -1032,7 +1039,8 @@ c_common_post_options (const char **pfilename)
|
||||
warn_narrowing = 1;
|
||||
|
||||
/* 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))
|
||||
cpp_opts->ext_numeric_literals = 0;
|
||||
}
|
||||
@ -1820,6 +1828,24 @@ set_std_cxx23 (int iso)
|
||||
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
|
||||
unrecognized options; they may be aimed at toplev.cc. */
|
||||
static void
|
||||
|
@ -2403,13 +2403,21 @@ C++ ObjC++
|
||||
Conform to the ISO 2020 C++ standard (experimental and incomplete support).
|
||||
|
||||
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).
|
||||
|
||||
std=c++23
|
||||
C++ ObjC++ Undocumented
|
||||
C++ ObjC++
|
||||
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
|
||||
C ObjC
|
||||
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).
|
||||
|
||||
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).
|
||||
|
||||
std=gnu++23
|
||||
C++ ObjC++ Undocumented
|
||||
C++ ObjC++
|
||||
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
|
||||
C ObjC
|
||||
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_CYAN "36"
|
||||
#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_RED "41"
|
||||
#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_CYAN "46"
|
||||
#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_END "m\33[K"
|
||||
#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)
|
||||
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=
|
||||
Common Joined UInteger Var(diagnostics_minimum_margin_width) Init(6)
|
||||
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
|
||||
Enum(fp_contract_mode) String(off) Value(FP_CONTRACT_OFF)
|
||||
|
||||
; Not implemented, fall back to conservative FP_CONTRACT_OFF.
|
||||
EnumValue
|
||||
Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_OFF)
|
||||
Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_ON)
|
||||
|
||||
EnumValue
|
||||
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,
|
||||
HOST_WIDE_INT);
|
||||
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_emit_approx_div (rtx, rtx, rtx);
|
||||
bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
|
||||
|
@ -1323,7 +1323,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(<SHIFTEXTEND>:<V2XWIDE>
|
||||
(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 1 "register_operand" "0")))]
|
||||
"TARGET_SIMD
|
||||
@ -6437,7 +6437,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(<SHIFTEXTEND>:<V2XWIDE>
|
||||
(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>"))))]
|
||||
"TARGET_SIMD
|
||||
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
||||
@ -6557,7 +6557,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(<TRUNCEXTEND>:<V2XWIDE>
|
||||
(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>"))))]
|
||||
"TARGET_SIMD
|
||||
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
||||
@ -6572,7 +6572,7 @@
|
||||
(plus:<DWI>
|
||||
(<TRUNCEXTEND>:<DWI>
|
||||
(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>"))))]
|
||||
"TARGET_SIMD
|
||||
&& aarch64_const_vec_rnd_cst_p (operands[3], operands[2])"
|
||||
@ -6702,7 +6702,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(sign_extend:<V2XWIDE>
|
||||
(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:<V2XWIDE> 4 "aarch64_simd_imm_zero"))
|
||||
(match_operand:<V2XWIDE> 5 "aarch64_simd_umax_quarter_mode"))))]
|
||||
@ -6713,14 +6713,14 @@
|
||||
)
|
||||
|
||||
(define_insn "aarch64_sqrshrun_n<mode>_insn"
|
||||
[(set (match_operand:<V2XWIDE> 0 "register_operand" "=w")
|
||||
(smin:<V2XWIDE>
|
||||
(smax:<V2XWIDE>
|
||||
(ashiftrt:<V2XWIDE>
|
||||
(plus:<V2XWIDE>
|
||||
(sign_extend:<V2XWIDE>
|
||||
[(set (match_operand:<DWI> 0 "register_operand" "=w")
|
||||
(smin:<DWI>
|
||||
(smax:<DWI>
|
||||
(ashiftrt:<DWI>
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(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>"))
|
||||
(const_int 0))
|
||||
(const_int <half_mask>)))]
|
||||
@ -6736,10 +6736,10 @@
|
||||
(match_operand:SI 2 "aarch64_simd_shift_imm_offset_<ve_mode>")]
|
||||
"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);
|
||||
rtx rnd = immed_wide_int_const (rnd_wi, <V2XWIDE>mode);
|
||||
rtx dst = gen_reg_rtx (<V2XWIDE>mode);
|
||||
rtx rnd = immed_wide_int_const (rnd_wi, <DWI>mode);
|
||||
rtx dst = gen_reg_rtx (<DWI>mode);
|
||||
emit_insn (gen_aarch64_sqrshrun_n<mode>_insn (dst, operands[1], operands[2], rnd));
|
||||
emit_move_insn (operands[0], gen_lowpart (<VNARROWQ>mode, dst));
|
||||
DONE;
|
||||
@ -6831,7 +6831,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(<TRUNCEXTEND>:<V2XWIDE>
|
||||
(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>")))))]
|
||||
"TARGET_SIMD && !BYTES_BIG_ENDIAN
|
||||
&& aarch64_const_vec_rnd_cst_p (operands[4], operands[3])"
|
||||
@ -6847,7 +6847,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(<TRUNCEXTEND>:<V2XWIDE>
|
||||
(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:<VNARROWQ> 1 "register_operand" "0")))]
|
||||
"TARGET_SIMD && BYTES_BIG_ENDIAN
|
||||
@ -6965,7 +6965,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(sign_extend:<V2XWIDE>
|
||||
(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:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
|
||||
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))))]
|
||||
@ -6985,7 +6985,7 @@
|
||||
(plus:<V2XWIDE>
|
||||
(sign_extend:<V2XWIDE>
|
||||
(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:<V2XWIDE> 5 "aarch64_simd_imm_zero"))
|
||||
(match_operand:<V2XWIDE> 6 "aarch64_simd_umax_quarter_mode")))
|
||||
|
@ -1929,7 +1929,7 @@ static const struct tune_params ampere1_tunings =
|
||||
"32:16", /* loop_align. */
|
||||
2, /* int_reassoc_width. */
|
||||
4, /* fp_reassoc_width. */
|
||||
1, /* fma_reassoc_width. */
|
||||
4, /* fma_reassoc_width. */
|
||||
2, /* vec_reassoc_width. */
|
||||
2, /* min_div_recip_mul_sf. */
|
||||
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 if X is a TImode constant or a constant vector of integer
|
||||
immediates that represent the rounding constant used in the RSRA
|
||||
instructions.
|
||||
The accepted form of the constant is (1 << (C - 1)) where C is within
|
||||
/* Return true if X is a scalar or a constant vector of integer
|
||||
immediates that represent the rounding constant used in the fixed-point
|
||||
arithmetic instructions.
|
||||
The accepted form of the constant is (1 << (C - 1)) where C is in the range
|
||||
[1, MODE_WIDTH/2]. */
|
||||
|
||||
bool
|
||||
aarch64_const_vec_rsra_rnd_imm_p (rtx x)
|
||||
aarch64_rnd_imm_p (rtx x)
|
||||
{
|
||||
wide_int rnd_cst;
|
||||
if (!aarch64_extract_vec_duplicate_wide_int (x, &rnd_cst))
|
||||
|
@ -626,15 +626,11 @@
|
||||
(and (match_code "const_vector")
|
||||
(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")
|
||||
(match_test "aarch64_const_vec_rsra_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))")))
|
||||
(match_test "aarch64_rnd_imm_p (op)")))
|
||||
|
||||
(define_predicate "aarch64_simd_raddsubhn_imm_vec"
|
||||
(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;
|
||||
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))
|
||||
op0 = safe_vector_operand (op0, mode0);
|
||||
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])
|
||||
opts->x_ix86_tune_string
|
||||
= 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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
*total = cost->sse_op;
|
||||
if (XVECLEN (x, 0) == 2
|
||||
&& GET_CODE (XVECEXP (x, 0, 0)) == AND)
|
||||
rtx test_op0 = XVECEXP (x, 0, 0);
|
||||
if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
|
||||
return false;
|
||||
if (GET_CODE (test_op0) == AND)
|
||||
{
|
||||
rtx andop = XVECEXP (x, 0, 0);
|
||||
*total += rtx_cost (XEXP (andop, 0), GET_MODE (andop),
|
||||
AND, opno, speed)
|
||||
+ rtx_cost (XEXP (andop, 1), GET_MODE (andop),
|
||||
AND, opno, speed);
|
||||
return true;
|
||||
rtx and_op0 = XEXP (test_op0, 0);
|
||||
if (GET_CODE (and_op0) == NOT)
|
||||
and_op0 = XEXP (and_op0, 0);
|
||||
*total += rtx_cost (and_op0, GET_MODE (and_op0),
|
||||
AND, 0, speed)
|
||||
+ 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;
|
||||
|
||||
|
@ -11380,6 +11380,8 @@
|
||||
[(set_attr "type" "alu")
|
||||
(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
|
||||
;; equivalents when possible.
|
||||
;; Don't do the splitting with memory operands, since it introduces risk
|
||||
@ -12092,6 +12094,26 @@
|
||||
[(set_attr "type" "alu")
|
||||
(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
|
||||
;; equivalents when possible.
|
||||
;; Don't do the splitting with memory operands, since it introduces risk
|
||||
@ -12206,6 +12228,18 @@
|
||||
(set_attr "type" "alu")
|
||||
(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.
|
||||
(define_insn_and_split "*concat<mode><dwi>3_1"
|
||||
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
|
||||
@ -13365,6 +13399,28 @@
|
||||
[(const_int 0)]
|
||||
"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"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
|
||||
(ior:DI (ashift:DI (match_dup 0)
|
||||
|
@ -1465,12 +1465,12 @@
|
||||
})
|
||||
|
||||
(define_insn "*<avx512>_load<mode>_mask"
|
||||
[(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
|
||||
(vec_merge:VI12_AVX512VL
|
||||
(unspec:VI12_AVX512VL
|
||||
[(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
|
||||
[(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand" "=v")
|
||||
(vec_merge:VI12HFBF_AVX512VL
|
||||
(unspec:VI12HFBF_AVX512VL
|
||||
[(match_operand:VI12HFBF_AVX512VL 1 "memory_operand" "m")]
|
||||
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")))]
|
||||
"TARGET_AVX512BW"
|
||||
"vmovdqu<ssescalarsize>\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
|
||||
@ -1479,9 +1479,9 @@
|
||||
(set_attr "mode" "<sseinsnmode>")])
|
||||
|
||||
(define_insn_and_split "*<avx512>_load<mode>"
|
||||
[(set (match_operand:VI12_AVX512VL 0 "register_operand" "=v")
|
||||
(unspec:VI12_AVX512VL
|
||||
[(match_operand:VI12_AVX512VL 1 "memory_operand" "m")]
|
||||
[(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand" "=v")
|
||||
(unspec:VI12HFBF_AVX512VL
|
||||
[(match_operand:VI12HFBF_AVX512VL 1 "memory_operand" "m")]
|
||||
UNSPEC_MASKLOAD))]
|
||||
"TARGET_AVX512BW"
|
||||
"#"
|
||||
@ -23490,6 +23490,70 @@
|
||||
[(set (reg:CCZ FLAGS_REG)
|
||||
(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"
|
||||
[(set (match_operand:VFH 0 "register_operand")
|
||||
(unspec:VFH
|
||||
@ -26915,17 +26979,21 @@
|
||||
"TARGET_AVX")
|
||||
|
||||
(define_expand "maskload<mode><avx512fmaskmodelower>"
|
||||
[(set (match_operand:V48H_AVX512VL 0 "register_operand")
|
||||
(vec_merge:V48H_AVX512VL
|
||||
(match_operand:V48H_AVX512VL 1 "memory_operand")
|
||||
[(set (match_operand:V48_AVX512VL 0 "register_operand")
|
||||
(vec_merge:V48_AVX512VL
|
||||
(unspec:V48_AVX512VL
|
||||
[(match_operand:V48_AVX512VL 1 "memory_operand")]
|
||||
UNSPEC_MASKLOAD)
|
||||
(match_dup 0)
|
||||
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
|
||||
"TARGET_AVX512F")
|
||||
|
||||
(define_expand "maskload<mode><avx512fmaskmodelower>"
|
||||
[(set (match_operand:VI12_AVX512VL 0 "register_operand")
|
||||
(vec_merge:VI12_AVX512VL
|
||||
(match_operand:VI12_AVX512VL 1 "memory_operand")
|
||||
[(set (match_operand:VI12HFBF_AVX512VL 0 "register_operand")
|
||||
(vec_merge:VI12HFBF_AVX512VL
|
||||
(unspec:VI12HFBF_AVX512VL
|
||||
[(match_operand:VI12HFBF_AVX512VL 1 "memory_operand")]
|
||||
UNSPEC_MASKLOAD)
|
||||
(match_dup 0)
|
||||
(match_operand:<avx512fmaskmode> 2 "register_operand")))]
|
||||
"TARGET_AVX512BW")
|
||||
|
@ -22,29 +22,27 @@
|
||||
;; == Loads/Stores
|
||||
;; =========================================================================
|
||||
|
||||
;; len_load/len_store is a sub-optimal pattern for RVV auto-vectorization support.
|
||||
;; We will replace them when len_maskload/len_maskstore is supported in loop vectorizer.
|
||||
(define_expand "len_load_<mode>"
|
||||
(define_expand "len_maskload<mode><vm>"
|
||||
[(match_operand:V 0 "register_operand")
|
||||
(match_operand:V 1 "memory_operand")
|
||||
(match_operand 2 "vector_length_operand")
|
||||
(match_operand 3 "const_0_operand")]
|
||||
(match_operand 2 "autovec_length_operand")
|
||||
(match_operand:<VM> 3 "vector_mask_operand")
|
||||
(match_operand 4 "const_0_operand")]
|
||||
"TARGET_VECTOR"
|
||||
{
|
||||
riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
|
||||
riscv_vector::RVV_UNOP, operands, operands[2]);
|
||||
riscv_vector::expand_load_store (operands, true);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "len_store_<mode>"
|
||||
(define_expand "len_maskstore<mode><vm>"
|
||||
[(match_operand:V 0 "memory_operand")
|
||||
(match_operand:V 1 "register_operand")
|
||||
(match_operand 2 "vector_length_operand")
|
||||
(match_operand 3 "const_0_operand")]
|
||||
(match_operand 2 "autovec_length_operand")
|
||||
(match_operand:<VM> 3 "vector_mask_operand")
|
||||
(match_operand 4 "const_0_operand")]
|
||||
"TARGET_VECTOR"
|
||||
{
|
||||
riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
|
||||
riscv_vector::RVV_UNOP, operands, operands[2]);
|
||||
riscv_vector::expand_load_store (operands, false);
|
||||
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
|
||||
;; -------------------------------------------------------------------------
|
||||
@ -596,40 +556,41 @@
|
||||
;; result after reload_completed.
|
||||
(define_expand "fma<mode>4"
|
||||
[(parallel
|
||||
[(set (match_operand:VI 0 "register_operand" "=vr")
|
||||
[(set (match_operand:VI 0 "register_operand")
|
||||
(plus:VI
|
||||
(mult:VI
|
||||
(match_operand:VI 1 "register_operand" " vr")
|
||||
(match_operand:VI 2 "register_operand" " vr"))
|
||||
(match_operand:VI 3 "register_operand" " vr")))
|
||||
(clobber (match_scratch:SI 4))])]
|
||||
(match_operand:VI 1 "register_operand")
|
||||
(match_operand:VI 2 "register_operand"))
|
||||
(match_operand:VI 3 "register_operand")))
|
||||
(clobber (match_dup 4))])]
|
||||
"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")
|
||||
(plus:VI
|
||||
(mult:VI
|
||||
(match_operand:VI 1 "register_operand" " %0, vr, vr")
|
||||
(match_operand:VI 2 "register_operand" " vr, vr, 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"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
PUT_MODE (operands[4], Pmode);
|
||||
riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
|
||||
riscv_vector::emit_vlmax_vsetvl (<VI: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_ternary_insn (code_for_pred_mul_plus (<MODE>mode),
|
||||
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||
riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<VI:MODE>mode),
|
||||
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "vimuladd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
(set_attr "mode" "<VI:MODE>")])
|
||||
|
||||
;; -------------------------------------------------------------------------
|
||||
;; ---- [INT] VNMSAC and VNMSUB
|
||||
@ -641,40 +602,225 @@
|
||||
|
||||
(define_expand "fnma<mode>4"
|
||||
[(parallel
|
||||
[(set (match_operand:VI 0 "register_operand" "=vr")
|
||||
[(set (match_operand:VI 0 "register_operand")
|
||||
(minus:VI
|
||||
(match_operand:VI 3 "register_operand" " vr")
|
||||
(match_operand:VI 3 "register_operand")
|
||||
(mult:VI
|
||||
(match_operand:VI 1 "register_operand" " vr")
|
||||
(match_operand:VI 2 "register_operand" " vr"))))
|
||||
(clobber (match_scratch:SI 4))])]
|
||||
(match_operand:VI 1 "register_operand")
|
||||
(match_operand:VI 2 "register_operand"))))
|
||||
(clobber (match_dup 4))])]
|
||||
"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")
|
||||
(minus:VI
|
||||
(match_operand:VI 3 "register_operand" " vr, 0, vr")
|
||||
(mult:VI
|
||||
(match_operand:VI 1 "register_operand" " %0, 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"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
PUT_MODE (operands[4], Pmode);
|
||||
riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
|
||||
riscv_vector::emit_vlmax_vsetvl (<VI: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_ternary_insn (code_for_pred_minus_mul (<MODE>mode),
|
||||
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||
riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<VI:MODE>mode),
|
||||
riscv_vector::RVV_TERNOP, ops, operands[4]);
|
||||
DONE;
|
||||
}
|
||||
[(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
|
||||
|
@ -73,6 +73,9 @@ valid_type (unsigned sew, int lmul_log2, unsigned nf, bool float_p)
|
||||
if (nf > 8 || nf < 1)
|
||||
return false;
|
||||
|
||||
if (sew == 16 && nf != 1 && float_p) // Disable FP16 tuple in temporarily.
|
||||
return false;
|
||||
|
||||
switch (lmul_log2)
|
||||
{
|
||||
case 1:
|
||||
|
@ -276,6 +276,13 @@
|
||||
(ior (match_operand 0 "pmode_register_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"
|
||||
(ior (match_operand 0 "register_operand")
|
||||
(match_operand 0 "memory_operand")))
|
||||
|
@ -220,7 +220,6 @@ ADJUST_ALIGNMENT (VNx1QI, 1);
|
||||
#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, 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, FLOAT, SF, NBYTES / 4, 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, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VD##DI##mode, \
|
||||
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, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x##VS##SF##mode, \
|
||||
VS * NSUBPARTS)); \
|
||||
@ -251,7 +247,6 @@ ADJUST_ALIGNMENT (VNx1QI, 1);
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VH##HI, 2); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x##VS##SI, 4); \
|
||||
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##VD##DF, 8);
|
||||
|
||||
@ -280,12 +275,10 @@ RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8)
|
||||
#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, 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, FLOAT, SF, 1, 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, FLOAT, HF, 2, 1); \
|
||||
VECTOR_MODE_WITH_PREFIX (VNx##NSUBPARTS##x, INT, QI, 4, 1); \
|
||||
\
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1QI, \
|
||||
@ -294,9 +287,6 @@ RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8)
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1HI, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HI##mode, \
|
||||
NSUBPARTS)); \
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1HF, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1HF##mode, \
|
||||
NSUBPARTS)); \
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x1SI, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x1SI##mode, \
|
||||
NSUBPARTS)); \
|
||||
@ -309,20 +299,15 @@ RVV_TUPLE_MODES (64, 2, 64, 32, 16, 8)
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x2HI, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HI##mode, \
|
||||
2 * NSUBPARTS)); \
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x2HF, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x2HF##mode, \
|
||||
2 * NSUBPARTS)); \
|
||||
ADJUST_NUNITS (VNx##NSUBPARTS##x4QI, \
|
||||
riscv_v_adjust_nunits (VNx##NSUBPARTS##x4QI##mode, \
|
||||
4 * NSUBPARTS)); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1QI, 1); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HI, 2); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1HF, 2); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SI, 4); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x1SF, 4); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2QI, 1); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HI, 2); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x2HF, 2); \
|
||||
ADJUST_ALIGNMENT (VNx##NSUBPARTS##x4QI, 1);
|
||||
|
||||
RVV_TUPLE_PARTIAL_MODES (2)
|
||||
|
@ -143,6 +143,7 @@ enum insn_type
|
||||
RVV_CMP_OP = 4,
|
||||
RVV_CMP_MU_OP = RVV_CMP_OP + 2, /* +2 means mask and maskoff operand. */
|
||||
RVV_UNOP_MU = RVV_UNOP + 2, /* Likewise. */
|
||||
RVV_UNOP_M = RVV_UNOP + 2, /* Likewise. */
|
||||
RVV_TERNOP = 5,
|
||||
RVV_WIDEN_TERNOP = 4,
|
||||
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_fp_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_vlmax_slide_insn (unsigned, 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);
|
||||
void expand_vec_series (rtx, rtx, rtx);
|
||||
void expand_vec_init (rtx, rtx);
|
||||
void expand_vcond (rtx *);
|
||||
void expand_vec_perm (rtx, rtx, rtx, rtx);
|
||||
void expand_select_vl (rtx *);
|
||||
void expand_load_store (rtx *, bool);
|
||||
|
||||
/* Rounding mode bitfield for fixed point VXRM. */
|
||||
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 mask_mode = get_mask_mode (dest_mode).require ();
|
||||
/* We have a maximum of 11 operands for RVV instruction patterns according to
|
||||
* vector.md. */
|
||||
insn_expander<11> 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);
|
||||
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_vl (vl);
|
||||
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
|
||||
* actual operation. */
|
||||
void
|
||||
@ -841,17 +864,56 @@ emit_vlmax_cmp_mu_insn (unsigned icode, rtx *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. */
|
||||
void
|
||||
emit_vlmax_masked_mu_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<11> 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);
|
||||
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_UNDISTURBED);
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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>. */
|
||||
|
||||
void
|
||||
@ -2721,4 +2761,45 @@ expand_select_vl (rtx *ops)
|
||||
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
|
||||
|
@ -1567,7 +1567,7 @@ public:
|
||||
{
|
||||
tree arg = CALL_EXPR_ARG (e.exp, 0);
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
@ -121,8 +121,6 @@ extern const function_base *const vsmul;
|
||||
extern const function_base *const vssra;
|
||||
extern const function_base *const vssrl;
|
||||
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 vmand;
|
||||
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 vid;
|
||||
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 vfrsub;
|
||||
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 vfdiv;
|
||||
extern const function_base *const vfdiv;
|
||||
extern const function_base *const vfrdiv;
|
||||
extern const function_base *const vfwmul;
|
||||
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 (vint64m4x2_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 (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)
|
||||
|
@ -3636,6 +3636,7 @@ function_expander::use_contiguous_store_insn (insn_code icode)
|
||||
for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++)
|
||||
add_input_operand (argno);
|
||||
|
||||
add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
|
||||
return generate_insn (icode);
|
||||
}
|
||||
|
||||
|
@ -494,48 +494,18 @@ DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, uint64, VNx16DI, VNx8DI, VOID,
|
||||
/* LMUL = 1/4. */
|
||||
DEF_RVV_TYPE (vfloat16mf4_t, 18, __rvv_float16mf4_t, float16, VNx2HF, VNx1HF, VOID,
|
||||
_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. */
|
||||
DEF_RVV_TYPE (vfloat16mf2_t, 18, __rvv_float16mf2_t, float16, VNx4HF, VNx2HF, VNx1HF,
|
||||
_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. */
|
||||
DEF_RVV_TYPE (vfloat16m1_t, 17, __rvv_float16m1_t, float16, VNx8HF, VNx4HF, VNx2HF,
|
||||
_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. */
|
||||
DEF_RVV_TYPE (vfloat16m2_t, 17, __rvv_float16m2_t, float16, VNx16HF, VNx8HF, VNx4HF,
|
||||
_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. */
|
||||
DEF_RVV_TYPE (vfloat16m4_t, 17, __rvv_float16m4_t, float16, VNx32HF, VNx16HF, VNx8HF,
|
||||
_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. */
|
||||
DEF_RVV_TYPE (vfloat16m8_t, 16, __rvv_float16m8_t, float16, VNx64HF, VNx32HF, VNx16HF,
|
||||
_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 (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 (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_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);
|
||||
if (!same_vlmax_p (new_info) && !scalar_move_insn_p (insn->rtl ()))
|
||||
return;
|
||||
/* TODO: Currently, we don't forward AVL for non-VLMAX vsetvl. */
|
||||
if (vlmax_avl_p (new_info.get_avl ()))
|
||||
set_avl_info (avl_info (new_info.get_avl (), get_avl_source ()));
|
||||
|
||||
if (new_info.has_avl ())
|
||||
{
|
||||
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 ())
|
||||
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_no_reg () const { return !get_value (); }
|
||||
bool has_non_zero_avl () const;
|
||||
bool has_avl () const { return get_value (); }
|
||||
};
|
||||
|
||||
/* 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_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_avl () const { return m_avl.has_avl (); }
|
||||
|
||||
rtx get_avl () const { return m_avl.get_value (); }
|
||||
const avl_info &get_avl_info () const { return m_avl; }
|
||||
|
@ -191,11 +191,6 @@
|
||||
VNx2x4HI,VNx3x4HI,VNx4x4HI,VNx5x4HI,VNx6x4HI,VNx7x4HI,VNx8x4HI,
|
||||
VNx2x2HI,VNx3x2HI,VNx4x2HI,VNx5x2HI,VNx6x2HI,VNx7x2HI,VNx8x2HI,
|
||||
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,
|
||||
VNx2x4SI,VNx3x4SI,VNx4x4SI,VNx5x4SI,VNx6x4SI,VNx7x4SI,VNx8x4SI,
|
||||
VNx2x2SI,VNx3x2SI,VNx4x2SI,VNx5x2SI,VNx6x2SI,VNx7x2SI,VNx8x2SI,
|
||||
|
@ -652,38 +652,6 @@
|
||||
(VNx6x1DI "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")
|
||||
(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")
|
||||
(VNx2x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 64")
|
||||
(VNx3x8SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
|
||||
@ -1154,11 +1122,6 @@
|
||||
(VNx2x8DI "VNx8BI") (VNx2x4DI "VNx4BI") (VNx3x4DI "VNx4BI") (VNx4x4DI "VNx4BI")
|
||||
(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")
|
||||
(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")
|
||||
(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")
|
||||
|
@ -425,14 +425,14 @@
|
||||
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
|
||||
viwalu,viwmul,vnshift,vaalu,vsmul,vsshift,\
|
||||
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,\
|
||||
vlsegds,vlsegdux,vlsegdox")
|
||||
(symbol_ref "INTVAL (operands[8])")
|
||||
(eq_attr "type" "vstux,vstox,vssegts,vssegtux,vssegtox")
|
||||
(symbol_ref "INTVAL (operands[5])")
|
||||
|
||||
(eq_attr "type" "vimuladd")
|
||||
(eq_attr "type" "vimuladd,vfmuladd")
|
||||
(symbol_ref "INTVAL (operands[9])")
|
||||
|
||||
(eq_attr "type" "vmsfs,vmidx,vcompress")
|
||||
@ -1063,6 +1063,7 @@
|
||||
(unspec:<VM>
|
||||
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
|
||||
(match_operand 3 "vector_length_operand" " rK")
|
||||
(match_operand 4 "const_int_operand" " i")
|
||||
(reg:SI VL_REGNUM)
|
||||
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
||||
(match_operand:V 2 "register_operand" " vr")
|
||||
@ -1071,7 +1072,7 @@
|
||||
"vse<sew>.v\t%2,%0%p1"
|
||||
[(set_attr "type" "vste")
|
||||
(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")])
|
||||
|
||||
;; vlm.v/vsm.v/vmclr.m/vmset.m.
|
||||
@ -1113,6 +1114,7 @@
|
||||
(unspec:VB
|
||||
[(match_operand:VB 1 "vector_all_trues_mask_operand" "Wc1")
|
||||
(match_operand 3 "vector_length_operand" " rK")
|
||||
(match_operand 4 "const_int_operand" " i")
|
||||
(reg:SI VL_REGNUM)
|
||||
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
||||
(match_operand:VB 2 "register_operand" " vr")
|
||||
@ -1121,7 +1123,7 @@
|
||||
"vsm.v\t%2,%0"
|
||||
[(set_attr "type" "vstm")
|
||||
(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")])
|
||||
|
||||
(define_insn "@pred_merge<mode>"
|
||||
@ -1433,6 +1435,7 @@
|
||||
(unspec:<VM>
|
||||
[(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
|
||||
(match_operand 4 "vector_length_operand" " rK")
|
||||
(match_operand 5 "const_int_operand" " i")
|
||||
(reg:SI VL_REGNUM)
|
||||
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
|
||||
(unspec:V
|
||||
@ -1442,7 +1445,8 @@
|
||||
"TARGET_VECTOR"
|
||||
"vsse<sew>.v\t%3,%0,%z2%p1"
|
||||
[(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
|
||||
|
@ -22,7 +22,7 @@
|
||||
;; 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"
|
||||
[(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")))
|
||||
(clobber (match_scratch:DI 0 "=r"))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
@ -43,7 +43,7 @@
|
||||
;; 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"
|
||||
[(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")))
|
||||
(clobber (match_scratch:DI 0 "=r"))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
@ -64,7 +64,7 @@
|
||||
;; 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"
|
||||
[(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")))
|
||||
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
@ -85,7 +85,7 @@
|
||||
;; 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"
|
||||
[(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")))
|
||||
(set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
@ -104,17 +104,17 @@
|
||||
|
||||
;; 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
|
||||
(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")
|
||||
(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")))
|
||||
(clobber (match_scratch:SI 0 "=r"))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
"lwa%X1 %0,%1\;cmpdi %2,%0,%3"
|
||||
"lwz%X1 %0,%1\;cmpwi %2,%0,%3"
|
||||
"&& reload_completed
|
||||
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
||||
|| !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 2)
|
||||
(compare:CC (match_dup 0) (match_dup 3)))]
|
||||
@ -146,17 +146,17 @@
|
||||
|
||||
;; 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
|
||||
(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")
|
||||
(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")))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
"lwa%X1 %0,%1\;cmpdi %2,%0,%3"
|
||||
"lwz%X1 %0,%1\;cmpwi %2,%0,%3"
|
||||
"&& reload_completed
|
||||
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
||||
|| !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 2)
|
||||
(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
|
||||
(define_insn_and_split "*lwa_cmpdi_cr0_SI_EXTSI_CC_sign"
|
||||
[(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")))
|
||||
(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") (sign_extend:EXTSI (match_dup 1)))]
|
||||
"(TARGET_P10_FUSION)"
|
||||
@ -205,6 +205,7 @@
|
||||
""
|
||||
[(set_attr "type" "fused_load_cmpi")
|
||||
(set_attr "cost" "8")
|
||||
(set_attr "sign_extend" "yes")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
;; 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 $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") {
|
||||
# ld and lwa are both DS-FORM.
|
||||
($lmode =~ /^[SD]I$/) and $np = "NON_PREFIXED_DS";
|
||||
($lmode =~ /^[SD]I$/) and $mempred = "ds_form_mem_operand";
|
||||
($lmode eq "DI") and $np = "NON_PREFIXED_DS";
|
||||
($lmode eq "SI" && $cmp_size_char eq "d") and $np = "NON_PREFIXED_DS";
|
||||
} else {
|
||||
if ($lmode eq "DI") {
|
||||
# ld is DS-form, but lwz is not.
|
||||
$np = "NON_PREFIXED_DS";
|
||||
$mempred = "ds_form_mem_operand";
|
||||
}
|
||||
}
|
||||
|
||||
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 = ""; }
|
||||
my $constpred = ($ccmode eq "CC") ? "const_m1_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);
|
||||
|
||||
# DS-form addresses need YZ, and not m.
|
||||
my $constraint = ($np eq "NON_PREFIXED_DS") ? "YZ" : "m";
|
||||
print <<HERE;
|
||||
;; 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
|
||||
(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")
|
||||
(compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "m")
|
||||
(compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "${constraint}")
|
||||
HERE
|
||||
print " " if $ccmode eq "CCUNS";
|
||||
print <<HERE;
|
||||
@ -119,7 +133,7 @@ HERE
|
||||
|
||||
print <<HERE;
|
||||
"(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
|
||||
&& (cc_reg_not_cr0_operand (operands[2], CCmode)
|
||||
|| !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
|
||||
@ -140,6 +154,15 @@ HERE
|
||||
""
|
||||
[(set_attr "type" "fused_load_cmpi")
|
||||
(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")])
|
||||
|
||||
HERE
|
||||
|
@ -1125,20 +1125,6 @@
|
||||
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.
|
||||
(define_predicate "symbol_ref_operand"
|
||||
(and (match_code "symbol_ref")
|
||||
|
@ -287,7 +287,7 @@
|
||||
;; Whether this insn has a prefixed form and a non-prefixed form.
|
||||
(define_attr "maybe_prefixed" "no,yes"
|
||||
(if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
|
||||
integer,add")
|
||||
integer,add,fused_load_cmpi")
|
||||
(const_string "yes")
|
||||
(const_string "no")))
|
||||
|
||||
@ -302,7 +302,7 @@
|
||||
(eq_attr "maybe_prefixed" "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)")
|
||||
(const_string "yes")
|
||||
(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
|
||||
a larl/load-relative instruction. We only handle the cases
|
||||
that can go wrong (i.e. no FUNC_DECLs). */
|
||||
if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
|
||||
that can go wrong (i.e. no FUNC_DECLs).
|
||||
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));
|
||||
else if (DECL_ALIGN (decl) % 32)
|
||||
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
|
||||
|
@ -9269,7 +9269,7 @@
|
||||
(match_operand:SF 3 "arith_reg_operand" "0")))
|
||||
(clobber (reg:SI FPSCR_STAT_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"
|
||||
"&& can_create_pseudo_p ()"
|
||||
[(parallel [(set (match_dup 0)
|
||||
|
22
gcc/configure
vendored
22
gcc/configure
vendored
@ -635,6 +635,7 @@ CET_HOST_FLAGS
|
||||
LD_PICFLAG
|
||||
PICFLAG
|
||||
enable_default_pie
|
||||
enable_host_bind_now
|
||||
enable_host_pie
|
||||
enable_host_shared
|
||||
enable_plugin
|
||||
@ -1031,6 +1032,7 @@ enable_version_specific_runtime_libs
|
||||
enable_plugin
|
||||
enable_host_shared
|
||||
enable_host_pie
|
||||
enable_host_bind_now
|
||||
enable_libquadmath_support
|
||||
with_linker_hash_style
|
||||
with_diagnostics_color
|
||||
@ -1794,6 +1796,7 @@ Optional Features:
|
||||
--enable-plugin enable plugin support
|
||||
--enable-host-shared build host code as shared libraries
|
||||
--enable-host-pie build host code as PIE
|
||||
--enable-host-bind-now link host code as BIND_NOW
|
||||
--disable-libquadmath-support
|
||||
disable libquadmath support for Fortran
|
||||
--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_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 19850 "configure"
|
||||
#line 19853 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -19953,7 +19956,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 19956 "configure"
|
||||
#line 19959 "configure"
|
||||
#include "confdefs.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.
|
||||
if test "${enable_libquadmath_support+set}" = set; then :
|
||||
enableval=$enable_libquadmath_support; ENABLE_LIBQUADMATH_SUPPORT=$enableval
|
||||
@ -32286,6 +32297,8 @@ else
|
||||
PICFLAG=
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test x$enable_host_pie = xyes; then
|
||||
LD_PICFLAG=-pie
|
||||
elif test x$gcc_cv_no_pie = xyes; then
|
||||
@ -32294,6 +32307,9 @@ else
|
||||
LD_PICFLAG=
|
||||
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 ;;
|
||||
"gccdepdir":C)
|
||||
${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
|
||||
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
|
||||
done ;;
|
||||
|
@ -1382,7 +1382,7 @@ AC_CHECK_HEADERS(ext/hash_map)
|
||||
ZW_CREATE_DEPDIR
|
||||
AC_CONFIG_COMMANDS([gccdepdir],[
|
||||
${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
|
||||
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$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])])
|
||||
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,
|
||||
[AS_HELP_STRING([--disable-libquadmath-support],
|
||||
[disable libquadmath support for Fortran])],
|
||||
@ -7566,6 +7572,8 @@ else
|
||||
PICFLAG=
|
||||
fi
|
||||
|
||||
AC_SUBST([PICFLAG])
|
||||
|
||||
if test x$enable_host_pie = xyes; then
|
||||
LD_PICFLAG=-pie
|
||||
elif test x$gcc_cv_no_pie = xyes; then
|
||||
@ -7574,7 +7582,10 @@ else
|
||||
LD_PICFLAG=
|
||||
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])
|
||||
|
||||
# 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>
|
||||
|
||||
* 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_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_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. */
|
||||
|
||||
#include "config.h"
|
||||
#define INCLUDE_MEMORY
|
||||
#include "system.h"
|
||||
#include "coretypes.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-pragma.h"
|
||||
#include "c-family/c-ubsan.h"
|
||||
#include "cp/cp-name-hint.h"
|
||||
#include "debug.h"
|
||||
#include "plugin.h"
|
||||
#include "builtins.h"
|
||||
@ -5995,7 +5997,11 @@ start_decl_1 (tree decl, bool initialized)
|
||||
; /* An auto type is ok. */
|
||||
else if (TREE_CODE (type) != ARRAY_TYPE)
|
||||
{
|
||||
auto_diagnostic_group d;
|
||||
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;
|
||||
}
|
||||
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));
|
||||
else
|
||||
{
|
||||
auto_diagnostic_group d;
|
||||
error ("aggregate %q#D has incomplete type and cannot be defined",
|
||||
decl);
|
||||
maybe_suggest_missing_header (input_location,
|
||||
TYPE_IDENTIFIER (type),
|
||||
CP_TYPE_CONTEXT (type));
|
||||
/* Change the type so that assemble_variable will give
|
||||
DECL an rtl we can live with: (mem (const_int 0)). */
|
||||
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
|
||||
applicable. */
|
||||
|
||||
static name_hint
|
||||
name_hint
|
||||
maybe_suggest_missing_header (location_t location, tree name, tree scope)
|
||||
{
|
||||
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>
|
||||
|
||||
* 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 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. */
|
||||
|
||||
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
|
||||
violates @safe code, so enforce that it is never invalid. */
|
||||
if (CONSTANT_CLASS_P (expr))
|
||||
result = d_truthvalue_conversion (expr);
|
||||
else
|
||||
for (tree ref = expr; TREE_CODE (ref) == COMPONENT_REF;
|
||||
ref = TREE_OPERAND (ref, 0))
|
||||
{
|
||||
/* Reinterpret the boolean as an integer and test the first bit.
|
||||
The generated code should end up being equivalent to:
|
||||
/* If the expression is a field that's part of a union, reinterpret
|
||||
the boolean as an integer and test the first bit. The generated
|
||||
code should end up being equivalent to:
|
||||
*cast(ubyte *)&expr & 1; */
|
||||
machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
|
||||
tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
|
||||
result = fold_build2 (BIT_AND_EXPR, mtype,
|
||||
build_vconvert (mtype, expr),
|
||||
build_one_cst (mtype));
|
||||
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
|
||||
{
|
||||
machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
|
||||
tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -844,7 +851,7 @@ convert_for_condition (tree expr, Type *type)
|
||||
break;
|
||||
|
||||
default:
|
||||
result = expr;
|
||||
result = convert_for_rvalue (expr, type, type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
5f7552bb2829b75d5e36cc767a476e1ab35147b7
|
||||
a45f4e9f43e9fdbf0b666175e5e66b1ce4f561f6
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
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)
|
||||
|
||||
Visibility visibility;
|
||||
bool noDefaultCtor; // no default construction
|
||||
bool disableNew; // disallow allocations using `new`
|
||||
d_bool noDefaultCtor; // no default construction
|
||||
d_bool disableNew; // disallow allocations using `new`
|
||||
Sizeok sizeok; // set when structsize contains valid data
|
||||
|
||||
virtual Scope *newScope(Scope *sc);
|
||||
@ -269,10 +269,10 @@ public:
|
||||
// their own vtbl[]
|
||||
|
||||
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||
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 com; // true if this is a COM class (meaning it derives from IUnknown)
|
||||
d_bool stack; // true if this is a scope class
|
||||
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
|
||||
Baseok baseok; // set the progress of base classes resolving
|
||||
|
@ -132,7 +132,7 @@ public:
|
||||
class AnonDeclaration final : public AttribDeclaration
|
||||
{
|
||||
public:
|
||||
bool isunion;
|
||||
d_bool isunion;
|
||||
int sem; // 1 if successful semantic()
|
||||
unsigned anonoffset; // offset of anonymous struct
|
||||
unsigned anonstructsize; // size of anonymous struct
|
||||
@ -175,8 +175,8 @@ class StaticIfDeclaration final : public ConditionalDeclaration
|
||||
{
|
||||
public:
|
||||
ScopeDsymbol *scopesym;
|
||||
bool addisdone;
|
||||
bool onStack;
|
||||
d_bool addisdone;
|
||||
d_bool onStack;
|
||||
|
||||
StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
Dsymbols *include(Scope *sc) override;
|
||||
@ -193,8 +193,8 @@ class StaticForeachDeclaration final : public AttribDeclaration
|
||||
public:
|
||||
StaticForeach *sfe;
|
||||
ScopeDsymbol *scopesym;
|
||||
bool onStack;
|
||||
bool cached;
|
||||
d_bool onStack;
|
||||
d_bool cached;
|
||||
Dsymbols *cache;
|
||||
|
||||
StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
@ -227,7 +227,7 @@ public:
|
||||
Expressions *exps;
|
||||
|
||||
ScopeDsymbol *scopesym;
|
||||
bool compiled;
|
||||
d_bool compiled;
|
||||
|
||||
CompileDeclaration *syntaxCopy(Dsymbol *s) override;
|
||||
void addMember(Scope *sc, ScopeDsymbol *sds) override;
|
||||
|
@ -21,11 +21,11 @@ struct OutBuffer
|
||||
private:
|
||||
DArray<unsigned char> data;
|
||||
d_size_t offset;
|
||||
bool notlinehead;
|
||||
d_bool notlinehead;
|
||||
void *fileMapping; // pointer to a file mapping object not used on the C++ side
|
||||
public:
|
||||
bool doindent;
|
||||
bool spaces;
|
||||
d_bool doindent;
|
||||
d_bool spaces;
|
||||
int level;
|
||||
|
||||
OutBuffer()
|
||||
|
@ -935,9 +935,6 @@ extern (C++) final class StaticIfCondition : Condition
|
||||
import dmd.staticcond;
|
||||
bool errors;
|
||||
|
||||
if (!exp)
|
||||
return errorReturn();
|
||||
|
||||
bool result = evalStaticCondition(sc, exp, exp, errors);
|
||||
|
||||
// Prevent repeated condition evaluation.
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
ForeachStatement *aggrfe;
|
||||
ForeachRangeStatement *rangefe;
|
||||
|
||||
bool needExpansion;
|
||||
d_bool needExpansion;
|
||||
|
||||
StaticForeach *syntaxCopy();
|
||||
};
|
||||
|
@ -213,6 +213,11 @@ private final class CppMangleVisitor : Visitor
|
||||
{
|
||||
auto tf = cast(TypeFunction)this.context.res.asFuncDecl().type;
|
||||
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)
|
||||
rt = rt.referenceTo();
|
||||
auto prev = this.context.push(tf.nextOf());
|
||||
@ -560,7 +565,11 @@ private final class CppMangleVisitor : Visitor
|
||||
foreach (j; i .. (*ti.tiargs).length)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user