[PATCH v2 #1/2] enable adjustment of return_pc debug attrs

2023-03-22 Thread oliva--- via Gcc-patches


This patch introduces infrastructure for targets to add an offset to
the label issued after the call_insn to set the call_return_pc
attribute.  This will be used on rs6000, that sometimes issues another
instruction after the call proper as part of a call insn.

Regstrapped on x86_64-linux-gnu and ppc64-linux-gnu.  Ok to install?


for  gcc/ChangeLog

* target.def (call_offset_return_label): New hook.
* gcc/doc/tm.texi.in (TARGET_CALL_OFFSET_RETURN_LABEL): Add
placeholder.
* gcc/doc/tm.texi: Rebuild.
* dwarf2out.cc (struct call_arg_loc_node): Record call_insn
instad of call_arg_loc_note.
(add_AT_lbl_id): Add optional offset argument.
(gen_call_site_die): Compute and pass on a return pc offset.
(gen_subprogram_die): Move call_arg_loc_note computation...
(dwarf2out_var_location): ... from here.  Set call_insn.
---
 gcc/doc/tm.texi|7 +++
 gcc/doc/tm.texi.in |2 ++
 gcc/dwarf2out.cc   |   26 +-
 gcc/target.def |9 +
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c4a92a5ebee90..44e4c18ad5c0a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5426,6 +5426,13 @@ except the last are treated as named.
 You need not define this hook if it always returns @code{false}.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_CALL_OFFSET_RETURN_LABEL (rtx_insn 
*@var{call_insn})
+While generating call-site debug info for a CALL insn, or a SEQUENCE
+insn starting with a CALL, this target hook is invoked to compute the
+offset to be added to the debug label emitted after the call to obtain
+the return address that should be recorded as the return PC.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_CALL_ARGS (rtx, @var{tree})
 While generating RTL for a function call, this target hook is invoked once
 for each argument passed to the function, either a register returned by
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 4075e71624c04..68856978fe364 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3785,6 +3785,8 @@ These machine description macros help implement varargs:
 
 @hook TARGET_STRICT_ARGUMENT_NAMING
 
+@hook TARGET_CALL_OFFSET_RETURN_LABEL
+
 @hook TARGET_CALL_ARGS
 
 @hook TARGET_END_CALL_ARGS
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 1711ad2c2da31..d1db918c43900 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -3584,7 +3584,7 @@ typedef struct var_loc_list_def var_loc_list;
 
 /* Call argument location list.  */
 struct GTY ((chain_next ("%h.next"))) call_arg_loc_node {
-  rtx GTY (()) call_arg_loc_note;
+  rtx_insn * GTY (()) call_insn;
   const char * GTY (()) label;
   tree GTY (()) block;
   bool tail_call_p;
@@ -3768,7 +3768,8 @@ static void remove_addr_table_entry (addr_table_entry *);
 static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool);
 static inline rtx AT_addr (dw_attr_node *);
 static void add_AT_symview (dw_die_ref, enum dwarf_attribute, const char *);
-static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *,
+  int = 0);
 static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
 static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
 static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
@@ -5327,14 +5328,17 @@ add_AT_symview (dw_die_ref die, enum dwarf_attribute 
attr_kind,
 
 static inline void
 add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind,
-   const char *lbl_id)
+  const char *lbl_id, int offset)
 {
   dw_attr_node attr;
 
   attr.dw_attr = attr_kind;
   attr.dw_attr_val.val_class = dw_val_class_lbl_id;
   attr.dw_attr_val.val_entry = NULL;
-  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
+  if (!offset)
+attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
+  else
+attr.dw_attr_val.v.val_lbl_id = xasprintf ("%s%+i", lbl_id, offset);
   if (dwarf_split_debug_info)
 attr.dw_attr_val.val_entry
 = add_addr_table_entry (attr.dw_attr_val.v.val_lbl_id,
@@ -23405,7 +23409,9 @@ gen_call_site_die (tree decl, dw_die_ref subr_die,
   if (stmt_die == NULL)
 stmt_die = subr_die;
   die = new_die (dwarf_TAG (DW_TAG_call_site), stmt_die, NULL_TREE);
-  add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc), ca_loc->label);
+  add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc),
+ca_loc->label,
+targetm.calls.call_offset_return_label (ca_loc->call_insn));
   if (ca_loc->tail_call_p)
 add_AT_flag (die, dwarf_AT (DW_AT_call_tail_call), 1);
   if (ca_loc->symbol_ref)
@@ -24092,11 +24098,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
  dw_die_ref die = NULL;
  rtx tloc = NULL_RTX, tlocc = NULL_RTX;
+ rtx call_arg_loc_note
+ 

[PATCH] [libstdc++] [testsuite] xfail double-prec from_chars for x86_64 ldbl

2023-05-29 Thread Alexandre Oliva via Gcc-patches


When long double is wider than double, but from_chars is implemented
in terms of double, tests that involve the full precision of long
double are expected to fail.  Mark them as such on x86_64-*-vxworks*.

Tested on x86_64-vxworks7r2 with gcc-12.  Ok to install?


for  libstdc++-v3/ChangeLog

* testsuite/20_util/from_chars/4.cc: Skip long double test06
on x86_64-vxworks.
* testsuite/20_util/to_chars/long_double.cc: Xfail run on
x86_64-vxworks.
---
 libstdc++-v3/testsuite/20_util/from_chars/4.cc |2 +-
 .../testsuite/20_util/to_chars/long_double.cc  |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/20_util/from_chars/4.cc 
b/libstdc++-v3/testsuite/20_util/from_chars/4.cc
index c3594f9014bd3..63a32b511be4e 100644
--- a/libstdc++-v3/testsuite/20_util/from_chars/4.cc
+++ b/libstdc++-v3/testsuite/20_util/from_chars/4.cc
@@ -18,7 +18,7 @@
 //  is supported in C++14 as a GNU extension
 // { dg-do run { target c++14 } }
 // { dg-add-options ieee }
-// { dg-additional-options "-DSKIP_LONG_DOUBLE" { target aarch64-*-vxworks* } }
+// { dg-additional-options "-DSKIP_LONG_DOUBLE" { target aarch64-*-vxworks* 
x86_64-*-vxworks* } }
 
 #include 
 #include 
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc 
b/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
index 08363d9d04003..df02dff935f40 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
@@ -36,7 +36,7 @@
 
 // On systems that use double-precision from_chars for long double,
 // this is expected to fail.
-// { dg-xfail-run-if "from_chars limited to double-precision" { 
aarch64-*-vxworks* i*86-*-vxworks* } }
+// { dg-xfail-run-if "from_chars limited to double-precision" { 
aarch64-*-vxworks* i*86-*-vxworks* x86_64-*-vxworks* } }
 
 // { dg-require-effective-target ieee_floats }
 // { dg-require-effective-target size32plus }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] libstdc++: Correct NTTP and simd_mask ctor call

2023-06-02 Thread Alexandre Oliva via Gcc-patches
Hello, Matthias,

On May 26, 2023, Matthias Kretz via Libstdc++  wrote:

> OK for master and all backports (after 11.4 is done)?
> tested on powerpc64le-linux-gnu and x86_64-pc-linux-gnu

>   * testsuite/experimental/simd/pr109822_cast_functions.cc: New
>   test.

This testcase fails to compile on PowerPC targets without VSX: 64-bit
integer and floating-point types cannot be vectorized.

I wonder if the test is malformed (and should be amended to test for
available simd types), or whether a patch like this would be desirable
to make simd constructs more portable.  I'm not sure about the
requirements.


[libstdc++] [simd] [ppc] use nonvector intrinsic fallback types

From: Alexandre Oliva 

Compiling such tests as pr109822_cast_functions.cc on powerpc targets
that don't support VSX fails because some intrinsic types that are
expected to be vectorizable are not defined without VSX.

Introduce fallback non-vector types to enable the code to compile.


for  libstdc++-v3/ChangeLog

* include/experimental/bits/simd.h: Introduce fallback
non-vector intrinsic_type_impl specializations for PowerPC
without VSX.
---
 libstdc++-v3/include/experimental/bits/simd.h |   12 
 1 file changed, 12 insertions(+)

diff --git a/libstdc++-v3/include/experimental/bits/simd.h 
b/libstdc++-v3/include/experimental/bits/simd.h
index 834fe923065bd..2691823e869e8 100644
--- a/libstdc++-v3/include/experimental/bits/simd.h
+++ b/libstdc++-v3/include/experimental/bits/simd.h
@@ -2431,9 +2431,14 @@ template 
 #define _GLIBCXX_SIMD_PPC_INTRIN(_Tp)  
\
   template <>  
\
 struct __intrinsic_type_impl<_Tp> { using type = __vector _Tp; }
+#define _GLIBCXX_SIMD_PPC_INTRIN_NOVEC(_Tp)   \
+  template <>  
\
+struct __intrinsic_type_impl<_Tp> { using type = _Tp; }
 _GLIBCXX_SIMD_PPC_INTRIN(float);
 #ifdef __VSX__
 _GLIBCXX_SIMD_PPC_INTRIN(double);
+#else
+_GLIBCXX_SIMD_PPC_INTRIN_NOVEC(double);
 #endif
 _GLIBCXX_SIMD_PPC_INTRIN(signed char);
 _GLIBCXX_SIMD_PPC_INTRIN(unsigned char);
@@ -2444,12 +2449,19 @@ _GLIBCXX_SIMD_PPC_INTRIN(unsigned int);
 #if defined __VSX__ || __SIZEOF_LONG__ == 4
 _GLIBCXX_SIMD_PPC_INTRIN(signed long);
 _GLIBCXX_SIMD_PPC_INTRIN(unsigned long);
+#else
+_GLIBCXX_SIMD_PPC_INTRIN_NOVEC(signed long);
+_GLIBCXX_SIMD_PPC_INTRIN_NOVEC(unsigned long);
 #endif
 #ifdef __VSX__
 _GLIBCXX_SIMD_PPC_INTRIN(signed long long);
 _GLIBCXX_SIMD_PPC_INTRIN(unsigned long long);
+#else
+_GLIBCXX_SIMD_PPC_INTRIN_NOVEC(signed long long);
+_GLIBCXX_SIMD_PPC_INTRIN_NOVEC(unsigned long long);
 #endif
 #undef _GLIBCXX_SIMD_PPC_INTRIN
+#undef _GLIBCXX_SIMD_PPC_INTRIN_NOVEC
 
 template 
   struct __intrinsic_type<_Tp, _Bytes, enable_if_t<__is_vectorizable_v<_Tp> && 
_Bytes <= 16>>


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] libstdc++: Correct NTTP and simd_mask ctor call

2023-06-02 Thread Alexandre Oliva via Gcc-patches
On Jun  2, 2023, Matthias Kretz  wrote:

> I'm looking at that function again, also in light of recent improvements wrt. 
> code-gen, and will remove that assumption, that long long is vectorizable.

Thanks, I'll leave that to you, then.


I also noticed the same test is failing on rtems6 (at least with gcc
11).  AFAICT the problem is that _GLIBCXX_SIMD_MATH_CALL* macros in
simd_math.h expect the named functions to be in std::, but I get such
errors as:

.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1299: 
error: 'remainder' is not a member of 'std'
.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1299: note: 
suggested alternatives:
[...]
.../aarch64-rtems6/include/math.h:346: note:   'remainder'
[...]
.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1299: note: 
  'std::experimental::parallelism_v2::remainder'
.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1299: 
error: template argument 1 is invalid
[...]
.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1328: 
error: 'fmin' is not a member of 'std'; did you mean 'min'?
.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1328: 
error: 'fmin' is not a member of 'std'; did you mean 'min'?
.../aarch64-rtems6/include/c++/11.4.1/experimental/bits/simd_math.h:1328: 
error: template argument 1 is invalid

ISTM that rtems is missing some of the math.h functions expected by
libstdc++, but also that even those that are present are not visible in
namespace ::std::, where the macros reasonably expect to find them.  Is
this known?  Should I file a PR about it?

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [RFC] Introduce -finline-memset-loops

2023-06-02 Thread Alexandre Oliva via Gcc-patches
On Jan 19, 2023, Alexandre Oliva  wrote:

> Would it make more sense to extend it, even constrained by the
> limitations mentioned above, or handle memset only?  In the latter case,
> would it still make sense to adopt a command-line option that suggests a
> broader effect than it already has, even if it's only a hopeful future
> extension?  -finline-all-stringops[={memset,memcpy,...}], that you
> suggested, seems to be a reasonable and extensible one to adopt.

I ended up implementing all of memset, memcpy, memmove, and memcmp:

Introduce -finline-stringops

try_store_by_multiple_pieces was added not long ago, enabling
variable-sized memset to be expanded inline when the worst-case
in-range constant length would, using conditional blocks with powers
of two to cover all possibilities of length and alignment.

This patch introduces -finline-stringops[=fn] to request expansions to
start with a loop, so as to still take advantage of known alignment
even with long lengths, but without necessarily adding store blocks
for every power of two.

This makes it possible for the supported stringops (memset, memcpy,
memmove, memset) to be expanded, even if storing a single byte per
iteration.  Surely efficient implementations can run faster, with a
pre-loop to increase alignment, but that would likely be excessive for
inline expansions.

Still, in some cases, such as in freestanding environments, users
prefer to inline such stringops, especially those that the compiler
may introduce itself, even if the expansion is not as performant as a
highly optimized C library implementation could be, to avoid
depending on a C runtime library.

Regstrapped on x86_64-linux-gnu, also bootstrapped with
-finline-stringops enabled by default, and tested with arm, aarch, 32-
and 64-bit riscv with gcc-12.  Ok to install?


for  gcc/ChangeLog

* expr.cc (emit_block_move_hints): Take ctz of len.  Obey
-finline-stringops.  Use oriented or sized loop.
(emit_block_move): Take ctz of len, and pass it on.
(emit_block_move_via_sized_loop): New.
(emit_block_move_via_oriented_loop): New.
(emit_block_move_via_loop): Take incr.  Move an incr-sized
block per iteration.
(emit_block_cmp_via_cmpmem): Take ctz of len.  Obey
-finline-stringops.
(emit_block_cmp_via_loop): New.
* expr.h (emit_block_move): Add ctz of len defaulting to zero.
(emit_block_move_hints): Likewise.
(emit_block_cmp_hints): Likewise.
* builtins.cc (expand_builtin_memory_copy_args): Pass ctz of
len to emit_block_move_hints.
(try_store_by_multiple_pieces): Support starting with a loop.
(expand_builtin_memcmp): Pass ctz of len to
emit_block_cmp_hints.
(expand_builtin): Allow inline expansion of memset, memcpy,
memmove and memcmp if requested.
* common.opt (finline-stringops): New.
(ilsop_fn): New enum.
* flag-types.h (enum ilsop_fn): New.
* doc/invoke.texi (-finline-stringops): Add.

for  gcc/testsuite/ChangeLog

* gcc.dg/torture/inline-mem-cmp-1.c: New.
* gcc.dg/torture/inline-mem-cpy-1.c: New.
* gcc.dg/torture/inline-mem-cpy-cmp-1.c: New.
* gcc.dg/torture/inline-mem-move-1.c: New.
* gcc.dg/torture/inline-mem-set-1.c: New.
---
 gcc/builtins.cc|  114 ++
 gcc/common.opt |   34 ++
 gcc/doc/invoke.texi|   15 +
 gcc/expr.cc|  374 +++-
 gcc/expr.h |9 
 gcc/flag-types.h   |   11 +
 gcc/testsuite/gcc.dg/torture/inline-mem-cmp-1.c|7 
 gcc/testsuite/gcc.dg/torture/inline-mem-cpy-1.c|8 
 .../gcc.dg/torture/inline-mem-cpy-cmp-1.c  |   11 +
 gcc/testsuite/gcc.dg/torture/inline-mem-move-1.c   |9 
 gcc/testsuite/gcc.dg/torture/inline-mem-set-1.c|   84 
 11 files changed, 646 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/inline-mem-cmp-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/inline-mem-cpy-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/inline-mem-cpy-cmp-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/inline-mem-move-1.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/inline-mem-set-1.c

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 8400adaf5b4db..1beaa4eae97a5 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -3769,7 +3769,7 @@ expand_builtin_memory_copy_args (tree dest, tree src, 
tree len,
 expected_align, expected_size,
 min_size, max_size, probable_max_size,
 use_mempcpy_call, &is_move_done,
-might_overlap);
+might_overlap, tree_ctz (len));
 
   /* Bail 

[testsuite] bump some tsvc timeouts

2023-06-07 Thread Alexandre Oliva via Gcc-patches


Several tests are timing out when targeting x86-*-vxworks with qemu.

Bump their timeout factor.


for  gcc/testsuite/ChangeLog

* gcc.dg/vect/tsvc/vect-tsvc-s116.c: Bump timeout factor.
* gcc.dg/vect/tsvc/vect-tsvc-s241.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s254.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s271.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s2711.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s2712.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-s276.c: Likewise.
* gcc.dg/vect/tsvc/vect-tsvc-vdotr.c: Likewise.
---
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s116.c  |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s241.c  |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s254.c  |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s271.c  |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2711.c |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2712.c |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s276.c  |1 +
 gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-vdotr.c |3 ++-
 8 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s116.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s116.c
index 93d16b3f50d16..9702ec8f52302 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s116.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s116.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s241.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s241.c
index 14b4188e57b0e..95652d1415307 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s241.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s241.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 1.5 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s254.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s254.c
index 06e9b0a849dc4..92f00d8af6416 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s254.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s254.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s271.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s271.c
index 0c9b67d2fd707..03f806e74d6e6 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s271.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s271.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2711.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2711.c
index c1a5f35473874..4510fae890042 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2711.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2711.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2712.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2712.c
index 765d230b54c1d..92e9742874a50 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2712.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s2712.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s276.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s276.c
index 7389c61e127a2..7ca7166a46d1e 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s276.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s276.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-vdotr.c 
b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-vdotr.c
index 80ed9f81e506f..013d3f4473c5b 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-vdotr.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-vdotr.c
@@ -3,6 +3,7 @@
 
 /* { dg-additional-options "--param vect-epilogues-nomask=0" } */
 /* { dg-require-effective-target vect_float } */
+/* { dg-timeout-factor 2 } */
 
 #include "tsvc.h"
 
@@ -38,4 +39,4 @@ int main (int argc, char **argv)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
\ No newline at end of file
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */


-- 
Alexandre O

[PATCH] fix frange_nextafter odr violation

2023-06-08 Thread Alexandre Oliva via Gcc-patches


C++ requires inline functions to be declared inline and defined in
every translation unit that uses them.  frange_nextafter is used in
gimple-range-op.cc but it's only defined as inline in
range-op-float.cc.  Drop the extraneous inline specifier.

Other non-static inline functions in range-op-float.cc are not
referenced elsewhere, so I'm making them static.

Bootstrapping on x86_64-linux-gnu, along with other changes that exposed
the problem; it's already into stage3, and it wouldn't get past stage2
before.  Ok to install?


for  gcc/ChangeLog

* range-op-float.cc (frange_nextafter): Drop inline.
(frelop_early_resolve): Add static.
(frange_float): Likewise.
---
 gcc/range-op-float.cc |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index a99a6b01ed835..d6da2aa701ee3 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -255,7 +255,7 @@ maybe_isnan (const frange &op1, const frange &op2)
 // Floating version of relop_early_resolve that takes into account NAN
 // and -ffinite-math-only.
 
-inline bool
+static inline bool
 frelop_early_resolve (irange &r, tree type,
  const frange &op1, const frange &op2,
  relation_trio rel, relation_kind my_rel)
@@ -272,7 +272,7 @@ frelop_early_resolve (irange &r, tree type,
 
 // Set VALUE to its next real value, or INF if the operation overflows.
 
-inline void
+void
 frange_nextafter (enum machine_mode mode,
  REAL_VALUE_TYPE &value,
  const REAL_VALUE_TYPE &inf)
@@ -2878,7 +2878,7 @@ namespace selftest
 
 // Build an frange from string endpoints.
 
-inline frange
+static inline frange
 frange_float (const char *lb, const char *ub, tree type = float_type_node)
 {
   REAL_VALUE_TYPE min, max;


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] fix frange_nextafter odr violation

2023-06-09 Thread Alexandre Oliva via Gcc-patches
On Jun  9, 2023, Richard Biener  wrote:

> On Thu, Jun 8, 2023 at 4:38 PM Alexandre Oliva via Gcc-patches
>  wrote:

>> C++ requires inline functions to be declared inline and defined in
>> every translation unit that uses them.  frange_nextafter is used in
>> gimple-range-op.cc but it's only defined as inline in
>> range-op-float.cc.  Drop the extraneous inline specifier.

> OK

>> for  gcc/ChangeLog
>> 
>> * range-op-float.cc (frange_nextafter): Drop inline.
>> (frelop_early_resolve): Add static.
>> (frange_float): Likewise.

The problem is also present in gcc-13.  Ok there as well?  Regstrapped
on x86_64-linux-gnu.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about <https://stallmansupport.org>


libstdc++-v3: do not duplicate some math functions when using newlib

2023-06-14 Thread Alexandre Oliva via Gcc-patches


Contributing a patch by Joel Brobecker .
Regstrapped on x86_64-linux-gnu just to be sure, also tested with
aarch64-rtems6.  I'm going to put this in later this week if there
aren't any objections.


When running the libstdc++ testsuite on AArch64 RTEMS, we noticed
that about 25 tests are failing during the link, due to the "sqrtl"
function being defined twice:
  - once inside RTEMS' libm;
  - once inside our libstdc++.

One test that fails, for instance, would be 26_numerics/complex/13450.cc.

In comparing libm and libstdc++, we found that libstc++ also
duplicates "hypotf", and "hypotl".

For "sqrtl" and "hypotl", the symbosl come a unit called
from math_stubs_long_double.cc, while "hypotf" comes from
the equivalent unit for the float version, called math_stubs_float.cc.
Those units are always compiled in libstdc++ and provide our own
version of various math routines when those are missing from
the target system. The definition of those symbols is predicated
on the existance of various macros provided by c++config.h, which
themselves are predicated by the corresponding HAVE_xxx macros
in config.h.

One key element behind what's happening, here, is that the target
uses newlib, and therefore GCC was configured --with-newlib.
The section of libstdc++v3's configure script that handles which math
functions are available has a newlib-specific section, and that
section provides a hardcoded list of symbols.

For "hypotf", this commit fixes the issue by doing the same
as for the other routines already declared in that section.
I verified by inspection in the newlib code that this function
should always be present, so hardcoding it in our configure
script should not be an issue.

For the math routines handling doubles ("sqrtl" and "hypotl"),
however, I do not believe we can assume that newlib's libm
will always provide them. Therefore, this commit fixes that
part of the issue by ading a compile-check for "sqrtl" and "hypotl".
And while at it, we also include checks for all the other math
functions that math_stubs_long_double.cc re-implements, allowing
us to be resilient to future newlib enhancements adding support
for more functions.

libstdc++-v3/ChangeLog:

* configure.ac ["x${with_newlib}" = "xyes"]: Define
HAVE_HYPOTF.  Add compile-checks for various long double
math functions as well.
* configure: Regenerate.
---
 libstdc++-v3/configure| 1179 +
 libstdc++-v3/configure.ac |9 
 2 files changed, 1188 insertions(+)

diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 354c566b0055c..bda8053ecc279 100755
[omitted]
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 0abe54e7b9a21..9770c1787679f 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -349,6 +349,7 @@ else
 AC_DEFINE(HAVE_FLOORF)
 AC_DEFINE(HAVE_FMODF)
 AC_DEFINE(HAVE_FREXPF)
+AC_DEFINE(HAVE_HYPOTF)
 AC_DEFINE(HAVE_LDEXPF)
 AC_DEFINE(HAVE_LOG10F)
 AC_DEFINE(HAVE_LOGF)
@@ -360,6 +361,14 @@ else
 AC_DEFINE(HAVE_TANF)
 AC_DEFINE(HAVE_TANHF)
 
+dnl # Support for the long version of some math libraries depends on
+dnl # architecture and newlib version.  So test for their availability
+dnl # rather than hardcoding that information.
+GLIBCXX_CHECK_MATH_DECLS([
+  acosl asinl atan2l atanl ceill coshl cosl expl fabsl floorl fmodl
+  frexpl hypotl ldexpl log10l logl modfl powl sinhl sinl sqrtl
+  tanhl tanl])
+
 AC_DEFINE(HAVE_ICONV)
 AC_DEFINE(HAVE_MEMALIGN)
 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[libstdc++] [testsuite] xfail dbl from_chars for aarch64 rtems ldbl

2023-06-14 Thread Alexandre Oliva via Gcc-patches


rtems, like vxworks, uses fast-float doubles for from_chars even for
long double, so it loses precision, so expect the long double bits to
fail on aarch64.

Regstrapped on x86_64-linux-gnu, also tested on aarch64-rtems6.  Ok to
install?


for  libstdc++-v3/ChangeLog

* testsuite/20_util/from_chars/4.cc: Skip long double on
aarch64-rtems.
---
 libstdc++-v3/testsuite/20_util/from_chars/4.cc |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/20_util/from_chars/4.cc 
b/libstdc++-v3/testsuite/20_util/from_chars/4.cc
index 206e18daeb229..76e07df9d2bf3 100644
--- a/libstdc++-v3/testsuite/20_util/from_chars/4.cc
+++ b/libstdc++-v3/testsuite/20_util/from_chars/4.cc
@@ -18,7 +18,7 @@
 //  is supported in C++14 as a GNU extension
 // { dg-do run { target c++14 } }
 // { dg-add-options ieee }
-// { dg-additional-options "-DSKIP_LONG_DOUBLE" { target aarch64-*-vxworks* 
x86_64-*-vxworks* } }
+// { dg-additional-options "-DSKIP_LONG_DOUBLE" { target aarch64-*-rtems* 
aarch64-*-vxworks* x86_64-*-vxworks* } }
 
 #include 
 #include 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[libstdc++] [testsuite] expect zero entropy matching implementation

2023-06-14 Thread Alexandre Oliva via Gcc-patches


random_device::get_entropy() returns 0.0 when _GLIBCXX_USE_DEV_RANDOM
is not defined, but the test expects otherwise.  Adjust.

Regstrapped on x86_64-linux-gnu, also tested on aarch64-rtems6.  Ok to
install?


for  libstdc++-v3/ChangeLog

* testsuite/26_numerics/random/random_device/entropy.cc:
Expect get_entropy to return zero when _GLIBCXX_USE_DEV_RANDOM
is not defined.
---
 .../26_numerics/random/random_device/entropy.cc|8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc 
b/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc
index 9f529f5d81410..3e6872c8a613f 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/entropy.cc
@@ -13,7 +13,13 @@ test01()
   VERIFY( std::random_device(token).entropy() == 0.0 );
 
   using result_type = std::random_device::result_type;
+#ifdef _GLIBCXX_USE_DEV_RANDOM
   const double max = std::numeric_limits::digits;
+#else
+  // random_device::entropy() always returns 0.0 when
+  // _GLIBCXX_USE_DEV_RANDOM is not defined.
+  const double max = 0.0;
+#endif
 
   for (auto token : { "/dev/random", "/dev/urandom" })
 if (__gnu_test::random_device_available(token))
@@ -30,7 +36,7 @@ test01()
   VERIFY( entropy == max );
 }
 
-for (auto token : { "getentropy", "arc4random" })
+  for (auto token : { "getentropy", "arc4random" })
 if (__gnu_test::random_device_available(token))
 {
   const double entropy = std::random_device(token).entropy();

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2023-06-15 Thread Alexandre Oliva via Gcc-patches
On Aug  9, 2022, Alexandre Oliva  wrote:

> Ping?

Ping?  Refreshed, added setting of ENUM_UNDERLYING_TYPE, retested on
x86_64-linux-gnu (also on gcc-13).


Introduce hardbool attribute for C

This patch introduces hardened booleans in C.  The hardbool attribute,
when attached to an integral type, turns it into an enumerate type
with boolean semantics, using the named or implied constants as
representations for false and true.

Expressions of such types decay to _Bool, trapping if the value is
neither true nor false, and _Bool can convert implicitly back to them.
Other conversions go through _Bool first.


for  gcc/c-family/ChangeLog

* c-attribs.cc (c_common_attribute_table): Add hardbool.
(handle_hardbool_attribute): New.
(type_valid_for_vector_size): Reject hardbool.
* c-common.cc (convert_and_check): Skip warnings for convert
and check for hardbool.
(c_hardbool_type_attr_1): New.
* c-common.h (c_hardbool_type_attr): New.

for  gcc/c/ChangeLog

* c-typeck.cc (convert_lvalue_to_rvalue): Decay hardbools.
* c-convert.cc (convert): Convert to hardbool through
truthvalue.
* c-decl.cc (check_bitfield_type_and_width): Skip enumeral
truncation warnings for hardbool.
(finish_struct): Propagate hardbool attribute to bitfield
types.
(digest_init): Convert to hardbool.

for  gcc/ChangeLog

* doc/extend.texi (hardbool): New type attribute.

for  gcc/testsuite/ChangeLog

* gcc.dg/hardbool-err.c: New.
* gcc.dg/hardbool-trap.c: New.
* gcc.dg/hardbool.c: New.
* gcc.dg/hardbool-s.c: New.
* gcc.dg/hardbool-us.c: New.
* gcc.dg/hardbool-i.c: New.
* gcc.dg/hardbool-ul.c: New.
* gcc.dg/hardbool-ll.c: New.
* gcc.dg/hardbool-5a.c: New.
* gcc.dg/hardbool-s-5a.c: New.
* gcc.dg/hardbool-us-5a.c: New.
* gcc.dg/hardbool-i-5a.c: New.
* gcc.dg/hardbool-ul-5a.c: New.
* gcc.dg/hardbool-ll-5a.c: New.
---
 gcc/c-family/c-attribs.cc |   98 -
 gcc/c-family/c-common.cc  |   21 
 gcc/c-family/c-common.h   |   18 
 gcc/c/c-convert.cc|   14 +++
 gcc/c/c-decl.cc   |   10 ++
 gcc/c/c-typeck.cc |   31 ++-
 gcc/doc/extend.texi   |   52 +++
 gcc/testsuite/gcc.dg/hardbool-err.c   |   28 ++
 gcc/testsuite/gcc.dg/hardbool-trap.c  |   13 +++
 gcc/testsuite/gcc.dg/torture/hardbool-5a.c|6 +
 gcc/testsuite/gcc.dg/torture/hardbool-i-5a.c  |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-i.c |5 +
 gcc/testsuite/gcc.dg/torture/hardbool-ll-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-ll.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool-s-5a.c  |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-s.c |5 +
 gcc/testsuite/gcc.dg/torture/hardbool-ul-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-ul.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool-us-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-us.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool.c   |  118 +
 21 files changed, 460 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/hardbool-err.c
 create mode 100644 gcc/testsuite/gcc.dg/hardbool-trap.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-i-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-i.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ll-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ll.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-s-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-s.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ul-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ul.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-us-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-us.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index c12211cb4d499..365319e642b1a 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -176,6 +176,7 @@ static tree handle_objc_root_class_attribute (tree *, tree, 
tree, int, bool *);
 static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool 
*);
 static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int,
bool *);
+static tree handle_hardbool_attribute (tree *, tree, tree, int, bool *);
 static tree handle_retain_attribute (tree *, tree, tree, int, bool *);
 static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *);
 
@@ -293,6 +294,8 @@ const struct attribute_spec c_common

Re: [PATCH zero-call-used-regs] Add leafy mode for zero-call-used-regs

2023-06-16 Thread Alexandre Oliva via Gcc-patches
Hello, Qing,

On Oct 27, 2022, Qing Zhao  wrote:


> On Oct 26, 2022, at 5:29 PM, Alexandre Oliva  wrote:
>> I'm sure there are other scenarios in which keeping at least the
>> possibility of 'all' is useful.
> Okay.


> i.e, instead introducing a new MODE “LEAFY_MODE” and a new user
> sub-option, for LEAF functions, only
> Clear its’ used registers even for “ALL”.

> However, since there is need to clear the un-used registers for leaf
> functions. It looks like it is needed to provide
> This new sub-option to users.

> Is this clear this time?

Yeah, I guess I understand what you mean.  But since there are cases in
which clearing all (call-clobbered) registers in a leaf function is
useful, I suppose it makes sense to offer both possibilities.

If there was a default operation mode for -fzero-call-used-regs, I guess
it would make sense to consider leafy the default, rather than all, but
since there isn't, and it always has to be specified explicitly, that's
not something to be considered.

So the available choices are:

1. introduce 'leafy' as a separate mode, leaving 'all' alone

2. change the behavior of 'all' to that of the proposed 'leafy', and either

2.a) add another mode that retains the currently-useful behavior of 'all',
   or

2.b) make the current behavior of 'all' no longer available

Personally, I find 1. the least disruptive to existing users of
-fzero-call-used-regs.  If we were introducing the option now, maybe 2.a
would be more sensible, but at this point, changing the meaning of 'all'
seems to be a disservice to security-sensitive users.

Those who would prefer the leaner operation on leaf functions can then
switch to 'leafy' mode, but that's better than finding carefully-crafted
code relying on the current behavior of 'all' for security suddenly
changes from under them, isn't it?


That said, I'm willing to implement the alternate change, if changing
the expected behavior is preferred over offering a different choice, if
needed to get closure on this feature.

For now, I'm just pinging the refreshed and retested patch.
Ok to install?


Add leafy mode for zero-call-used-regs

Introduce 'leafy' to auto-select between 'used' and 'all' for leaf and
nonleaf functions, respectively.


for  gcc/ChangeLog

* doc/extend.texi (zero-call-used-regs): Document leafy and
variants thereof.
* flag-types.h (zero_regs_flags): Add LEAFY_MODE, as well as
LEAFY and variants.
* function.cc (gen_call_ued_regs_seq): Set only_used for leaf
functions in leafy mode.
* opts.cc (zero_call_used_regs_opts): Add leafy and variants.

for  gcc/testsuite/ChangeLog

* c-c++-common/zero-scratch-regs-leafy-1.c: New.
* c-c++-common/zero-scratch-regs-leafy-2.c: New.
* gcc.target/i386/zero-scratch-regs-leafy-1.c: New.
* gcc.target/i386/zero-scratch-regs-leafy-2.c: New.
---
 gcc/doc/extend.texi|   22 ++--
 gcc/flag-types.h   |5 +
 gcc/function.cc|3 +++
 gcc/opts.cc|4 
 .../c-c++-common/zero-scratch-regs-leafy-1.c   |   15 ++
 .../c-c++-common/zero-scratch-regs-leafy-2.c   |   21 +++
 .../gcc.target/i386/zero-scratch-regs-leafy-1.c|   12 +++
 .../gcc.target/i386/zero-scratch-regs-leafy-2.c|   16 +++
 8 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c
 create mode 100644 gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b5592502734e..f8b0bb53ef5d4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4412,10 +4412,28 @@ zeros all call-used registers that pass arguments.
 @item all-gpr-arg
 zeros all call-used general purpose registers that pass
 arguments.
+
+@item leafy
+Same as @samp{used} in a leaf function, and same as @samp{all} in a
+nonleaf function.
+
+@item leafy-gpr
+Same as @samp{used-gpr} in a leaf function, and same as @samp{all-gpr}
+in a nonleaf function.
+
+@item leafy-arg
+Same as @samp{used-arg} in a leaf function, and same as @samp{all-arg}
+in a nonleaf function.
+
+@item leafy-gpr-arg
+Same as @samp{used-gpr-arg} in a leaf function, and same as
+@samp{all-gpr-arg} in a nonleaf function.
+
 @end table
 
-Of this list, @samp{used-arg}, @samp{used-gpr-arg}, @samp{all-arg},
-and @samp{all-gpr-arg} are mainly used for ROP mitigation.
+Of this list, @samp{used-arg}, @samp{used-gpr-arg}, @samp{leafy-arg},
+@samp{leafy-gpr-arg}, @samp{all-arg}, and @samp{all-gpr-arg} are mainly
+used for ROP mitigation.
 
 The default for the at

[PATCH v3] Introduce attribute reverse_alias

2023-07-14 Thread Alexandre Oliva via Gcc-patches


This patch introduces an attribute to add extra aliases to a symbol
when its definition is output.  The main goal is to ease interfacing
C++ with Ada, as C++ mangled names have to be named, and in some cases
(e.g. when using stdint.h typedefs in function arguments) the symbol
names may vary across platforms.

The attribute is usable in C and C++, presumably in all C-family
languages.  It can be attached to global variables and functions.  In
C++, it can also be attached to namespace-scoped variables and
functions, static data members, member functions, explicit
instantiations and specializations of template functions, members and
classes.

When applied to constructors or destructor, additional reverse_aliases
with _Base and _Del suffixes are defined for variants other than
complete-object ones.  This changes the assumption that clones always
carry the same attributes as their abstract declarations, so there is
now a function to adjust them.

C++ also had a bug in which attributes from local extern declarations
failed to be propagated to a preexisting corresponding
namespace-scoped decl.  I've fixed that, and adjusted acc tests that
distinguished between C and C++ in this regard.

Applying the attribute to class types is only valid in C++, and the
effect is to attach the alias to the RTTI object associated with the
class type.

Regstrapped on x86_64-linux-gnu.  Ok to install?

This is refreshed and renamed from earlier versions that named the
attribute 'exalias', and that AFAICT got stuck in name bikeshedding.
https://gcc.gnu.org/pipermail/gcc-patches/2020-August/551614.html


for  gcc/ChangeLog

* attribs.cc: Include cgraph.h.
(decl_attributes): Allow late introduction of reverse_alias in
types.
(create_reverse_alias_decl, create_reverse_alias_decls): New.
* attribs.h: Declare them.
(FOR_EACH_REVERSE_ALIAS): New macro.
* cgraph.cc (cgraph_node::create): Create reverse_alias decls.
* varpool.cc (varpool_node::get_create): Create reverse_alias
decls.
* cgraph.h (symtab_node::remap_reverse_alias_target): New.
* symtab.cc (symtab_node::remap_reverse_alias_target):
Define.
* cgraphunit.cc (cgraph_node::analyze): Create alias_target
node if needed.
(analyze_functions): Fixup visibility of implicit alias only
after its node is analyzed.
* doc/extend.texi (reverse_alias): Document for variables,
functions and types.

for  gcc/ada/ChangeLog

* doc/gnat_rm/interfacing_to_other_languages.rst: Mention
attribute reverse_alias to give RTTI symbols mnemonic names.
* doc/gnat_ugn/the_gnat_compilation_model.rst: Mention
attribute reverse_alias.  Fix incorrect ref to C1 ctor variant.

for  gcc/c-family/ChangeLog

* c-ada-spec.cc (pp_asm_name): Use first reverse_alias if
available.
* c-attribs.cc (handle_reverse_alias_attribute): New.
(c_common_attribute_table): Add reverse_alias.
(handle_copy_attribute): Do not copy reverse_alias.

for  gcc/c/ChangeLog

* c-decl.cc (duplicate_decls): Remap reverse_alias target.

for  gcc/cp/ChangeLog

* class.cc (adjust_clone_attributes): New.
(copy_fndecl_with_name, build_clone): Call it.
* cp-tree.h (adjust_clone_attributes): Declare.
(update_reverse_alias_interface): Declare.
(update_tinfo_reverse_alias): Declare.
* decl.cc (duplicate_decls): Remap reverse_alias target.
Adjust clone attributes.
(grokfndecl): Tentatively create reverse_alias decls after
adding attributes in e.g. a template member function explicit
instantiation.
* decl2.cc (cplus_decl_attributes): Update tinfo
reverse_alias.
(copy_interface, update_reverse_alias_interface): New.
(determine_visibility): Update reverse_alias interface.
(tentative_decl_linkage, import_export_decl): Likewise.
* name-lookup.cc: Include target.h and cgraph.h.
(push_local_extern_decl_alias): Merge attributes with
namespace-scoped decl, and drop duplicate reverse_alias.
* optimize.cc (maybe_clone_body): Re-adjust attributes after
cloning them.  Update reverse_alias interface.
* rtti.cc: Include attribs.h and cgraph.h.
(get_tinfo_decl): Copy reverse_alias attributes from type to
tinfo decl.  Create reverse_alias decls.
(update_tinfo_reverse_alias): New.

for  gcc/testsuite/ChangeLog

* c-c++-common/goacc/declare-1.c: Adjust.
* c-c++-common/goacc/declare-2.c: Adjust.
* c-c++-common/torture/attr-revalias-1.c: New.
* c-c++-common/torture/attr-revalias-2.c: New.
* c-c++-common/torture/attr-revalias-3.c: New.
* c-c++-common/torture/attr-revalias-4.c: New.
* g++.dg/torture/attr-revalias-1.C: New.
* g++.dg/torture/attr-revalias-2.C: New.
* g++.dg/torture/attr-revalias-3.C: 

Re: [PATCH v3] Introduce attribute reverse_alias

2023-07-17 Thread Alexandre Oliva via Gcc-patches
Hello, Nathan,

On Jul 15, 2023, Nathan Sidwell  wrote:

> Not commenting on the semantics, but the name seems unfortunate (hello
> bikeshed).

Yeah, it's a bit challenging to express the concept, when the notion of
"alias" is kind of symmetric between decl and target, but the
previously-implemented extension attaches it to decl rather than to
target.  I tried "extra alias" before, but that didn't fly either.

Maybe I should give up and just recommend the use of asm ("name")
instead of allowing alternative names (AKA aliases, in the dictionary
sense; oh, the irony) to be introduced for a decl?  Maybe that would be
simpler and enough to sidestep the problem of varying mangled names when
trying to import into Ada (or defining C++ aliases for) C++ symbols that
use standard types in signatures that are not fundamental types, such as
size_t.  That they mangle differently depending on what size_t is
typedef'ed to makes for some undesirable inconvenience, which this
attribute attempts to alleviate.

> The documentation starts with 'attribute causes @var{name}
> to be emitted as an alias to the definition'.  So not emitting a
> 'reverse alias', whatever that might be.

It's reverse in that it doesn't alias another declaration, as in the
preexisting meaning of the alias attribute, it adds an alias for the
present declaration.

> It doesn;t seem to mention how reverse alias differs from 'alias'.
> Why would 'alias' not DTRT?

contrast:

int foo();
int __attribute__ ((alias ("foo"))) bar();

static_assert (&foo == &bar); // ok

with:

int __attribute__ ((reverse_alias ("bar"))) foo();

static_assert (&foo == &bar); // error, bar is not a C++ symbol

int __attribute__ ((alias ("bar"))) baz(); // ok

static_assert (&foo == &baz); // ok

asm (".quad bar"); // ok, even in other TUs
asm (".quad foo"); // not necessarily ok, foo's symbol may be mangled
asm (".quad baz"); // not necessarily ok, baz's symbol may be mangled

> Is is emitting a an additiona symbol -- ie, something like 'altname'.

Yup.  Is there precedent for this attribute name elsewhere?  I think it
could work.

> Is that symbol known in the current TU, or other TUs?

Only in the assembly/linker name space, not in any C++ namespace.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH v4] Introduce attribute sym

2023-07-19 Thread Alexandre Oliva via Gcc-patches
On Jul 18, 2023, Richard Biener  wrote:

> I think the __symver__ attribute does something similar already so
> maybe use __attribute__((__sym__("foo")))?

Cool, thanks, that will do.  Regstrapped on x86_64-linux-gnu.  Ok to
install?


This patch introduces an attribute to add extra asm names (aliases)
for a decl when its definition is output.  The main goal is to ease
interfacing C++ with Ada, as C++ mangled names have to be named, and
in some cases (e.g. when using stdint.h typedefs in function
arguments) the symbol names may vary across platforms.

The attribute is usable in C and C++, presumably in all C-family
languages.  It can be attached to global variables and functions.  In
C++, it can also be attached to class types, namespace-scoped
variables and functions, static data members, member functions,
explicit instantiations and specializations of template functions,
members and classes.

When applied to constructors or destructor, additional sym aliases
with _Base and _Del suffixes are defined for variants other than
complete-object ones.  This changes the assumption that clones always
carry the same attributes as their abstract declarations, so there is
now a function to adjust them.

C++ also had a bug in which attributes from local extern declarations
failed to be propagated to a preexisting corresponding
namespace-scoped decl.  I've fixed that, and adjusted acc tests that
distinguished between C and C++ in this regard.

Applying the attribute to class types is only valid in C++, and the
effect is to attach the alias to the RTTI object associated with the
class type.

for  gcc/ChangeLog

* attribs.cc: Include cgraph.h.
(decl_attributes): Allow late introduction of sym alias in
types.
(create_sym_alias_decl, create_sym_alias_decls): New.
* attribs.h: Declare them.
(FOR_EACH_SYM_ALIAS): New macro.
* cgraph.cc (cgraph_node::create): Create sym alias decls.
* varpool.cc (varpool_node::get_create): Create sym alias
decls.
* cgraph.h (symtab_node::remap_sym_alias_target): New.
* symtab.cc (symtab_node::remap_sym_alias_target): Define.
* cgraphunit.cc (cgraph_node::analyze): Create alias_target
node if needed.
(analyze_functions): Fixup visibility of implicit alias only
after its node is analyzed.
* doc/extend.texi (sym): Document for variables, functions and
types.

for  gcc/ada/ChangeLog

* doc/gnat_rm/interfacing_to_other_languages.rst: Mention
attribute sym to give RTTI symbols mnemonic names.
* doc/gnat_ugn/the_gnat_compilation_model.rst: Mention
aliases.  Fix incorrect ref to C1 ctor variant.

for  gcc/c-family/ChangeLog

* c-ada-spec.cc (pp_asm_name): Use first sym alias if
available.
* c-attribs.cc (handle_sym_attribute): New.
(c_common_attribute_table): Add sym.
(handle_copy_attribute): Do not copy sym attribute.

for  gcc/c/ChangeLog

* c-decl.cc (duplicate_decls): Remap sym alias target.

for  gcc/cp/ChangeLog

* class.cc (adjust_clone_attributes): New.
(copy_fndecl_with_name, build_clone): Call it.
* cp-tree.h (adjust_clone_attributes): Declare.
(update_sym_alias_interface): Declare.
(update_tinfo_sym_alias): Declare.
* decl.cc (duplicate_decls): Remap sym_alias target.
Adjust clone attributes.
(grokfndecl): Tentatively create sym alias decls after
adding attributes in e.g. a template member function explicit
instantiation.
* decl2.cc (cplus_decl_attributes): Update tinfo sym alias.
(copy_interface, update_sym_alias_interface): New.
(determine_visibility): Update sym alias interface.
(tentative_decl_linkage, import_export_decl): Likewise.
* name-lookup.cc: Include target.h and cgraph.h.
(push_local_extern_decl_alias): Merge attributes with
namespace-scoped decl, and drop duplicate sym alias.
* optimize.cc (maybe_clone_body): Re-adjust attributes after
cloning them.  Update sym alias interface.
* rtti.cc: Include attribs.h and cgraph.h.
(get_tinfo_decl): Copy sym attributes from type to tinfo decl.
Create sym alias decls.
(update_tinfo_sym_alias): New.

for  gcc/testsuite/ChangeLog

* c-c++-common/goacc/declare-1.c: Adjust.
* c-c++-common/goacc/declare-2.c: Adjust.
* c-c++-common/torture/attr-sym-1.c: New.
* c-c++-common/torture/attr-sym-2.c: New.
* c-c++-common/torture/attr-sym-3.c: New.
* c-c++-common/torture/attr-sym-4.c: New.
* g++.dg/torture/attr-sym-1.C: New.
* g++.dg/torture/attr-sym-2.C: New.
* g++.dg/torture/attr-sym-3.C: New.
* g++.dg/torture/attr-sym-4.C: New.
* g++.dg/torture/attr-sym-5.C: New.
---
 .../doc/gnat_rm/interfacing_to_other_languages.rst |6 +
 .../doc/gnat_ugn/the_gnat_compilation_model

Re: [PATCH v4] Introduce attribute sym

2023-07-21 Thread Alexandre Oliva via Gcc-patches
On Jul 20, 2023, Richard Biener  wrote:

> I wonder if we could have shared some of the cgraph/varasm bits
> with the symver attribute handling?  It's just a new 'sym' but
> without the version part?

Possibly.  process_common_attributes could be a good place to create the
alias decl, like symver does.  But that wouldn't cover clones of C++
ctors and dtors, that get variants of the named sym, nor sym attributes
attached to C++ classes.  Aside from these special cases, it is an alias
declaration, without much else to do, which is not very much unlike
symver, but the named sym alias needs to be introduced in the symtab
early enough that other (non-sym) alias declarations can refer to it,
which symver doesn't need to worry about.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] aarch64: testsuite: symbol-range compile only

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jun 30, 2022, Hans-Peter Nilsson  wrote:

> On Thu, 23 Jun 2022, Alexandre Oliva via Gcc-patches wrote:
>> +proc check_effective_target_two_plus_gigs { } {
>> +return [check_no_compiler_messages two_plus_gigs executable {
>> +int dummy[0x8000];

> Don't you mean "char" as in "char dummy[0x8000]"?

Doh.  Of course!  Thanks for catching this.

Here's what I'm installing, regstrapped on x86_64-linux-gnu, also tested
on aarch64-rtems6.0 and ppc64-vx7r2.


testsuite: fix array type in two_plus_gigs test

The array element type for the two_plus_gigs test was mistakely put in
as int rather than char.


for  gcc/testsuite/ChangeLog

* target-supports.exp (check_effective_target_two_plus_gigs):
Fix array element type.  Reported by Hans-Peter Nilsson.

---
 gcc/testsuite/lib/target-supports.exp |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 48c5dda6a1278..4ed7b25b9a4de 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2909,7 +2909,7 @@ proc check_effective_target_le { } {
 
 proc check_effective_target_two_plus_gigs { } {
 return [check_no_compiler_messages two_plus_gigs executable {
-   int dummy[0x8000];
+   char dummy[0x8000];
int main () { return 0; }
 }]
 }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about <https://stallmansupport.org>


Re: [PATCH] libstdc++: testsuite: avoid predictable mkstemp

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jun 27, 2022, Alexandre Oliva  wrote:

> On Jun 23, 2022, Jonathan Wakely  wrote:
>> The attached makes this a bit more efficient, and makes more of the
>> code common to the mkstemp and non-mkstmp branches. I'll wait to hear
>> back from you before pushing it (since it has Joel's name on the
>> patch).

> Thanks, I've given it a spin, both trunk and gcc-11, and I confirm it
> works for us.

The bad news is that it broke on some other systems I didn't test back
then.  It turns out the type cast for the ::getpid result was not just
because it was passed to printf before :-/


libstdc++: testsuite: cast getpid result

On vxworks, in kernel mode, getpid's return type is a pointer type, so
std::to_string on it fails overload resolution.  Restore the type cast
from the original patch that suggested adding the pid.

Regstrapped on x86_64-linux-gnu, also tested on aarch64-rtems6.0 and
ppc64-vx7r2.  I'm going ahead and checking this in as obvious.  Please
let me know if you'd prefer this to be fixed in a different way.


for  libstdc++/ChangeLog

* testsuite/util/testsuite_fs.h (nonexistent_path): Convert
the getpid result to an integral type.
---
 libstdc++-v3/testsuite/util/testsuite_fs.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_fs.h 
b/libstdc++-v3/testsuite/util/testsuite_fs.h
index 908fcdbcaeed1..25f8f734dc792 100644
--- a/libstdc++-v3/testsuite/util/testsuite_fs.h
+++ b/libstdc++-v3/testsuite/util/testsuite_fs.h
@@ -163,7 +163,7 @@ namespace __gnu_test
   file.resize(64);
 // The combination of random counter and PID should be unique for a given
 // run of the testsuite.
-file += std::to_string(::getpid());
+file += std::to_string((unsigned long) ::getpid());
 p = std::move(file);
 if (test_fs::exists(p))
   throw test_fs::filesystem_error("Failed to generate unique pathname", p,


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] libstdc++: retry removal of dir entries if dir removal fails

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jun 30, 2022, Sebastian Huber  wrote:

> From my point of view this is behaviour is an RTEMS bug. Instead of
> adding tweaks for RTEMS, it would be better to report the issues and
> fix them in RTEMS. It could be also a Newlib issue.

Thanks, I've just filed https://devel.rtems.org/ticket/4674

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] libstdc++: testsuite: avoid predictable mkstemp

2022-07-05 Thread Alexandre Oliva via Gcc-patches
On Jul  5, 2022, Jonathan Wakely  wrote:

> The cast itself is fine, but I'd like a comment like "N.B. pid_t is a
> pointer on vxworks" so I don't "simplify" it again.


libstdc++: testsuite: why cast getpid result

Add a comment next to the getpid call to explain why the typecast is
needed.

Regstrapped on x86_64-linux-gnu, will install later today if there's no
objection.


for  libstdc++-v3/ChangeLog

* testsuite/util/testsuite_fs (nonexistent_path): Explain why
we need the typecast.
---
 libstdc++-v3/testsuite/util/testsuite_fs.h |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_fs.h 
b/libstdc++-v3/testsuite/util/testsuite_fs.h
index 25f8f734dc792..0e28385e99aca 100644
--- a/libstdc++-v3/testsuite/util/testsuite_fs.h
+++ b/libstdc++-v3/testsuite/util/testsuite_fs.h
@@ -162,7 +162,8 @@ namespace __gnu_test
 if (file.length() > 64)
   file.resize(64);
 // The combination of random counter and PID should be unique for a given
-// run of the testsuite.
+// run of the testsuite.  N.B. getpid() returns a pointer type on vxworks
+// in kernel mode.
 file += std::to_string((unsigned long) ::getpid());
 p = std::move(file);
 if (test_fs::exists(p))


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] Introduce hardbool attribute for C

2022-07-07 Thread Alexandre Oliva via Gcc-patches


This patch introduces hardened booleans in C.  The hardbool attribute,
when attached to an integral type, turns it into an enumerate type
with boolean semantics, using the named or implied constants as
representations for false and true.

Expressions of such types decay to _Bool, trapping if the value is
neither true nor false, and _Bool can convert implicitly back to them.
Other conversions go through _Bool first.

Regstrapped on x86_64-linux-gnu.  Ok to install?


for  gcc/c-family/ChangeLog

* c-attribs.cc (c_common_attribute_table): Add hardbool.
(handle_hardbool_attribute): New.
(type_valid_for_vector_size): Reject hardbool.
* c-common.cc (convert_and_check): Skip warnings for convert
and check for hardbool.
(c_hardbool_type_attr_1): New.
* c-common.h (c_hardbool_type_attr): New.

for  gcc/c/ChangeLog

* c-typeck.cc (convert_lvalue_to_rvalue): Decay hardbools.
* c-convert.cc (convert): Convert to hardbool through
truthvalue.
* c-decl.cc (check_bitfield_type_and_width): Skip enumeral
truncation warnings for hardbool.
(finish_struct): Propagate hardbool attribute to bitfield
types.
(digest_init): Convert to hardbool.

for  gcc/ChangeLog

* doc/extend.texi (hardbool): New type attribute.

for  gcc/testsuite/ChangeLog

* gcc.dg/hardbool-err.c: New.
* gcc.dg/hardbool-trap.c: New.
* gcc.dg/hardbool.c: New.
* gcc.dg/hardbool-s.c: New.
* gcc.dg/hardbool-us.c: New.
* gcc.dg/hardbool-i.c: New.
* gcc.dg/hardbool-ul.c: New.
* gcc.dg/hardbool-ll.c: New.
* gcc.dg/hardbool-5a.c: New.
* gcc.dg/hardbool-s-5a.c: New.
* gcc.dg/hardbool-us-5a.c: New.
* gcc.dg/hardbool-i-5a.c: New.
* gcc.dg/hardbool-ul-5a.c: New.
* gcc.dg/hardbool-ll-5a.c: New.
---
 gcc/c-family/c-attribs.cc |   97 -
 gcc/c-family/c-common.cc  |   21 
 gcc/c-family/c-common.h   |   18 
 gcc/c/c-convert.cc|   14 +++
 gcc/c/c-decl.cc   |   10 ++
 gcc/c/c-typeck.cc |   31 ++-
 gcc/doc/extend.texi   |   37 
 gcc/testsuite/gcc.dg/hardbool-err.c   |   28 ++
 gcc/testsuite/gcc.dg/hardbool-trap.c  |   13 +++
 gcc/testsuite/gcc.dg/torture/hardbool-5a.c|6 +
 gcc/testsuite/gcc.dg/torture/hardbool-i-5a.c  |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-i.c |5 +
 gcc/testsuite/gcc.dg/torture/hardbool-ll-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-ll.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool-s-5a.c  |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-s.c |5 +
 gcc/testsuite/gcc.dg/torture/hardbool-ul-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-ul.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool-us-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-us.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool.c   |  118 +
 21 files changed, 444 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/hardbool-err.c
 create mode 100644 gcc/testsuite/gcc.dg/hardbool-trap.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-i-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-i.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ll-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ll.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-s-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-s.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ul-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ul.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-us-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-us.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index c8d96723f4c30..e385d780c49ce 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -172,6 +172,7 @@ static tree handle_objc_root_class_attribute (tree *, tree, 
tree, int, bool *);
 static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool 
*);
 static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int,
bool *);
+static tree handle_hardbool_attribute (tree *, tree, tree, int, bool *);
 static tree handle_retain_attribute (tree *, tree, tree, int, bool *);
 
 /* Helper to define attribute exclusions.  */
@@ -288,6 +289,8 @@ const struct attribute_spec c_common_attribute_table[] =
affects_type_identity, handler, exclude } */
   { "signed_bool_precision",  1, 1, false, true, false, true,
  ha

[PATCH] Control flow redundancy hardening

2022-07-07 Thread Alexandre Oliva via Gcc-patches


This patch introduces an optional hardening pass to catch unexpected
execution flows.  Functions are transformed so that basic blocks set a
bit in an automatic array, and (non-exceptional) function exit edges
check that the bits in the array represent an expected execution path
in the CFG.

Functions with multiple exit edges, or with too many blocks, call an
out-of-line checker builtin implemented in libgcc.  For simpler
functions, the verification is performed in-line.

-fharden-control-flow-redundancy enables the pass for eligible
functions, --param hardcfr-max-blocks sets a block count limit for
functions to be eligible, and --param hardcfr-max-inline-blocks
tunes the "too many blocks" limit for in-line verification.

Regstrapped on x86_64-linux-gnu.  Also bootstrapped with a patchlet that
enables it by default, with --param hardcfr-max-blocks=32.  Ok to
install?


for  gcc/ChangeLog

* Makefile.in (OBJS): Add gimple-harden-control-flow.o.
* builtins.def (BUILT_IN___HARDCFR_CHECK): New.
* common.opt (fharden-control-flow-redundancy): New.
* doc/invoke.texi (fharden-control-flow-redundancy): New.
(hardcfr-max-blocks, hardcfr-max-inline-blocks): New params.
* gimple-harden-control-flow.cc: New.
* params.opt (-param=hardcfr-max-blocks=): New.
(-param=hradcfr-max-inline-blocks=): New.
* passes.def (pass_harden_control_flow_redundancy): Add.
* tree-pass.h (make_pass_harden_control_flow_redundancy):
Declare.

for  gcc/testsuite/ChangeLog

* c-c++-common/torture/harden-cfr.c: New.
* c-c++-common/torture/harden-abrt.c: New.
* c-c++-common/torture/harden-bref.c: New.
* c-c++-common/torture/harden-tail.c: New.
* gnat.dg/hardcfr.adb: New.

for  libgcc/ChangeLog

* Makefile.in (LIB2ADD): Add hardcfr.c.
* hardcfr.c: New.
---
 gcc/Makefile.in|1 
 gcc/builtins.def   |3 
 gcc/common.opt |4 
 gcc/doc/invoke.texi|   19 +
 gcc/gimple-harden-control-flow.cc  |  713 
 gcc/params.opt |8 
 gcc/passes.def |1 
 .../c-c++-common/torture/harden-cfr-abrt.c |   11 
 .../c-c++-common/torture/harden-cfr-bret.c |   11 
 .../c-c++-common/torture/harden-cfr-tail.c |   17 
 gcc/testsuite/c-c++-common/torture/harden-cfr.c|   81 ++
 gcc/testsuite/gnat.dg/hardcfr.adb  |   76 ++
 gcc/tree-pass.h|2 
 libgcc/Makefile.in |3 
 libgcc/hardcfr.c   |  176 +
 15 files changed, 1126 insertions(+)
 create mode 100644 gcc/gimple-harden-control-flow.cc
 create mode 100644 gcc/testsuite/c-c++-common/torture/harden-cfr-abrt.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/harden-cfr-bret.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/harden-cfr-tail.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/harden-cfr.c
 create mode 100644 gcc/testsuite/gnat.dg/hardcfr.adb
 create mode 100644 libgcc/hardcfr.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3ae237024265c..2a15e6ecf0802 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1403,6 +1403,7 @@ OBJS = \
gimple-iterator.o \
gimple-fold.o \
gimple-harden-conditionals.o \
+   gimple-harden-control-flow.o \
gimple-laddress.o \
gimple-loop-interchange.o \
gimple-loop-jam.o \
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 005976f34e913..b987f9af425fd 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -1055,6 +1055,9 @@ DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", 
BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LI
 DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, 
ATTR_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
 
+/* Control Flow Redundancy hardening out-of-line checker.  */
+DEF_BUILTIN_STUB (BUILT_IN___HARDCFR_CHECK, "__builtin___hardcfr_check")
+
 /* Synchronization Primitives.  */
 #include "sync-builtins.def"
 
diff --git a/gcc/common.opt b/gcc/common.opt
index e7a51e882bade..54eb30fba642f 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1797,6 +1797,10 @@ fharden-conditional-branches
 Common Var(flag_harden_conditional_branches) Optimization
 Harden conditional branches by checking reversed conditions.
 
+fharden-control-flow-redundancy
+Common Var(flag_harden_control_flow_redundancy) Optimization
+Harden control flow by recording and checking execution paths.
+
 ; Nonzero means ignore `#ident' directives.  0 means handle them.
 ; Generate position-independent code for executables if possible
 ; On SVR4 targets, it also controls whether or not to emit a
diff --git a/gcc/doc/invoke.texi b/gcc/do

Re: [PATCH] Introduce hardbool attribute for C

2022-07-08 Thread Alexandre Oliva via Gcc-patches
On Jul  8, 2022, Richard Biener  wrote:

> The documentation should probably be explicit about this case.

Please consider, for purposes of review, the following incremental
patchlet as if integrated with yesterday's submission.

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a63a94158341a..a1dcd581dd8ad 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8483,7 +8483,22 @@ followed by a mapping from @code{false} and @code{true} 
to
 typedef char __attribute__ ((__hardbool__ (0x5a))) hbool;
 hbool first = 0;   /* False, stored as (char)0x5a.  */
 hbool second = !first; /* True, stored as ~(char)0x5a.  */
-@end smallexample
+
+static hbool zeroinit; /* False, stored as (char)0x5a.  */
+auto hbool uninit; /* Undefined, may trap.  */
+@end smallexample
+
+When zero-initializing a variable or field of hardened boolean type
+(presumably held in static storage) the implied zero initializer gets
+converted to @code{_Bool}, and then to the hardened boolean type, so
+that the initial value is the hardened representation for @code{false}.
+Using that value is well defined.  This is @emph{not} the case when
+variables and fields of such types are uninitialized (presumably held in
+automatic or dynamic storage): their values are indeterminate, and using
+them invokes undefined behavior.  Using them may trap or not, depending
+on the bits held in the storage (re)used for the variable, if any, and
+on optimizations the compiler may perform on the grounds that using
+uninitialized values invokes undefined behavior.
 
 
 @item may_alias


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2022-07-08 Thread Alexandre Oliva via Gcc-patches
On Jul  8, 2022, Richard Biener  wrote:

> Does this follow some other compilers / language?

It is analogous to Ada's booleans with representation clauses and
runtime validation checking at use points.

> Is such feature used in existing code?

Not that I know.  The attribute name was my choice.

That said, we have already delivered the experimental implementation to
the customer who requested it (GCC was in stage3, thus the delayed
submission), so by now they may already have some code using it.

> Why is it useful to allow arbitrary values for true/false?

Increasing the hamming distance between legitimate values is desirable
to catch hardware-based attacks, but booleans are probably the only
builtin type that has room for that.

> Why is the default 0 and ~0 rather than 0 and 1 as for _Bool?

My understanding is that the goal is to maximize the hamming distance
between the legitimate values, so as to increase the sensibility to
errors.

There was no requirement for defaults to be these values, however.  The
examples often used 0x5a and 0xa5, but those seemed too arbitrary to be
defaults.  I found ~1 and 1 to be too nasty, so I went for 0 and ~0,
that are still recognizable as false and true values, respectively,
though I'm not sure whether this is advantageous.

>> +@smallexample
>> +typedef char __attribute__ ((__hardbool__ (0x5a))) hbool;
>> +hbool first = 0;   /* False, stored as (char)0x5a.  */
>> +hbool second = !first; /* True, stored as ~(char)0x5a.  */
> hbool thrid;

> what's the initial value of 'third'?

If it's an automatic variable, it's uninitialized, as expected for C.
It might by chance happen to hold one of the legitimate values, but odds
are it doesn't, and if so, accessing it will trap.

If it's a static-storage variable, it will be zero-initialized as
expected, but the zero will be mapped to the representation for false.

> The documentation should probably be explicit about this case.

Agreed, thanks, will do.

> If the underlying representation is an Enum, why not have
> hardened_enum instead?

In Ada, Booleans are enumerator types with various conventions and
builtin operations, with or without a representation clause, that sets
the representation values for the enumerators.  Other enumerations
aren't subject to such conventions as automatic conversions between
Boolean types with different representations, that enable all of them to
be used interchangeably (source-wise) in logical expressions.

It would nevertheless be feasible to implement hardened enumerator
types, that, like Ada, perform runtime validation checking that the
stored value corresponds to one of the enumerators.  This would not fit
some common use cases of enumerator types, e.g. those in which
enumerators define bits or masks, and different enumerators are combined
into a single variable.  This was not the feature that we were asked to
implement, though.

> A hardened _Bool might want to have a special NaT value as well I
> guess?

That might sound appealing, but ISTM that it would instead break the
symmetry of the maximal hamming distance between the representation
values for true and false.  OTOH, NaB, if so desired, would be just any
other value; the challenge would be to get such a value stored in a
variable, given that actual booleans can only hold true (nonzero) or
false (zero), and neither would convert to NaB.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Control flow redundancy hardening

2022-07-08 Thread Alexandre Oliva via Gcc-patches
On Jul  8, 2022, Richard Biener  wrote:

> I'm possibly missing the importance of 'redundancy' in -fharden-control-flow

I took "Control Flow Redundancy" as a term of the art and never
questioned it.  I think the "redundancy" has to do with the fact that
control flow is generally affected by tests and conditionals, and the
checks that an expected path was seemingly taken is redundant with
those.

> but how can you, from a set of visited blocks local to a function,
> determine whether the control flow through the function is "expected"

Hmm, maybe the definition should be in the negated form: what the check
catches is *unexpected* execution flows, e.g. when a block that
shouldn't have been reached (because none of its predecessors was)
somehow was.  This unexpected circumstance indicates some kind of fault
or attack, which is what IIUC this check is about.

Whether the fault was that the hardware took a wrong turn because it was
power deprived, or some software exploit returned to an artifact at the
end of a function to get it to serve an alternate purpose, the check at
the end of the function would catch the unexpected execution of a block
that couldn't be reached under normal circumstances, and flag the error
before further damage occurs.

> Can you elaborate on what kind of "derailed" control flow this catches
> (example?) and what cases it does not?

As in the comments for the pass: for each visited block, check that at
least one predecessor and at least one successor were also visited.  


> I'm also curious as of how this compares to hardware
> mitigations like x86 indirect branch tracking and shadow stack

I'm not expert in the field, but my understanding is that these are
complementary.

Indirect branch tracking constrains the set of available artifacts one
might indirectly branch to, but if you reach one of them, you'd be no
wiser that something fishy was going on without checking that you got
there from some of the predecessor blocks.  (we don't really check
precisely that, nor do we check at that precise time, but we check at
the end of the function that at least one of the predecessor blocks was
run.)  Constraining the available indirect branch targets helps avoid
bypassing the code that sets the bit corresponding to that block, which
might enable an attacker to use an artifact without detection., if
there's no subsequent block that would be inexplicably reached.

Shadow stacks avoid corruption of return addresses, so you're less
likely to reach an unexpected block by means of buffer overruns that
corrupt the stack and overwrite the return address.  Other means to land
in the middle of a function, such as corrupting memory or logical units
through power deprivation remain, and this pass helps guard against
those too.

> and how this relates to the LLVM control flow hardening (ISTR such
> thing exists).

I've never heard of it.  I've just tried to learn about it, but I
couldn't find anything pertinent.

Are you by any chance thinking of
https://clang.llvm.org/docs/ControlFlowIntegrity.html
?

This appears to be entirely unrelated: the control flow nodes it's
concerned with are functions/methods/subprograms in a program, rather
than basic blocks within a function.


Thanks a lot for these questions.  They're going to help me be better
prepared for a presentation about various hardening features (*) that
I've submitted and am preparing for the upcoming Cauldron.

(*) 
https://docs.adacore.com/live/wave/gnat_rm/html/gnat_rm/gnat_rm/security_hardening_features.html

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] i386 testsuite: cope with --enable-default-pie

2022-07-11 Thread Alexandre Oliva via Gcc-patches


Running the testsuite on a toolchain build with --enable-default-pie
had some unexpected fails.  Adjust the tests to tolerate the effects
of this configuration option on x86_64-linux-gnu and i686-linux-gnu.

The cet-sjlj* tests get offsets before the base symbol name with PIC
or PIE.  A single pattern covering both alternatives somehow triggered
two matches rather than the single expected match, thus my narrowing
the '.*' to not skip line breaks, but that was not enough.  Still
puzzled, I separated the patterns into nonpic and !nonpic, and we get
the expected matchcounts this way.

Tests for -mfentry require an mfentry effective target, which excludes
32-bit x86 with PIC or PIE enabled, that's why the patterns that
accept the PIC sym@RELOC annotations only cover x86_64.

The pr24414 test stores in an unadorned named variable in an old-style
asm statement, to check that such asm statements get an implicit
memory clobber.  Rewriting the asm into a GCC extended asm with the
variable as an output would remove the regression it checks against.
Problem is, the literal reference to the variable is not PIC, so it's
rejected by the elf64 linker with an error, and flagged with a warning
by the elf32 one.  We could presumably make the variable references
PIC-friendly with #ifdefs, but I doubt that's worth the trouble.  I'm
just arranging for the test to be skipped if PIC or PIE are enabled by
default.

Regstrapped on x86_64-linux-gnu, and also tested on i686-linux-gnu, with
and without --enable-default-pie on both platforms.  Ok to install?

PS: There's at least one additional FAIL with --enable-default-pie in
the trunk, namely gcc.target/i386/mvc7.c, compared with the build
without default PIE, but I believe that's out of scope for my current
project.  I could sneak in a fix for it if just rerunning this specific
testcase is enough; rerunning all the tests over it, not so much.  At
the end of the patch is the patchlet that enables this one test to also
pass on all 4 test combinations.  WDYT?


for  gcc/testsuite/ChangeLog

* gcc.target/i386/cet-sjlj-6a.c: Cope with --enable-default-pie.
* gcc.target/i386/cet-sjlj-6b.c: Likewise.
* gcc.target/i386/fentryname3.c: Likewise.
* gcc.target/i386/pr24414.c: Likewise.
* gcc.target/i386/pr93492-3.c: Likewise.
* gcc.target/i386/pr93492-5.c: Likewise.
* gcc.target/i386/pr98482-1.c: Likewise.
---
 gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c |6 --
 gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c |6 --
 gcc/testsuite/gcc.target/i386/fentryname3.c |3 ++-
 gcc/testsuite/gcc.target/i386/pr24414.c |1 +
 gcc/testsuite/gcc.target/i386/pr93492-3.c   |2 +-
 gcc/testsuite/gcc.target/i386/pr93492-5.c   |2 +-
 gcc/testsuite/gcc.target/i386/pr98482-1.c   |3 ++-
 7 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c 
b/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c
index 040b297aeb023..c3d0eb929424d 100644
--- a/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c
@@ -2,8 +2,10 @@
 /* { dg-require-effective-target maybe_x32 } */
 /* { dg-options "-O -maddress-mode=short -fcf-protection -mx32" } */
 /* { dg-final { scan-assembler-times "endbr64" 2 } } */
-/* { dg-final { scan-assembler-times "movq\t.*buf\\+8" 1 } } */
-/* { dg-final { scan-assembler-times "subq\tbuf\\+8" 1 } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*buf\\+8" 1 { target nonpic 
} } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*8\\+buf" 1 { target { ! 
nonpic } } } } */
+/* { dg-final { scan-assembler-times "subq\tbuf\\+8" 1 { target nonpic } } } */
+/* { dg-final { scan-assembler-times "subq\t8\\+buf" 1 { target { ! nonpic } } 
} } */
 /* { dg-final { scan-assembler-times "shrl\t\\\$3," 1 } } */
 /* { dg-final { scan-assembler-times "rdsspq" 2 } } */
 /* { dg-final { scan-assembler-times "incsspq" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c 
b/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c
index b2376e710df6a..4c52685d7d1e1 100644
--- a/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c
@@ -2,8 +2,10 @@
 /* { dg-require-effective-target maybe_x32 } */
 /* { dg-options "-O -maddress-mode=long -fcf-protection -mx32" } */
 /* { dg-final { scan-assembler-times "endbr64" 2 } } */
-/* { dg-final { scan-assembler-times "movq\t.*buf\\+16" 1 } } */
-/* { dg-final { scan-assembler-times "subq\tbuf\\+16" 1 } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*buf\\+16" 1 { target 
nonpic } } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*16\\+buf" 1 { target { ! 
nonpic } } } } */
+/* { dg-final { scan-assembler-times "subq\tbuf\\+16" 1 { target nonpic } } } 
*/
+/* { dg-final { scan-assembler-times "subq\t16\\+buf" 1 { target { ! nonpic } 
} } } */
 /* { dg-final { scan-assembler-times "shrl\t\\\$3," 1 } } */
 /* { dg-final { scan-assembler-times "rds

Re: [PATCH] i386 testsuite: cope with --enable-default-pie

2022-07-12 Thread Alexandre Oliva via Gcc-patches
On Jul 11, 2022, Mike Stump  wrote:

> Ok.

>> PS: There's at least one additional FAIL with --enable-default-pie in
>> the trunk, namely gcc.target/i386/mvc7.c

>> WDYT?

> Seems reasonable.

Thanks, here's what I installed.


i386 testsuite: cope with --enable-default-pie

Running the testsuite on a toolchain build with --enable-default-pie
had some unexpected fails.  Adjust the tests to tolerate the effects
of this configuration option on x86_64-linux-gnu and i686-linux-gnu.

The cet-sjlj* tests get offsets before the base symbol name with PIC
or PIE.  A single pattern covering both alternatives somehow triggered
two matches rather than the single expected match, thus my narrowing
the '.*' to not skip line breaks, but that was not enough.  Still
puzzled, I separated the patterns into nonpic and !nonpic, and we get
the expected matchcounts this way.

Tests for -mfentry require an mfentry effective target, which excludes
32-bit x86 with PIC or PIE enabled, that's why the patterns that
accept the PIC sym@RELOC annotations only cover x86_64.  mvc7 is
getting regexps extended to cover PIC reloc annotatios and all of the
named variants, and tightened to avoid unexpected '.' matches.

The pr24414 test stores in an unadorned named variable in an old-style
asm statement, to check that such asm statements get an implicit
memory clobber.  Rewriting the asm into a GCC extended asm with the
variable as an output would remove the regression it checks against.
Problem is, the literal reference to the variable is not PIC, so it's
rejected by the elf64 linker with an error, and flagged with a warning
by the elf32 one.  We could presumably make the variable references
PIC-friendly with #ifdefs, but I doubt that's worth the trouble.  I'm
just arranging for the test to be skipped if PIC or PIE are enabled by
default.


for  gcc/testsuite/ChangeLog

* gcc.target/i386/cet-sjlj-6a.c: Cope with --enable-default-pie.
* gcc.target/i386/cet-sjlj-6b.c: Likewise.
* gcc.target/i386/fentryname3.c: Likewise.
* gcc.target/i386/mvc7.c: Likewise.
* gcc.target/i386/pr24414.c: Likewise.
* gcc.target/i386/pr93492-3.c: Likewise.
* gcc.target/i386/pr93492-5.c: Likewise.
* gcc.target/i386/pr98482-1.c: Likewise.
---
 gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c |6 --
 gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c |6 --
 gcc/testsuite/gcc.target/i386/fentryname3.c |3 ++-
 gcc/testsuite/gcc.target/i386/mvc7.c|   12 ++--
 gcc/testsuite/gcc.target/i386/pr24414.c |1 +
 gcc/testsuite/gcc.target/i386/pr93492-3.c   |2 +-
 gcc/testsuite/gcc.target/i386/pr93492-5.c   |2 +-
 gcc/testsuite/gcc.target/i386/pr98482-1.c   |3 ++-
 8 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c 
b/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c
index 040b297aeb023..c3d0eb929424d 100644
--- a/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-6a.c
@@ -2,8 +2,10 @@
 /* { dg-require-effective-target maybe_x32 } */
 /* { dg-options "-O -maddress-mode=short -fcf-protection -mx32" } */
 /* { dg-final { scan-assembler-times "endbr64" 2 } } */
-/* { dg-final { scan-assembler-times "movq\t.*buf\\+8" 1 } } */
-/* { dg-final { scan-assembler-times "subq\tbuf\\+8" 1 } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*buf\\+8" 1 { target nonpic 
} } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*8\\+buf" 1 { target { ! 
nonpic } } } } */
+/* { dg-final { scan-assembler-times "subq\tbuf\\+8" 1 { target nonpic } } } */
+/* { dg-final { scan-assembler-times "subq\t8\\+buf" 1 { target { ! nonpic } } 
} } */
 /* { dg-final { scan-assembler-times "shrl\t\\\$3," 1 } } */
 /* { dg-final { scan-assembler-times "rdsspq" 2 } } */
 /* { dg-final { scan-assembler-times "incsspq" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c 
b/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c
index b2376e710df6a..4c52685d7d1e1 100644
--- a/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-6b.c
@@ -2,8 +2,10 @@
 /* { dg-require-effective-target maybe_x32 } */
 /* { dg-options "-O -maddress-mode=long -fcf-protection -mx32" } */
 /* { dg-final { scan-assembler-times "endbr64" 2 } } */
-/* { dg-final { scan-assembler-times "movq\t.*buf\\+16" 1 } } */
-/* { dg-final { scan-assembler-times "subq\tbuf\\+16" 1 } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*buf\\+16" 1 { target 
nonpic } } } */
+/* { dg-final { scan-assembler-times "movq\t\[^\n\]*16\\+buf" 1 { target { ! 
nonpic } } } } */
+/* { dg-final { scan-assembler-times "subq\tbuf\\+16" 1 { target nonpic } } } 
*/
+/* { dg-final { scan-assembler-times "subq\t16\\+buf" 1 { target { ! nonpic } 
} } } */
 /* { dg-final { scan-assembler-times "shrl\t\\\$3," 1 } } */
 /* { dg-final { scan-assembler-times "rdsspq" 2 } } */
 /* { dg-final { scan-assembler-times "incsspq" 2 } } */
diff -

[PATCH] i386 PIE: accept @GOTOFF in load/store multi base address

2022-07-26 Thread Alexandre Oliva via Gcc-patches


Looking at the code generated for sse2-{load,store}-multi.c with PIE,
I realized we could use UNSPEC_GOTOFF as a base address, and that this
would enable the test to use the vector insns expected by the tests
even with PIC, so I extended the base + offset logic used by the SSE2
multi-load/store peepholes to accept reg + symbolic base + offset too,
so that the test generated the expected insns even with PIE.

Regstrapped on x86_64-linux-gnu; also tested, along with other patches
I'm posting today with "i386 PIE" in the subject, and compared
default-PIE and default-nonPIE results on it, and on i686-linux-gnu.  Ok
to install?


for  gcc/ChangeLog

* config/i386/i386.cc (symbolic_base_address_p,
base_address_p): New, factored out from...
(extract_base_offset_in_addr): ... here and extended to
recognize REG+GOTOFF, as in gcc.target/i386/sse2-load-multi.c
and sse2-store-multi.c with PIE enabled by default.
---
 gcc/config/i386/i386.cc |   89 ---
 1 file changed, 75 insertions(+), 14 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index e03f86d4a2386..aab28da4b5d4b 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -23910,11 +23910,40 @@ ix86_reloc_rw_mask (void)
 }
 #endif
 
-/* If MEM is in the form of [base+offset], extract the two parts
-   of address and set to BASE and OFFSET, otherwise return false.  */
+/* Return true iff ADDR can be used as a symbolic base address.  */
 
 static bool
-extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset)
+symbolic_base_address_p (rtx addr)
+{
+  if (GET_CODE (addr) == SYMBOL_REF)
+return true;
+
+  if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
+return true;
+
+  return false;
+}
+
+/* Return true iff ADDR can be used as a base address.  */
+
+static bool
+base_address_p (rtx addr)
+{
+  if (REG_P (addr))
+return true;
+
+  if (symbolic_base_address_p (addr))
+return true;
+
+  return false;
+}
+
+/* If MEM is in the form of [(base+symbase)+offset], extract the three
+   parts of address and set to BASE, SYMBASE and OFFSET, otherwise
+   return false.  */
+
+static bool
+extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
 {
   rtx addr;
 
@@ -23925,21 +23954,52 @@ extract_base_offset_in_addr (rtx mem, rtx *base, rtx 
*offset)
   if (GET_CODE (addr) == CONST)
 addr = XEXP (addr, 0);
 
-  if (REG_P (addr) || GET_CODE (addr) == SYMBOL_REF)
+  if (base_address_p (addr))
 {
   *base = addr;
+  *symbase = const0_rtx;
   *offset = const0_rtx;
   return true;
 }
 
   if (GET_CODE (addr) == PLUS
-  && (REG_P (XEXP (addr, 0))
- || GET_CODE (XEXP (addr, 0)) == SYMBOL_REF)
-  && CONST_INT_P (XEXP (addr, 1)))
+  && base_address_p (XEXP (addr, 0)))
 {
-  *base = XEXP (addr, 0);
-  *offset = XEXP (addr, 1);
-  return true;
+  rtx addend = XEXP (addr, 1);
+
+  if (GET_CODE (addend) == CONST)
+   addend = XEXP (addend, 0);
+
+  if (CONST_INT_P (addend))
+   {
+ *base = XEXP (addr, 0);
+ *symbase = const0_rtx;
+ *offset = addend;
+ return true;
+   }
+
+  /* Also accept REG + symbolic ref, with or without a CONST_INT
+offset.  */
+  if (REG_P (XEXP (addr, 0)))
+   {
+ if (symbolic_base_address_p (addend))
+   {
+ *base = XEXP (addr, 0);
+ *symbase = addend;
+ *offset = const0_rtx;
+ return true;
+   }
+
+ if (GET_CODE (addend) == PLUS
+ && symbolic_base_address_p (XEXP (addend, 0))
+ && CONST_INT_P (XEXP (addend, 1)))
+   {
+ *base = XEXP (addr, 0);
+ *symbase = XEXP (addend, 0);
+ *offset = XEXP (addend, 1);
+ return true;
+   }
+   }
 }
 
   return false;
@@ -23954,7 +24014,8 @@ ix86_operands_ok_for_move_multiple (rtx *operands, bool 
load,
machine_mode mode)
 {
   HOST_WIDE_INT offval_1, offval_2, msize;
-  rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2, offset_1, offset_2;
+  rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
+symbase_1, symbase_2, offset_1, offset_2;
 
   if (load)
 {
@@ -23977,13 +24038,13 @@ ix86_operands_ok_for_move_multiple (rtx *operands, 
bool load,
 return false;
 
   /* Check if the addresses are in the form of [base+offset].  */
-  if (!extract_base_offset_in_addr (mem_1, &base_1, &offset_1))
+  if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
 return false;
-  if (!extract_base_offset_in_addr (mem_2, &base_2, &offset_2))
+  if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
 return false;
 
   /* Check if the bases are the same.  */
-  if (!rtx_equal_p (base_1, base_2))
+  if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))

[PATCH] [PR83782] i386 PIE: avoid @GOTOFF for ifuncs and their aliases

2022-07-26 Thread Alexandre Oliva via Gcc-patches


g++.dg/ext/attr-ifunc-3.C and gcc.target/i386/mvc10.c, not changed,
have made it clear that there were problems in the optimizations to
use @GOTOFF to refer to locally-bound ifuncs.  GNU ld as recently as
May 2018 would reject such constructs, whereas later versions will
silently accept but generate incorrect PIE with them (attr-ifunc-3.C)
or still reject them if referenced through aliases (mvc10.c).  The use
of @GOTOFF for locally-bound but externally-visible symbols
(e.g. protected visibility) also breaks pointer identity if the
canonical address ends up preempted by a PLT entry.  This patch
modifies the local_symbolic_operand predicate to disable @GOTOFF for
locally-bound symbols that would require @PLT for calls, restoring
earlier behavior and disabling the optimization that has proven
problematic even on amd64.  Eventually we may reintroduce the
optimization, when the linker is fixed and we test for the fix before
enabling it, and we exclude symbols whose canonical addresses may be
preempted even when the symbol definition can't.  pr83782 tests have
been adjusted to expect @GOT instead of @GOTOFF.

Regstrapped on x86_64-linux-gnu; also tested, along with other patches
I'm posting today with "i386 PIE" in the subject, and compared
default-PIE and default-nonPIE results on it, and on i686-linux-gnu.  Ok
to install?


for  gcc/ChangeLog

PR target/83782
* config/i386/predicates.md (local_symbolic_operand): Disable
GOTOFF even for locally-bound ifuncs.
* config/i386/i386.cc (ix86_call_use_plt_p): Follow the alias
chain looking for an ifunc, as in gcc.target/i386/mvc10.c.

for  gcc/testsuite/ChangeLog

PR target/83782
* gcc.target/i386/pr83782-1.c: Adjust to require GOT rather
than GOTOFF on ia32.
* gcc.target/i386/pr83782-2.c: Likewise.
---
 gcc/config/i386/i386.cc   |   16 ++--
 gcc/config/i386/predicates.md |4 +++-
 gcc/testsuite/gcc.target/i386/pr83782-1.c |4 ++--
 gcc/testsuite/gcc.target/i386/pr83782-2.c |4 ++--
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index aab28da4b5d4b..5c5dc8d2373ff 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -16058,13 +16058,17 @@ ix86_call_use_plt_p (rtx call_op)
 {
   if (SYMBOL_REF_DECL (call_op)
  && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
-   {
- /* NB: All ifunc functions must be called via PLT.  */
- cgraph_node *node
-   = cgraph_node::get (SYMBOL_REF_DECL (call_op));
- if (node && node->ifunc_resolver)
+   /* NB: All ifunc functions must be called via PLT, and we have
+  to explicitly iterate over an alias chain looking for a
+  node marked as an ifunc(_resolver) to tell.  That node is
+  itself aliased to the actual resolver function, so
+  ultimate_alias_target would skip the marker, and the call
+  may be to another declaration aliased to the ifunc.  */
+   for (cgraph_node *node
+  = cgraph_node::get (SYMBOL_REF_DECL (call_op));
+node && node->alias; node = node->get_alias_target ())
+ if (node->ifunc_resolver)
return true;
-   }
   return false;
 }
   return true;
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 42053ea7209f6..411c06e22e600 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -596,7 +596,9 @@ (define_predicate "local_symbolic_operand"
   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op))
 return false;
   if (SYMBOL_REF_LOCAL_P (op))
-return true;
+/* ifuncname@GOTOFF was rejected by the x86 linker before May
+   2018, and silently generated wrong code for PIE afterwards.  */
+return !ix86_call_use_plt_p (op);
 
   /* There is, however, a not insubstantial body of code in the rest of
  the compiler that assumes it can just stick the results of
diff --git a/gcc/testsuite/gcc.target/i386/pr83782-1.c 
b/gcc/testsuite/gcc.target/i386/pr83782-1.c
index ce97b12e65d58..af52278ec4df2 100644
--- a/gcc/testsuite/gcc.target/i386/pr83782-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr83782-1.c
@@ -20,7 +20,7 @@ bar(void)
   return foo;
 }
 
-/* { dg-final { scan-assembler {leal[ \t]foo@GOTOFF\(%[^,]*\),[ \t]%eax} { 
target ia32 } } } */
+/* { dg-final { scan-assembler-not {leal[ \t]foo@GOTOFF\(%[^,]*\),[ \t]%eax} { 
target ia32 } } } */
 /* { dg-final { scan-assembler {lea(?:l|q)[ \t]foo\(%rip\),[ \t]%(?:e|r)ax} { 
target { ! ia32 } } } } */
-/* { dg-final { scan-assembler-not "foo@GOT\\\(" { target ia32 } } } */
+/* { dg-final { scan-assembler "foo@GOT\\\(" { target ia32 } } } */
 /* { dg-final { scan-assembler-not "foo@GOTPCREL\\\(" { target { ! ia32 } } } 
} */
diff --git a/gcc/testsuite/gcc.target/i386/pr83782-2.c 
b/gcc/testsuite/gcc.target/i386/pr83782-2.c
index e25d

Re: [PATCH] i386 testsuite: cope with --enable-default-pie

2022-07-26 Thread Alexandre Oliva via Gcc-patches
On Jul 11, 2022, Mike Stump  wrote:

> On Jul 11, 2022, at 6:47 PM, Alexandre Oliva  wrote:
>> 
>> Running the testsuite on a toolchain build with --enable-default-pie
>> had some unexpected fails.

>> Regstrapped on x86_64-linux-gnu, and also tested on i686-linux-gnu, with
>> and without --enable-default-pie on both platforms.  Ok to install?

> Ok.

Here's some more:


i386 PIE: testsuite: cope with default pie on ia32

This patch continues the effort of cleaning up the testsuite for
--enable-default-pie; the focus herein is mostly 32-bit x86.

As much as I tried to avoid it, most of the changes to the testsuite
simply disable PIC/PIE, for reasons I'm going to detail below.

static-cdtor1.C gets new patterns to match PIE output.  Some
avx512fp16 tests change only in register allocation, because of the
register used to hold the GOT base address.  Interrupt tests changed
in this regard as well, but here it also affected register saving and
restoring.

The previous patch modified cet-sjlj tests, mentioning a single regexp
covering PIC and nonPIC got incorrect match counts.  I found out that
adding ?: to parenthesized subpatterns avoids miscounting matches.
Other tests that count certain kinds of insns needed adjustment over
insns in get_pc_thunk, extra loads from the GOT, or extra adds to
compute addresses.  In one case, namely stack-check-12, it is nonPIC
that had extra insns, that PIC gets rid of, or rather, pushing and
popping the PIC register obviates the dummy push and matching pop used
for stack probing in nonpic.

pr95126 tests were supposed to optimize loads into known constants,
but the @GOTOFF addresses prevent that for reasons I have not
investigated, but that would be clearly desirable, so I've XFAILed
these.  pr95852 is another case of missed optimization: sibcalls are
not possible when the PIC register needs to be set up for the call,
which prevents the expected constant propagation to the return block;
I have adjusted the codegen expectations of these tests.

As for tests that disable PIE...  Some are judgment calls, that fail
for similar reasons as tests described above, but I chose not to
adjust their expectations; others are just not possible with PIC, or
not worth the effort of adjusting.

anon[14].C check for no global or comdat symbols, respectively, but
-fPIE outputs get_pc_thunk, as global hidden comdat.
initlist-const1.C wants .rodata and checks for no .data, but PIC
outputs constant data that needs relocations in .data.rel.ro.local.
no-stack-protector-attr-3.C and stackprotectexplicit2.C count
stack_check_fail matches; -fPIE calls stack_check_fail_local instead,
which matches the pattern, but this symbol is also marked as .hidden,
so the match count needs to be adjusted.

pr71694.C checks for no movl, but get_pc_thunk contains one.
pr102892-1.c is a missed optimization, ivopts creates an induction
variable because the array address can't be part of an indexing base
address with PIE, and that ends up stopping a load from being resolved
to a constant as expected.  sibcall-11.c needs @PLT for the call,
which requires the PIC register, which makes sibcalling impossible.
builtin-self.c, in turn, expects no calls, but PIC calls get_pc_thunk.

avx* vector tests that had PIE disabled were affected in that the need
for GOT-based addressing modes changed instruction selection in ways
that deviated from the expectations of the tests.  Ditto other vector
tests: pr100865*, pr101796-1, pr101846, pr101989-broadcast-1, and
pr102021, pr54855-[37], and pr90773-17.

pr15184* tests need a PIC register to access global variables, which
affects register allocation, so the patterns would have to be
adjusted.  pr27971 can't use the expected addressing mode to
dereference the array with PIC, so it ends up selecting an indexed
addressing mode, obviating the expected separate shift insn.

pr70263-2 is another case that implicitly expects a sibcall,
impossible because of the need for the PIC register; without a
sibcall, the expected REG_EQUIV for the reuse of the stack slot of an
incoming argument does not occur.  pr78035 duplicates the final
compare in both then and else blocks with PIE, which deviates from the
expected cmp count.  pr81736-[57] test for no frame pointer, but the
PIC register assignment to a call-saved register forces a frame; the
former ends up not using the PIC register, but it's only optimized out
after committing to a stack frame to preserve it.  pr85620-6 also
expects a tail call in a situation that is impossible on ia32 PIC.

pr85667-6 doesn't expect the movl in get_pc_thunk.  pr93492-5 tests
-mfentry, not available with PIC on ia32.  pr96539 expects a
tail-call, to avoid copying a large-ish struct argument, but the call
requires the PIC register, so no tail-call.  stack-prot-sym.c expects
a nonpic addressing mode.

Regstrapped on x86_64-linux-gnu; also tested, along with other patches
I'm posting today with "i386 PIE" in the subject, and compared
default-PIE and default-nonPIE results o

Re: [PATCH] [PR83782] i386 PIE: avoid @GOTOFF for ifuncs and their aliases

2022-07-28 Thread Alexandre Oliva via Gcc-patches
On Jul 27, 2022, "H.J. Lu"  wrote:

> On Tue, Jul 26, 2022 at 10:14 PM Alexandre Oliva  wrote:

>> The use of @GOTOFF for locally-bound but externally-visible symbols
>> (e.g. protected visibility) also breaks pointer identity if the
>> canonical address ends up preempted by a PLT entry.

> Here is a different fix:

> https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598667.html

Oh, thanks, I'd missed that.

It doesn't seem to fix the part of the problem I quoted above, though.
I think fixing that requires testing the visibility, to make sure the
symbol's canonical address cannot be preempted, which may occur with
local binding, if the symbol is protected and referenced in the main
program, otherwise pointer identity is broken again, admittedly for a
more obscure case, but pointer identity was the point of the PR.

>> * config/i386/i386.cc (ix86_call_use_plt_p): Follow the alias
>> chain looking for an ifunc, as in gcc.target/i386/mvc10.c.

You may also need to do something like this bit for mvc10.c on ia32 PIE.
Because the ifunc is called through an alias, AFAICT we don't even
notice that the call target is (an alias to) an ifunc.  GCC's
gotoff_operand predicate accepts it, but binutils (the linker, IIRC)
then rejects that reference, because the named symbol is an alias to an
ifunc.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH v2 00/10] Introduce strub: machine-independent stack scrubbing

2022-07-28 Thread Alexandre Oliva via Gcc-patches


This patch adds the strub attribute for function and variable types,
command-line options, passes and adjustments to implement it,
documentation, and tests.

Stack scrubbing is implemented in a machine-independent way: functions
with strub enabled are modified so that they take an extra stack
watermark argument, that they update with their stack use, and the
caller can then zero it out once it regains control, whether by return
or exception.  There are two ways to go about it: at-calls, that
modifies the visible interface (signature) of the function, and
internal, in which the body is moved to a clone, the clone undergoes
the interface change, and the function becomes a wrapper, preserving
its original interface, that calls the clone and then clears the stack
used by it.

Variables can also be annotated with the strub attribute, so that
functions that read from them get stack scrubbing enabled implicitly,
whether at-calls, for functions only usable within a translation unit,
or internal, for functions whose interfaces must not be modified.

There is a strict mode, in which functions that have their stack
scrubbed can only call other functions with stack-scrubbing
interfaces, or those explicitly marked as callable from strub
contexts, so that an entire call chain gets scrubbing, at once or
piecemeal depending on optimization levels.  In the default mode,
relaxed, this requirement is not enforced by the compiler.

The implementation adds two IPA passes, one that assigns strub modes
early on, another that modifies interfaces and adds calls to the
builtins that jointly implement stack scrubbing.  Another builtin,
that obtains the stack pointer, is added for use in the implementation
of the builtins, whether expanded inline or called in libgcc.

There are new command-line options to change operation modes and to
force the feature disabled; it is enabled by default, but it has no
effect and is implicitly disabled if the strub attribute is never
used.  There are also options meant to use for testing the feature,
enabling different strubbing modes for all (viable) functions.

I'm going to split up the very large patch into separate posts:
1:documentation, tests (2:C/C++ torture, 3:C/C++ non-torture, 4:C++
and Ada), 5:builtins and runtime, 6:attributes, 7:interfaces and
adjustments, and ipa-strub.cc fragments (8:strub modes, 9:strub mode
assignment pass, and 10:strub pass proper).

This is an refreshed and updated version of the patch posted in Sept
last year.  It was regstrapped on x86_64-linux-gnu, bootstrapped with a
patchlet that enables -fstrub=all by default (with a fix for a warning
exposed by it).  Earlier, essentially the same change has undergone
significant testing, with and without -fstrub=all on multiple embedded
platforms.  Ok to install?


for  gcc/ChangeLog

* Makefile.in (OBJS): Add ipa-strub.o.
* builtins.def (BUILT_IN_STACK_ADDRESS): New.
(BUILT_IN___STRUB_ENTER): New.
(BUILT_IN___STRUB_UPDATE): New.
(BUILT_IN___STRUB_LEAVE): New.
* builtins.cc: Include ipa-strub.h.
(STACK_STOPS, STACK_UNSIGNED): Define.
(expand_builtin_stack_address): New.
(expand_builtin_strub_enter): New.
(expand_builtin_strub_update): New.
(expand_builtin_strub_leave): New.
(expand_bulitin): Call them.
* common.opt (fstrub=*): New options.
* doc/extend.texi (strub): New type attribute.
(__builtin_stack_address): New function.
(Stack Scrubbing): New section.
* doc/invoke.texi (-fstrub=*): New options.
(-fdump-ipa-*): New passes.
* ipa-inline.cc: Include ipa-strub.h.
(can_inline_edge_p): Test strub_inlinable_to_p.
* ipa-split.cc: Include ipa-strub.h.
(execute_split_functions): Test strub_splittable_p.
* ipa-strub.cc, ipa-strub.h: New.
* passes.def: Add strub_mode and strub passes.
* tree-cfg.cc (gimple_verify_flow_info): Note on debug stmts.
* tree-pass.h (make_pass_ipa_strub_mode): Declare.
(make_pass_ipa_strub): Declare.
(make_pass_ipa_function_and_variable_visibility): Fix
formatting.
* tree-ssa-ccp.cc (optimize_stack_restore): Keep restores
before strub leave.
* multiple_target.cc (pass_target_clone::gate): Test seen_error.
* attribs.cc: Include ipa-strub.h.
(decl_attributes): Support applying attributes to function
type, rather than pointer type, at handler's request.
(comp_type_attributes): Combine strub_comptypes and target
comp_type results.

for  gcc/c-family/ChangeLog

* c-attribs.cc: Include ipa-strub.h.
(handle_strub_attribute): New.
(c_common_attribute_table): Add strub.

for  gcc/ada/ChangeLog

* gcc-interface/trans.cc: Include ipa-strub.h.
(gigi): Make internal decls for targets of compiler-generated
calls strub-callable too.
(build_raise_check): Likewise.
*

[PATCH v2 01/10] Introduce strub: documentation, and new command-line options

2022-07-28 Thread Alexandre Oliva via Gcc-patches


Ada already has some strub documentation in
gcc/ada/doc/gnat_rm/security_hardening_features.rst.

for  gcc/ChangeLog

* common.opt (fstrub=*): New options.
* doc/extend.texi (strub): New type attribute.
(__builtin_stack_address): New function.
(Stack Scrubbing): New section.
* doc/invoke.texi (-fstrub=*): New options.
(-fdump-ipa-*): New passes.

diff --git a/gcc/common.opt b/gcc/common.opt
index e7a51e882bade..2c635806bbf2c 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2780,6 +2780,35 @@ fstrict-overflow
 Common
 Treat signed overflow as undefined.  Negated as -fwrapv -fwrapv-pointer.
 
+fstrub=disable
+Common RejectNegative Var(flag_strub, 0)
+Disable stack scrub entirely, disregarding strub attributes.
+
+fstrub=strict
+Common RejectNegative Var(flag_strub, -4)
+Enable stack scrub as per attributes, with strict call checking.
+
+; If any strub-enabling attribute is seen when the default or strict
+; initializer values are in effect, flag_strub is bumped up by 2.  The
+; scrub mode gate function will then bump these initializer values to
+; 0 if no strub-enabling attribute is seen.  This minimizes the strub
+; overhead.
+fstrub=relaxed
+Common RejectNegative Var(flag_strub, -3) Init(-3)
+Restore default strub mode: as per attributes, with relaxed checking.
+
+fstrub=all
+Common RejectNegative Var(flag_strub, 3)
+Enable stack scrubbing for all viable functions.
+
+fstrub=at-calls
+Common RejectNegative Var(flag_strub, 1)
+Enable at-calls stack scrubbing for all viable functions.
+
+fstrub=internal
+Common RejectNegative Var(flag_strub, 2)
+Enable internal stack scrubbing for all viable functions.
+
 fsync-libcalls
 Common Var(flag_sync_libcalls) Init(1)
 Implement __atomic operations via libcalls to legacy __sync functions.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7fe7f8817cdd4..90d38c9f08362 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -77,6 +77,7 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Function Names::  Printable strings which are the name of the current
 function.
 * Return Address::  Getting the return or frame address of a function.
+* Stack Scrubbing:: Stack scrubbing internal interfaces.
 * Vector Extensions::   Using vector instructions through built-in functions.
 * Offsetof::Special syntax for implementing @code{offsetof}.
 * __sync Builtins:: Legacy built-in functions for atomic memory access.
@@ -8890,6 +8891,263 @@ pid_t wait (wait_status_ptr_t p)
 @}
 @end smallexample
 
+@item strub
+@cindex @code{strub} type attribute
+This attribute defines stack-scrubbing properties of functions and
+variables.  Being a type attribute, it attaches to types, even when
+specified in function and variable declarations.  When applied to
+function types, it takes an optional string argument.  When applied to a
+pointer-to-function type, if the optional argument is given, it gets
+propagated to the function type.
+
+@smallexample
+/* A strub variable.  */
+int __attribute__ ((strub)) var;
+/* A strub variable that happens to be a pointer.  */
+__attribute__ ((strub)) int *strub_ptr_to_int;
+/* A pointer type that may point to a strub variable.  */
+typedef int __attribute__ ((strub)) *ptr_to_strub_int_type;
+
+/* A declaration of a strub function.  */
+extern int __attribute__ ((strub)) foo (void);
+/* A pointer to that strub function.  */
+int __attribute__ ((strub ("at-calls"))) (*ptr_to_strub_fn)(void) = foo;
+@end smallexample
+
+A function associated with @code{at-calls} @code{strub} mode
+(@code{strub("at-calls")}, or just @code{strub}) undergoes interface
+changes.  Its callers are adjusted to match the changes, and to scrub
+(overwrite with zeros) the stack space used by the called function after
+it returns.  The interface change makes the function type incompatible
+with an unadorned but otherwise equivalent type, so @emph{every}
+declaration and every type that may be used to call the function must be
+associated with this strub mode.
+
+A function associated with @code{internal} @code{strub} mode
+(@code{strub("internal")}) retains an unmodified, type-compatible
+interface, but it may be turned into a wrapper that calls the wrapped
+body using a custom interface.  The wrapper then scrubs the stack space
+used by the wrapped body.  Though the wrapped body has its stack space
+scrubbed, the wrapper does not, so arguments and return values may
+remain unscrubbed even when such a function is called by another
+function that enables @code{strub}.  This is why, when compiling with
+@option{-fstrub=strict}, a @code{strub} context is not allowed to call
+@code{internal} @code{strub} functions.
+
+@smallexample
+/* A declaration of an internal-strub function.  */
+extern int __attribute__ ((strub ("internal"))) bar (void);
+
+int __attribute__ ((strub))
+baz (void)
+@{
+  /* Ok, foo was declared above as an at-calls strub function.  */
+  foo ();

[PATCH v2 02/10] Introduce strub: torture tests for C and C++

2022-07-28 Thread Alexandre Oliva via Gcc-patches


for  gcc/testsuite/ChangeLog

* c-c++-common/torture/strub-callable1.c: New.
* c-c++-common/torture/strub-callable2.c: New.
* c-c++-common/torture/strub-const1.c: New.
* c-c++-common/torture/strub-const2.c: New.
* c-c++-common/torture/strub-const3.c: New.
* c-c++-common/torture/strub-const4.c: New.
* c-c++-common/torture/strub-data1.c: New.
* c-c++-common/torture/strub-data2.c: New.
* c-c++-common/torture/strub-data3.c: New.
* c-c++-common/torture/strub-data4.c: New.
* c-c++-common/torture/strub-data5.c: New.
* c-c++-common/torture/strub-indcall1.c: New.
* c-c++-common/torture/strub-indcall2.c: New.
* c-c++-common/torture/strub-indcall3.c: New.
* c-c++-common/torture/strub-inlinable1.c: New.
* c-c++-common/torture/strub-inlinable2.c: New.
* c-c++-common/torture/strub-ptrfn1.c: New.
* c-c++-common/torture/strub-ptrfn2.c: New.
* c-c++-common/torture/strub-ptrfn3.c: New.
* c-c++-common/torture/strub-ptrfn4.c: New.
* c-c++-common/torture/strub-pure1.c: New.
* c-c++-common/torture/strub-pure2.c: New.
* c-c++-common/torture/strub-pure3.c: New.
* c-c++-common/torture/strub-pure4.c: New.
* c-c++-common/torture/strub-run1.c: New.
* c-c++-common/torture/strub-run2.c: New.
* c-c++-common/torture/strub-run3.c: New.
* c-c++-common/torture/strub-run4.c: New.
* c-c++-common/torture/strub-run4c.c: New.
* c-c++-common/torture/strub-run4d.c: New.
* c-c++-common/torture/strub-run4i.c: New.

diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable1.c 
b/gcc/testsuite/c-c++-common/torture/strub-callable1.c
new file mode 100644
index 0..b5e45ab0525ad
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-callable1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=strict" } */
+
+/* Check that strub and non-strub functions can be called from non-strub
+   contexts, and that strub and callable functions can be called from strub
+   contexts.  */
+
+#define OMIT_IMPERMISSIBLE_CALLS 1
+#include "strub-callable2.c"
diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable2.c 
b/gcc/testsuite/c-c++-common/torture/strub-callable2.c
new file mode 100644
index 0..96aa7fe4b07f7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-callable2.c
@@ -0,0 +1,264 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=strict" } */
+
+/* Check that impermissible (cross-strub-context) calls are reported.  */
+
+extern int __attribute__ ((__strub__ ("callable"))) xcallable (void);
+extern int __attribute__ ((__strub__ ("internal"))) xinternal (void);
+extern int __attribute__ ((__strub__ ("at-calls"))) xat_calls (void);
+extern int __attribute__ ((__strub__ ("disabled"))) xdisabled (void);
+
+int __attribute__ ((__strub__ ("callable"))) callable (void);
+int __attribute__ ((__strub__ ("internal"))) internal (void);
+int __attribute__ ((__strub__ ("at-calls"))) at_calls (void);
+int __attribute__ ((__strub__ ("disabled"))) disabled (void);
+
+int __attribute__ ((__strub__)) var;
+int var_user (void);
+
+static inline int __attribute__ ((__always_inline__, __strub__ ("callable")))
+icallable (void);
+static inline int __attribute__ ((__always_inline__, __strub__ ("internal")))
+iinternal (void);
+static inline int __attribute__ ((__always_inline__, __strub__ ("at-calls")))
+iat_calls (void);
+static inline int __attribute__ ((__always_inline__, __strub__ ("disabled")))
+idisabled (void);
+static inline int __attribute__ ((__always_inline__))
+ivar_user (void);
+
+static inline int __attribute__ ((__always_inline__, __strub__ ("callable")))
+i_callable (void) { return 0; }
+static inline int __attribute__ ((__always_inline__, __strub__ ("internal")))
+i_internal (void) { return var; }
+static inline int __attribute__ ((__always_inline__, __strub__ ("at-calls")))
+i_at_calls (void) { return var; }
+static inline int __attribute__ ((__always_inline__, __strub__ ("disabled")))
+i_disabled (void) { return 0; }
+static inline int __attribute__ ((__always_inline__))
+i_var_user (void) { return var; }
+
+#define CALLS_GOOD_FOR_STRUB_CONTEXT(ISEP) \
+  do { \
+ret += i ## ISEP ## at_calls ();   \
+ret += i ## ISEP ## internal ();   \
+ret += i ## ISEP ## var_user ();   \
+  } while (0)
+
+#define CALLS_GOOD_FOR_NONSTRUB_CONTEXT(ISEP)  \
+  do { \
+ret += internal ();\
+ret += disabled ();\
+ret += var_user ();\
+   \
+ret += i ## ISEP ## disabled ();   \
+   \
+ret += xinternal ();   \
+ret += xdisa

[PATCH v2 03/10] Introduce strub: non-torture tests for C and C++

2022-07-28 Thread Alexandre Oliva via Gcc-patches


for  gcc/testsuite/ChangeLog

* c-c++-common/strub-O0.c: New.
* c-c++-common/strub-O1.c: New.
* c-c++-common/strub-O2.c: New.
* c-c++-common/strub-O2fni.c: New.
* c-c++-common/strub-O3.c: New.
* c-c++-common/strub-O3fni.c: New.
* c-c++-common/strub-Og.c: New.
* c-c++-common/strub-Os.c: New.
* c-c++-common/strub-all1.c: New.
* c-c++-common/strub-all2.c: New.
* c-c++-common/strub-apply1.c: New.
* c-c++-common/strub-apply2.c: New.
* c-c++-common/strub-apply3.c: New.
* c-c++-common/strub-apply4.c: New.
* c-c++-common/strub-at-calls1.c: New.
* c-c++-common/strub-at-calls2.c: New.
* c-c++-common/strub-defer-O1.c: New.
* c-c++-common/strub-defer-O2.c: New.
* c-c++-common/strub-defer-O3.c: New.
* c-c++-common/strub-defer-Os.c: New.
* c-c++-common/strub-internal1.c: New.
* c-c++-common/strub-internal2.c: New.
* c-c++-common/strub-parms1.c: New.
* c-c++-common/strub-parms2.c: New.
* c-c++-common/strub-parms3.c: New.
* c-c++-common/strub-relaxed1.c: New.
* c-c++-common/strub-relaxed2.c: New.
* c-c++-common/strub-short-O0-exc.c: New.
* c-c++-common/strub-short-O0.c: New.
* c-c++-common/strub-short-O1.c: New.
* c-c++-common/strub-short-O2.c: New.
* c-c++-common/strub-short-O3.c: New.
* c-c++-common/strub-short-Os.c: New.
* c-c++-common/strub-strict1.c: New.
* c-c++-common/strub-strict2.c: New.
* c-c++-common/strub-tail-O1.c: New.
* c-c++-common/strub-tail-O2.c: New.

diff --git a/gcc/testsuite/c-c++-common/strub-O0.c 
b/gcc/testsuite/c-c++-common/strub-O0.c
new file mode 100644
index 0..c7a79a6ea0d8a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/strub-O0.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -fstrub=strict -fdump-rtl-expand" } */
+
+/* At -O0, none of the strub builtins are expanded inline.  */
+
+int __attribute__ ((__strub__)) var;
+
+int f() {
+  return var;
+}
+
+/* { dg-final { scan-rtl-dump "strub_enter" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_update" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-O1.c 
b/gcc/testsuite/c-c++-common/strub-O1.c
new file mode 100644
index 0..96285c975d98e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/strub-O1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fstrub=strict -fdump-rtl-expand" } */
+
+/* At -O1, without -fno-inline, we fully expand enter, but neither update nor
+   leave.  */
+
+int __attribute__ ((__strub__)) var;
+
+int f() {
+  return var;
+}
+
+/* { dg-final { scan-rtl-dump-not "strub_enter" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_update" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-O2.c 
b/gcc/testsuite/c-c++-common/strub-O2.c
new file mode 100644
index 0..8edc0d8aa1321
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/strub-O2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrub=strict -fdump-rtl-expand" } */
+
+/* At -O2, without -fno-inline, we fully expand enter and update, and add a 
test
+   around the leave call.  */
+
+int __attribute__ ((__strub__)) var;
+
+int f() {
+  return var;
+}
+
+/* { dg-final { scan-rtl-dump-not "strub_enter" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "strub_update" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
+/* { dg-final { scan-rtl-dump 
"\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-O2fni.c 
b/gcc/testsuite/c-c++-common/strub-O2fni.c
new file mode 100644
index 0..c6d900cf3c45b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/strub-O2fni.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstrub=strict -fdump-rtl-expand -fno-inline" } */
+
+/* With -fno-inline, none of the strub builtins are inlined.  */
+
+int __attribute__ ((__strub__)) var;
+
+int f() {
+  return var;
+}
+
+/* { dg-final { scan-rtl-dump "strub_enter" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_update" "expand" } } */
+/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
+/* { dg-final { scan-rtl-dump-not 
"\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-O3.c 
b/gcc/testsuite/c-c++-common/strub-O3.c
new file mode 100644
index 0..33ee465e51cb6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/strub-O3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fstrub=strict -fdump-rtl-expand" } */
+
+int __attribute__ ((__strub__)) var;
+
+int f() {
+  return var;
+}
+
+/* { dg-final { scan-rtl-dump-not "strub_enter" "expand" } } */
+/* { dg-final { scan-rtl-dump-not

[PATCH v2 04/10] Introduce strub: tests for C++ and Ada

2022-07-28 Thread Alexandre Oliva via Gcc-patches


for  gcc/testsuite/ChangeLog

* g++.dg/strub-run1.C: New.
* g++.dg/torture/strub-init1.C: New.
* g++.dg/torture/strub-init2.C: New.
* g++.dg/torture/strub-init3.C: New.
* gnat.dg/strub_attr.adb, gnat.dg/strub_attr.ads: New.
* gnat.dg/strub_ind.adb, gnat.dg/strub_ind.ads: New.

diff --git a/gcc/testsuite/g++.dg/strub-run1.C 
b/gcc/testsuite/g++.dg/strub-run1.C
new file mode 100644
index 0..0d367fb83d09d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/strub-run1.C
@@ -0,0 +1,19 @@
+// { dg-do run }
+// { dg-options "-fstrub=internal" }
+
+// Check that we don't get extra copies.
+
+struct T {
+  T &self;
+  void check () const { if (&self != this) __builtin_abort (); }
+  T() : self (*this) { check (); }
+  T(const T& ck) : self (*this) { ck.check (); check (); }
+  ~T() { check (); }
+};
+
+T foo (T q) { q.check (); return T(); }
+T bar (T p) { p.check (); return foo (p); }
+
+int main () {
+  bar (T()).check ();
+}
diff --git a/gcc/testsuite/g++.dg/torture/strub-init1.C 
b/gcc/testsuite/g++.dg/torture/strub-init1.C
new file mode 100644
index 0..c226ab10ff651
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/strub-init1.C
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
+
+extern int __attribute__((__strub__)) initializer ();
+
+int f() {
+  static int x = initializer ();
+  return x;
+}
+
+/* { dg-final { scan-ipa-dump "strub_enter" "strub" } } */
+/* { dg-final { scan-ipa-dump "strub_leave" "strub" } } */
+/* { dg-final { scan-ipa-dump-not "strub_update" "strub" } } */
diff --git a/gcc/testsuite/g++.dg/torture/strub-init2.C 
b/gcc/testsuite/g++.dg/torture/strub-init2.C
new file mode 100644
index 0..a7911f1fa7212
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/strub-init2.C
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
+
+extern int __attribute__((__strub__)) initializer ();
+
+static int x = initializer ();
+
+int f() {
+  return x;
+}
+
+/* { dg-final { scan-ipa-dump "strub_enter" "strub" } } */
+/* { dg-final { scan-ipa-dump "strub_leave" "strub" } } */
+/* { dg-final { scan-ipa-dump-not "strub_update" "strub" } } */
diff --git a/gcc/testsuite/g++.dg/torture/strub-init3.C 
b/gcc/testsuite/g++.dg/torture/strub-init3.C
new file mode 100644
index 0..6ebebcd01e8ea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/strub-init3.C
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
+
+extern int __attribute__((__strub__)) initializer ();
+
+int f() {
+  int x = initializer ();
+  return x;
+}
+
+/* { dg-final { scan-ipa-dump "strub_enter" "strub" } } */
+/* { dg-final { scan-ipa-dump "strub_leave" "strub" } } */
+/* { dg-final { scan-ipa-dump-not "strub_update" "strub" } } */
diff --git a/gcc/testsuite/gnat.dg/strub_access.adb 
b/gcc/testsuite/gnat.dg/strub_access.adb
new file mode 100644
index 0..29e6996ecf61c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/strub_access.adb
@@ -0,0 +1,21 @@
+--  { dg-do compile }
+--  { dg-options "-fstrub=relaxed -fdump-ipa-strubm" }
+
+--  The main subprogram doesn't read from the automatic variable, but
+--  being an automatic variable, its presence should be enough for the
+--  procedure to get strub enabled.
+
+procedure Strub_Access is
+   type Strub_Int is new Integer;
+   pragma Machine_Attribute (Strub_Int, "strub");
+   
+   X : aliased Strub_Int := 0;
+
+   function F (P : access Strub_Int) return Strub_Int is (P.all);
+
+begin
+   X := F (X'Access);
+end Strub_Access;
+
+--  { dg-final { scan-ipa-dump-times "\[(\]strub \[(\]internal\[)\]\[)\]" 1 
"strubm" } }
+--  { dg-final { scan-ipa-dump-times "\[(\]strub \[(\]at-calls-opt\[)\]\[)\]" 
1 "strubm" } }
diff --git a/gcc/testsuite/gnat.dg/strub_access1.adb 
b/gcc/testsuite/gnat.dg/strub_access1.adb
new file mode 100644
index 0..dae4706016436
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/strub_access1.adb
@@ -0,0 +1,16 @@
+--  { dg-do compile }
+--  { dg-options "-fstrub=relaxed" }
+
+--  Check that we reject 'Access of a strub variable whose type does
+--  not carry a strub modifier.
+
+procedure Strub_Access1 is
+   X : aliased Integer := 0;
+   pragma Machine_Attribute (X, "strub");
+
+   function F (P : access Integer) return Integer is (P.all);
+   
+begin
+   X := F (X'Unchecked_access); -- OK.
+   X := F (X'Access); -- { dg-error "target access type drops .strub. mode" }
+end Strub_Access1;
diff --git a/gcc/testsuite/gnat.dg/strub_attr.adb 
b/gcc/testsuite/gnat.dg/strub_attr.adb
new file mode 100644
index 0..10445d7cf8451
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/strub_attr.adb
@@ -0,0 +1,37 @@
+--  { dg-do compile }
+--  { dg-options "-fstrub=strict -fdump-ipa-strubm -fdump-ipa-strub" }
+
+package body Strub_Attr is
+   E : exception;
+
+   procedure P (X : Integer) is
+   begin
+  raise E;
+   end;
+   
+   function F (X : Integer) return Integer 

[PATCH v2 05/10] Introduce strub: builtins and runtime

2022-07-28 Thread Alexandre Oliva via Gcc-patches


for  gcc/ChangeLog

* builtins.def (BUILT_IN_STACK_ADDRESS): New.
(BUILT_IN___STRUB_ENTER): New.
(BUILT_IN___STRUB_UPDATE): New.
(BUILT_IN___STRUB_LEAVE): New.
* builtins.cc: Include ipa-strub.h.
(STACK_STOPS, STACK_UNSIGNED): Define.
(expand_builtin_stack_address): New.
(expand_builtin_strub_enter): New.
(expand_builtin_strub_update): New.
(expand_builtin_strub_leave): New.
(expand_bulitin): Call them.

for  libgcc/ChangeLog

* Makefile.in (LIB2ADD): Add strub.c.
* libgcc2.h (__strub_enter, __strub_update, __strub_leave):
Declare.
* strub.c: New.

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index b08b4365da36b..656186c308997 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -71,6 +71,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-fold.h"
 #include "intl.h"
 #include "file-prefix-map.h" /* remap_macro_filename()  */
+#include "ipa-strub.h" /* strub_watermark_parm()  */
 #include "gomp-constants.h"
 #include "omp-general.h"
 #include "tree-dfa.h"
@@ -151,6 +152,7 @@ static rtx expand_builtin_strnlen (tree, rtx, machine_mode);
 static rtx expand_builtin_alloca (tree);
 static rtx expand_builtin_unop (machine_mode, tree, rtx, rtx, optab);
 static rtx expand_builtin_frame_address (tree, tree);
+static rtx expand_builtin_stack_address ();
 static tree stabilize_va_list_loc (location_t, tree, int);
 static rtx expand_builtin_expect (tree, rtx);
 static rtx expand_builtin_expect_with_probability (tree, rtx);
@@ -4968,6 +4970,256 @@ expand_builtin_frame_address (tree fndecl, tree exp)
 }
 }
 
+#ifndef STACK_GROWS_DOWNWARD
+# define STACK_TOPS GT
+#else
+# define STACK_TOPS LT
+#endif
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+# define STACK_UNSIGNED POINTERS_EXTEND_UNSIGNED
+#else
+# define STACK_UNSIGNED true
+#endif
+
+/* Expand a call to builtin function __builtin_stack_address.  */
+
+static rtx
+expand_builtin_stack_address ()
+{
+  return convert_to_mode (ptr_mode, copy_to_reg (stack_pointer_rtx),
+ STACK_UNSIGNED);
+}
+
+/* Expand a call to builtin function __builtin_strub_enter.  */
+
+static rtx
+expand_builtin_strub_enter (tree exp)
+{
+  if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
+return NULL_RTX;
+
+  if (optimize < 1 || flag_no_inline)
+return NULL_RTX;
+
+  rtx stktop = NULL_RTX;
+
+#if 1 || defined RED_ZONE_SIZE
+  if (tree wmptr = (optimize
+   ? strub_watermark_parm (current_function_decl)
+   : NULL_TREE))
+{
+  tree wmtype = TREE_TYPE (TREE_TYPE (wmptr));
+  tree wmtree = fold_build2 (MEM_REF, wmtype, wmptr,
+build_int_cst (TREE_TYPE (wmptr), 0));
+  rtx wmark = expand_expr (wmtree, NULL_RTX, ptr_mode, EXPAND_MEMORY);
+  stktop = force_reg (ptr_mode, wmark);
+}
+#endif
+
+  if (!stktop)
+stktop = expand_builtin_stack_address ();
+
+  tree wmptr = CALL_EXPR_ARG (exp, 0);
+  tree wmtype = TREE_TYPE (TREE_TYPE (wmptr));
+  tree wmtree = fold_build2 (MEM_REF, wmtype, wmptr,
+build_int_cst (TREE_TYPE (wmptr), 0));
+  rtx wmark = expand_expr (wmtree, NULL_RTX, ptr_mode, EXPAND_MEMORY);
+
+  emit_move_insn (wmark, stktop);
+
+  return const0_rtx;
+}
+
+/* Expand a call to builtin function __builtin_strub_update.  */
+
+static rtx
+expand_builtin_strub_update (tree exp)
+{
+  if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
+return NULL_RTX;
+
+  if (optimize < 2 || flag_no_inline)
+return NULL_RTX;
+
+  rtx stktop = expand_builtin_stack_address ();
+
+#ifdef RED_ZONE_SIZE
+  /* Here's how the strub enter, update and leave functions deal with red 
zones.
+
+ If it weren't for red zones, update, called from within a strub context,
+ would bump the watermark to the top of the stack.  Enter and leave, 
running
+ in the caller, would use the caller's top of stack address both to
+ initialize the watermark passed to the callee, and to start strubbing the
+ stack afterwards.
+
+ Ideally, we'd update the watermark so as to cover the used amount of red
+ zone, and strub starting at the caller's other end of the (presumably
+ unused) red zone.  Normally, only leaf functions use the red zone, but at
+ this point we can't tell whether a function is a leaf, nor can we tell how
+ much of the red zone it uses.  Furthermore, some strub contexts may have
+ been inlined so that update and leave are called from the same stack 
frame,
+ and the strub builtins may all have been inlined, turning a strub function
+ into a leaf.
+
+ So cleaning the range from the caller's stack pointer (one end of the red
+ zone) to the (potentially inlined) callee's (other end of the) red zone
+ could scribble over the caller's own red zone.
+
+ We avoid this possibility by arranging for callers that are strub contexts
+ to use their own watermark 

[PATCH v2 06/10] Introduce strub: attributes

2022-07-28 Thread Alexandre Oliva via Gcc-patches


Ada already has support for the strub attributes stubbed-out, and the
front-end code already has support for them and their effects in the
type system.

for  gcc/ChangeLog

* attribs.cc: Include ipa-strub.h.
(decl_attributes): Support applying attributes to function
type, rather than pointer type, at handler's request.
(comp_type_attributes): Combine strub_comptypes and target
comp_type results.

for  gcc/c-family/ChangeLog

* c-attribs.cc: Include ipa-strub.h.
(handle_strub_attribute): New.
(c_common_attribute_table): Add strub.

for  gcc/ada/ChangeLog

* gcc-interface/utils.cc: Include ipa-strub.h.
(handle_strub_attribute): New.
(gnat_internal_attribute_table): Add strub.

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index fb89616ff296b..d559cfc1b9f4e 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "attribs.h"
 #include "fold-const.h"
+#include "ipa-strub.h"
 #include "stor-layout.h"
 #include "langhooks.h"
 #include "plugin.h"
@@ -774,12 +775,11 @@ decl_attributes (tree *node, tree attributes, int flags,
  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
}
 
-  if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
- && TREE_CODE (*anode) != METHOD_TYPE)
+  if (spec->function_type_required
+ && !FUNC_OR_METHOD_TYPE_P (*anode))
{
  if (TREE_CODE (*anode) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (*anode)))
{
  /* OK, this is a bit convoluted.  We can't just make a copy
 of the pointer type and modify its TREE_TYPE, because if
@@ -887,7 +887,24 @@ decl_attributes (tree *node, tree attributes, int flags,
  TYPE_NAME (tt) = *node;
}
 
- *anode = cur_and_last_decl[0];
+ if (*anode != cur_and_last_decl[0])
+   {
+ /* Even if !spec->function_type_required, allow the attribute
+handler to request the attribute to be applied to the function
+type, rather than to the function pointer type, by setting
+cur_and_last_decl[0] to the function type.  */
+ if (!fn_ptr_tmp
+ && POINTER_TYPE_P (*anode)
+ && TREE_TYPE (*anode) == cur_and_last_decl[0]
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (*anode)))
+   {
+ fn_ptr_tmp = TREE_TYPE (*anode);
+ fn_ptr_quals = TYPE_QUALS (*anode);
+ anode = &fn_ptr_tmp;
+   }
+ *anode = cur_and_last_decl[0];
+   }
+
  if (ret == error_mark_node)
{
  warning (OPT_Wattributes, "%qE attribute ignored", name);
@@ -1491,9 +1508,20 @@ comp_type_attributes (const_tree type1, const_tree type2)
   if ((lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type1)) != NULL)
   ^ (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type2)) != NULL))
 return 0;
+  int strub_ret = strub_comptypes (CONST_CAST_TREE (type1),
+  CONST_CAST_TREE (type2));
+  if (strub_ret == 0)
+return strub_ret;
   /* As some type combinations - like default calling-convention - might
  be compatible, we have to call the target hook to get the final result.  
*/
-  return targetm.comp_type_attributes (type1, type2);
+  int target_ret = targetm.comp_type_attributes (type1, type2);
+  if (target_ret == 0)
+return target_ret;
+  if (strub_ret == 2 || target_ret == 2)
+return 2;
+  if (strub_ret == 1 && target_ret == 1)
+return 1;
+  gcc_unreachable ();
 }
 
 /* PREDICATE acts as a function of type:
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index e4f1d3542f378..08c7d71f827a2 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "common/common-target.h"
 #include "langhooks.h"
 #include "tree-inline.h"
+#include "ipa-strub.h"
 #include "toplev.h"
 #include "tree-iterator.h"
 #include "opts.h"
@@ -69,6 +70,7 @@ static tree handle_asan_odr_indicator_attribute (tree *, 
tree, tree, int,
 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_stack_protector_function_attribute (tree *, tree,
tree, int, bool *);
+static tree handle_strub_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *);
@@ -314,6 +316,8 @@ const s

[PATCH v2 07/10] Introduce strub: infrastructure interfaces and adjustments

2022-07-28 Thread Alexandre Oliva via Gcc-patches


Introduce the new strub passes, adjust other passes and front-end
declaration for strub.

for  gcc/ChangeLog

* Makefile.in (OBJS): Add ipa-strub.o.
* ipa-inline.cc: Include ipa-strub.h.
(can_inline_edge_p): Test strub_inlinable_to_p.
* ipa-split.cc: Include ipa-strub.h.
(execute_split_functions): Test strub_splittable_p.
* ipa-strub.h: New.
* passes.def: Add strub_mode and strub passes.
* tree-cfg.cc (gimple_verify_flow_info): Note on debug stmts.
* tree-pass.h (make_pass_ipa_strub_mode): Declare.
(make_pass_ipa_strub): Declare.
(make_pass_ipa_function_and_variable_visibility): Fix
formatting.
* tree-ssa-ccp.cc (optimize_stack_restore): Keep restores
before strub leave.
* multiple_target.cc (pass_target_clone::gate): Test seen_error.

for  gcc/ada/ChangeLog

* gcc-interface/trans.cc: Include ipa-strub.h.
(gigi): Make internal decls for targets of compiler-generated
calls strub-callable too.
(build_raise_check): Likewise.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 203f0a15187d2..4100531d73ae7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1480,6 +1480,7 @@ OBJS = \
ipa-reference.o \
ipa-ref.o \
ipa-utils.o \
+   ipa-strub.o \
ipa.o \
ira.o \
ira-build.o \
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index c1dd567b2e4e2..e3553a7a87bfc 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -69,6 +69,21 @@
 #include "ada-tree.h"
 #include "gigi.h"
 
+/* The following #include is for strub_make_callable.
+
+   This function marks a function as safe to call from strub contexts.  We mark
+   Ada subprograms that may be called implicitly by the compiler, and that 
won't
+   leave on the stack caller data passed to them.  This stops implicit calls
+   introduced in subprograms that have their stack scrubbed from being flagged
+   as unsafe, even in -fstrub=strict mode.
+
+   These subprograms are also marked with the strub(callable) attribute in Ada
+   sources, but their declarations aren't necessarily imported by GNAT, or made
+   visible to gigi, in units that end up relying on them.  So when gigi
+   introduces their declarations on its own, it must also add the attribute, by
+   calling strub_make_callable.  */
+#include "ipa-strub.h"
+
 /* We should avoid allocating more than ALLOCA_THRESHOLD bytes via alloca,
for fear of running out of stack space.  If we need more, we use xmalloc
instead.  */
@@ -449,6 +464,7 @@ gigi (Node_Id gnat_root,
 int64_type, NULL_TREE),
   NULL_TREE, is_default, true, true, true, false,
   false, NULL, Empty);
+  strub_make_callable (mulv64_decl);
 
   if (Enable_128bit_Types)
 {
@@ -461,6 +477,7 @@ gigi (Node_Id gnat_root,
 NULL_TREE),
   NULL_TREE, is_default, true, true, true, false,
   false, NULL, Empty);
+  strub_make_callable (mulv128_decl);
 }
 
   /* Name of the _Parent field in tagged record types.  */
@@ -716,6 +733,7 @@ build_raise_check (int check, enum exception_info_kind kind)
 = create_subprog_decl (get_identifier (Name_Buffer), NULL_TREE, ftype,
   NULL_TREE, is_default, true, true, true, false,
   false, NULL, Empty);
+  strub_make_callable (result);
 
   return result;
 }
diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
index 14969198cde1c..0674fe138574d 100644
--- a/gcc/ipa-inline.cc
+++ b/gcc/ipa-inline.cc
@@ -119,6 +119,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
+#include "ipa-strub.h"
 
 typedef fibonacci_heap  edge_heap_t;
 typedef fibonacci_node  edge_heap_node_t;
@@ -397,6 +398,11 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
   inlinable = false;
 }
 
+  if (inlinable && !strub_inlinable_to_p (callee, caller))
+{
+  e->inline_failed = CIF_UNSPECIFIED;
+  inlinable = false;
+}
   if (!inlinable && report)
 report_inline_failed_reason (e);
   return inlinable;
diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
index 16734617d0381..b3b9963f13669 100644
--- a/gcc/ipa-split.cc
+++ b/gcc/ipa-split.cc
@@ -104,6 +104,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-fnsummary.h"
 #include "cfgloop.h"
 #include "attribs.h"
+#include "ipa-strub.h"
 
 /* Per basic block info.  */
 
@@ -1810,6 +1811,12 @@ execute_split_functions (void)
 "section.\n");
   return 0;
 }
+  if (!strub_splittable_p (node))
+{
+  if (dump_file)
+   fprintf (dump_file, "Not splitting: function is a strub context.\n");
+  return 0;
+}
 
   /* We enforc

[PATCH v2 08/10] Introduce strub: strub modes

2022-07-28 Thread Alexandre Oliva via Gcc-patches


This initial fragment of ipa-strub.cc covers strub modes and their
internal representation.

for  gcc/ChangeLog

* ipa-strub.cc: New.

diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
new file mode 100644
index 0..d61b7e2e36e43
--- /dev/null
+++ b/gcc/ipa-strub.cc
@@ -0,0 +1,3489 @@
+/* strub (stack scrubbing) support.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Alexandre Oliva .
+
+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
+.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "gimplify.h"
+#include "tree-pass.h"
+#include "ssa.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "tree-into-ssa.h"
+#include "tree-ssa.h"
+#include "tree-cfg.h"
+#include "cfghooks.h"
+#include "cfgloop.h"
+#include "cfgcleanup.h"
+#include "tree-eh.h"
+#include "except.h"
+#include "builtins.h"
+#include "attribs.h"
+#include "tree-inline.h"
+#include "cgraph.h"
+#include "alloc-pool.h"
+#include "symbol-summary.h"
+#include "ipa-prop.h"
+#include "ipa-fnsummary.h"
+#include "gimple-fold.h"
+#include "fold-const.h"
+#include "gimple-walk.h"
+#include "tree-dfa.h"
+#include "langhooks.h"
+#include "calls.h"
+#include "vec.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "alias.h"
+#include "diagnostic.h"
+#include "intl.h"
+#include "ipa-strub.h"
+
+#if BUILDING_GCC_MAJOR >= 11
+# include "symtab-thunks.h"
+# include "attr-fnspec.h"
+# define HAVE_ATTR_FNSPEC 1
+# define FOR_GCC_11P 1
+#else
+# define HAVE_ATTR_FNSPEC 0
+# define FOR_GCC_11P 0
+#endif
+
+/* Const and pure functions that gain a watermark parameter for strub purposes
+   are still regarded as such, which may cause the inline expansions of the
+   __strub builtins to malfunction.  Ideally, attribute "fn spec" would enable
+   us to inform the backend about requirements and side effects of the call, 
but
+   call_fusage building in calls.c:expand_call does not even look at
+   attr_fnspec, so we resort to asm loads and updates to attain an equivalent
+   effect.  Once expand_call gains the ability to issue extra memory uses and
+   clobbers based on pure/const function's fnspec, we can define this to 1.  */
+#define ATTR_FNSPEC_DECONST_WATERMARK 0
+
+enum strub_mode {
+  /* This mode denotes a regular function, that does not require stack
+ scrubbing (strubbing).  It may call any other functions, but if
+ it calls AT_CALLS (or WRAPPED) ones, strubbing logic is
+ automatically introduced around those calls (the latter, by
+ inlining INTERNAL wrappers).  */
+  STRUB_DISABLED = 0,
+
+  /* This denotes a function whose signature is (to be) modified to
+ take an extra parameter, for stack use annotation, and its
+ callers must initialize and pass that argument, and perform the
+ strubbing.  Functions that are explicitly marked with attribute
+ strub must have the mark visible wherever the function is,
+ including aliases, and overriders and overriding methods.
+ Functions that are implicitly marked for strubbing, for accessing
+ variables explicitly marked as such, will only select this
+ strubbing method if they are internal to a translation unit.  It
+ can only be inlined into other strubbing functions, i.e.,
+ STRUB_AT_CALLS or STRUB_WRAPPED.  */
+  STRUB_AT_CALLS = 1,
+
+  /* This denotes a function that is to perform strubbing internally,
+ without any changes to its interface (the function is turned into
+ a strubbing wrapper, and its original body is moved to a separate
+ STRUB_WRAPPED function, with a modified interface).  Functions
+ may be explicitly marked with attribute strub(2), and the
+ attribute must be visible at the point of definition.  Functions
+ that are explicitly marked for strubbing, for accessing variables
+ explicitly marked as such, may select this strubbing mode if
+ their interface cannot change, e.g. because its interface is
+ visible to other translation units, directly, by indirection
+ (having its address taken), inheritance, etc.  Functions that use
+ this method must not have the noclone attribute, nor the noipa
+ one.  Functions marked as always_inline may select this mode, but
+ they are NOT wrapped, they remain unchanged, and are only inlined
+ into strubbed contexts.  O

[PATCH v2 09/10] Introduce strub: strubm (mode assignment) pass

2022-07-28 Thread Alexandre Oliva via Gcc-patches


This middle fragment of ipa-strub.cc covers strub mode selection and
assignment logic, and most of the pass that performs that assignment.

+/* Return TRUE iff NODE calls builtin va_start.  */
+
+static bool
+calls_builtin_va_start_p (cgraph_node *node)
+{
+  bool result = false;
+
+  for (cgraph_edge *e = node->callees; e; e = e->next_callee)
+{
+  tree cdecl = e->callee->decl;
+  if (fndecl_built_in_p (cdecl, BUILT_IN_VA_START))
+   return true;
+}
+
+  return result;
+}
+
+/* Return TRUE iff NODE calls builtin apply_args, and optionally REPORT it.  */
+
+static bool
+calls_builtin_apply_args_p (cgraph_node *node, bool report = false)
+{
+  bool result = false;
+
+  for (cgraph_edge *e = node->callees; e; e = e->next_callee)
+{
+  tree cdecl = e->callee->decl;
+  if (!fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS))
+   continue;
+
+  result = true;
+
+  if (!report)
+   break;
+
+  sorry_at (gimple_location (e->call_stmt),
+   "at-calls % does not support call to %qD",
+   cdecl);
+}
+
+  return result;
+}
+
+/* Return TRUE iff NODE carries the always_inline attribute.  */
+
+static inline bool
+strub_always_inline_p (cgraph_node *node)
+{
+  return lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl));
+}
+
+/* Return TRUE iff NODE is potentially eligible for any strub-enabled mode, and
+   optionally REPORT the reasons for ineligibility.  */
+
+static inline bool
+can_strub_p (cgraph_node *node, bool report = false)
+{
+  bool result = true;
+
+  if (!report && strub_always_inline_p (node))
+return result;
+
+  if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
+{
+  result = false;
+
+  if (!report)
+   return result;
+
+  sorry_at (DECL_SOURCE_LOCATION (node->decl),
+   "%qD is not eligible for %"
+   " because of attribute %",
+   node->decl);
+}
+
+  /* We can't, and don't want to vectorize the watermark and other
+ strub-introduced parms.  */
+  if (lookup_attribute ("simd", DECL_ATTRIBUTES (node->decl)))
+{
+  result = false;
+
+  if (!report)
+   return result;
+
+  sorry_at (DECL_SOURCE_LOCATION (node->decl),
+   "%qD is not eligible for %"
+   " because of attribute %",
+   node->decl);
+}
+
+  return result;
+}
+
+/* Return TRUE iff NODE is eligible for at-calls strub, and optionally REPORT
+   the reasons for ineligibility.  Besides general non-eligibility for
+   strub-enabled modes, at-calls rules out calling builtin apply_args.  */
+
+static bool
+can_strub_at_calls_p (cgraph_node *node, bool report = false)
+{
+  bool result = !report || can_strub_p (node, report);
+
+  if (!result && !report)
+return result;
+
+  return !calls_builtin_apply_args_p (node, report);
+}
+
+/* Return TRUE iff the called function (pointer or, if available,
+   decl) undergoes a significant type conversion for the call.  Strub
+   mode changes between function types, and other non-useless type
+   conversions, are regarded as significant.  When the function type
+   is overridden, the effective strub mode for the call is that of the
+   call fntype, rather than that of the pointer or of the decl.
+   Functions called with type overrides cannot undergo type changes;
+   it's as if their address was taken, so they're considered
+   non-viable for implicit at-calls strub mode.  */
+
+static inline bool
+strub_call_fntype_override_p (const gcall *gs)
+{
+  if (gimple_call_internal_p (gs))
+return false;
+  tree fn_type = TREE_TYPE (TREE_TYPE (gimple_call_fn (gs)));
+  if (tree decl = gimple_call_fndecl (gs))
+fn_type = TREE_TYPE (decl);
+
+  /* We do NOT want to take the mode from the decl here.  This
+ function is used to tell whether we can change the strub mode of
+ a function, and whether the effective mode for the call is to be
+ taken from the decl or from an overrider type.  When the strub
+ mode is explicitly declared, or overridden with a type cast, the
+ difference will be noticed in function types.  However, if the
+ strub mode is implicit due to e.g. strub variables or -fstrub=*
+ command-line flags, we will adjust call types along with function
+ types.  In either case, the presence of type or strub mode
+ overriders in calls will prevent a function from having its strub
+ modes changed in ways that would imply type changes, but taking
+ strub modes from decls would defeat this, since we set strub
+ modes and then call this function to tell whether the original
+ type was overridden to decide whether to adjust the call.  We
+ need the answer to be about the type, not the decl.  */
+  enum strub_mode mode = get_strub_mode_from_type (fn_type);
+  return (get_strub_mode_from_type (gs->u.fntype) != mode
+ || !useless_type_conversion_p (gs->u.fntype, fn_type));
+}
+
+/* Return TRUE iff NODE is called dir

[PATCH v2 10/10] Introduce strub: strub pass

2022-07-28 Thread Alexandre Oliva via Gcc-patches


This final fragment of ipa-strub.cc adds the strub pass, that
implements the needed function interface changes and adds calls to the
strub builtins.

+/* Define a pass to introduce strub transformations.  */
+const pass_data pass_data_ipa_strub = {
+  SIMPLE_IPA_PASS,
+  "strub",
+  OPTGROUP_NONE,
+  TV_NONE,
+  PROP_cfg | PROP_ssa, // properties_required
+  0,   // properties_provided
+  0,   // properties_destroyed
+  0,   // properties_start
+  TODO_update_ssa
+  | TODO_cleanup_cfg
+  | TODO_rebuild_cgraph_edges
+  | TODO_verify_il, // properties_finish
+};
+
+class pass_ipa_strub : public simple_ipa_opt_pass
+{
+public:
+  pass_ipa_strub (gcc::context *ctxt)
+: simple_ipa_opt_pass (pass_data_ipa_strub, ctxt)
+  {}
+  opt_pass *clone () { return new pass_ipa_strub (m_ctxt); }
+  virtual bool gate (function *) { return flag_strub && !seen_error (); }
+  virtual unsigned int execute (function *);
+
+  /* Define on demand and cache some types we use often.  */
+#define DEF_TYPE(NAME, INIT)   \
+  static inline tree get_ ## NAME () { \
+static tree type = NULL_TREE;  \
+if (!type) \
+  type = (INIT);   \
+return type;   \
+  }
+
+  /* Use a distinct ptr_type_node to denote the watermark, so that we can
+ recognize it in arg lists and avoid modifying types twice.  */
+  DEF_TYPE (wmt, build_variant_type_copy (ptr_type_node))
+
+  DEF_TYPE (pwmt, build_reference_type (get_wmt ()))
+
+  DEF_TYPE (qpwmt,
+   build_qualified_type (get_pwmt (),
+ TYPE_QUAL_RESTRICT
+ /* | TYPE_QUAL_CONST */))
+
+  DEF_TYPE (qptr,
+   build_qualified_type (ptr_type_node,
+ TYPE_QUAL_RESTRICT
+ | TYPE_QUAL_CONST))
+
+  DEF_TYPE (qpvalst,
+   build_qualified_type (build_reference_type
+ (va_list_type_node),
+ TYPE_QUAL_RESTRICT
+ /* | TYPE_QUAL_CONST */))
+
+#undef DEF_TYPE
+
+  /* Define non-strub builtins on demand.  */
+#define DEF_NM_BUILTIN(NAME, CODE, FNTYPELIST) \
+  static tree get_ ## NAME () {\
+tree decl = builtin_decl_explicit (CODE);  \
+if (!decl) \
+  {\
+   tree type = build_function_type_list FNTYPELIST;\
+   decl = add_builtin_function \
+ ("__builtin_" #NAME,  \
+  type, CODE, BUILT_IN_NORMAL, \
+  NULL, NULL); \
+   TREE_NOTHROW (decl) = true; \
+   set_builtin_decl ((CODE), decl, true);  \
+  }\
+return decl;   \
+  }
+
+  DEF_NM_BUILTIN (stack_address,
+ BUILT_IN_STACK_ADDRESS,
+ (ptr_type_node, NULL))
+
+#undef DEF_NM_BUILTIN
+
+  /* Define strub builtins on demand.  */
+#define DEF_SS_BUILTIN(NAME, FNSPEC, CODE, FNTYPELIST) \
+  static tree get_ ## NAME () {\
+tree decl = builtin_decl_explicit (CODE);  \
+if (!decl) \
+  {\
+   tree type = build_function_type_list FNTYPELIST;\
+   tree attrs = NULL;  \
+   if (FNSPEC && HAVE_ATTR_FNSPEC) \
+ attrs = tree_cons (get_identifier ("fn spec"),\
+build_tree_list\
+(NULL_TREE,\
+ build_string (strlen (FNSPEC),\
+   (FNSPEC))), \
+attrs);\
+   decl = add_builtin_function_ext_scope   \
+ ("__builtin___strub_" #NAME,  \
+  type, CODE, BUILT_IN_NORMAL, \
+  "__strub_" #NAME, attrs);\
+   TREE_NOTHROW (decl) = true; \
+   set_builtin_decl ((CODE), decl, true);  \
+  }\
+return decl;   \
+  }
+
+  DEF_SS_BUILTIN (enter, ". Ot",
+ BUILT_IN___STRUB_ENTER,
+ (void_type_node, get_qpwmt (), NULL))
+  DEF_SS

Re: [PATCH v2 00/10] Introduce strub: machine-independent stack scrubbing

2022-07-28 Thread Alexandre Oliva via Gcc-patches
On Jul 29, 2022, Alexandre Oliva  wrote:

> This patch adds the strub attribute for function and variable types,
> command-line options, passes and adjustments to implement it,
> documentation, and tests.

The entire patch, and the patchlets used for testing, are available from
the GCC git repo, branch refs/users/aoliva/heads/strub:

e9d1e252e0bcd silence warnings
4a93638ee91b1 enable strub for all viable functions by default, for testing
29e98f10c5faa Introduce strub: machine-independent stack scrubbing

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] configure: respect --with-build-time-tools [PR43301]

2022-08-01 Thread Alexandre Oliva via Gcc-patches
Hello, Eric,

Thanks for looking into this.

On Aug  1, 2022, Eric Gallager via Gcc-patches  wrote:

>> This just reassigns the value that was retrieved a couple of lines
>> above from the very same variable.

> Oh, ok, so I guess this isn't necessary after all?

Yeah, I don't see how this patch could make any difference as to the
reported problem.

> In which case we can just close 43301 as INVALID then?

AFAICT, with_build_time_tools is dealt with in the top level configure,
setting up *_FOR_TARGET after searching for the tool names in the
specified location.

However, there's a potentially confusing consequence of the current
code: gcc/configure looks for ./as$build_exeext in the build tree, and
uses that without overwriting it if found, so if an earlier configure
run created an 'as' script, a reconfigure will just use it, without
creating the file again, even if it would have changed
ORIGINAL_AS_FOR_TARGET in it.

I suppose if the patch was tested by the original submitter on a clean
build tree, so it would *appear* to have made a difference in fixing the
problem, while it was actually just a no-op, and the apparent fix was a
consequence of the clean build tree.

So, the patch is not useful, but we may want to avoid the confusing
scenario somehow.

I suppose the point of not creating such a tiny script again is not to
avoid unnecessary rebuilding of dependencies (I don't even see how
dependencies on the script would come into play), so creating it again
wouldn't hurt.  However, we wish to avoid overwriting an assembler
copied into the build tree for use by gcc during the build.  Perhaps:

-elif test -x as$build_exeext; then
+elif test -x as$build_exeext \
+   && { test "x$build_exeext" != "x" \
+|| test "x`grep '^# Invoke as, ld or nm from the build tree' \
+ as`" = "x"; }; then

WDYT?

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] configure: respect --with-build-time-tools [PR43301]

2022-08-02 Thread Alexandre Oliva via Gcc-patches
On Aug  2, 2022, Eric Gallager  wrote:

> On Tue, Aug 2, 2022 at 1:24 AM Alexandre Oliva  wrote:

>> -elif test -x as$build_exeext; then
>> +elif test -x as$build_exeext \
>> +   && { test "x$build_exeext" != "x" \
>> +|| test "x`grep '^# Invoke as, ld or nm from the build tree' \
>> + as`" = "x"; }; then
>> 
>> WDYT?

> Hi, thanks for the feedback; I'm a bit confused, though: where exactly
> would this proposed change go?

gcc/configure.ac, just before:

# Build using assembler in the current directory.
gcc_cv_as=./as$build_exeext

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] configure: respect --with-build-time-tools [PR43301]

2022-08-04 Thread Alexandre Oliva via Gcc-patches
On Aug  3, 2022, Eric Gallager  wrote:

> OK, after reviewing the surrounding code, I think it makes sense; do
> you want to commit it, or should I?

Please proceed, if you have the cycles to give it a round of meaningful
testing (as in, including reconfigure with configure-generated as, and
also with external as in place).

Adjusting the analogous test patterns covering the other tools and
generated scripts would surely be welcome as well ;-)

Thanks!

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] [PR83782] i386 PIE: avoid @GOTOFF for ifuncs and their aliases

2022-08-08 Thread Alexandre Oliva via Gcc-patches
On Aug  1, 2022, "H.J. Lu"  wrote:

> On Thu, Jul 28, 2022 at 9:31 AM H.J. Lu  wrote:

>> > You may also need to do something like this bit for mvc10.c on ia32 PIE.
>> > Because the ifunc is called through an alias, AFAICT we don't even
>> > notice that the call target is (an alias to) an ifunc.  GCC's
>> > gotoff_operand predicate accepts it, but binutils (the linker, IIRC)
>> > then rejects that reference, because the named symbol is an alias to an
>> > ifunc.
>> 
>> Yes, this change is needed.

> I think this fix should be applied to default_binds_local_p_3:

I was concerned that other tests might require such alias pointer
chasing, and figured we might be better off propagating the flag setting
to aliases.


[PR83782] ifunc: back-propagate ifunc_resolver to aliases

gcc.target/i386/mvc10.c fails with -fPIE on ia32 because we omit the
@PLT mark when calling an alias to an indirect function.  Such aliases
aren't marked as ifunc_resolvers in the cgraph, so the test that would
have forced the PLT call fails.

I've arranged for ifunc_resolver to be back-propagated to aliases, and
relaxed the test that required the ifunc attribute to be attached to
directly the decl, rather than taken from an aliased decl, when the
ifunc_resolver bit is set.

Regstrapped on x86_64-linux-gnu, also tested mvc10.c with -m32 -fPIE.
Ok to install?


for  gcc/ChangeLog

PR target/83782
* cgraph.h (symtab_node::set_ifunc_resolver): New, overloaded.
Back-propagate flag to aliases.
* cgraph.cc (cgraph_node::create): Use set_ifunc_resolver.
(cgraph_node::create_alias): Likewise.
* lto-cgraph.cc (input_node): Likewise.
* multiple_target.cc (create_dispatcher_calls): Propagate to
aliases when redirecting them.
* symtab.cc (symtab_node::verify_base): Accept ifunc_resolver
set in an alias to another ifunc_resolver nodes.
(symtab_node::resolve_alias): Propagate ifunc_resolver from
resolved target to alias.
* varasm.cc (do_assemble_alias): Checking for the attribute.
---
 gcc/cgraph.cc  |4 ++--
 gcc/cgraph.h   |   13 +
 gcc/lto-cgraph.cc  |2 +-
 gcc/multiple_target.cc |2 ++
 gcc/symtab.cc  |   15 ++-
 gcc/varasm.cc  |5 -
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 8d6ed38efa25d..699f2c20defa4 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -518,7 +518,7 @@ cgraph_node::create (tree decl)
 }
 
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
-node->ifunc_resolver = true;
+node->set_ifunc_resolver ();
 
   node->register_symbol ();
   maybe_record_nested_function (node);
@@ -576,7 +576,7 @@ cgraph_node::create_alias (tree alias, tree target)
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
 alias_node->transparent_alias = alias_node->weakref = true;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
-alias_node->ifunc_resolver = true;
+alias_node->set_ifunc_resolver ();
   return alias_node;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 4be67e3cea906..9468b8a4e3662 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -467,6 +467,19 @@ public:
 return decl->decl_with_vis.symtab_node;
   }
 
+  /* Worked for the nonstatic set_ifunc_resolver, to vback-propagate
+ ifunc_resolver in the alias chain.  */
+  static bool set_ifunc_resolver (symtab_node *n, void * = NULL)
+  {
+n->ifunc_resolver = true;
+return false;
+  }
+
+  /* Set the ifunc_resolver bit in this node and in any aliases thereof.  */
+  void set_ifunc_resolver () {
+call_for_symbol_and_aliases (set_ifunc_resolver, NULL, true);
+  }
+
   /* Try to find a symtab node for declaration DECL and if it does not
  exist or if it corresponds to an inline clone, create a new one.  */
   static inline symtab_node * get_create (tree node);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 6d9c36ea8b67f..3d8ade1f9f042 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1280,7 +1280,7 @@ input_node (struct lto_file_decl_data *file_data,
   node = symtab->create_empty ();
   node->decl = fn_decl;
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
-   node->ifunc_resolver = 1;
+   node->set_ifunc_resolver ();
   node->register_symbol ();
 }
 
diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
index 3e2d26882c8e9..97801a4cc9ea9 100644
--- a/gcc/multiple_target.cc
+++ b/gcc/multiple_target.cc
@@ -160,6 +160,8 @@ create_dispatcher_calls (struct cgraph_node *node)
  source->create_reference (inode, IPA_REF_ALIAS);
  if (inode->get_comdat_group ())
source->add_to_same_comdat_group (inode);
+ if (!source->ifunc_resolver)
+   source->set_ifunc_resolver ();
}
  else
gcc_unreachable ();
diff --git a/gcc/symtab.cc b/gcc/symtab.

Re: [PATCH v2 02/10] Introduce strub: torture tests for C and C++

2022-08-09 Thread Alexandre Oliva via Gcc-patches
Ping?
https://gcc.gnu.org/pipermail/gcc-patches/2022-July/599011.html

Here's an incremental patch for some of these tests, that avoids some
relatively rare spurious failures.


diff --git a/gcc/testsuite/c-c++-common/torture/strub-run1.c 
b/gcc/testsuite/c-c++-common/torture/strub-run1.c
index b24a1c7a345fa..7458b3fb54da5 100644
--- a/gcc/testsuite/c-c++-common/torture/strub-run1.c
+++ b/gcc/testsuite/c-c++-common/torture/strub-run1.c
@@ -80,11 +80,16 @@ internal ()
 
 int main ()
 {
-  if (!look_for_string (callable ()))
-__builtin_abort ();
-  if (look_for_string (at_calls ()))
-__builtin_abort ();
-  if (look_for_string (internal ()))
-__builtin_abort ();
+  /* Since these test check stack contents above the top of the stack, an
+ unexpected asynchronous signal or interrupt might overwrite the bits we
+ expect to find and cause spurious fails.  Tolerate one such overall
+ spurious fail by retrying.  */
+  int i = 1;
+  while (!look_for_string (callable ()))
+if (!i--) __builtin_abort ();
+  while (look_for_string (at_calls ()))
+if (!i--) __builtin_abort ();
+  while (look_for_string (internal ()))
+if (!i--) __builtin_abort ();
   __builtin_exit (0);
 }
diff --git a/gcc/testsuite/c-c++-common/torture/strub-run2.c 
b/gcc/testsuite/c-c++-common/torture/strub-run2.c
index 1df2ffe2fe58c..5d60a7775f4bb 100644
--- a/gcc/testsuite/c-c++-common/torture/strub-run2.c
+++ b/gcc/testsuite/c-c++-common/torture/strub-run2.c
@@ -69,11 +69,16 @@ internal ()
 
 int main ()
 {
-  if (!look_for_string (callable ()))
-__builtin_abort ();
-  if (look_for_string (at_calls ()))
-__builtin_abort ();
-  if (look_for_string (internal ()))
-__builtin_abort ();
+  /* Since these test check stack contents above the top of the stack, an
+ unexpected asynchronous signal or interrupt might overwrite the bits we
+ expect to find and cause spurious fails.  Tolerate one such overall
+ spurious fail by retrying.  */
+  int i = 1;
+  while (!look_for_string (callable ()))
+if (!i--) __builtin_abort ();
+  while (look_for_string (at_calls ()))
+if (!i--) __builtin_abort ();
+  while (look_for_string (internal ()))
+if (!i--) __builtin_abort ();
   __builtin_exit (0);
 }
diff --git a/gcc/testsuite/c-c++-common/torture/strub-run3.c 
b/gcc/testsuite/c-c++-common/torture/strub-run3.c
index afbc2cc9ab484..c2ad710858e87 100644
--- a/gcc/testsuite/c-c++-common/torture/strub-run3.c
+++ b/gcc/testsuite/c-c++-common/torture/strub-run3.c
@@ -65,11 +65,16 @@ internal ()
 
 int main ()
 {
-  if (!look_for_string (callable ()))
-__builtin_abort ();
-  if (look_for_string (at_calls ()))
-__builtin_abort ();
-  if (look_for_string (internal ()))
-__builtin_abort ();
+  /* Since these test check stack contents above the top of the stack, an
+ unexpected asynchronous signal or interrupt might overwrite the bits we
+ expect to find and cause spurious fails.  Tolerate one such overall
+ spurious fail by retrying.  */
+  int i = 1;
+  while (!look_for_string (callable ()))
+if (!i--) __builtin_abort ();
+  while (look_for_string (at_calls ()))
+if (!i--) __builtin_abort ();
+  while (look_for_string (internal ()))
+if (!i--) __builtin_abort ();
   __builtin_exit (0);
 }
diff --git a/gcc/testsuite/c-c++-common/torture/strub-run4.c 
b/gcc/testsuite/c-c++-common/torture/strub-run4.c
index 5300f1d330b87..3b36b8e5d68ef 100644
--- a/gcc/testsuite/c-c++-common/torture/strub-run4.c
+++ b/gcc/testsuite/c-c++-common/torture/strub-run4.c
@@ -95,7 +95,12 @@ internal ()
 int __attribute__ ((__strub__ ("disabled")))
 main ()
 {
-  if (look_for_string (internal ()))
-__builtin_abort ();
+  /* Since these test check stack contents above the top of the stack, an
+ unexpected asynchronous signal or interrupt might overwrite the bits we
+ expect to find and cause spurious fails.  Tolerate one such overall
+ spurious fail by retrying.  */
+  int i = 1;
+  while (look_for_string (internal ()))
+if (!i--) __builtin_abort ();
   __builtin_exit (0);
 }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2022-08-09 Thread Alexandre Oliva via Gcc-patches
Ping? (sorry, Joseph, I failed to Cc: you last time)

https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598034.html
https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598084.html

On Jul  7, 2022, Alexandre Oliva  wrote:

> for  gcc/c-family/ChangeLog

>   * c-attribs.cc (c_common_attribute_table): Add hardbool.
>   (handle_hardbool_attribute): New.
>   (type_valid_for_vector_size): Reject hardbool.
>   * c-common.cc (convert_and_check): Skip warnings for convert
>   and check for hardbool.
>   (c_hardbool_type_attr_1): New.
>   * c-common.h (c_hardbool_type_attr): New.

> for  gcc/c/ChangeLog

>   * c-typeck.cc (convert_lvalue_to_rvalue): Decay hardbools.
>   * c-convert.cc (convert): Convert to hardbool through
>   truthvalue.
>   * c-decl.cc (check_bitfield_type_and_width): Skip enumeral
>   truncation warnings for hardbool.
>   (finish_struct): Propagate hardbool attribute to bitfield
>   types.
>   (digest_init): Convert to hardbool.

> for  gcc/ChangeLog

>   * doc/extend.texi (hardbool): New type attribute.

> for  gcc/testsuite/ChangeLog

>   * gcc.dg/hardbool-err.c: New.
>   * gcc.dg/hardbool-trap.c: New.
>   * gcc.dg/hardbool.c: New.
>   * gcc.dg/hardbool-s.c: New.
>   * gcc.dg/hardbool-us.c: New.
>   * gcc.dg/hardbool-i.c: New.
>   * gcc.dg/hardbool-ul.c: New.
>   * gcc.dg/hardbool-ll.c: New.
>   * gcc.dg/hardbool-5a.c: New.
>   * gcc.dg/hardbool-s-5a.c: New.
>   * gcc.dg/hardbool-us-5a.c: New.
>   * gcc.dg/hardbool-i-5a.c: New.
>   * gcc.dg/hardbool-ul-5a.c: New.
>   * gcc.dg/hardbool-ll-5a.c: New.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] i386 PIE: accept @GOTOFF in load/store multi base address

2022-08-09 Thread Alexandre Oliva via Gcc-patches
Ping?

https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598872.html

On Jul 27, 2022, Alexandre Oliva  wrote:

> for  gcc/ChangeLog

>   * config/i386/i386.cc (symbolic_base_address_p,
>   base_address_p): New, factored out from...
>   (extract_base_offset_in_addr): ... here and extended to
>   recognize REG+GOTOFF, as in gcc.target/i386/sse2-load-multi.c
>   and sse2-store-multi.c with PIE enabled by default.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] i386 testsuite: cope with --enable-default-pie

2022-08-09 Thread Alexandre Oliva via Gcc-patches
Ping?

https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598276.html

On Jul 27, 2022, Alexandre Oliva  wrote:

> for  gcc/testsuite/ChangeLog

>   * g++.dg/abi/anon1.C: Disable pie on ia32.
>   * g++.dg/abi/anon4.C: Likewise.
>   * g++.dg/cpp0x/initlist-const1.C: Likewise.
>   * g++.dg/no-stack-protector-attr-3.C: Likewise.
>   * g++.dg/stackprotectexplicit2.C: Likewise.
>   * g++.dg/pr71694.C: Likewise.
>   * gcc.dg/pr102892-1.c: Likewise.
>   * gcc.dg/sibcall-11.c: Likewise.
>   * gcc.dg/torture/builtin-self.c: Likewise.
>   * gcc.target/i386/avx2-dest-false-dep-for-glc.c: Likewise.
>   * gcc.target/i386/avx512bf16-cvtsbh2ss-1.c: Likewise.
>   * gcc.target/i386/avx512f-broadcast-pr87767-1.c: Likewise.
>   * gcc.target/i386/avx512f-broadcast-pr87767-3.c: Likewise.
>   * gcc.target/i386/avx512f-broadcast-pr87767-5.c: Likewise.
>   * gcc.target/i386/avx512f-broadcast-pr87767-7.c: Likewise.
>   * gcc.target/i386/avx512fp16-broadcast-1.c: Likewise.
>   * gcc.target/i386/avx512fp16-pr101846.c: Likewise.
>   * gcc.target/i386/avx512vl-broadcast-pr87767-1.c: Likewise.
>   * gcc.target/i386/avx512vl-broadcast-pr87767-3.c: Likewise.
>   * gcc.target/i386/avx512vl-broadcast-pr87767-5.c: Likewise.
>   * gcc.target/i386/pr100865-2.c: Likewise.
>   * gcc.target/i386/pr100865-3.c: Likewise.
>   * gcc.target/i386/pr100865-4a.c: Likewise.
>   * gcc.target/i386/pr100865-4b.c: Likewise.
>   * gcc.target/i386/pr100865-5a.c: Likewise.
>   * gcc.target/i386/pr100865-5b.c: Likewise.
>   * gcc.target/i386/pr100865-6a.c: Likewise.
>   * gcc.target/i386/pr100865-6b.c: Likewise.
>   * gcc.target/i386/pr100865-6c.c: Likewise.
>   * gcc.target/i386/pr100865-7b.c: Likewise.
>   * gcc.target/i386/pr101796-1.c: Likewise.
>   * gcc.target/i386/pr101846-2.c: Likewise.
>   * gcc.target/i386/pr101989-broadcast-1.c: Likewise.
>   * gcc.target/i386/pr102021.c: Likewise.
>   * gcc.target/i386/pr90773-17.c: Likewise.
>   * gcc.target/i386/pr54855-3.c: Likewise.
>   * gcc.target/i386/pr54855-7.c: Likewise.
>   * gcc.target/i386/pr15184-1.c: Likewise.
>   * gcc.target/i386/pr15184-2.c: Likewise.
>   * gcc.target/i386/pr27971.c: Likewise.
>   * gcc.target/i386/pr70263-2.c: Likewise.
>   * gcc.target/i386/pr78035.c: Likewise.
>   * gcc.target/i386/pr81736-5.c: Likewise.
>   * gcc.target/i386/pr81736-7.c: Likewise.
>   * gcc.target/i386/pr85620-6.c: Likewise.
>   * gcc.target/i386/pr85667-6.c: Likewise.
>   * gcc.target/i386/pr93492-5.c: Likewise.
>   * gcc.target/i386/pr96539.c: Likewise.
>   PR target/81708 (%gs:my_guard)
>   * gcc.target/i386/stack-prot-sym.c: Likewise.
>   * g++.dg/init/static-cdtor1.C: Add alternate patterns for PIC.
>   * gcc.target/i386/avx512fp16-vcvtsh2si-1a.c: Extend patterns
>   for PIC/PIE register allocation.
>   * gcc.target/i386/pr100704-3.c: Likewise.
>   * gcc.target/i386/avx512fp16-vcvtsh2usi-1a.c: Likewise.
>   * gcc.target/i386/avx512fp16-vcvttsh2si-1a.c: Likewise.
>   * gcc.target/i386/avx512fp16-vcvttsh2usi-1a.c: Likewise.
>   * gcc.target/i386/avx512fp16-vmovsh-1a.c: Likewise.
>   * gcc.target/i386/interrupt-11.c: Likewise, allowing for
>   preservation of the PIC register.
>   * gcc.target/i386/interrupt-12.c: Likewise.
>   * gcc.target/i386/interrupt-13.c: Likewise.
>   * gcc.target/i386/interrupt-15.c: Likewise.
>   * gcc.target/i386/interrupt-16.c: Likewise.
>   * gcc.target/i386/interrupt-17.c: Likewise.
>   * gcc.target/i386/interrupt-8.c: Likewise.
>   * gcc.target/i386/cet-sjlj-6a.c: Combine patterns from
>   previous change.
>   * gcc.target/i386/cet-sjlj-6b.c: Likewise.
>   * gcc.target/i386/pad-10.c: Accept insns in get_pc_thunk.
>   * gcc.target/i386/pr70321.c: Likewise.
>   * gcc.target/i386/pr81563.c: Likewise.
>   * gcc.target/i386/pr84278.c: Likewise.
>   * gcc.target/i386/pr90773-2.c: Likewise, plus extra loads from
>   the GOT.
>   * gcc.target/i386/pr90773-3.c: Likewise.
>   * gcc.target/i386/pr94913-2.c: Accept additional PIC insns.
>   * gcc.target/i386/stack-check-17.c: Likewise.
>   * gcc.target/i386/stack-check-12.c: Do not require dummy stack
>   probing obviated with PIC.
>   * gcc.target/i386/pr95126-m32-1.c: Expect missed optimization
>   with PIC.
>   * gcc.target/i386/pr95126-m32-2.c: Likewise.
>   * gcc.target/i386/pr95852-2.c: Accept different optimization
>   with PIC.
>   * gcc.target/i386/pr95852-4.c: Likewise.


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] i386 testsuite: cope with --enable-default-pie

2022-08-09 Thread Alexandre Oliva via Gcc-patches
On Aug  9, 2022, Alexandre Oliva  wrote:

> Ping?
> https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598276.html

Oops, sorry, I linked to the wrong patch.  This is the one I meant to ping:

https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598874.html

> On Jul 27, 2022, Alexandre Oliva  wrote:

>> for  gcc/testsuite/ChangeLog

>> * g++.dg/abi/anon1.C: Disable pie on ia32.
>> * g++.dg/abi/anon4.C: Likewise.
>> * g++.dg/cpp0x/initlist-const1.C: Likewise.
>> * g++.dg/no-stack-protector-attr-3.C: Likewise.
>> * g++.dg/stackprotectexplicit2.C: Likewise.
>> * g++.dg/pr71694.C: Likewise.
>> * gcc.dg/pr102892-1.c: Likewise.
>> * gcc.dg/sibcall-11.c: Likewise.
>> * gcc.dg/torture/builtin-self.c: Likewise.
>> * gcc.target/i386/avx2-dest-false-dep-for-glc.c: Likewise.
>> * gcc.target/i386/avx512bf16-cvtsbh2ss-1.c: Likewise.
>> * gcc.target/i386/avx512f-broadcast-pr87767-1.c: Likewise.
>> * gcc.target/i386/avx512f-broadcast-pr87767-3.c: Likewise.
>> * gcc.target/i386/avx512f-broadcast-pr87767-5.c: Likewise.
>> * gcc.target/i386/avx512f-broadcast-pr87767-7.c: Likewise.
>> * gcc.target/i386/avx512fp16-broadcast-1.c: Likewise.
>> * gcc.target/i386/avx512fp16-pr101846.c: Likewise.
>> * gcc.target/i386/avx512vl-broadcast-pr87767-1.c: Likewise.
>> * gcc.target/i386/avx512vl-broadcast-pr87767-3.c: Likewise.
>> * gcc.target/i386/avx512vl-broadcast-pr87767-5.c: Likewise.
>> * gcc.target/i386/pr100865-2.c: Likewise.
>> * gcc.target/i386/pr100865-3.c: Likewise.
>> * gcc.target/i386/pr100865-4a.c: Likewise.
>> * gcc.target/i386/pr100865-4b.c: Likewise.
>> * gcc.target/i386/pr100865-5a.c: Likewise.
>> * gcc.target/i386/pr100865-5b.c: Likewise.
>> * gcc.target/i386/pr100865-6a.c: Likewise.
>> * gcc.target/i386/pr100865-6b.c: Likewise.
>> * gcc.target/i386/pr100865-6c.c: Likewise.
>> * gcc.target/i386/pr100865-7b.c: Likewise.
>> * gcc.target/i386/pr101796-1.c: Likewise.
>> * gcc.target/i386/pr101846-2.c: Likewise.
>> * gcc.target/i386/pr101989-broadcast-1.c: Likewise.
>> * gcc.target/i386/pr102021.c: Likewise.
>> * gcc.target/i386/pr90773-17.c: Likewise.
>> * gcc.target/i386/pr54855-3.c: Likewise.
>> * gcc.target/i386/pr54855-7.c: Likewise.
>> * gcc.target/i386/pr15184-1.c: Likewise.
>> * gcc.target/i386/pr15184-2.c: Likewise.
>> * gcc.target/i386/pr27971.c: Likewise.
>> * gcc.target/i386/pr70263-2.c: Likewise.
>> * gcc.target/i386/pr78035.c: Likewise.
>> * gcc.target/i386/pr81736-5.c: Likewise.
>> * gcc.target/i386/pr81736-7.c: Likewise.
>> * gcc.target/i386/pr85620-6.c: Likewise.
>> * gcc.target/i386/pr85667-6.c: Likewise.
>> * gcc.target/i386/pr93492-5.c: Likewise.
>> * gcc.target/i386/pr96539.c: Likewise.
>> PR target/81708 (%gs:my_guard)
>> * gcc.target/i386/stack-prot-sym.c: Likewise.
>> * g++.dg/init/static-cdtor1.C: Add alternate patterns for PIC.
>> * gcc.target/i386/avx512fp16-vcvtsh2si-1a.c: Extend patterns
>> for PIC/PIE register allocation.
>> * gcc.target/i386/pr100704-3.c: Likewise.
>> * gcc.target/i386/avx512fp16-vcvtsh2usi-1a.c: Likewise.
>> * gcc.target/i386/avx512fp16-vcvttsh2si-1a.c: Likewise.
>> * gcc.target/i386/avx512fp16-vcvttsh2usi-1a.c: Likewise.
>> * gcc.target/i386/avx512fp16-vmovsh-1a.c: Likewise.
>> * gcc.target/i386/interrupt-11.c: Likewise, allowing for
>> preservation of the PIC register.
>> * gcc.target/i386/interrupt-12.c: Likewise.
>> * gcc.target/i386/interrupt-13.c: Likewise.
>> * gcc.target/i386/interrupt-15.c: Likewise.
>> * gcc.target/i386/interrupt-16.c: Likewise.
>> * gcc.target/i386/interrupt-17.c: Likewise.
>> * gcc.target/i386/interrupt-8.c: Likewise.
>> * gcc.target/i386/cet-sjlj-6a.c: Combine patterns from
>> previous change.
>> * gcc.target/i386/cet-sjlj-6b.c: Likewise.
>> * gcc.target/i386/pad-10.c: Accept insns in get_pc_thunk.
>> * gcc.target/i386/pr70321.c: Likewise.
>> * gcc.target/i386/pr81563.c: Likewise.
>> * gcc.target/i386/pr84278.c: Likewise.
>> * gcc.target/i386/pr90773-2.c: Likewise, plus extra loads from
>> the GOT.
>> * gcc.target/i386/pr90773-3.c: Likewise.
>> * gcc.target/i386/pr94913-2.c: Accept additional PIC insns.
>> * gcc.target/i386/stack-check-17.c: Likewise.
>> * gcc.target/i386/stack-check-12.c: Do not require dummy stack
>> probing obviated with PIC.
>> * gcc.target/i386/pr95126-m32-1.c: Expect missed optimization
>> with PIC.
>> * gcc.target/i386/pr95126-m32-2.c: Likewise.
>> * gcc.target/i386/pr95852-2.c: Accept different optimization
>> with PIC.
>> * gcc.target/i386/pr95852-4.c: Likewise.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Introduce -msmp to select /lib_smp/ on ppc-vx6

2023-08-03 Thread Alexandre Oliva via Gcc-patches


The .spec files used for linking on ppc-vx6, when the rtp-smp runtime
is selected, add -L flags for /lib_smp/ and /lib/.

There was a problem, though: although /lib_smp/ and /lib/ were to be
searched in this order, and the specs files do that correctly, the
compiler would search /lib/ first regardless, because
STARTFILE_PREFIX_SPEC said so, and specs files cannot override that.

With this patch, we arrange for the presence of -msmp to affect
STARTFILE_PREFIX_SPEC, so that the compiler searches /lib_smp/ rather
than /lib/ for crt files.  A separate patch for GNAT ensures that when
the rtp-smp runtime is selected, -msmp is passed to the compiler
driver for linking, along with the --specs flags.

Preapproved by Olivier Hainque.  I'm checking this in.


for  gcc/ChangeLog

* config/vxworks-smp.opt: New.  Introduce -msmp.
* config.gcc: Enable it on powerpc* vxworks prior to 7r*.
* config/rs6000/vxworks.h (STARTFILE_PREFIX_SPEC): Choose
lib_smp when -msmp is present in the command line.
* doc/invoke.texi: Document it.
---
 gcc/config.gcc  |2 +-
 gcc/config/rs6000/vxworks.h |2 +-
 gcc/config/vxworks-smp.opt  |   25 +
 gcc/doc/invoke.texi |9 -
 4 files changed, 35 insertions(+), 3 deletions(-)
 create mode 100644 gcc/config/vxworks-smp.opt

diff --git a/gcc/config.gcc b/gcc/config.gcc
index eba69a463be0d..7438e0be4a2c0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3046,7 +3046,7 @@ powerpc*-wrs-vxworks7r*)
 powerpc-wrs-vxworks*)
tm_file="${tm_file} elfos.h gnu-user.h freebsd-spec.h rs6000/sysv4.h"
tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm 
rs6000/t-vxworks"
-   extra_options="${extra_options} rs6000/sysv4.opt"
+   extra_options="${extra_options} rs6000/sysv4.opt vxworks-smp.opt"
extra_headers="${extra_headers} ppc-asm.h"
case ${target} in
   *-vxworksmils*)
diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h
index 690e92439b94f..f38b4bd1dff2f 100644
--- a/gcc/config/rs6000/vxworks.h
+++ b/gcc/config/rs6000/vxworks.h
@@ -206,7 +206,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef  STARTFILE_PREFIX_SPEC
 #define STARTFILE_PREFIX_SPEC  \
- "%{mrtp:%{!shared:/lib/usr/lib/ppc/PPC32/common}}"
+ "%{mrtp:%{!shared:/lib%{msmp:_smp}/usr/lib/ppc/PPC32/common}}"
 
 /* For aggregates passing, use the same, consistent ABI as Linux.  */
 #define AGGREGATE_PADDING_FIXED 0
diff --git a/gcc/config/vxworks-smp.opt b/gcc/config/vxworks-smp.opt
new file mode 100644
index 0..5ef1521634ab5
--- /dev/null
+++ b/gcc/config/vxworks-smp.opt
@@ -0,0 +1,25 @@
+; Options for VxWorks configurations where smp/!smp variants of the
+; system libraries are installed in separate locations.
+;
+; Copyright (C) 2023 Free Software Foundation, Inc.
+; Contributed by AdaCore.
+;
+; 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
+; .
+
+msmp
+Driver Target RejectNegative
+Select VxWorks SMP C runtimes for linking.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 104766f446d11..adb10a3528dae 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1403,7 +1403,7 @@ See RS/6000 and PowerPC Options.
 -mpointer-size=@var{size}}
 
 @emph{VxWorks Options}
-@gccoptlist{-mrtp  -non-static  -Bstatic  -Bdynamic
+@gccoptlist{-mrtp  -msmp  -non-static  -Bstatic  -Bdynamic
 -Xbind-lazy  -Xbind-now}
 
 @emph{x86 Options}
@@ -32442,6 +32442,13 @@ GCC can generate code for both VxWorks kernels and 
real time processes
 (RTPs).  This option switches from the former to the latter.  It also
 defines the preprocessor macro @code{__RTP__}.
 
+@opindex msmp
+@item -msmp
+Select SMP runtimes for linking.  Not available on architectures other
+than PowerPC, nor on VxWorks version 7 or later, in which the selection
+is part of the VxWorks build configuration and the library paths are the
+same for either choice.
+
 @opindex non-static
 @item -non-static
 Link an RTP executable against shared libraries rather than static


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 

Re: [PATCH v4] Introduce attribute sym

2023-08-15 Thread Alexandre Oliva via Gcc-patches
On Jul 22, 2023, Fangrui Song  wrote:

> I wonder whether this attribute can be named "alias" without arguments.

Erhm...  Maybe I'm missing something about your suggestion, but without
arguments, how would we tell the compiler the symbol name of the
additional alias we want for the definition?

Maybe, instead of no arguments, we could use something like:

  attribute (alias (..., "alt_sym_name"))

but I don't find that clearer, and I have a hunch that the
implementation would be significantly more convoluted.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice but
very few check the facts.  Think Assange & Stallman.  The empires strike back


Re: [PATCH] Introduce hardbool attribute for C

2023-06-16 Thread Alexandre Oliva via Gcc-patches
On Jun 16, 2023, Thomas Koenig  wrote:

> So, such a type would be incompatible with vanilla LOGICAL variables
> and with C interop logical variables.

Yeah, it would.  It's something else, and if you choose to use such a
type in an interface, it would need to be handled as such.  Presumably,
absent direct support in the desired language, using the underlying type
and the explicitly chosen constants would work.

This is nothing to call home about.  It's not unusual for languages to
support features that are not directly representable in other languages.
And this is one that isn't even hard to work around.

But I'd first doubt the wisdom of whoever adds such a type to a
cross-language interface.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2023-06-21 Thread Alexandre Oliva via Gcc-patches
Thanks for the test.

Did you mean for me to incorporate it into the patch, or do you mean to
contribute it separately, if the feature happens to be accepted?

On Jun 19, 2023, Bernhard Reutner-Fischer  wrote:

> I don't see explicit tests with _Complex nor __complex__. Would we
> want to check these here, or are they handled thought the "underlying"
> tests above?

Good question.  The notion of using complex types to hold booleans
hadn't even crossed my mind.

On the one hand, there doesn't seem to be reason to rule them out, and
that could go for literally any other type.

On the other, there doesn't seem to be any useful case for them.  Can
anyone think of one?

> I'd welcome a fortran interop note in the docs

Is there any good place for such interop notes?  I'm not sure I'm
best-suited to write them up, since Fortran is not a language I'm
very familiar with, but I suppose I could give it a try.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH zero-call-used-regs] Add leafy mode for zero-call-used-regs

2023-06-21 Thread Alexandre Oliva via Gcc-patches
Hello, Qing,

On Jun 16, 2023, Qing Zhao  wrote:

> As I mentioned in the previous round of review, I think that the documentation
>  might need to add more details on what’s the LEAFY mode,
> The purpose of it, and how to use it, provide more details to the end-users.

I'm afraid I'm having difficulty picturing what it is that you're
looking for.  The proposal incorporates, by reference, all the
documentation for 'used' and for 'all', and the way to use it is no
different.

>> +Same as @samp{used} in a leaf function, and same as @samp{all} in a
>> +nonleaf function.

If there was documentation on how to choose between e.g. all and used, I
suppose I could build on that to add this intermediate choice, but...  I
can't find any such docs, and I'm uncertain on whether adding that would
be useful to begin with.

Did you have something else in mind?

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2023-06-21 Thread Alexandre Oliva via Gcc-patches
On Jun 21, 2023, Qing Zhao  wrote:

> I see that you have testing case to check the above built_in_trap call
> is generated by FE.
> Do you have a testing case to check the trap is happening at runtime? 

I have written such tests, using type-punning, but I don't think our
testing infrastructure could take trapping as success and other results
as failure.

> So, when -ftrivial-auto-var-init presents, what’s the behavior for the
> hardened Boolean auto variables?

Good question.  This option was not even available when hardbool was
designed and implemented.  (tests) The deferred_init internal function
initializes with bit-patterns 0x00 or 0xfe, regardless of type, when the
data lives in memory, and otherwise forces the 0x00 bit pattern for
booleans, variable-sized types, types that cannot be accessed with a
single mode or for modes that don't have a set pattern.

It's hard for me to tell what "correct" or "expected" would be here.
Enumerators don't seem to be given special treatment.  Checked
enumerators, constrained integral subtypes, none of these would get
well-formed values or even checking at the assignments.

If I were to design this option myself, I'd probably arrange for it to
handle booleans (including hardened booleans) by zero-initializing as
false and pattern-initializing as true, though I realize that this could
be very confusing if one chose to use 0xfe as the value for false and/or
0x00 as the value for true.

I'd probably have arranged for the front-end to create the initializer
value, because expansion time is too late to figure it out: we may not
even have the front-end at hand any more, in case of lto compilation.


But with the current description and implementation, I guess the
behavior is correct, if not ideal: the bit patterns refer to the
representation, rather than to the language interpretation of the value.
When it comes ot integral types, they may match, but floating-point,
fixed fractional types, offsets and multipliers, even boolean member of
larger structs...  not so much: the effect is that of a memset, rather
than that of an assignment of zero or of the pattern to a variable.

Now, I acknowledge that the decision to make implicit
zero-initialization of boolean types set them to the value for false,
rather than to all-bits-zero representation, is a departure from common
practice of zero-initialization yielding logical zero.  That was unusual
enough that I thought it worth mentioning in the docs.


> This might need to be documented and also handled correctly. 

I suppose the place to document this distinction between logical values
and representation would be under -ftrivial-auto-var-init.  That's
likely where someone using that option would look for guidance on how it
interacts with unusual types, and where exceptions to general
expectations WRT initialization would go.  Do you concur?

That said, it probalby makes sense to refer to / mention that
-ftrivial-auto-var-init does not special-case hardened booleans in the
hardened booleans documentation.  I wonder if there are other
conflicting options I'm not even aware of.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Introduce -finline-stringops (was: Re: [RFC] Introduce -finline-memset-loops)

2023-06-22 Thread Alexandre Oliva via Gcc-patches
On Jun  2, 2023, Alexandre Oliva  wrote:

> Introduce -finline-stringops

Ping?  https://gcc.gnu.org/pipermail/gcc-patches/2023-June/620472.html

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[testsuite] note pitfall in how outputs.exp sets gld

2023-06-22 Thread Alexandre Oliva via Gcc-patches


This patch documents a glitch in gcc.misc-tests/outputs.exp: it checks
whether the linker is GNU ld, and uses that to decide whether to
expect collect2 to create .ld1_args files under -save-temps, but
collect2 bases that decision on whether HAVE_GNU_LD is set, which may
be false zero if the linker in use is GNU ld.  Configuring
--with-gnu-ld fixes this misalignment.  Without that, atsave tests are
likely to fail, because without HAVE_GNU_LD, collect2 won't use @file
syntax to run the linker (so it won't create .ld1_args files).

Long version: HAVE_GNU_LD is set when (i) DEFAULT_LINKER is set during
configure, pointing at GNU ld; (ii) --with-gnu-ld is passed to
configure; or (iii) config.gcc sets gnu_ld=yes.  If a port doesn't set
gnu_ld, and the toolchain isn't configured so as to assume GNU ld,
configure and thus collect2 conservatively assume the linker doesn't
support @file arguments.

But outputs.exp can't see how configure set HAVE_GNU_LD (it may be
used to test an installed compiler), and upon finding that the linker
used by the compiler is GNU ld, it will expect collect2 to use @file
arguments when running the linker.  If that assumption doesn't hold,
atsave tests will fail.

Does it make sense to put this in?  I'd like to preserve this knowledge
somehow, and I suppose this would be most useful for someone observing
these failures and trying to figure out why they come about, so this
seems the best place for them.  Ok to install?


for  gcc/testsuite/ChangeLog

* outputs.exp (gld): Note a known mismatch and record a
workaround.
---
 gcc/testsuite/gcc.misc-tests/outputs.exp |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.misc-tests/outputs.exp 
b/gcc/testsuite/gcc.misc-tests/outputs.exp
index 7ee355034ccaf..9f44cbdb0b5d5 100644
--- a/gcc/testsuite/gcc.misc-tests/outputs.exp
+++ b/gcc/testsuite/gcc.misc-tests/outputs.exp
@@ -50,7 +50,15 @@ if !$skip_lto {
 set ltop [check_linker_plugin_available]
 }
 
-# Check for GNU LD.  Some files like .ld1_args depend on this.
+# Check for GNU LD.  Some files like .ld1_args depend on this.  This
+# should really be testing whether HAVE_GNU_LD was set by configure.
+# If we find GNU ld here, but the compiler wasn't configured
+# --with-gnu-ld or with DEFAULT_LINKER pointing at GNU ld, on a target
+# that doesn't set gnu_ld=yes unconditionally, configure and thus
+# collect2 will conservatively assume there's no support for @file in
+# the linker, but our atfile tests will expect ld1_args files to be
+# created, and thus fail.  Configuring the compiler --with-gnu-ld
+# fixes this.
 set gld [check_effective_target_gld]
 
 # Prepare additional options to be used for linking.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH v3] Add leafy mode for zero-call-used-regs

2023-06-23 Thread Alexandre Oliva via Gcc-patches
On Jun 23, 2023, Qing Zhao via Gcc-patches  wrote:

> It’s better to add this definition earlier in the list of the “three
> basic values”, to make it “four basic values”, like the following:

Oh, my, sorry for being so dense, I had managed to miss that bit all
this time somehow :-(

> The sentence "This value is mainly to provide users a more efficient mode to 
> zero 
> call-used registers in leaf functions.” just for your reference,
> the wording can certainly be improved.  -:)

:-)  got it, thanks.  How about this?


Add leafy mode for zero-call-used-regs

Introduce 'leafy' to auto-select between 'used' and 'all' for leaf and
nonleaf functions, respectively.

Regstrapped on x86_64-linux-gnu.  Ok to install?


for  gcc/ChangeLog

* doc/extend.texi (zero-call-used-regs): Document leafy and
variants thereof.
* flag-types.h (zero_regs_flags): Add LEAFY_MODE, as well as
LEAFY and variants.
* function.cc (gen_call_ued_regs_seq): Set only_used for leaf
functions in leafy mode.
* opts.cc (zero_call_used_regs_opts): Add leafy and variants.

for  gcc/testsuite/ChangeLog

* c-c++-common/zero-scratch-regs-leafy-1.c: New.
* c-c++-common/zero-scratch-regs-leafy-2.c: New.
* gcc.target/i386/zero-scratch-regs-leafy-1.c: New.
* gcc.target/i386/zero-scratch-regs-leafy-2.c: New.
---
 gcc/doc/extend.texi|   30 ++--
 gcc/flag-types.h   |5 +++
 gcc/function.cc|3 ++
 gcc/opts.cc|4 +++
 .../c-c++-common/zero-scratch-regs-leafy-1.c   |   15 ++
 .../c-c++-common/zero-scratch-regs-leafy-2.c   |   21 ++
 .../gcc.target/i386/zero-scratch-regs-leafy-1.c|   12 
 .../gcc.target/i386/zero-scratch-regs-leafy-2.c|   16 +++
 8 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c
 create mode 100644 gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 852f6b629bea8..739c40368f556 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4349,7 +4349,7 @@ through registers.
 In order to satisfy users with different security needs and control the
 run-time overhead at the same time, the @var{choice} parameter provides a
 flexible way to choose the subset of the call-used registers to be zeroed.
-The three basic values of @var{choice} are:
+The four basic values of @var{choice} are:
 
 @itemize @bullet
 @item
@@ -4362,10 +4362,16 @@ the function.
 
 @item
 @samp{all} zeros all call-used registers.
+
+@item
+@samp{leafy} behaves like @samp{used} in a leaf function, and like
+@samp{all} in a nonleaf function.  This makes for leaner zeroing in leaf
+functions, where the set of used registers is known, and that may be
+enough for some purposes of register zeroing.
 @end itemize
 
 In addition to these three basic choices, it is possible to modify
-@samp{used} or @samp{all} as follows:
+@samp{used}, @samp{all}, and @samp{leafy} as follows:
 
 @itemize @bullet
 @item
@@ -4412,10 +4418,28 @@ zeros all call-used registers that pass arguments.
 @item all-gpr-arg
 zeros all call-used general purpose registers that pass
 arguments.
+
+@item leafy
+Same as @samp{used} in a leaf function, and same as @samp{all} in a
+nonleaf function.
+
+@item leafy-gpr
+Same as @samp{used-gpr} in a leaf function, and same as @samp{all-gpr}
+in a nonleaf function.
+
+@item leafy-arg
+Same as @samp{used-arg} in a leaf function, and same as @samp{all-arg}
+in a nonleaf function.
+
+@item leafy-gpr-arg
+Same as @samp{used-gpr-arg} in a leaf function, and same as
+@samp{all-gpr-arg} in a nonleaf function.
+
 @end table
 
 Of this list, @samp{used-arg}, @samp{used-gpr-arg}, @samp{all-arg},
-and @samp{all-gpr-arg} are mainly used for ROP mitigation.
+@samp{all-gpr-arg}, @samp{leafy-arg}, and @samp{leafy-gpr-arg} are
+mainly used for ROP mitigation.
 
 The default for the attribute is controlled by @option{-fzero-call-used-regs}.
 @end table
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 2e650bf1c487c..0d2dab1b99dd4 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -348,6 +348,7 @@ namespace zero_regs_flags {
   const unsigned int ONLY_GPR = 1UL << 2;
   const unsigned int ONLY_ARG = 1UL << 3;
   const unsigned int ENABLED = 1UL << 4;
+  const unsigned int LEAFY_MODE = 1UL << 5;
   const unsigned int USED_GPR_ARG = ENABLED | ONLY_USED | ONLY_GPR | ONLY_ARG;
   const unsigned int USED_GPR = ENABLED | ONLY_USED | ONLY_GPR;
   const unsigned int USED_ARG = ENABLED | ONLY_USED | ONLY_ARG;
@@ -356,6 +357,10 @@ namespace zero_regs_flags {
   const unsigned int ALL_GPR = ENAB

Re: [PATCH] Introduce hardbool attribute for C

2023-06-23 Thread Alexandre Oliva via Gcc-patches
On Jun 23, 2023, Qing Zhao via Gcc-patches  wrote:

> -ftrivial-auto-var-init has been in GCC since GCC12.  

*nod*.  IIRC I started designing hardbool in GCC10, but the first
complete implementation was for GCC11.

> The decision to use 0x00 for zero-initiation, 0xfe for pattern-initiation
> has been discussed thoroughly during the design phase. -:)

*nod*, and it's a good one

> Since this hardbool attribute will also  be a security feature, users that 
> seek
> security features of GCC will likely ask the same question for these two
> features.

> So, their interaction is better to be at least documented. That’s my main 
> point.

*nod*.  At first, I thought the ideal place to clarify the issue was in
the documentation for the option, because there's nothing exceptional
about the option's behavior when it comes to hardbool specifically.  But
it doesn't hurt to mention it in both places, so I did.  How about the
incremental patchlet below (at the end)?

> For normal Boolean variables, 0x00 is false, this is a reasonable init
> value with zero-initialization.

*nod*.  I was surprised by zero initialization of (non-hardened)
booleans even when pattern is requested, but not consistently
(e.g. boolean fields of a larger struct would still get
pattern-initialized IIUC).  I'd have expected pattern would translate to
nonzero and thus to true, rather than false.

> For hardbool variables, what 0x00 represents if it’s not false or true
> value?

It depends on how hardbool is parameterized.  One may pick 0x00 or 0xFE
as the representations for true or false, or neither, in which case the
trivial initializer will end up as a trapping value.

>> I'd probably have arranged for the front-end to create the initializer
>> value, because expansion time is too late to figure it out: we may not
>> even have the front-end at hand any more, in case of lto compilation.

> Is the hardbool attribute information available during the rtl expansion 
> phase?

It is in the sense that the attribute lives on, but c_hardbool_type_attr
is a frontend function, it cannot be called from e.g. lto1.

The hardbool attribute is also implemented in Ada, but there it only
affects validity checking in the front end: Boolean types in Ada are
Enumeration types, and there is standard syntax to specify the
representations for true and false.  AFAICT, once we translate GNAT IR
to GNU IR, hardened booleans would not be recognizable as boolean types.
Even non-hardened booleans with representation clauses would.  So
handling these differently from other enumeration types, to make them
closer to booleans, would be a bit of a challenge, and a
backwards-compatibility issue (because such booleans have already been
handled in the present way since the introduction of -ftrivial-* back in
GCC12)

>> Now, I acknowledge that the decision to make implicit
>> zero-initialization of boolean types set them to the value for false,
>> rather than to all-bits-zero representation, is a departure from common
>> practice of zero-initialization yielding logical zero.

> Dont’s quite understand the above, for normal boolean variables,

Sorry, I meant hardened boolean types.  This was WRT to the design
decision that led to this bit in the documentation:

typedef char __attribute__ ((__hardbool__ (0x5a))) hbool;
[...]
static hbool zeroinit; /* False, stored as (char)0x5a.  */
auto hbool uninit; /* Undefined, may trap.  */
  
> And this is a very reasonable initial value for Boolean variables,

Agreed.  The all-zeros bit pattern is not so great for booleans that use
alternate representations, though, such as the following standard Ada:

   type MyBool is new Boolean;
   for MyBool use (16#5a#, 16#a5#);
   for MyBool'Size use 8;

or for biased variables such as:

  X : Integer range 254 .. 507;
  for X'Size use 8; -- bits, so a biased representation is required.

Just to make things more interesting, I chose a range for X that causes
the compiler to represent 0xfe as 0x00 in in the byte that holds X, but
that places the 0xfe pattern just out of the range :-) So with
-ftrivial-auto-var-init=zero, X = 254, whereas with
-ftrivial-auto-var-init=pattern, it fails validity checking, and might
come out as 508 if that's disabled.

> From my understanding, only with the introduction of “hardbool”
> attribute, all-bits-zero will not be equal to the
> logical false anymore. 

Ada booleans have long allowed nonzero representations for false.


diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 772209c1793e8..ae7867bb35696 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8774,6 +8774,12 @@ on the bits held in the storage (re)used for the 
variable, if any, and
 on optimizations the compiler may perform on the grounds that using
 uninitialized values invokes undefined behavior.
 
+Users of @option{-ftrivial-auto-var-init} should be aware that the bit
+patterns used as its trivial initializers are @emph{not} converted to
+@code{hardbool} types, so using variables i

Re: [PATCH] Introduce hardbool attribute for C

2023-06-23 Thread Alexandre Oliva via Gcc-patches
On Jun 22, 2023, Bernhard Reutner-Fischer  wrote:

> On Wed, 21 Jun 2023 22:08:55 -0300
> Alexandre Oliva  wrote:

>> Thanks for the test.
>> 
>> Did you mean for me to incorporate it into the patch, or do you mean to
>> contribute it separately, if the feature happens to be accepted?

> These were your tests that i quoted

Aaah.  I didn't look too closely, I just assumed you'd tweaked something
in there.

>> > I don't see explicit tests with _Complex nor __complex__. Would we
>> > want to check these here, or are they handled thought the "underlying"
>> > tests above?  
>> 
>> Good question.  The notion of using complex types to hold booleans
>> hadn't even crossed my mind.

> Maybe it is not real, it just sparkled through somehow.

Is it imaginary, then? :-D

>> On the other, there doesn't seem to be any useful case for them.  Can
>> anyone think of one?

> We could either not reject other such uses and wait or we could reject
> them and equally wait for complaints. I would not dare to bet who pops
> up first, fuzzers or users

I bet on fuzzers :-)

> it was just a thought (i mentioned tinfoil hat, did i ;).

indeed ;-)

Having verified that it gets rejected (phew :-) I'm inclined to add it
to the test you quoted and be done with it.  If a reason ever comes up
to support it, the test can be adjusted accordingly.

>> 
>> > I'd welcome a fortran interop note in the docs  
>> 
>> Is there any good place for such interop notes?  I'm not sure I'm
>> best-suited to write them up, since Fortran is not a language I'm
>> very familiar with, but I suppose I could give it a try.

> I'd append to your extend.texi hunk below the para about uninitialized a
> note to the effect of:
> Note: Types annotated with this attribute may not be Fortran
> interoperable.

I'm not comfortable single-casing Fortran like that.  I expect other
languages could face similar interop issues when relying on
single-language extensions.  How about:

  Since this is a language extension only available in C, interoperation
  with other languages may pose difficulties.  It should interoperate
  with Ada Booleans defined with the same size and equivalent
  representation clauses, and with enumerations or other languages'
  integral types that correspond to C's chosen integral type.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2023-06-23 Thread Alexandre Oliva via Gcc-patches
On Jun 16, 2023, Alexandre Oliva  wrote:

> On Aug  9, 2022, Alexandre Oliva  wrote:
>> Ping?

> Ping?  Refreshed, added setting of ENUM_UNDERLYING_TYPE, retested on
> x86_64-linux-gnu (also on gcc-13).

Here's a consolidated patch incorporating the doc and test patchlets
sent out in response to Qing's and Berhard's suggestions.

Regstrapped on x86_64-linux-gnu.  Ok to install?


Introduce hardbool attribute for C

This patch introduces hardened booleans in C.  The hardbool attribute,
when attached to an integral type, turns it into an enumerate type
with boolean semantics, using the named or implied constants as
representations for false and true.

Expressions of such types decay to _Bool, trapping if the value is
neither true nor false, and _Bool can convert implicitly back to them.
Other conversions go through _Bool first.


for  gcc/c-family/ChangeLog

* c-attribs.cc (c_common_attribute_table): Add hardbool.
(handle_hardbool_attribute): New.
(type_valid_for_vector_size): Reject hardbool.
* c-common.cc (convert_and_check): Skip warnings for convert
and check for hardbool.
(c_hardbool_type_attr_1): New.
* c-common.h (c_hardbool_type_attr): New.

for  gcc/c/ChangeLog

* c-typeck.cc (convert_lvalue_to_rvalue): Decay hardbools.
* c-convert.cc (convert): Convert to hardbool through
truthvalue.
* c-decl.cc (check_bitfield_type_and_width): Skip enumeral
truncation warnings for hardbool.
(finish_struct): Propagate hardbool attribute to bitfield
types.
(digest_init): Convert to hardbool.

for  gcc/ChangeLog

* doc/extend.texi (hardbool): New type attribute.
* doc/invoke.texi (-ftrivial-auto-var-init): Document
representation vs values.

for  gcc/testsuite/ChangeLog

* gcc.dg/hardbool-err.c: New.
* gcc.dg/hardbool-trap.c: New.
* gcc.dg/hardbool.c: New.
* gcc.dg/hardbool-s.c: New.
* gcc.dg/hardbool-us.c: New.
* gcc.dg/hardbool-i.c: New.
* gcc.dg/hardbool-ul.c: New.
* gcc.dg/hardbool-ll.c: New.
* gcc.dg/hardbool-5a.c: New.
* gcc.dg/hardbool-s-5a.c: New.
* gcc.dg/hardbool-us-5a.c: New.
* gcc.dg/hardbool-i-5a.c: New.
* gcc.dg/hardbool-ul-5a.c: New.
* gcc.dg/hardbool-ll-5a.c: New.
---
 gcc/c-family/c-attribs.cc |   98 -
 gcc/c-family/c-common.cc  |   21 
 gcc/c-family/c-common.h   |   18 
 gcc/c/c-convert.cc|   14 +++
 gcc/c/c-decl.cc   |   10 ++
 gcc/c/c-typeck.cc |   31 ++-
 gcc/doc/extend.texi   |   64 ++
 gcc/doc/invoke.texi   |   21 
 gcc/testsuite/gcc.dg/hardbool-err.c   |   31 +++
 gcc/testsuite/gcc.dg/hardbool-trap.c  |   13 +++
 gcc/testsuite/gcc.dg/torture/hardbool-5a.c|6 +
 gcc/testsuite/gcc.dg/torture/hardbool-i-5a.c  |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-i.c |5 +
 gcc/testsuite/gcc.dg/torture/hardbool-ll-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-ll.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool-s-5a.c  |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-s.c |5 +
 gcc/testsuite/gcc.dg/torture/hardbool-ul-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-ul.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool-us-5a.c |6 +
 gcc/testsuite/gcc.dg/torture/hardbool-us.c|5 +
 gcc/testsuite/gcc.dg/torture/hardbool.c   |  118 +
 22 files changed, 496 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/hardbool-err.c
 create mode 100644 gcc/testsuite/gcc.dg/hardbool-trap.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-i-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-i.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ll-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ll.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-s-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-s.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ul-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-ul.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-us-5a.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool-us.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/hardbool.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index c12211cb4d499..365319e642b1a 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -176,6 +176,7 @@ static tree handle_objc_root_class_attribute (tree *, tree, 
tree, int, bool *);
 static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool 
*);
 static tree handle_signed_boo

Re: [PATCH] Introduce hardbool attribute for C

2023-06-28 Thread Alexandre Oliva via Gcc-patches
On Jun 26, 2023, Qing Zhao  wrote:

>>> For hardbool variables, what 0x00 represents if it’s not false or true
>>> value?
>> 
>> It depends on how hardbool is parameterized.  One may pick 0x00 or 0xFE
>> as the representations for true or false, or neither, in which case the
>> trivial initializer will end up as a trapping value.

> Okay, then, this looks like a good behavior (trapping with
> -ftrival-auto-var-init most of the time,
>  i.e, when neither 0x00 or 0xFE was chosen as the representations for true or 
> false), 
> it will urge the user to fix the uninitialized hardbool variables.

Agreed

 I'd probably have arranged for the front-end to create the initializer
 value, because expansion time is too late to figure it out: we may not
 even have the front-end at hand any more, in case of lto compilation.
>> 
>>> Is the hardbool attribute information available during the rtl expansion 
>>> phase?
>> 
>> It is in the sense that the attribute lives on, but c_hardbool_type_attr
>> is a frontend function, it cannot be called from e.g. lto1.
> does lookup_attribute work for this attribute during rtl expansion?
> (Still a little confusing here)

Yes, the hardbool attribute would be there in C.
But not in Ada.

And that should be fine, because Ada hardbool is handled entirely in the
frontend, as are non-hardened booleans with representation clauses, that
become enumeration types without any distinguishing feature.

>> The hardbool attribute is also implemented in Ada, but there it only
>> affects validity checking in the front end: Boolean types in Ada are
>> Enumeration types, and there is standard syntax to specify the
>> representations for true and false.  AFAICT, once we translate GNAT IR
>> to GNU IR, hardened booleans would not be recognizable as boolean types.
>> Even non-hardened booleans with representation clauses would.

> So, right now, the GNU IR represents Ada’s boolean type as enumeration type? 

All Ada boolean types are defined by the language as enumeration types:

  There is a predefined enumeration type named Boolean, [declared in the
  visible part of package Standard].  It has the two enumeration
  literals False and True ordered with the relation False < True.  Any
  descendant of the predefined type Boolean is called a boolean type.

However, boolean types without representation clauses are mapped to the
language-independent boolean_type_node.  Those that do are mapped to
enumeration types.

>> So
>> handling these differently from other enumeration types, to make them
>> closer to booleans, would be a bit of a challenge,

> is there any special handling in GNU IR when representing Ada’s
> boolean type as enumeration type?
> Any issue right now?

Not that I'm aware of.  The front end takes care of converting between
non-boolean_type_node enumeration types and boolean_type_node as needed,
so that the GNU IR needs no extra information.

>> and a
>> backwards-compatibility issue (because such booleans have already been
>> handled in the present way since the introduction of -ftrivial-* back in
>> GCC12)

> With the new hardbool attribute added for C, an original bool type
> becomes an enumeration type logically,

There's no change to the original bool type.

Only hardbool types are represented as enumeration types in C.

In Ada, boolean types with representation clauses are still represented
as enumeration types, whether or not they're hardbool.

> But such information is not passed to middle end through GNU IR, So,
> in GCC middle-end, We still treat such type as boolean, not an
> enumeration type.

The middle-end doesn't know (and ATM cannot know) that those represented
as enumeration types are conceptually booleans, so they are treated as
enumeration types, not as booleans.

>> static hbool zeroinit; /* False, stored as (char)0x5a.  */
>> auto hbool uninit; /* Undefined, may trap.  */

> For the hardbool variable "uninit", -ftrivial-auto-var-init=zero will
> initialize it to zero, and it will trap during runtime.
> And at the same time, -ftrivial-auto-var-init=pattern will initialize
> it to 0xfe, and it will trap during runtime, too.

> I think these are good behaviors, just need to be documented. 

You mean more than what's in the patch posted last week?

>> 
>>> And this is a very reasonable initial value for Boolean variables,
>> 
>> Agreed.  The all-zeros bit pattern is not so great for booleans that use
>> alternate representations, though, such as the following standard Ada:
>> 
>> type MyBool is new Boolean;
>> for MyBool use (16#5a#, 16#a5#);
>> for MyBool'Size use 8;
>> 
>> or for biased variables such as:
>> 
>> X : Integer range 254 .. 507;
>> for X'Size use 8; -- bits, so a biased representation is required.
>> 
>> Just to make things more interesting, I chose a range for X that causes
>> the compiler to represent 0xfe as 0x00 in in the byte that holds X, but
>> that places the 0xfe pattern just out of the range :-) So with
>> -ftrivial-auto-var-init=zero

Re: [PATCH v3] Introduce strub: machine-independent stack scrubbing

2023-06-28 Thread Alexandre Oliva via Gcc-patches
Hello, Qing,

On Jun 27, 2023, Qing Zhao  wrote:

> I am wondering why stack scrubbing, proposed in this patch series, cannot do 
> the stack scrubbing in the routine’s epilogue similar as
> register scrubbing?

There were multiple considerations that led to this design decision:

- Stack scrubbing in epilogues would be highly target-dependent

An epilogue expected to scrub the stack of its containing function would
not usually be able to call memset; there might not even be registers
available to do the cleaning, let alone to do it efficiently.  Since
epilogues are output after register allocation, the epilogue code
generator would have to allocate registers itself to do the job,
avoiding call-saved registers (that would have to be restored before
scrubbing the stack holding them), those holding return values, and
taking care of any machine- or ABI-specific conventions that apply to
epilogues.

- Exception Handling

Raising or propagating an exception requires a function's stack frame to
be active.  It wouldn't be possible for e.g. a cleanup handler to clean
up the stack frame holding it and then propagating the exception: either
the scrubbing would have to leave much of the stack frame alone for
propagation to work, or it would scrub too much and propagation would
fail.

So we had to devise a way for stack frames to be scrubbed and protect
the sensitive data in them even if an exception is raised or propagated
out of the sensitive frame.

- Variable frame size

Though many functions have static frame sizes, there are cases in which
a function dynamically allocates and releases stack space, and that
extra space should be scrubbed as well.  So the improvements out of a
known frame size are not a given, and we may need a watermark to handle
the general case.

Now consider that this watermark needs to survive past the point in
which the epilogue restores call-saved registers, so that the save area
can be scrubbed.  Call-clobbered registers might not be available, or
need scrubbing themselves.

A caller-owned watermark relieves the callee from these contradictory
requirements, enables the register pointing to the watermark to be
reused by the callee as soon as it's no longer needed; aggregation of
scrubbing, passing on the watermark when tail-calling another scrubbed
subprogram; caller and callee to be compiled separately, circumstances
in which the caller (in the strub("at-calls") mode) wouldn't know how
much stack space used by the callee is to be scrubbed.

- Watermark as in/out argument

Thus, watermarks, and caller-based scrubbing were required, so we might
as well use the same strategy for non-exceptional exit paths to make it
portable.

We've explored various possibilities of watermark passing to reduce the
impact on the ABI:

-- a single global variable wouldn't do in multi-threaded programs;
we need per-thread stack information.  TLS is not available on every
target, it's emulated with high overhead on some, and even when it
doesn't use part of the thread's stack for static thread-local
storage, each caller of a scrubbing function would have to preserve
that variable somehow (presumably in its own stack frame) before
reusing it to communicate with its callee.

-- a thread-local pointer to a heap-allocated parallel stack of
stack-scrubbing ranges might avoid holding the watermarks in the
stack, or passing pointers to them as arguments, leaving the entire
scrub range management in the library.  that would make the __strub_*
library components heavy enough that inlining them would not be
viable.  Furthermore, making such low-level APIs heap allocators
normally makes for problems of async-signal safety, and prevents heap
implementations from relying on such low-level APIs.

-- using the static chain machinery to convey to scrubbed callees
access to the callee's watermark seems viable, if onerous, but the
chained records live in the stack anyway, and there are targets that
do not support static chains.

-- an out parameter might do for "amount of stack used", but
making it an in/out watermark enabled aggregation and tail-calling;
early set-and-forget on fixed-size stack frames; and assured
initialization, even in case of an early asynchronous exception.

- Internal scrubbing

Though we have implemented strub("internal") through wrappers that call
the actual function and then scrub its stack space, we have envisioned
an alternate implementation that, through machine-specific support,
performs actual internal scrubbing, arranging the stack frame in such a
way that epilogues and EH cleanups can scrub most, if not all of the
stack frame (analogous to how the wrapper only scrubs the wrapped frame,
not its own), and taking advantage of constant frame sizes where
possible.  At least with variable frame sizes, the amount of stack space
to be scrubbed in the epilogue (or in an EH cleanup) will have to be
held in a local variable or somesuch, and at least for nonleaf
functions, that surely will end up in the stack 

[testsuite] tolerate enabled but missing language frontends

2023-06-28 Thread Alexandre Oliva via Gcc-patches


When a language is enabled but we run the testsuite against a tree in
which the frontend compiler is not present, help.exp fails.  It
recognizes the output pattern for a disabled language, but not a
missing frontend.  Extend the pattern so that it covers both cases.

Tested on x86_64-linux-gnu.  Ok to install?


for  gcc/testsuite/ChangeLog

* lib/options.exp (check_for_options_with_filter): Handle
missing frontend compiler like disabled language.
---
 gcc/testsuite/lib/options.exp |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/options.exp b/gcc/testsuite/lib/options.exp
index 30e6e50d703dc..a4b15c14f9c6c 100644
--- a/gcc/testsuite/lib/options.exp
+++ b/gcc/testsuite/lib/options.exp
@@ -59,7 +59,7 @@ proc check_for_options_with_filter { language gcc_options 
exclude \
 set gcc_output [gcc_target_compile $srcfname $filebase.x executable 
$gcc_options]
 remote_file build delete $srcfname $filebase.x $filebase.gcno
 
-if {[regexp -- "compiler not installed on this system" $gcc_output]} {
+if {[regexp -- "compiler not installed on this system|cannot execute" 
$gcc_output]} {
unsupported "$test: $language compiler not available"
return
 }

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Introduce hardbool attribute for C

2023-06-29 Thread Alexandre Oliva via Gcc-patches
On Jun 28, 2023, Qing Zhao  wrote:

> In summary, Ada’s Boolean variables (whether it’s hardened or not) are
> represented as
> enumeration types in GNU IR.

Not quite.  Only boolean types with representation clauses are.  Those
without (such as Standard.Boolean) are BOOLEAN_TYPEs.  But those without
a representation clause are not so relevant and could be disregarded,
for purposes of this conversation.

> FE takes care of the converting between non-boolean_type_node
> enumeration types and boolean_type_node as needed, no special handling
> in Middle end.

> So, is this exactly the same situation as the new hardbool attribute
> for C being implemented in this patch?

That's correct.

> (Another question, for Ada’s Boolean variables, does the ada FE also
> insert BUILT_IN_TRAP when
>   The value is neither true_value nor false_value?)

Ada raises exceptions when validity checking fails; such as upon using a
boolean variable with a representation clause holds a value that is
neither true nor false.

>> The middle-end doesn't know (and ATM cannot know) that those represented
>> as enumeration types are conceptually booleans, so they are treated as
>> enumeration types, not as booleans.

> They should know it’s a boolean if using the lookup_attribute to get
> the attribute info -:)

I meant boolean types that have a representation clause but are not
hardbools.  Those don't have any attribute whatsoever.

>> You mean more than what's in the patch posted last week?
> No, the updated doc is good I think.

Great, thanks

> So, from my current understanding, a summary on my major concern and
> the possible solution to this concern:

That was a good summary.

> Is it necessary to fix such inconsistency?

I don't think it is even desirable.

Initialization of static variables is well-defined, one is allowed to
count on a specific value after initialization, and we have that
covered.

Automatic variables, OTOH, when not explicitly initialized, may hold
undefined, random, even malformed values.  Picking an initializer to
make them predictable needs not follow the semantics of zero
initialization for static variables.  =pattern makes it clear that using
something other than zero initialization is useful to catch errors.  The
Ada language standard even suggests that compilers may set uninitialized
variables to out-of-range values so as to catch this sort of error.  So,
though it might seem desirable, for symmetry, to have automatic
variables implicitly initialized similarly to static variables, it's not
clear that doing so serves a useful purpose, at least for such types as
hardened booleans, that are *intended* to catch malformed values.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: C++ modules and AAPCS/ARM EABI clash on inline key methods

2023-02-16 Thread Alexandre Oliva via Gcc-patches
On Apr  5, 2022, Alexandre Oliva  wrote:

> Would something like this be acceptable/desirable?  It's overreaching,
> in that not all arm platforms are expected to fail, but the result on
> them will be an unexpected pass, which is not quite as bad as the
> unexpected fail we get on most arm variants now.

Ping?
https://gcc.gnu.org/pipermail/gcc-patches/2022-April/592763.html

[PR105224] C++ modules and AAPCS/ARM EABI clash on inline key methods

g++.dg/modules/virt-2_a.C fails on arm-eabi and many other arm targets
that use the AAPCS variant.  ARM is the only target that overrides
TARGET_CXX_KEY_METHOD_MAY_BE_INLINE.  It's not clear to me which way
the clash between AAPCS and C++ Modules design should be resolved, but
currently it favors AAPCS and thus the test fails.

Skipping the test or conditionally dropping the inline keyword breaks
subsequent tests, so I'm XFAILing the expectation that vtable and rtti
symbols are output on arm*-*-*.

Retested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?


for  gcc/testsuite/ChangeLog

PR c++/105224
* g++.dg/modules/virt-2_a.C: XFAIL syms on arm*-*-*.
---
 gcc/testsuite/g++.dg/modules/virt-2_a.C |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/g++.dg/modules/virt-2_a.C 
b/gcc/testsuite/g++.dg/modules/virt-2_a.C
index 580552be5a0d8..b265515e2c7fd 100644
--- a/gcc/testsuite/g++.dg/modules/virt-2_a.C
+++ b/gcc/testsuite/g++.dg/modules/virt-2_a.C
@@ -22,6 +22,6 @@ export int Visit (Visitor *v)
 }
 
 // Emit here
-// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} } }
-// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } }
-// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} { xfail arm*-*-* } } }
+// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} { xfail arm*-*-* } } }
+// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} { xfail arm*-*-* } } }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[arm] [testsuite] asm-flag-4.c: match quotes in expected message

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Quotes were added around the "asm" keyword in the message expected by
the test, so the test needs adjusting.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).
Ok to install?


for  gcc/testsuite/ChangeLog

* gcc.target/arm/asm-flag-4.c: Match quotes around "asm" in
message.
---
 gcc/testsuite/gcc.target/arm/asm-flag-4.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/arm/asm-flag-4.c 
b/gcc/testsuite/gcc.target/arm/asm-flag-4.c
index 75378cc89b092..6841b6ea1e272 100644
--- a/gcc/testsuite/gcc.target/arm/asm-flag-4.c
+++ b/gcc/testsuite/gcc.target/arm/asm-flag-4.c
@@ -11,5 +11,5 @@ void __attribute__((target("arm"))) f(char *out)
 
 void __attribute__((target("thumb"))) g(char *out)
 {
-  asm("" : "=@ccne"(out[0]));  /* { dg-message "asm flags not supported" } */
+  asm("" : "=@ccne"(out[0]));  /* { dg-message ".asm. flags not supported" } */
 }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[libstdc++] [testsuite] intro/names.cc: undef func on vxw7krn

2023-02-16 Thread Alexandre Oliva via Gcc-patches


The '#define func' added in 2021, to test that system headers don't
violate the user namespace, exposes such a bug in the vxworks sysLib.h
header, so add yet another such annotated workaround.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

* testsuite/17_intro/names.cc: Undef func on vxworks >= 7 in
kernel mode.
---
 libstdc++-v3/testsuite/17_intro/names.cc |2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/testsuite/17_intro/names.cc 
b/libstdc++-v3/testsuite/17_intro/names.cc
index d3e0db9bab6b9..c2d67ebe01276 100644
--- a/libstdc++-v3/testsuite/17_intro/names.cc
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
@@ -329,6 +329,8 @@
 #undef d
 #undef e
 #undef f
+// in sysLib.h, func appears as a formal parameter name
+#undef func
 #endif // __RTP__
 
 #endif // VxWorks Major >= 7

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [arm] xfail fp-uint64-convert-double-* on all arm targets

2023-02-16 Thread Alexandre Oliva via Gcc-patches


It wasn't long ago that I xfailed these tests on arm-*-eabi, but the
fail is expected on all other arm targets: even when hard float is
available, conversions between 64-bit integers and double are always
emulated on ARM, and the emulation disregards rounding modes.  So,
bump the xfail to all of arm-*-*.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* gcc.dg/torture/fp-uint64-convert-double-1.c: XFAIL on all of
arm-*-*.
* gcc.dg/torture/fp-uint64-convert-double-2.c: Likewise.
---
 .../gcc.dg/torture/fp-uint64-convert-double-1.c|2 +-
 .../gcc.dg/torture/fp-uint64-convert-double-2.c|2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c 
b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c
index 61cfa96374631..8f437e2efb1db 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c
@@ -1,5 +1,5 @@
 /* PR84407 */
-/* { dg-do run { xfail { arm-*-eabi* } } } */
+/* { dg-do run { xfail { arm-*-* } } } */
 /* { dg-require-effective-target fenv } */
 /* { dg-require-effective-target hard_float } */
 /* { dg-additional-options "-frounding-math -fexcess-precision=standard" } */
diff --git a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c 
b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c
index b32b28a329580..fd3f4cbfb830f 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c
@@ -1,5 +1,5 @@
 /* PR84407 */
-/* { dg-do run { xfail { arm-*-eabi* } } } */
+/* { dg-do run { xfail { arm-*-* } } } */
 /* { dg-require-effective-target fenv } */
 /* { dg-require-effective-target hard_float } */
 /* { dg-additional-options "-frounding-math" } */


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[libstdc++] Use __gthread_join in jthread/95989

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Ref: https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570617.html

Bernd Edlinger  reported that the 95989.cc
test fails without pthread_join at the end of main, but pthread_join
is no good for a test that doesn't require pthreads.

This patch adds a __gthread_join call instead.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

* testsuite/30_threads/jthread/95989.cc (main): Call
__gthread_join at the end.
---
 libstdc++-v3/testsuite/30_threads/jthread/95989.cc |1 +
 1 file changed, 1 insertion(+)

diff --git a/libstdc++-v3/testsuite/30_threads/jthread/95989.cc 
b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
index e98836d094531..407b52748438c 100644
--- a/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
+++ b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc
@@ -52,4 +52,5 @@ main()
   test01();
   test02();
   test03();
+  __gthread_join(0, NULL);
 }

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PR100127] Test for coroutine header in clang-compatible tests

2023-02-16 Thread Alexandre Oliva via Gcc-patches


The test is compatible with clang as well as gcc, but ISTM that
testing for the __clang__ macro is just as potentially error-prone as
macros that used to be GCC-specific are now defined in compilers that
aim for GCC compatibility.  Use a __has_include feature test instead.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

PR c++/100127
* g++.dg/coroutines/pr100127.C: Test for header rather than
compiler macro.
---
 gcc/testsuite/g++.dg/coroutines/pr100127.C   |2 +-
 gcc/testsuite/g++.dg/coroutines/pr100772-a.C |2 +-
 gcc/testsuite/g++.dg/coroutines/pr100772-b.C |2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/g++.dg/coroutines/pr100127.C 
b/gcc/testsuite/g++.dg/coroutines/pr100127.C
index 374cd710077af..1eaa72ff0acdd 100644
--- a/gcc/testsuite/g++.dg/coroutines/pr100127.C
+++ b/gcc/testsuite/g++.dg/coroutines/pr100127.C
@@ -1,4 +1,4 @@
-#ifdef __clang__
+#if __has_include() // for __clang__
 #include 
 namespace std {
   using namespace std::experimental;
diff --git a/gcc/testsuite/g++.dg/coroutines/pr100772-a.C 
b/gcc/testsuite/g++.dg/coroutines/pr100772-a.C
index a325d384fc390..724c377c82e5b 100644
--- a/gcc/testsuite/g++.dg/coroutines/pr100772-a.C
+++ b/gcc/testsuite/g++.dg/coroutines/pr100772-a.C
@@ -1,5 +1,5 @@
 //  { dg-additional-options "-fsyntax-only " }
-#ifdef __clang__
+#if __has_include() // for __clang__
 #include 
 namespace std {
   using namespace std::experimental;
diff --git a/gcc/testsuite/g++.dg/coroutines/pr100772-b.C 
b/gcc/testsuite/g++.dg/coroutines/pr100772-b.C
index 6cdf8d1e529e5..4cf31e5f9e0c2 100644
--- a/gcc/testsuite/g++.dg/coroutines/pr100772-b.C
+++ b/gcc/testsuite/g++.dg/coroutines/pr100772-b.C
@@ -1,4 +1,4 @@
-#ifdef __clang__
+#if __has_include() // for __clang__
 #include 
 namespace std {
   using namespace std::experimental;

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] Skip module_cmi_p and related unsupported module test

2023-02-16 Thread Alexandre Oliva via Gcc-patches


When a multi-source module is found to be unsupported, we fail
module_cmi_p and subsequent sources.  Override proc unsupported to
mark the result in module_do, and test it to skip module_cmp_p and
subsequent related tests.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* g++.dg/modules/modules.exp: Override unsupported to update
module_do, and test it after dg-test.
---
 gcc/testsuite/g++.dg/modules/modules.exp |   14 ++
 1 file changed, 14 insertions(+)

diff --git a/gcc/testsuite/g++.dg/modules/modules.exp 
b/gcc/testsuite/g++.dg/modules/modules.exp
index 61994b059457b..ba1287427bf05 100644
--- a/gcc/testsuite/g++.dg/modules/modules.exp
+++ b/gcc/testsuite/g++.dg/modules/modules.exp
@@ -315,6 +315,14 @@ proc module-check-requirements { tests } {
 # cleanup any detritus from previous run
 cleanup_module_files [find $DEFAULT_REPO *.gcm]
 
+set module_do {"compile" "P"}
+rename unsupported saved-unsupported
+proc unsupported { args } {
+global module_do
+lset module_do 1 "N"
+return [saved-unsupported $args]
+}
+
 # not grouped tests, sadly tcl doesn't have negated glob
 foreach test [prune [lsort [find $srcdir/$subdir {*.[CH]}]] \
  "$srcdir/$subdir/*_?.\[CH\]"] {
@@ -327,6 +335,9 @@ foreach test [prune [lsort [find $srcdir/$subdir {*.[CH]}]] 
\
set module_cmis {}
verbose "Testing $nshort $std" 1
dg-test $test "$std" $DEFAULT_MODFLAGS
+   if { [lindex $module_do 1] == "N" } {
+   continue
+   }
set testcase [string range $test [string length "$srcdir/"] end]
cleanup_module_files [module_cmi_p $testcase $module_cmis]
}
@@ -372,6 +383,9 @@ foreach src [lsort [find $srcdir/$subdir {*_a.[CHX}]] {
}
}
dg-test -keep-output $test "$std" $DEFAULT_MODFLAGS
+   if { [lindex $module_do 1] == "N" } {
+   break
+   }
set testcase [string range $test [string length "$srcdir/"] 
end]
lappend mod_files [module_cmi_p $testcase $module_cmis]
}

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] Drop need for constant I in ctf test

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Though I is supposed to be a constant expression, this is not the case
on vxworks, but this is not what this debug information format test is
testing for, so use real constants to initialize complex variables.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* gcc.dg/debug/ctf/ctf-complex-1.c: Do not test whether I is
usable in initializers.
---
 gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c 
b/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c
index a36dd9b6b90a9..e6c3199f913d7 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-complex-1.c
@@ -14,8 +14,8 @@
 
 #include 
 
-double complex z1 = I * I;
+double complex z1 = -1;
 
-const long double complex z2 = I * I;
+const long double complex z2 = -1;
 
-float complex z4 = 1+2.11*I;
+float complex z4 = 1;

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] Accept pmf-vbit-in-delta extra warning

2023-02-16 Thread Alexandre Oliva via Gcc-patches


cp_build_binary_op, that issues -Waddress warnings, issues an extra
warning on arm targets, that g++.dg/warn/Waddress-5.C does not expect
when comparing a pointer-to-member-function literal with null.

The reason for the extra warning is that, on arm targets,
TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta, which
causes a different path to be taken, that extracts the
pointer-to-function and the delta fields (minus the vbit) and compares
each one with zero.  It's when comparing this pointer-to-function with
zero, in a recursive cp_build_binary_op, that another warning is
issued.

I suppose there should be a way to skip the warning in this recursive
call, without disabling other warnings that might be issued there, but
this patch only arranges for the test to tolerate the extra warning.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* g++.dg/warn/Waddress-5.C: Tolerate extra -Waddress warning.
---
 gcc/testsuite/g++.dg/warn/Waddress-5.C |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/warn/Waddress-5.C 
b/gcc/testsuite/g++.dg/warn/Waddress-5.C
index b1287b2fac316..1de88076f7767 100644
--- a/gcc/testsuite/g++.dg/warn/Waddress-5.C
+++ b/gcc/testsuite/g++.dg/warn/Waddress-5.C
@@ -23,7 +23,11 @@ void T (bool);
 void warn_memptr_if ()
 {
   // Exercise warnings for addresses of nonstatic member functions.
-  if (&A::f == 0) // { dg-warning "the address '&A::f'" }
+  // On targets with TARGET_PTRMEMFUNC_VBIT_LOCATION ==
+  // ptrmemfunc_vbit_in_delta, cp_build_binary_op recurses to compare
+  // the pfn from the ptrmemfunc with null, so we get two warnings.
+  // This matches both.  ??? Should we disable one of them?
+  if (&A::f == 0) // { dg-warning "A::f" }
 T (0);
 
   if (&A::vf) // { dg-warning "-Waddress" }

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [vxworks] make wint_t and wchar_t the same distinct type

2023-02-16 Thread Alexandre Oliva via Gcc-patches


We used to define WINT_TYPE to WCHAR_TYPE, so that both wint_t and
wchar_t mapped to the same underlying type, but this caused a glitch
in Wstringop-overflow-6.C: on vxworks, wint_t is typedef'ed to
wchar_t, headers got included in the test that declared functions that
take wint_t parameters, and those conflicted with the builtin
declarations that had wint_t mapped to the underlying integral type.

The problem is that, in C++, wchar_t is a distinct type.  Having
wint_t be a typedef to wchar_t in the headers, but a typedef to
wchar_t's underlying integral type in builtins, makes for mismatches
between the declarations.

This patch defines WINT_TYPE to "wchar_t" for vxworks, and adjusts the
fallout, namely:

- since wchar_t may not have been defined yet when
  c_common_nodes_and_builtins runs, use the node already reserved for
  wchar_t for wint_t when WINT_TYPE is defined to wchar_t.

- for the same reason, when WINT_TYPE is wchar_t and we're not
  compiling C++ where wchar_t is a compiler built-in, define
  __WINT_TYPE__ to WCHAR_TYPE rather than WINT_TYPE, because wchar_t
  may not even be defined in the translation unit.

- recognize and handle wchar_type_node when type_suffix is called for
  wint_type_node.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/ChangeLog

* config/vx-common.h (WINT_TYPE): Alias to "wchar_t".

for  gcc/c-family/ChangeLog

* c-common.cc (c_common_nodes_and_builtins): Take
wchar_type_node for wint_type_node when aliased.
(c_stddef_cpp_builtins): Define __WINT_TYPE__, when aliased to
wchar_t, to the underlying type rather than wchar_t in
non-C++.
* c-cppbuiltin.cc (type_suffix): Handle wchar_type_node.
---
 gcc/c-family/c-common.cc |   16 +---
 gcc/c-family/c-cppbuiltin.cc |2 ++
 gcc/config/vx-common.h   |2 +-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index ae92cd5adaf5e..a92597c2f544f 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -4576,8 +4576,11 @@ c_common_nodes_and_builtins (void)
   char32_array_type_node
 = build_array_type (char32_type_node, array_domain_type);
 
-  wint_type_node =
-TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE)));
+  if (strcmp (WINT_TYPE, "wchar_t") == 0)
+wint_type_node = wchar_type_node;
+  else
+wint_type_node =
+  TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE)));
 
   intmax_type_node =
 TREE_TYPE (identifier_global_value (get_identifier (INTMAX_TYPE)));
@@ -5359,7 +5362,14 @@ c_stddef_cpp_builtins(void)
   builtin_define_with_value ("__SIZE_TYPE__", SIZE_TYPE, 0);
   builtin_define_with_value ("__PTRDIFF_TYPE__", PTRDIFF_TYPE, 0);
   builtin_define_with_value ("__WCHAR_TYPE__", MODIFIED_WCHAR_TYPE, 0);
-  builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0);
+  /* C++ has wchar_t as a builtin type, C doesn't, so if WINT_TYPE
+ maps to wchar_t, define it to the underlying WCHAR_TYPE in C, and
+ to wchar_t in C++, so the desired type equivalence holds.  */
+  if (!c_dialect_cxx ()
+  && strcmp (WINT_TYPE, "wchar_t") == 0)
+builtin_define_with_value ("__WINT_TYPE__", WCHAR_TYPE, 0);
+  else
+builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0);
   builtin_define_with_value ("__INTMAX_TYPE__", INTMAX_TYPE, 0);
   builtin_define_with_value ("__UINTMAX_TYPE__", UINTMAX_TYPE, 0);
   if (flag_char8_t)
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index b333f97fd3237..98f5aef2af95d 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1903,6 +1903,8 @@ type_suffix (tree type)
  systems use it anyway.  */
   || type == char_type_node)
 is_long = 0;
+  else if (type == wchar_type_node)
+return type_suffix (underlying_wchar_type_node);
   else
 gcc_unreachable ();
 
diff --git a/gcc/config/vx-common.h b/gcc/config/vx-common.h
index 83580d0dec288..9733c90fe4c6f 100644
--- a/gcc/config/vx-common.h
+++ b/gcc/config/vx-common.h
@@ -69,7 +69,7 @@ along with GCC; see the file COPYING3.  If not see
 #undef WINT_TYPE_SIZE
 #define WINT_TYPE_SIZE WCHAR_TYPE_SIZE
 #undef WINT_TYPE
-#define WINT_TYPE WCHAR_TYPE
+#define WINT_TYPE "wchar_t"
 
 /* -- Debug and unwind info formats --  */
 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [arm] disable aes-1742098 mitigation for a72 combine tests

2023-02-16 Thread Alexandre Oliva via Gcc-patches


The expected asm output for aes-fuse-[12].c does not correspond to
that which is generated when -mfix-cortex-a57-aes-1742098 is enabled.
It was introduced after the test, and enabled by default for the
selected processor.  Disabling the option restores the circumstance
that was tested for.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* gcc.target/arm/aes-fuse-1.c: Add
-mno-fix-cortex-a57-aes-1742098.
* gcc.target/arm/aes-fuse-2.c: Likewise.
---
 gcc/testsuite/gcc.target/arm/aes-fuse-1.c |4 
 gcc/testsuite/gcc.target/arm/aes-fuse-2.c |4 
 2 files changed, 8 insertions(+)

diff --git a/gcc/testsuite/gcc.target/arm/aes-fuse-1.c 
b/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
index 27b08aeef7ba7..6ffb4991cca69 100644
--- a/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
+++ b/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
@@ -2,6 +2,10 @@
 /* { dg-require-effective-target arm_crypto_ok } */
 /* { dg-add-options arm_crypto } */
 /* { dg-additional-options "-mcpu=cortex-a72 -O3 -dp" } */
+/* The mitigation applies to a72 by default, and protects the CRYPTO_AES
+   inputs, such as the explicit xor ops, from being combined like test used to
+   expect.  */
+/* { dg-additional-options "-mno-fix-cortex-a57-aes-1742098" } */
 
 #include 
 
diff --git a/gcc/testsuite/gcc.target/arm/aes-fuse-2.c 
b/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
index 1266a28753169..b72479c0e5726 100644
--- a/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
+++ b/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
@@ -2,6 +2,10 @@
 /* { dg-require-effective-target arm_crypto_ok } */
 /* { dg-add-options arm_crypto } */
 /* { dg-additional-options "-mcpu=cortex-a72 -O3 -dp" } */
+/* The mitigation applies to a72 by default, and protects the CRYPTO_AES
+   inputs, such as the explicit xor ops, from being combined like test used to
+   expect.  */
+/* { dg-additional-options "-mno-fix-cortex-a57-aes-1742098" } */
 
 #include 
 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] -Wdangling-pointer: don't mark SSA lhs sets as stores

2023-02-16 Thread Alexandre Oliva via Gcc-patches


check_dangling_stores has some weirdnesses that causes its behavior to
change when the target ABI requires C++ ctors to return this: while
scanning stmts backwards in e.g. the AS ctor on a target that returns
this in ctors, the scan first encounters a copy of this to the SSA
name used to hold the return value.  m_ptr_query.get_ref resolves lhs
(the return SSA name) to the rhs (the default SSA name for this), does
not skip it because auto_var_p is false for SSA_NAMEs, and proceeds to
add it to stores, which seems to prevent later attempts to add stores
into *this from succeeding, which disables warnings that should have
triggered.

This is also the case when the backwards search finds unrelated stores
to other fields of *this before it reaches stores that IMHO should be
warned about.  The store found first disables checking of other
stores, as if the store appearing later in the code would necessarily
overwrite the store that should be warned about.  I've added an
xfailed variant of the existing test (struct An) that triggers this
problem, but I'm not sure how to go about fixing it.

Meanwhile, this patch prevents assignments with SSA_NAMEs in the lhs
from being regarded as stores, which is enough to remove the
undesirable side effect on -Wdangling-pointer of ABI-mandated ctors'
returning this.  Another variant of the existing test (struct Al) that
demonstrates the problem regardless of this aspect of the ABI, and
that gets the desired warning with the proposed patch, but not
without.

Curiously, this fix exposes yet another problem in
Wdangling-pointer-5.c: it is the return stmt of the unrelated pointer
p, not the store into possibly-overlapping *vpp2, that caused the
warning to not be issued for the store in *vpp1.  I'm not sure whether
we should or should not warn in that case, but this patch adjusts the
test to reflect the behavior change.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/ChangeLog

* gimple-ssa-warn-access.cc
(pass_waccess::check_dangling_stores): Skip non-stores.

for  gcc/testsuite/ChangeLog

* g++.dg/warn/Wdangling-pointer.C (warn_init_ref_member): Add
two new variants, one fixed, one xfailed.
* c-c++-common/Wdangling-pointer-5.c
(nowarn_store_arg_store_arg): Add now-expected warnings.
---
 gcc/gimple-ssa-warn-access.cc|3 ++
 gcc/testsuite/c-c++-common/Wdangling-pointer-5.c |4 ++-
 gcc/testsuite/g++.dg/warn/Wdangling-pointer.C|   29 +-
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 2eab1d59abd05..c0efb3fdb4e52 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -4511,7 +4511,8 @@ pass_waccess::check_dangling_stores (basic_block bb,
   use the escaped locals.  */
return;
 
-  if (!is_gimple_assign (stmt) || gimple_clobber_p (stmt))
+  if (!is_gimple_assign (stmt) || gimple_clobber_p (stmt)
+ || !gimple_store_p (stmt))
continue;
 
   access_ref lhs_ref;
diff --git a/gcc/testsuite/c-c++-common/Wdangling-pointer-5.c 
b/gcc/testsuite/c-c++-common/Wdangling-pointer-5.c
index 2a165cea76768..cb6da9e86394d 100644
--- a/gcc/testsuite/c-c++-common/Wdangling-pointer-5.c
+++ b/gcc/testsuite/c-c++-common/Wdangling-pointer-5.c
@@ -75,9 +75,9 @@ void nowarn_store_arg_store (void **vpp)
 
 void* nowarn_store_arg_store_arg (void **vpp1, void **vpp2)
 {
-  int x;
+  int x;  // { dg-message "'x' declared here" }
   void **p = (void**)sink (0);
-  *vpp1 = &x; // warn here?
+  *vpp1 = &x; // { dg-warning "storing the address of local variable 
'x' in '\\*vpp1'" }
   *vpp2 = 0;  // might overwrite *vpp1
   return p;
 }
diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-pointer.C 
b/gcc/testsuite/g++.dg/warn/Wdangling-pointer.C
index 22c559e4adafe..a94477a647666 100644
--- a/gcc/testsuite/g++.dg/warn/Wdangling-pointer.C
+++ b/gcc/testsuite/g++.dg/warn/Wdangling-pointer.C
@@ -35,7 +35,34 @@ void warn_init_ref_member ()
 { }
   } ai;
 
-  sink (&as, &ai);
+  struct Al
+  {
+const S &sref;
+Al ():
+  // The temporary S object is destroyed when Al::Al() returns.
+  sref (S ())  // { dg-warning "storing the address" }
+{
+  // Copying this to an SSA_NAME used to disable the warning:
+  Al *ptr = this;
+  asm ("" : "+r" (ptr));
+}
+  } al;
+
+  struct An
+  {
+An *next;
+const S &sref;
+An ():
+  next (0),
+  // The temporary S object is destroyed when An::An() returns.
+  sref (S ())  // { dg-warning "storing the address" "" { xfail *-*-* } }
+{
+  // ??? Writing to another part of *this disables the warning:
+  next = 0;
+}
+  } an;
+
+  sink (&as, &ai, &al, &an);
 }
 
 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist 

[PATCH] [arm] adjust tests for quotes around +cdecp

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Back when quotes were added around "+cdecp" in the "coproc must be
a constant immediate" error in arm-builtins.cc, tests for that message
lagged behind.  Fixed thusly.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* gcc.target/arm/acle/cde-errors.c: Adjust messages for quote
around +cdecp.
* gcc.target/arm/acle/cde-mve-error-2.c: Likewise.
---
 gcc/testsuite/gcc.target/arm/acle/cde-errors.c |   52 ++---
 .../gcc.target/arm/acle/cde-mve-error-2.c  |   82 ++--
 2 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/acle/cde-errors.c 
b/gcc/testsuite/gcc.target/arm/acle/cde-errors.c
index 85a91666cd5ef..f38514848677e 100644
--- a/gcc/testsuite/gcc.target/arm/acle/cde-errors.c
+++ b/gcc/testsuite/gcc.target/arm/acle/cde-errors.c
@@ -47,19 +47,19 @@ uint64_t test_cde (uint32_t n, uint32_t m)
   accum += __arm_cx3da (7, accum, n, m,   0); /* { dg-error 
{coprocessor 7 is not enabled with \+cdecp7} } */
 
   /* `coproc` out of range.  */
-  accum += __arm_cx1   (8,0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx1a  (8, (uint32_t)accum,   0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx2   (8, n, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx2a  (8, (uint32_t)accum, n,0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx3   (8, n, m,  0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx3a  (8, (uint32_t)accum, n, m, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-
-  accum += __arm_cx1d  (8,0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx1da (8, accum, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx2d  (8, n, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx2da (8, accum, n,  0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx3d  (8, n, m,  0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
-  accum += __arm_cx3da (8, accum, n, m,   0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with \+cdecp} } */
+  accum += __arm_cx1   (8,0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx1a  (8, (uint32_t)accum,   0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx2   (8, n, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx2a  (8, (uint32_t)accum, n,0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx3   (8, n, m,  0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx3a  (8, (uint32_t)accum, n, m, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+
+  accum += __arm_cx1d  (8,0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx1da (8, accum, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx2d  (8, n, 0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx2da (8, accum, n,  0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx3d  (8, n, m,  0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
+  accum += __arm_cx3da (8, accum, n, m,   0); /* { dg-error {coproc 
must be a constant immediate in range \[0-7\] enabled with .\+cdecp.} } */
 
   /* `imm` out of range.  */
   accum += __arm_cx1   (0,8192); /* { dg-error 
{argument 2 to '__builtin_arm_cx1si' must be a constant immediate in range 
\[0-8191\]} } */
@@ -92

[PATCH] [PR51534] [arm] split out pr51534 test for softfp

2023-02-16 Thread Alexandre Oliva via Gcc-patches


The test uses arm_hard_ok and arm_softfp_ok as if they were mutually
exclusive, but they test whether the corresponding -mfloat-abi= flag
is usable, not whether it is in effect, so it is possible for both to
pass, and then the test comes out with incorrect expectations
whichever the default float-abi is.

Separate the test into hard and softfp variants, and extend the softfp
variant to accept both ARM and Thumb opcodes; it unwarrantedly assumed
the latter.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

PR target/51534
* gcc.target/arm/pr51534.c: Split softfp variant into...
* gcc.target/arm/pr51534s.c: ... this, and support ARM too.
---
 gcc/testsuite/gcc.target/arm/pr51534.c  |9 ++--
 gcc/testsuite/gcc.target/arm/pr51534s.c |   72 +++
 2 files changed, 76 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pr51534s.c

diff --git a/gcc/testsuite/gcc.target/arm/pr51534.c 
b/gcc/testsuite/gcc.target/arm/pr51534.c
index 5e121f5fb9946..ba21259bee554 100644
--- a/gcc/testsuite/gcc.target/arm/pr51534.c
+++ b/gcc/testsuite/gcc.target/arm/pr51534.c
@@ -1,9 +1,9 @@
 /* Test the vector comparison intrinsics when comparing to immediate zero.
*/
 
-/* { dg-do assemble } */
+/* { dg-do assemble { target { arm_hard_ok } } } */
 /* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-save-temps -O3" } */
+/* { dg-options "-save-temps -mfloat-abi=hard -O3" } */
 /* { dg-add-options arm_neon } */
 
 #include 
@@ -64,9 +64,8 @@ GEN_COND_TESTS(vceq)
 /* { dg-final { scan-assembler-times "vceq\.i8\[   \]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" 4 } } */
 /* { dg-final { scan-assembler-times "vceq\.i16\[  \]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" 4 } } */
 /* { dg-final { scan-assembler-times "vceq\.i32\[  \]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" 4 } } */
-/* { dg-final { scan-assembler-times "vmov\.i32\[  \]+\[dD\]\[0-9\]+, 
#0x" 3 { target { arm_hard_ok } } } } */
-/* { dg-final { scan-assembler-times "vmov\.i32\[  \]+\[qQ\]\[0-9\]+, 
#4294967295" 3 { target { arm_hard_ok } } } } */
-/* { dg-final { scan-assembler-times "mov\[\]+r\[0-9\]+, #-1" 6 { target { 
arm_softfp_ok } } } } */
+/* { dg-final { scan-assembler-times "vmov\.i32\[  \]+\[dD\]\[0-9\]+, 
#0x" 3 } } */
+/* { dg-final { scan-assembler-times "vmov\.i32\[  \]+\[qQ\]\[0-9\]+, 
#4294967295" 3 } } */
 
 /* And ensure we don't have unexpected output too.  */
 /* { dg-final { scan-assembler-not "vc\[gl\]\[te\]\.u\[0-9\]+\[
\]+\[qQdD\]\[0-9\]+, \[qQdD\]\[0-9\]+, #0" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr51534s.c 
b/gcc/testsuite/gcc.target/arm/pr51534s.c
new file mode 100644
index 0..b1638919c2f75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr51534s.c
@@ -0,0 +1,72 @@
+/* Test the vector comparison intrinsics when comparing to immediate zero.
+   */
+
+/* { dg-do assemble { target { arm_softfp_ok } } } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -mfloat-abi=softfp -O3" } */
+/* { dg-add-options arm_neon } */
+
+#include 
+
+#define GEN_TEST(T, D, C, R) \
+  R test_##C##_##T (T a) { return C (a, D (0)); }
+
+#define GEN_DOUBLE_TESTS(S, T, C) \
+  GEN_TEST (T, vdup_n_s##S, C##_s##S, u##T) \
+  GEN_TEST (u##T, vdup_n_u##S, C##_u##S, u##T) 
+
+#define GEN_QUAD_TESTS(S, T, C) \
+  GEN_TEST (T, vdupq_n_s##S, C##q_s##S, u##T) \
+  GEN_TEST (u##T, vdupq_n_u##S, C##q_u##S, u##T) 
+
+#define GEN_COND_TESTS(C) \
+  GEN_DOUBLE_TESTS (8, int8x8_t, C) \
+  GEN_DOUBLE_TESTS (16, int16x4_t, C) \
+  GEN_DOUBLE_TESTS (32, int32x2_t, C) \
+  GEN_QUAD_TESTS (8, int8x16_t, C) \
+  GEN_QUAD_TESTS (16, int16x8_t, C) \
+  GEN_QUAD_TESTS (32, int32x4_t, C)
+
+GEN_COND_TESTS(vcgt)
+GEN_COND_TESTS(vcge)
+GEN_COND_TESTS(vclt)
+GEN_COND_TESTS(vcle)
+GEN_COND_TESTS(vceq)
+
+/* Scan for expected outputs.  */
+/* { dg-final { scan-assembler "vcgt\.s8\[ \]+\[dD\]\[0-9\]+, 
\[dD\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcgt\.s16\[\]+\[dD\]\[0-9\]+, 
\[dD\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcgt\.s32\[\]+\[dD\]\[0-9\]+, 
\[dD\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcgt\.s8\[ \]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcgt\.s16\[\]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcgt\.s32\[\]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcge\.s8\[ \]+\[dD\]\[0-9\]+, 
\[dD\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcge\.s16\[\]+\[dD\]\[0-9\]+, 
\[dD\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcge\.s32\[\]+\[dD\]\[0-9\]+, 
\[dD\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcge\.s8\[ \]+\[qQ\]\[0-9\]+, 
\[qQ\]\[0-9\]+, #0" } } */
+/* { dg-final { scan-assembler "vcge\.s16\[\]+\[qQ\]

[PATCH] [arm] adjust expectations for armv8_2-fp16-move-[12].c

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Commit 3a7ba8fd0cda387809e4902328af2473662b6a4a, a patch for
tree-ssa-sink, enabled the removal of basic blocks in ways that
affected the generated code for both of these tests, deviating from
the expectations of the tests.

The simplest case is that of -2, in which the edge unsplitting ends up
enabling a conditional return rather than a conditional branch to a
set-and-return block.  That looks like an improvement to me, but the
condition in which the branch or the return takes place can be
reasonably reversed (and, with the current code, it is), I've relaxed
the pattern in the test so as to accept reversed and unreversed
conditions applied to return or branch opcodes.

The situation in -1 is a little more elaborate: conditional branches
based on FP compares in test_select_[78] are initially expanded with
CCFPE compare-and-cbranch on G{T,E}, but when ce2 turns those into a
cmove, because now we have a different fallthrough block, the
condition is reversed, and that lands us with a compare-and-cmove
sequence that needs CCFP for UNL{E,T}.  The insn output reverses the
condition and swaps the cmove input operands, so the vcmp and vsel
insns come out the same except for the missing 'e' (for the compare
mode) in vcmp, so, since such reversals could have happened to any of
the tests depending on legitimate basic block layout, I've combined
the vcmp and vcmpe counts.

I see room for improving cmove sequence generation, e.g. trying direct
and reversed conditions and selecting the cheapest one (which would
require CCFP conditions to be modeled as more expensive than CCFPE),
or for some other machine-specific (peephole2?) optimization to turn
CCFP-requiring compare and cmove into CCFPE compare and swapped-inputs
cmove, but I haven't tried that.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* gcc.target/arm/armv8_2-fp16-move-1.c: Combine vcmp and vcmpe
expected counts into a single pattern.
* gcc.target/arm/armv8_2-fp16-move-2.c: Accept conditional
return and reversed conditions.
---
 gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-1.c |3 +--
 gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-2.c |2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-1.c 
b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-1.c
index 009bb8d1575a4..444c4a3353555 100644
--- a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-1.c
+++ b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-1.c
@@ -196,5 +196,4 @@ test_compare_5 (__fp16 a, __fp16 b)
 /* { dg-final { scan-assembler-not {vcmp\.f16} } }  */
 /* { dg-final { scan-assembler-not {vcmpe\.f16} } }  */
 
-/* { dg-final { scan-assembler-times {vcmp\.f32} 4 } }  */
-/* { dg-final { scan-assembler-times {vcmpe\.f32} 8 } }  */
+/* { dg-final { scan-assembler-times {vcmpe?\.f32} 12 } }  */
diff --git a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-2.c 
b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-2.c
index fcb857f29ff15..dff57ac8147c2 100644
--- a/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-2.c
+++ b/gcc/testsuite/gcc.target/arm/armv8_2-fp16-move-2.c
@@ -8,4 +8,4 @@ test_select (__fp16 a, __fp16 b, __fp16 c)
 {
   return (a < b) ? b : c;
 }
-/* { dg-final { scan-assembler "bmi" } } */
+/* { dg-final { scan-assembler "bx?(mi|pl)" } } */

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [arm] complete vmsr/vmrs blank and case adjustments

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Back in September last year, some of the vmsr and vmrs patterns had an
extraneous blank removed, and the case of register names lowered, but
another instance remained, and so did a few testcases.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/ChangeLog

* config/arm/vfp.md (*thumb2_movsi_vfp): Drop blank after tab
after vmsr and vmrs, and lower the case of P0.

for  gcc/testsuite/ChangeLog

* gcc.target/arm/acle/cde-mve-full-assembly.c: Drop blank
after tab after vmsr, and lower the case of P0.
---
 gcc/config/arm/vfp.md  |4 
 .../gcc.target/arm/acle/cde-mve-full-assembly.c|  264 ++--
 2 files changed, 134 insertions(+), 134 deletions(-)

diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index f34f35e1185e2..60e7ba35d8b25 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -312,9 +312,9 @@ (define_insn "*thumb2_movsi_vfp"
 case 12: case 13:
   return output_move_vfp (operands);
 case 14:
-  return \"vmsr\\t P0, %1\";
+  return \"vmsr\\tp0, %1\";
 case 15:
-  return \"vmrs\\t %0, P0\";
+  return \"vmrs\\t%0, p0\";
 case 16:
   return \"mcr\\tp10, 7, %1, cr1, cr0, 0\\t @SET_FPSCR\";
 case 17:
diff --git a/gcc/testsuite/gcc.target/arm/acle/cde-mve-full-assembly.c 
b/gcc/testsuite/gcc.target/arm/acle/cde-mve-full-assembly.c
index d025c3391fbe5..72f330185944a 100644
--- a/gcc/testsuite/gcc.target/arm/acle/cde-mve-full-assembly.c
+++ b/gcc/testsuite/gcc.target/arm/acle/cde-mve-full-assembly.c
@@ -534,80 +534,80 @@
contain back references).  */
 /*
 ** test_cde_vcx1q_mfloat16x8_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_mfloat32x4_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_muint8x16_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_muint16x8_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_muint32x4_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_muint64x2_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_mint8x16_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_mint16x8_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx1q_mint32x4_tintint:
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
-** (?:vmov\.i32q0, #0  @ v16qi|vmsr P0, r2 @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
+** (?:vmov\.i32q0, #0  @ v16qi|vmsrp0, r2  @ movhi)
 ** vpst
 ** vcx1t   p0, q0, #32
 ** bx  lr
 */
 /*
 ** test_cde_vcx

[PATCH] [PR104882] [arm] require mve hw for mve run test

2023-02-16 Thread Alexandre Oliva via Gcc-patches


The pr104882.c test is an execution test, but arm_v8_1m_mve_ok only
tests for compile-time support.  Add a requirement for mve hardware.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

PR target/104882
* gcc.target/arm/simd/pr104882.c: Require mve hardware.
---
 gcc/testsuite/gcc.target/arm/simd/pr104882.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.target/arm/simd/pr104882.c 
b/gcc/testsuite/gcc.target/arm/simd/pr104882.c
index ae9709af42f22..1ea7a14836f54 100644
--- a/gcc/testsuite/gcc.target/arm/simd/pr104882.c
+++ b/gcc/testsuite/gcc.target/arm/simd/pr104882.c
@@ -1,4 +1,5 @@
 /* { dg-do run } */
+/* { dg-require-effective-target arm_mve_hw } */
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [libstdc++] xfail noreplace tests on vxworks

2023-02-16 Thread Alexandre Oliva via Gcc-patches


vxworks ignores O_EXCL in open, so noreplace open succeeds when it is
expected to fail.  xfail the tests.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

* testsuite/27_io/basic_ofstream/open/char/noreplace.cc: xfail
on vxworks.
* testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc:
Likewise.
---
 .../27_io/basic_ofstream/open/char/noreplace.cc|2 +-
 .../27_io/basic_ofstream/open/wchar_t/noreplace.cc |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/noreplace.cc 
b/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/noreplace.cc
index 56ff2d7cead3c..2e99707df86d0 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/noreplace.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/noreplace.cc
@@ -1,4 +1,4 @@
-// { dg-do run }
+// { dg-do run { xfail *-*-vxworks* } }
 
 #include 
 
diff --git 
a/libstdc++-v3/testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc 
b/libstdc++-v3/testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc
index f0425cdab3d23..ddb7fd691608c 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ofstream/open/wchar_t/noreplace.cc
@@ -1,4 +1,4 @@
-// { dg-do run }
+// { dg-do run { xfail *-*-vxworks* } }
 
 #include 
 

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [arm] [vxworks] xfail fp-double-convert-float-1.c

2023-02-16 Thread Alexandre Oliva via Gcc-patches


Even with vcvt.f32.f64, the FE_UPWARD test rounds down and fails.  I'm
not sure whether this opcode disregards the rounding mode (it looks
like it should take it into account) or it is a qemu bug, but it does
not look like GCC is doing anything wrong, and the test fails, so I'm
marking the fail as expected on arm-*-vxworks*.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  gcc/testsuite/ChangeLog

* gcc.dg/torture/fp-double-convert-float-1.c: XFAIL on
arm-*-vxworks*.
---
 .../gcc.dg/torture/fp-double-convert-float-1.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c 
b/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c
index 1c28a9e101eb7..c3ca69d64bbc6 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c
@@ -1,5 +1,5 @@
 /* PR57245 */
-/* { dg-do run } */
+/* { dg-do run { xfail { arm-*-vxworks* } } } */
 /* { dg-require-effective-target fenv } */
 /* { dg-require-effective-target hard_float } */
 /* { dg-additional-options "-frounding-math" } */

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [libstdc++] ensure mutex_pool survives _Safe_sequence_base

2023-02-16 Thread Alexandre Oliva via Gcc-patches


On vxworks, after destroying the semaphore used to implement a mutex,
__gthread_mutex_lock fails and __gnu_cxx::__mutex::lock calls
__throw_concurrence_lock_error.  Nothing ensures the mutex_pool
mutexes survive init-once objects containing _Safe_sequence_base.  If
such an object completes construction before mutex_pool
initialization, it will be registered for atexit destruction after the
mutex_pool mutexes, so the _M_detach_all() call in the
_Safe_sequence_base dtor will use already-destructed mutexes, and
basic_string/requirements/citerators_cc fails calling terminate.

This patch fixes this problem by ensuring the mutex pool completes
construction before any _Safe_sequence_base-containing object, so that
the mutex pool survives them all.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

* include/debug/safe_base.h (_Safe_sequence_base): Ensure
the mutex pool survives *this.
---
 libstdc++-v3/include/debug/safe_base.h |   10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/debug/safe_base.h 
b/libstdc++-v3/include/debug/safe_base.h
index 1dfa9f68b65b5..d4ba404cdac6e 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -203,7 +203,15 @@ namespace __gnu_debug
 // Initialize with a version number of 1 and no iterators
 _Safe_sequence_base() _GLIBCXX_NOEXCEPT
 : _M_iterators(0), _M_const_iterators(0), _M_version(1)
-{ }
+{
+  // Make sure the mutex_pool machinery is initialized before any
+  // full object containing a _Safe_sequence_base completes
+  // construction, so that any local static mutexes in the mutex
+  // pool won't be destructed before our destructor runs;
+  // _M_detach_all could fail otherwise, on targets whose mutexes
+  // stop working after being destroyed.
+  (void)this->_M_get_mutex();
+}
 
 #if __cplusplus >= 201103L
 _Safe_sequence_base(const _Safe_sequence_base&) noexcept

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


[PATCH] [PR77760] [libstdc++] encode __time_get_state in tm

2023-02-16 Thread Alexandre Oliva via Gcc-patches


On platforms that fail the ptrtomemfn-cast-to-pfn hack, such as
arm-*-vxworks*, time_get fails with %I and %p because the state is not
preserved across do_get calls.

This patch introduces an alternate hack, that encodes the state in
unused bits of struct tm before calling do_get, extracts them in
do_get, does the processing, and encodes it back, so that get extracts
it.

The finalizer is adjusted for idempotence, because both do_get and get
may call it.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

PR libstdc++/77760
* include/bits/locale_facets_nonio.h (__time_get_state): Add
_M_state_tm, _M_save_to and _M_restore_from.
* include/bits/locale_facets_nonio.tcc (time_get::get): Drop
do_get-overriding hack.  Use state unconditionally, and encode
it in tm around do_get.
(time_get::do_get): Extract state from tm, and encode it back,
around parsing and finalizing.
* src/c++98/locale_facets.cc
(__time_get_state::_M_finalize_state): Make tm_hour and
tm_year idempotent.
---
 libstdc++-v3/include/bits/locale_facets_nonio.h   |   80 +
 libstdc++-v3/include/bits/locale_facets_nonio.tcc |   43 ++-
 libstdc++-v3/src/c++98/locale_facets.cc   |8 ++
 3 files changed, 93 insertions(+), 38 deletions(-)

diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h 
b/libstdc++-v3/include/bits/locale_facets_nonio.h
index 372cf0429501d..711bede158427 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.h
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.h
@@ -361,6 +361,86 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 void
 _M_finalize_state(tm* __tm);
 
+  private:
+void
+_M_state_tm(tm* __tm, bool __totm)
+{
+  // Check we don't invade the in-range tm bits, even if int is
+  // 16-bits wide.
+#define _M_min_shift_tm_sec 6
+#define _M_min_shift_tm_min 6
+#define _M_min_shift_tm_hour 5
+#define _M_min_shift_tm_mday 5
+#define _M_min_shift_tm_mon 4
+#define _M_min_shift_tm_year 16 // 14, but signed, so avoid it.
+#define _M_min_shift_tm_wday 3
+#define _M_min_shift_tm_yday 9
+#define _M_min_shift_tm_isdst 1
+  // Represent __STF in __WDT bits of __TMF up to the __MSB bit.
+  // In __MSB, 0 stands for the most significant bit of __TMF,
+  // 1 the bit next to it, and so on.
+#define _M_time_get_state_bitfield_inout(__tmf, __msb, __wdt, __stf)   \
+  do   \
+  {\
+const unsigned __shift = (sizeof (__tm->__tmf) * __CHAR_BIT__  \
+ - (__msb) - (__wdt)); \
+static char __attribute__ ((__unused__))   \
+  __check_parms_##__tmf[(__msb) >= 0 && (__wdt) > 0
\
+   && __shift >= (_M_min_shift_##__tmf \
+  + (sizeof (__tm->__tmf)  \
+ * __CHAR_BIT__) - 16) \
+   ? 1 : -1];  \
+const unsigned __mask = ((1 << (__wdt)) - 1) << __shift;   \
+if (!__totm)   \
+  this->__stf = (__tm->__tmf & __mask) >> __shift; \
+__tm->__tmf &= ~__mask;\
+if (__totm)
\
+  __tm->__tmf |= ((unsigned)this->__stf << __shift) & __mask;  \
+}  \
+  while (0)
+
+  _M_time_get_state_bitfield_inout (tm_hour,  0, 1, _M_have_I);
+  _M_time_get_state_bitfield_inout (tm_wday,  0, 1, _M_have_wday);
+  _M_time_get_state_bitfield_inout (tm_yday,  0, 1, _M_have_yday);
+  _M_time_get_state_bitfield_inout (tm_mon,   0, 1, _M_have_mon);
+  _M_time_get_state_bitfield_inout (tm_mday,  0, 1, _M_have_mday);
+  _M_time_get_state_bitfield_inout (tm_yday,  1, 1, _M_have_uweek);
+  _M_time_get_state_bitfield_inout (tm_yday,  2, 1, _M_have_wweek);
+  _M_time_get_state_bitfield_inout (tm_isdst, 0, 1, _M_have_century);
+  _M_time_get_state_bitfield_inout (tm_hour,  1, 1, _M_is_pm);
+  _M_time_get_state_bitfield_inout (tm_isdst, 1, 1, _M_want_century);
+  _M_time_get_state_bitfield_inout (tm_yday,  3, 1, _M_want_xday);
+  // _M_pad1
+  _M_time_get_state_bitfield_inout (tm_wday,  1, 6, _M_week_no);
+  // _M_pad2
+  _M_time_get_state_bitfield_inout (tm_mon,   1, 8, _M_century);
+  // _M_pad3
+
+#undef _M_min_shift_tm_hour
+#undef _M_min_shift_tm_sec
+#undef _M_min_shift_tm_min
+#undef _M_min_shift_tm_hour
+#undef _M_min_shift_tm_mday
+#undef _M_min_shift_tm_mon
+#undef _M_min_shift_tm_year

Re: [PATCH] [libstdc++] ensure mutex_pool survives _Safe_sequence_base

2023-02-17 Thread Alexandre Oliva via Gcc-patches
On Feb 17, 2023, Alexandre Oliva  wrote:

> On vxworks, after destroying the semaphore used to implement a mutex,
> __gthread_mutex_lock fails and __gnu_cxx::__mutex::lock calls
> __throw_concurrence_lock_error.  Nothing ensures the mutex_pool
> mutexes survive init-once objects containing _Safe_sequence_base.  If
> such an object completes construction before mutex_pool
> initialization, it will be registered for atexit destruction after the
> mutex_pool mutexes, so the _M_detach_all() call in the
> _Safe_sequence_base dtor will use already-destructed mutexes, and
> basic_string/requirements/citerators_cc fails calling terminate.

Here's an alternative approach, with zero runtime overhead.  Negative
overhead, if you count the time it would have taken to destruct the
mutex pool :-) But it fails to destruct them, which is presumably of no
consequence.

[libstdc++] do not destruct mutex_pool mutexes

[Copy of the paragraph quoted above omitted here]

This patch fixes this problem by ensuring the mutex pool mutexes are
constructed on demand, on a statically-allocated buffer, but never
destructed.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

* src/c++11/shared_ptr.cc (__gnu_internal::get_mutex):
Avoid destruction of the mutex pool.
---
 libstdc++-v3/src/c++11/shared_ptr.cc |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++11/shared_ptr.cc 
b/libstdc++-v3/src/c++11/shared_ptr.cc
index bc70134359c87..74e879e582896 100644
--- a/libstdc++-v3/src/c++11/shared_ptr.cc
+++ b/libstdc++-v3/src/c++11/shared_ptr.cc
@@ -36,7 +36,11 @@ namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden)
   {
 // increase alignment to put each lock on a separate cache line
 struct alignas(64) M : __gnu_cxx::__mutex { };
-static M m[mask + 1];
+// Use a static buffer, so that the mutexes are not destructed
+// before potential users (or at all)
+static __attribute__ ((aligned(__alignof__(M
+  char buffer[(sizeof (M)) * (mask + 1)];
+static M *m = new (buffer) M[mask + 1];
 return m[i];
   }
 }

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] -Wdangling-pointer: don't mark SSA lhs sets as stores

2023-02-17 Thread Alexandre Oliva via Gcc-patches
Hi, richi,

On Feb 17, 2023, Richard Biener  wrote:

> It seems the case should run into

Yeah, but when the stmt is _7 = this_2(D), lhs is _7, whereas
lhs_ref.ref is this_2(D), a parm decl's default def, so def_stmt is a
gimple_nop, and this is not a decl_by_reference, so we don't skip
stores.add, and any subsequent stores into fields of *this fails
stores.add.  This looks so fishy that I couldn't guess what was supposed
or expected to happen there :-(

> ?  I wonder what the circumstances are that we want the latter to happen if
> the former condition is true?

Note that what I'm testing for, to skip non-store stmts, is the actual
lhs, whereas lhs_ref.ref may very well have been resolved to the rhs (as
in the cases I saw), and even if it could be an SSA_NAME, whether the
stmt is a store depends on the actual lhs, not on properties of the rhs
that get_ref resolved lhs to, right?

Now, really, I did not get as far as trying to make sense of the
algorithm in there (get_ref definitely doesn't do what its name suggests
to me), I just saw a bunch of weirdnesses in blackbox testing and
failing variations, that seemed to suggest some fundamental issue, that
would hopefully be obvious to someone more familiar with that code.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] -Wdangling-pointer: don't mark SSA lhs sets as stores

2023-02-17 Thread Alexandre Oliva via Gcc-patches
On Feb 17, 2023, Alexandre Oliva  wrote:

> Now, really, I did not get as far as trying to make sense of the
> algorithm in there (get_ref definitely doesn't do what its name suggests
> to me), I just saw a bunch of weirdnesses in blackbox testing and
> failing variations, that seemed to suggest some fundamental issue, that
> would hopefully be obvious to someone more familiar with that code.

Here's one more: the stores hash_set seems to be intended to help catch
overwrites, so as to detect assignments of pointers-to-auto-locals to
escaping pointers that reach exits, without flagging those that are
definitely overwritten afterwards.

In a linear backwards scan, that makes sense, but once blocks recurse
for their preds, ISTM it could suppress the desired warning in e.g.:

  if (condition)
*incoming_ptr = &localvar;
  else
*incoming_ptr = 0;

in case we scan the else bb before the then bb.


But how about asynchronous exceptions?  They might leave those dangling
pointers if they hit at an undesirable spot.  So should we really
suppress those warnings?

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] [arm] adjust tests for quotes around +cdecp

2023-02-22 Thread Alexandre Oliva via Gcc-patches
Hello, Christophe,

On Feb 20, 2023, Christophe Lyon  wrote:

> On 2/17/23 08:17, Alexandre Oliva via Gcc-patches wrote:
>> 
>> Back when quotes were added around "+cdecp" in the "coproc must be
>> a constant immediate" error in arm-builtins.cc, tests for that message
>> lagged behind.  Fixed thusly.
>> 
>> Regstrapped on x86_64-linux-gnu.
>> Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

> It seems this changed with r12-6553-gc3782843badbf3, right?

Yup.

> I see this commit added quotes in several others places: are the two
> tests you fix the only ones impacted?

https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612176.html in
asm-flag-4.c also fixed fallout from that patch, I realize now, but that
was all that came up in our testing.

I didn't start from that patch, I was just going through test results,
investigating the failures and fixing them or at least annotating the
failures as expected.

It is conceivable that other quoted strings appear in tests that are
skipped by all of the target variants that we test.  Indeed, I went
through some arm-*-eabi variants not long ago, and these didn't come up.
So, in case you're wondering whether to look for the other strings in
the tests or somesuch, please don't assume I've already done so.

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about <https://stallmansupport.org>


Re: [PATCH] [PR77760] [libstdc++] encode __time_get_state in tm

2023-02-22 Thread Alexandre Oliva via Gcc-patches
On Feb 17, 2023, Jakub Jelinek  wrote:

> My worry is that people often invoke the time_get APIs on uninitialized
> struct tm.

Yeah.  I thought you meant get(), but it looks like you meant do_get()
as well.  I seem to have overread the permissions to overwrite tm
members, to update its current contents, and to write unspecified values
in its members.

When I started down this path, I thought we might be able to hold the
state bits only in fields that were to be updated, but the century field
and allowing for 16-bit ints made that a bit challenging.


So, back to the drawing board, the other possibility that occurs to me
is to use a thread-local state-keeper chained stack, set up by get, and
that enabled state to be recovered and updated by do_get if relevant
incoming arguments match those recorded at the top of the stack (e.g.,
at least that we're looking at the same tm object).


Another approach is to encode state in tm in-place and progressively,
and compute derived fields when (i) we've just set one of the input
fields, and (ii) any other input fields are in range.  E.g., if we parse
%p, we make sure tm_hour will be in the 00..11 range for am or 12..23
for pm, using the value previously-held in tm_hour, modulo 12, only if
it was in the 00..23 range.  If it wasn't in range, we record 00 or 12.
When we parse %I, if we find that tm_hour is in the 12..23 range, we
take that as meaning a "pm" was parsed for %p before, and add 12 to the
parsed value.  For century, we'd encode it immediately in tm_year
(preserving the previous modulo-100 value), and when parsing %Y we'd use
the century data, both at the risk of using garbage in case of
uninitialized data.  That appears to be in line with the
standard-specified behavior.  Maybe this is what the specification
expects implementations to do?

> For the encoding in get, the questions are:
> 1) if it is ok if we clear some normally unused bits of certain tm_*
>fields even if they wouldn't be otherwise touched; perhaps nothing
>will care, but it is still a user visible change

Rereading the relevant passages in standards and drafts, ISTM that this
unconditional zeroing would be unexpected and not permitted by the
standard, indeed.

> 2) when those tm_* fields we want to encode the state into are unitialized,
>don't we effectively invoke UB by using the uninitialized member
>(admittedly we just overwrite some bits in it and leave others as is,
>but won't that e.g. cause -Wuninitialized warnings)?

ISTM that https://eel.is/c++draft/locale.time.get#virtuals-15 allows
do_get to read values of members, and even to expect them to have been
zero-initialized.  That, and the allowance for unspecified values to be
stored in tm in case of error, seem to me to hint at using out-of-range
values of struct tm.

However, at the end of do_get, we *should* have specified values in
place in the just-read member, and get rules out modifying other fields.
Could get() build a temporary, automatic tm object, zero-initialize it,
set a bit in each field that indicates it is not set, use it throughout
multiple do_get calls to hold parsed values and internal state, and then
copy to the user-supplied tm object only fields that are marked as set
(the bit is clear) and in range?

> More importantly, in the do_get the questions are:
> 3) while do_get is protected, are we guaranteed that it will never be called
>except from the public members of time_get?

That's IMHO the main element of risk in using bits from unrelated fields
to hold state.  Storing the expected values only implies encoding state
in tm where it would ultimately end up (i.e., am/pm in tm_hour / 12,
century in tm_year / 100 + 19), using a zero (or an equal-to-sign) bit
to flag "set", and leaving it for get() to compute derived fields (if
that's even standard-compliant; it's not clear that it is, desirable as
it seems)

> 4) I think we even shouldn't __state._M_finalize_state(__tm); in do_get
>if it is nested, then you wouldn't need to tweak 
> src/c++98/locale_facets.cc;
>generally state should be finalized once everything is parsed together,
>not many times in between (of course if user code will parse stuff
>separately that will not work, say get with "%I" in one call, then get
>with "%h" in another one etc., but that is user's decision).

Parsing "%h%p%I%p%h" should get into tm_hour the value that time_put
read to format with the same format string, so there's an argument for
"finalizing" tm_hour based on more than the state fields we hold atm,
perhaps even for progressive in-place encoding, as I have suggested
above.

> Just curious, why doesn't the pmf hack work on arm-vxworks7?

At first, I thought we were running into this just because we have to
define __clang__ because of some vxworks system headers aimed at clang.
But even as I tried to drop the #ifndef, the test still failed; I
suspected it had to do with ARM's encoding of ptrmemfunc_vbit_in_delta,
but I did not confirm that 

Re: [PATCH] [vxworks] make wint_t and wchar_t the same distinct type

2023-02-22 Thread Alexandre Oliva via Gcc-patches
Hello, Jason,

On Feb 17, 2023, Jason Merrill  wrote:

> On 2/17/23 23:04, Alexandre Oliva wrote:
>> 
>> We used to define WINT_TYPE to WCHAR_TYPE, so that both wint_t and
>> wchar_t mapped to the same underlying type, but this caused a glitch
>> in Wstringop-overflow-6.C: on vxworks, wint_t is typedef'ed to
>> wchar_t

> And fixing that isn't an option?

Erhm, why do you say "fixing"?  That implies it's broken, but I don't
see anything in the C++ standards, or in the relevant bits that it
imports from the C standards, that rules out using wint_t = wchar_t in
C++.  wint_t is imported from the C standard as an integral type that
meets certain requirements, and AFAICT in C++ wchar_t is an integral
type that meets those requirements.  Am I missing something?


Now, could it be changed so that wint_t is wchar_t's underlying type
rather than wchar_t?  If the equivalence is a compliance error, we could
file a bug report with WRS and request them to fix it, but modifying
their system headers would require a copyright license they don't grant,
so we avoid doing that.  I imagine that breaking this equivalence would
have ABI implications, and even break legitimate (though unportable)
programs because of overload, specializations and whatnot, so there
would have to be very strong reasons to support a request for such a
change.

> Do the integer builtins work properly if we force them to use wchar_t
> instead of an integer type?

I haven't observed any regressions, I don't see any builtin functions
with wint in their signature that we even expand as builtins, and my
imagination is failing me on why an integral type such as wchar_t would
fail for wint_t, where other integral types, including wchar_t's
underlying type, would work.  Did you have any specific risks in mind
about what could go wrong?

-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Accept pmf-vbit-in-delta extra warning

2023-02-22 Thread Alexandre Oliva via Gcc-patches
On Feb 17, 2023, Jason Merrill  wrote:

> On 2/17/23 23:02, Alexandre Oliva wrote:
>> 
>> cp_build_binary_op, that issues -Waddress warnings, issues an extra
>> warning on arm targets, that g++.dg/warn/Waddress-5.C does not expect
>> when comparing a pointer-to-member-function literal with null.
>> 
>> The reason for the extra warning is that, on arm targets,
>> TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta, which
>> causes a different path to be taken, that extracts the
>> pointer-to-function and the delta fields (minus the vbit) and compares
>> each one with zero.  It's when comparing this pointer-to-function with
>> zero, in a recursive cp_build_binary_op, that another warning is
>> issued.
>> 
>> I suppose there should be a way to skip the warning in this recursive
>> call, without disabling other warnings that might be issued there, but

> warning_sentinel ws (warn_address)

Oh, yeah, that will suppress the expected warning for pfn0, but isn't
there any risk whatsoever that it could suppress other -Waddress
warnings for tree operands of pfn0?

I see the cp_save_expr for side effects, but what if e.g. the pmfn we're
testing is an array element, and the index expression tests another pmfn
against NULL that should be warned about?  Or something else that
wouldn't have TREE_SIDE_EFFECTS, and would thus not go through
cp_save_expr.  Would we then warn for uses of both pfn0 and delta0?


Here's what I'm going to test for these concerns.  Ok to install if it
bootstraps successfully, and my concerns are unfounded?


[c++] suppress redundant null-addr warn in pfn from pmfn

From: Alexandre Oliva 

When TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta, when
we warn about comparing a pointer-to-member-function with NULL, we
also warn about comparing the pointer-to-function extracted from it
with NULL, which is redundant.  Suppress the redundant warning.


for  gcc/cp/ChangeLog

* typeck.cc (cp_build_binary_op): Suppress redundant warning
for pfn null test in pmfn test with vbit-in-delta.
---
 gcc/cp/typeck.cc |   17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 4afb5e4f0d420..d5a3e501d8e91 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -5780,11 +5780,18 @@ cp_build_binary_op (const op_location_t &location,
 
  pfn0 = pfn_from_ptrmemfunc (op0);
  delta0 = delta_from_ptrmemfunc (op0);
- e1 = cp_build_binary_op (location,
-  EQ_EXPR,
-  pfn0,
-  build_zero_cst (TREE_TYPE (pfn0)),
-  complain);
+ {
+   /* If we will warn below about a null-address compare
+  involving the orig_op0 ptrmemfunc, we'd likely also
+  warn about the pfn0's null-address compare, and
+  that would be redundant, so suppress it.  */
+   warning_sentinel ws (warn_address);
+   e1 = cp_build_binary_op (location,
+EQ_EXPR,
+pfn0,
+build_zero_cst (TREE_TYPE (pfn0)),
+complain);
+ }
  e2 = cp_build_binary_op (location,
   BIT_AND_EXPR,
   delta0,


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] [arm] disable aes-1742098 mitigation for a72 combine tests

2023-02-22 Thread Alexandre Oliva via Gcc-patches
Hello, Kyrylo,

On Feb 20, 2023, Kyrylo Tkachov  wrote:

> So rather than overriding this awkward part with
> -mno-fix-cortex-a57-aes-1742098 I'd rather just select a different
> CPU that enables that fusion and isn't afflicted by this workaround,
> such as -mcpu=cortex-a53.

Sounds good to me.

> Ok with changing the -mcpu option instead.

Thanks, here's what I've just retested and am now checking in.

[arm] avoid aes-1742098 mitigation in combine tests

The expected asm output for aes-fuse-[12].c does not correspond to
that which is generated when -mfix-cortex-a57-aes-1742098 is enabled.
The mitigation was introduced after the test, and enabled by default
for the selected processor, a72.  Select a53 instead, where the
migitation is not enabled by default, and all the expected fusions can
take place.


for  gcc/testsuite/ChangeLog

* gcc.target/arm/aes-fuse-1.c: Switch to -mcpu=cortex-a53.
* gcc.target/arm/aes-fuse-2.c: Likewise.
---
 gcc/testsuite/gcc.target/arm/aes-fuse-1.c |2 +-
 gcc/testsuite/gcc.target/arm/aes-fuse-2.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/aes-fuse-1.c 
b/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
index 27b08aeef7ba7..a1bbe054e0a01 100644
--- a/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
+++ b/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_crypto_ok } */
 /* { dg-add-options arm_crypto } */
-/* { dg-additional-options "-mcpu=cortex-a72 -O3 -dp" } */
+/* { dg-additional-options "-mcpu=cortex-a53 -O3 -dp" } */
 
 #include 
 
diff --git a/gcc/testsuite/gcc.target/arm/aes-fuse-2.c 
b/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
index 1266a28753169..ede3237ce2692 100644
--- a/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
+++ b/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_crypto_ok } */
 /* { dg-add-options arm_crypto } */
-/* { dg-additional-options "-mcpu=cortex-a72 -O3 -dp" } */
+/* { dg-additional-options "-mcpu=cortex-a53 -O3 -dp" } */
 
 #include 
 


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: [PATCH] Skip module_cmi_p and related unsupported module test

2023-02-22 Thread Alexandre Oliva via Gcc-patches
On Feb 20, 2023, Jason Merrill  wrote:

> This seems like an ugly kludge around that problem, but I don't have
> any clever ideas of a better approach short of rewriting everything.
> So, OK with a comment explaining the rationale above your overridden
> "unsupported".

> Also, your commit subject line needs a subsystem tag, I guess
> "testsuite:" in this case.

*nod*, thanks, I'm checking in the adjusted patch below.


testsuite: Skip module_cmi_p and related unsupported module test

From: Alexandre Oliva 

When a multi-source module is found to be unsupported, we fail
module_cmi_p and subsequent sources.  Override proc unsupported to
mark the result in module_do, and test it to skip module_cmp_p and
subsequent related tests.


for  gcc/testsuite/ChangeLog

* g++.dg/modules/modules.exp: Override unsupported to update
module_do, and test it after dg-test.
---
 gcc/testsuite/g++.dg/modules/modules.exp |   17 +
 1 file changed, 17 insertions(+)

diff --git a/gcc/testsuite/g++.dg/modules/modules.exp 
b/gcc/testsuite/g++.dg/modules/modules.exp
index 61994b059457b..e66b2082f2055 100644
--- a/gcc/testsuite/g++.dg/modules/modules.exp
+++ b/gcc/testsuite/g++.dg/modules/modules.exp
@@ -315,6 +315,17 @@ proc module-check-requirements { tests } {
 # cleanup any detritus from previous run
 cleanup_module_files [find $DEFAULT_REPO *.gcm]
 
+# Override unsupported to set the second element of module_do to "N",
+# so that, after an unsupported result in dg-test, we can skip rather
+# than fail subsequent related tests.
+set module_do {"compile" "P"}
+rename unsupported saved-unsupported
+proc unsupported { args } {
+global module_do
+lset module_do 1 "N"
+return [saved-unsupported $args]
+}
+
 # not grouped tests, sadly tcl doesn't have negated glob
 foreach test [prune [lsort [find $srcdir/$subdir {*.[CH]}]] \
  "$srcdir/$subdir/*_?.\[CH\]"] {
@@ -327,6 +338,9 @@ foreach test [prune [lsort [find $srcdir/$subdir {*.[CH]}]] 
\
set module_cmis {}
verbose "Testing $nshort $std" 1
dg-test $test "$std" $DEFAULT_MODFLAGS
+   if { [lindex $module_do 1] == "N" } {
+   continue
+   }
set testcase [string range $test [string length "$srcdir/"] end]
cleanup_module_files [module_cmi_p $testcase $module_cmis]
}
@@ -372,6 +386,9 @@ foreach src [lsort [find $srcdir/$subdir {*_a.[CHX}]] {
}
}
dg-test -keep-output $test "$std" $DEFAULT_MODFLAGS
+   if { [lindex $module_do 1] == "N" } {
+   break
+   }
set testcase [string range $test [string length "$srcdir/"] 
end]
lappend mod_files [module_cmi_p $testcase $module_cmis]
}


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


Re: C++ modules and AAPCS/ARM EABI clash on inline key methods

2023-02-22 Thread Alexandre Oliva via Gcc-patches
On Feb 21, 2023, Richard Earnshaw  wrote:

> Rather than scanning for the triplet, a better test would be

> { xfail { arm_eabi } }

Indeed, thanks.  Here's the updated patch, retested.  Ok to install?


[PR105224] C++ modules and AAPCS/ARM EABI clash on inline key methods

From: Alexandre Oliva 

g++.dg/modules/virt-2_a.C fails on arm-eabi and many other arm targets
that use the AAPCS variant.  ARM is the only target that overrides
TARGET_CXX_KEY_METHOD_MAY_BE_INLINE.  It's not clear to me which way
the clash between AAPCS and C++ Modules design should be resolved, but
currently it favors AAPCS and thus the test fails.

Skipping the test or conditionally dropping the inline keyword breaks
subsequent tests, so I'm XFAILing the expectation that vtable and rtti
symbols are output on arm_eabi targets.


for  gcc/testsuite/ChangeLog

PR c++/105224
* g++.dg/modules/virt-2_a.C: XFAIL syms on arm_eabi.
---
 gcc/testsuite/g++.dg/modules/virt-2_a.C |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/g++.dg/modules/virt-2_a.C 
b/gcc/testsuite/g++.dg/modules/virt-2_a.C
index 580552be5a0d8..f5d68878f50fb 100644
--- a/gcc/testsuite/g++.dg/modules/virt-2_a.C
+++ b/gcc/testsuite/g++.dg/modules/virt-2_a.C
@@ -22,6 +22,6 @@ export int Visit (Visitor *v)
 }
 
 // Emit here
-// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} } }
-// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } }
-// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } }
+// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} { xfail { arm_eabi } } } }
+// { dg-final { scan-assembler {_ZTIW3foo7Visitor:} { xfail { arm_eabi } } } }
+// { dg-final { scan-assembler {_ZTSW3foo7Visitor:} { xfail { arm_eabi } } } }


-- 
Alexandre Oliva, happy hackerhttps://FSFLA.org/blogs/lxo/
   Free Software Activist   GNU Toolchain Engineer
Disinformation flourishes because many people care deeply about injustice
but very few check the facts.  Ask me about 


  1   2   3   4   5   >