Merge from trunk revision 3a39a31b8a.

This commit is contained in:
Ian Lance Taylor 2023-06-26 09:57:21 -07:00
commit aa1e672b5d
356 changed files with 18027 additions and 1464 deletions

View File

@ -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

View File

@ -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>

View File

@ -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@';

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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):

View 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} */')

View 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};")

View 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};")

View File

@ -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

View File

@ -1 +1 @@
20230621
20230626

View File

@ -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.

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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 &reg, 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 &reg,
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 */

View File

@ -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);

View File

@ -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.

View File

@ -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;
}

View File

@ -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 ();

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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. */

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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)
{

View File

@ -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

View File

@ -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. */

View File

@ -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%>",

View File

@ -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 */

View File

@ -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;

View File

@ -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". */

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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. */

View File

@ -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:;
}

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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")))

View File

@ -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))

View File

@ -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")

View File

@ -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))

View File

@ -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. */

View File

@ -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;

View File

@ -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)

View File

@ -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")

View File

@ -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

View File

@ -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:

View File

@ -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")))

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;
}
};

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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; }

View File

@ -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,

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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"))

View File

@ -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));

View File

@ -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
View File

@ -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 ;;

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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.

View File

@ -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;
}

View File

@ -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.

View File

@ -1 +1 @@
v2.103.0-rc.1
v2.103.1

View File

@ -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

View File

@ -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;

View File

@ -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()

View File

@ -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.

View File

@ -52,7 +52,7 @@ public:
ForeachStatement *aggrfe;
ForeachRangeStatement *rangefe;
bool needExpansion;
d_bool needExpansion;
StaticForeach *syntaxCopy();
};

View File

@ -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