[PATCH] Add { target int128 } to gcc.dg/pr97488.c

2020-10-19 Thread Aldy Hernandez via Gcc-patches
__int128 does not exist on 32-bit targets.

Pushed.

gcc/testsuite/ChangeLog:

* gcc.dg/pr97488.c: Add target int128 predicate.
---
 gcc/testsuite/gcc.dg/pr97488.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/pr97488.c b/gcc/testsuite/gcc.dg/pr97488.c
index 96dc33cf258..de7396cd4ec 100644
--- a/gcc/testsuite/gcc.dg/pr97488.c
+++ b/gcc/testsuite/gcc.dg/pr97488.c
@@ -1,4 +1,4 @@
-// { dg-do compile }
+// { dg-do compile { target int128 } }
 // { dg-options "-O1 -ftree-vrp" }
 
 __int128
-- 
2.26.2



Re: [PATCH 1/2] [target 87767] Refactor AVX512 broadcast patterns with speical memory constraint.

2020-10-19 Thread Hongtao Liu via Gcc-patches
On Mon, Oct 19, 2020 at 11:38 PM Vladimir Makarov  wrote:
>
>
> On 2020-10-11 8:58 p.m., Hongtao Liu wrote:
> > Hi:
> >This is done in 2 steps:
> >1. Extend special memory constraint to handle non MEM_P cases, i.e.
> > (vec_duplicate:V4SF (mem:SF (addr)))
> >2. Refactor implementation of *_bcst{_1,_2,_3} patterns. Add new
> > predicate bcst_mem_operand and corresponding constraint "Br" to merge
> > "$(pattern)_bcst{_1,_2,_3}" into "$(pattern)", also delete those
> > separate "*_bcst{_1,_2,_3}" patterns.
> >
> >Bootstrap is ok, regression test on i386 backend is ok.
> >
> > gcc/ChangeLog:
> >
> >  PR target/87767
> >  * ira-costs.c (record_operand_costs): Extract memory operand
> >  from recog_data.operand[i] for record_address_regs.
> >  (record_reg_classes): Extract memory operand from OP for
> >  conditional judgement MEM_P.
> >  * ira.c (ira_setup_alts): Ditto.
> >  * lra-constraints.c (extract_mem_from_operand): New function.
> >  (satisfies_memory_constraint_p): Extract memory operand from
> >  OP for decompose_mem_address, return false when there's no
> >  memory operand inside OP.
> >  (process_alt_operands): Remove MEM_P (op) since it would be
> >  judged in satisfies_memory_constraint_p.
> >  * recog.c (asm_operand_ok): Extract memory operand from OP for
> >  judgement of memory_operand (OP, VOIDmode).
> >  (constrain_operands): Don't unwrapper unary operator when
> >  there's memory operand inside.
> >  * rtl.h (extract_mem_from_operand): New decl.
>
>
> Thank you for working on the PR.  In general patch is ok for me. The
> only thing is
>
> +/* For special_memory_operand, it could be false for MEM_P (op),
> +   i.e. bcst_mem_operand in i386 backend.
> +   Extract and return real memory operand or op.  */
> +rtx
> +extract_mem_from_operand (rtx op)
> +{
> +  if (MEM_P (op))
> +return op;
> +  /* Only allow one memory_operand inside special memory operand.  */
>
> The comment contradicts to the below code which returns the first memory 
> operand (not the only one).
>

Yes.

> +  subrtx_var_iterator::array_type array;
> +  FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
> +{
> +  rtx x = *iter;
> +  if (MEM_P (x))
> +   return x;
> +}
> +
> +  return op;
> +}
> +
>
> I think the code should look like
>
> /* For special_memory_operand, it could be false for MEM_P (op),
> i.e. bcst_mem_operand in i386 backend.
> Extract and return real memory operand or op.  */
> rtx
> extract_mem_from_operand (rtx op)
> {
>if (MEM_P (op))
>  return op;
>/* Only allow one memory_operand inside special memory operand.  */
>subrtx_var_iterator::array_type array;
>rtx res = op;
>FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
>  {
>rtx x = *iter;
>if (!MEM_P (x) || res != op)
>  return op;
>res = op;

Assume you want to assign res with x.
Also in the iteration, x would first be op which would be false for
MEM_P, then op would be returned.
That's not what you mean, so i changed to

  /* Only allow one memory_operand inside special memory operand.  */
  subrtx_var_iterator::array_type array;
  rtx res = op;
  FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
{
  rtx x = *iter;
  if (!MEM_P (x))
continue;
  /* Return op when there're multiple memory operands.  */
  if (res != op)
return op;
  else
res = x;
}

>  }
>
>return res;
> }
>
>
> With this change, the patch is ok for me and can be committed into the trunk.
>


--
BR,
Hongtao


Re: [PATCH] [PR rtl-optimization/97249]Simplify vec_select of paradoxical subreg.

2020-10-19 Thread Hongtao Liu via Gcc-patches
On Mon, Oct 19, 2020 at 11:31 PM Richard Sandiford
 wrote:
>
> Hongtao Liu  writes:
> > On Thu, Oct 15, 2020 at 8:38 PM Richard Sandiford
> >  wrote:
> >>
> >> Hongtao Liu via Gcc-patches  writes:
> >> > +   /* Simplify vec_select of a subreg of X to just a vec_select of X
> >> > +  when X has same component mode as vec_select.  */
> >> > +   int l2;
> >> > +   if (GET_CODE (trueop0) == SUBREG
> >> > +   && GET_MODE_INNER (mode)
> >> > +  == GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
> >>
> >> Better to use SUBREG_REG here and below.
> >>
> >
> > Yes and changed.
> >
> >> > +   && (GET_MODE_NUNITS (GET_MODE (trueop0))).is_constant (&l0)
> >> > +   && (GET_MODE_NUNITS (mode)).is_constant (&l1)
> >> > +   && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0
> >> > +   .is_constant (&l2)
> >> > +   && known_le (l1, l2))
> >> > + {
> >> > +   unsigned HOST_WIDE_INT subreg_offset = 0;
> >> > +   gcc_assert (known_eq (XVECLEN (trueop1, 0), l1));
> >> > +   gcc_assert (can_div_trunc_p (exact_div (subreg_lsb 
> >> > (trueop0), BITS_PER_UNIT),
> >> > +GET_MODE_SIZE (GET_MODE_INNER 
> >> > (mode)),
> >> > +&subreg_offset));
> >>
> >> can_div_trunc_p discards the remainder, whereas it looks like here
> >> you want an exact multiple.
> >>
> >> I don't think it's absolutely guaranteed that the “if” condition makes
> >> the division by GET_MODE_SIZE exact.  E.g. in principle you could have
> >> a subreg of a vector of TIs in which the subreg offset is misaligned by
> >> a DI offset.
> >>
> >> I'm not sure the subreg_lsb conversion is correct though.  On big-endian
> >> targets, lane numbering follows memory layout, just like subreg byte
> >> offsets do.  So ISTM that using SUBREG_BYTE (as per the earlier patch)
> >> was correct.
> >>
> >> In summary, I think the "if” condition should include something like:
> >>
> >>   constant_mulitple_p (SUBREG_BYTE (trueop0),
> >>GET_MODE_UNIT_BITSIZE (mode),
> >>&subreg_offset)
> >>
> >
> > Changed.
> >
> >> Thanks,
> >> Richard
> >
> >
> > Update patch.
> >
> > --
> > BR,
> > Hongtao
> >
> > From 8d154067963e453c337e6dc2c4f3f19bf0d6e11b Mon Sep 17 00:00:00 2001
> > From: liuhongt 
> > Date: Tue, 13 Oct 2020 15:35:29 +0800
> > Subject: [PATCH] Simplify vec_select of a subreg of X to just a vec_select 
> > of
> >  X.
> >
> > gcc/ChangeLog
> >   PR rtl-optimization/97249
> >   * simplify-rtx.c (simplify_binary_operation_1): Simplify
> >   vec_select of a subreg of X to a vec_select of X.
> >
> > gcc/testsuite/ChangeLog
> >
> >   * gcc.target/i386/pr97249-1.c: New test.
> > ---
> >  gcc/simplify-rtx.c| 44 +++
> >  gcc/testsuite/gcc.target/i386/pr97249-1.c | 30 
> >  2 files changed, 74 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr97249-1.c
> >
> > diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
> > index 869f0d11b2e..b1009837b2b 100644
> > --- a/gcc/simplify-rtx.c
> > +++ b/gcc/simplify-rtx.c
> > @@ -4170,6 +4170,50 @@ simplify_binary_operation_1 (enum rtx_code code, 
> > machine_mode mode,
> >   return subop1;
> >   }
> >   }
> > +
> > +   /* Simplify vec_select of a subreg of X to just a vec_select of X
> > +  when X has same component mode as vec_select.  */
> > +   int l2;
> > +   unsigned HOST_WIDE_INT subreg_offset = 0;
> > +   if (GET_CODE (trueop0) == SUBREG
> > +   && GET_MODE_INNER (mode)
> > +  == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
> > +   && (GET_MODE_NUNITS (GET_MODE (trueop0))).is_constant (&l0)
>
> Nothing really relies on this last line, and nothing uses l0, so better
> to drop it.
>

Changed, so there won't be any vector mode with variable number elts.

> > +   && (GET_MODE_NUNITS (mode)).is_constant (&l1)
> > +   && (GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0
> > +   .is_constant (&l2)
> > +   && known_le (l1, l2)
>
> I'm not sure the last two &&s are really the important condition.
> I think we should drop them for the suggestion below.
>

Changed, assume gcc also support something like (vec_select:v4di
(reg:v2di) (parallel [ (const_int 0) (const_int 1) (const_int 1)
(const_int 0)]))
as long as the range of selection guaranteed by
  || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))

> > +   && constant_multiple_p (SUBREG_BYTE (trueop0),
> > +   GET_MODE_UNIT_BITSIZE (mode),
> > +   &subreg_offset))
> > + {
> > +
>
> Excess blank line.
>

Changed.

> > +   gcc_assert (known_eq (XVECLEN (trueop1, 0), l1));
>
> This can just use ==.
>

Changed.

> > +   bool success = true;
> > + 

Re: [PATCH] [PR target/97194] [AVX2] Support variable index vec_set.

2020-10-19 Thread Hongtao Liu via Gcc-patches
On Mon, Oct 19, 2020 at 5:55 PM Richard Biener
 wrote:
>
> On Mon, Oct 19, 2020 at 11:37 AM Hongtao Liu  wrote:
> >
> > On Mon, Oct 19, 2020 at 5:07 PM Richard Biener
> >  wrote:
> > >
> > > On Mon, Oct 19, 2020 at 10:21 AM Hongtao Liu  wrote:
> > > >
> > > > Hi:
> > > >   It's implemented as below:
> > > > V setg (V v, int idx, T val)
> > > >
> > > > {
> > > >   V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
> > > >   V valv = (V){val, val, val, val, val, val, val, val};
> > > >   V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
> > > >   v = (v & ~mask) | (valv & mask);
> > > >   return v;
> > > > }
> > > >
> > > > Bootstrap is fine, regression test for i386/x86-64 backend is ok.
> > > > Ok for trunk?
> > >
> > > Hmm, I guess you're trying to keep the code for !AVX512BW simple
> > > but isn't just splitting the compare into
> > >
> > >  clow = {0, 1, 2, 3 ... } == idxv
> > >  chigh = {16, 17, 18, ... } == idxv;
> > >  cmp = {clow, chigh}
> > >
> >
> > We also don't have 512-bits byte/word blend instructions without
> > TARGET_AVX512W, so how to use 512-bits cmp?
>
> Oh, I see.  Guess two back-to-back vpternlog could emulate

Yes, we can have something like vpternlogd %zmm0, %zmm1, %zmm2, 0xD8,
but since we don't have 512-bits bytes/word broadcast instruction,
It would need 2 broadcast and 1 vec_concat to get 1 512-bits vector.
it wouldn't save many instructions compared to my version(as below).

---
leal-16(%rsi), %eax
vmovd   %edi, %xmm2
vmovdqa .LC0(%rip), %ymm4
vextracti64x4   $0x1, %zmm0, %ymm3
vmovd   %eax, %xmm1
vpbroadcastw%xmm2, %ymm2
vpbroadcastw%xmm1, %ymm1
vpcmpeqw%ymm4, %ymm1, %ymm1
vpblendvb   %ymm1, %ymm2, %ymm3, %ymm3
vmovd   %esi, %xmm1
vpbroadcastw%xmm1, %ymm1
vpcmpeqw%ymm4, %ymm1, %ymm1
vpblendvb   %ymm1, %ymm2, %ymm0, %ymm0
vinserti64x4$0x1, %ymm3, %zmm0, %zmm0
---

> the blend?  Not sure if important - I recall only knl didn't have bw?
>

Yes, after(including) SKX, all avx512 targets will support AVX512BW.
And i don't think performance for V32HI/V64QI without AVX512BW is important.


> > cut from i386-expand.c:
> > in ix86_expand_sse_movcc
> >  3682case E_V64QImode:
> >  3683  gen = gen_avx512bw_blendmv64qi; ---> TARGET_AVX512BW needed
> >  3684  break;
> >  3685case E_V32HImode:
> >  3686  gen = gen_avx512bw_blendmv32hi; --> TARGET_AVX512BW needed
> >  3687  break;
> >  3688case E_V16SImode:
> >  3689  gen = gen_avx512f_blendmv16si;
> >  3690  break;
> >  3691case E_V8DImode:
> >  3692  gen = gen_avx512f_blendmv8di;
> >  3693  break;
> >  3694case E_V8DFmode:
> >
> > > faster, smaller and eventually even easier during expansion?
> > >
> > > +  gcc_assert (ix86_expand_vector_init_duplicate (false, mode, valv, 
> > > val));
> > > +  gcc_assert (ix86_expand_vector_init_duplicate (false, cmp_mode,
> > > idxv, idx_tmp));
> > >
> > > side-effects in gcc_assert is considered bad style, use
> > >
> > >   ok = ix86_expand_vector_init_duplicate (false, mode, valv, val);
> > >   gcc_assert (ok);
> > >
> > > +  vec[5] = constv;
> > > +  ix86_expand_int_vcond (vec);
> > >
> > > this also returns a bool you probably should assert true.
> > >
> >
> > Yes, will change.
> >
> > > Otherwise thanks for tackling this.
> > >
> > > Richard.
> > >
> > > > gcc/ChangeLog:
> > > >
> > > > PR target/97194
> > > > * config/i386/i386-expand.c (ix86_expand_vector_set_var): New 
> > > > function.
> > > > * config/i386/i386-protos.h (ix86_expand_vector_set_var): New 
> > > > Decl.
> > > > * config/i386/predicates.md (vec_setm_operand): New predicate,
> > > > true for const_int_operand or register_operand under 
> > > > TARGET_AVX2.
> > > > * config/i386/sse.md (vec_set): Support both constant
> > > > and variable index vec_set.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > > * gcc.target/i386/avx2-vec-set-1.c: New test.
> > > > * gcc.target/i386/avx2-vec-set-2.c: New test.
> > > > * gcc.target/i386/avx512bw-vec-set-1.c: New test.
> > > > * gcc.target/i386/avx512bw-vec-set-2.c: New test.
> > > > * gcc.target/i386/avx512f-vec-set-2.c: New test.
> > > > * gcc.target/i386/avx512vl-vec-set-2.c: New test.
> > > >
> > > > --
> > > > BR,
> > > > Hongtao
> >
> >
> >
> > --
> > BR,
> > Hongtao



-- 
BR,
Hongtao


Re: [PATCH] libstdc++: use lt_host_flags for libstdc++.la

2020-10-19 Thread Jonathan Yong via Gcc-patches

On 9/16/20 1:16 PM, JonY wrote:

For platforms like Mingw and Cygwin, cygwin refuses to generate the
shared library without using -no-undefined.

Attached patch makes sure the right flags are used, since libtool is
already used to link libstdc++.

Patch OK?



Ping.


OpenPGP_0x713B5FE29C145D45_and_old_rev.asc
Description: application/pgp-keys


OpenPGP_signature
Description: OpenPGP digital signature


[PATCH] c++: Member template function lookup failure [PR94799]

2020-10-19 Thread Marek Polacek via Gcc-patches
My earlier patch for this PR, r11-86, broke pybind11.  That patch
changed cp_parser_class_name to also consider the object expression
scope (parser->context->object_type) to fix parsing of

  p->template A::foo(); // consider p's scope too

Here we reject

  b.operator typename B::type();

because 'typename_p' in cp_parser_class_name uses 'scope', which means
that 'typename_p' will be true for the example above.  Then we create
a TYPENAME_TYPE via make_typename_type, which fails when tsubsting it;
the code basically created 'typename B::B' and then we complain that there
is no member named 'B' in 'A'.  So, when deciding if we should
create a TYPENAME_TYPE, don't consider the object_type scope, like we
did pre-r11-86.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

gcc/cp/ChangeLog:

PR c++/94799
* parser.c (cp_parser_class_name): Use parser->scope when
setting typename_p.

gcc/testsuite/ChangeLog:

PR c++/94799
* g++.dg/template/lookup16.C: New test.
---
 gcc/cp/parser.c  | 13 ++---
 gcc/testsuite/g++.dg/template/lookup16.C | 23 +++
 2 files changed, 29 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/lookup16.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7ec7d42773c..ecbd4b7d15a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -23784,13 +23784,10 @@ cp_parser_class_name (cp_parser *parser,
  bool enum_ok)
 {
   tree decl;
-  tree scope;
-  bool typename_p;
-  cp_token *token;
   tree identifier = NULL_TREE;
 
   /* All class-names start with an identifier.  */
-  token = cp_lexer_peek_token (parser->lexer);
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
   if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
 {
   cp_parser_error (parser, "expected class-name");
@@ -23806,14 +23803,16 @@ cp_parser_class_name (cp_parser *parser,
 
   where we first want to look up A::a in the class of the object
   expression, as per [basic.lookup.classref].  */
-  scope = parser->scope ? parser->scope : parser->context->object_type;
+  tree scope = parser->scope ? parser->scope : parser->context->object_type;
   if (scope == error_mark_node)
 return error_mark_node;
 
   /* Any name names a type if we're following the `typename' keyword
  in a qualified name where the enclosing scope is type-dependent.  */
-  typename_p = (typename_keyword_p && scope && TYPE_P (scope)
-   && dependent_type_p (scope));
+  const bool typename_p = (typename_keyword_p
+  && parser->scope
+  && TYPE_P (parser->scope)
+  && dependent_type_p (parser->scope));
   /* Handle the common case (an identifier, but not a template-id)
  efficiently.  */
   if (token->type == CPP_NAME
diff --git a/gcc/testsuite/g++.dg/template/lookup16.C 
b/gcc/testsuite/g++.dg/template/lookup16.C
new file mode 100644
index 000..5b34c08282c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/lookup16.C
@@ -0,0 +1,23 @@
+// PR c++/94799
+// { dg-do compile { target c++11 } }
+
+template  struct A {
+  typedef int type;
+  operator int();
+};
+
+template  using B = A;
+
+template  typename B::type foo(B b)
+{
+  auto r1 = b.operator typename A::type();
+  auto r2 = b.operator typename A::template A::type();
+  auto r3 = b.operator typename B::type();
+  auto r4 = b.operator typename B::template A::type();
+  return r1 + r2 + r3 + r4;
+}
+
+void bar()
+{
+  foo(A());
+}

base-commit: 970d683f6319990b30302a21a860990e2ec8
-- 
2.26.2



[patch] Use precision and sign to compare types for ranges

2020-10-19 Thread Andrew MacLeod via Gcc-patches

This fixes the second test case in pr 97360.

There are a few places in the ranger where we sanity check the types of 
the ranges.  We were using types_compatible_p() but thats not really 
acccurate as gimple allows types which are useless_type_conversion_p() 
in only one direction, whereas types_compatible_p() requires casts in 
both directions to be useless_type_conversion_p().


And, since its only a sanity check, ranges really only require that the 
precision and sign be the same, so its a faster check anyway.


bootstrapped on x86_64-pc-linux-gnu, no regressions, pushed.

Andrew




	gcc/ChangeLog:

	PR tree-optimization/97360
	* gimple-range.h (range_compatible_p): New.
	* gimple-range-gori.cc (is_gimple_logical_p): Use range_compatible_p.
	(range_is_either_true_or_false): Ditto.
	(gori_compute::outgoing_edge_range_p): Cast result to the correct
	type if necessary.
	(logical_stmt_cache::cacheable_p): Use range_compatible_p.
	* gimple-range.cc (gimple_ranger::calc_stmt): Check range_compatible_p
	before casting the range.
	(gimple_ranger::range_on_exit): Use range_compatible_p.
	(gimple_ranger::range_on_edge): Ditto.

	gcc/testsuite/ChangeLog:

	* gcc.dg/pr97360-2.c: New test.
	

diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index c4bfc658319..983f4c97e87 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -552,7 +552,7 @@ is_gimple_logical_p (const gimple *gs)
 	case BIT_AND_EXPR:
 	case BIT_IOR_EXPR:
 	  // Bitwise operations on single bits are logical too.
-	  if (types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)),
+	  if (range_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)),
   boolean_type_node))
 	return true;
 	  break;
@@ -618,7 +618,7 @@ range_is_either_true_or_false (const irange &r)
   // This is complicated by the fact that Ada has multi-bit booleans,
   // so true can be ~[0, 0] (i.e. [1,MAX]).
   tree type = r.type ();
-  gcc_checking_assert (types_compatible_p (type, boolean_type_node));
+  gcc_checking_assert (range_compatible_p (type, boolean_type_node));
   return (r.singleton_p () || !r.contains_p (build_zero_cst (type)));
 }
 
@@ -999,11 +999,20 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name)
 
   // If NAME can be calculated on the edge, use that.
   if (m_gori_map->is_export_p (name, e->src))
-return compute_operand_range (r, stmt, lhs, name);
-
-  // Otherwise see if NAME is derived from something that can be
-  // calculated.  This performs no dynamic lookups whatsover, so it is
-  // low cost.
+{
+  if (compute_operand_range (r, stmt, lhs, name))
+	{
+	  // Sometimes compatible types get interchanged. See PR97360.
+	  // Make sure we are returning the type of the thing we asked for.
+	  if (!r.undefined_p () && r.type () != TREE_TYPE (name))
+	{
+	  gcc_checking_assert (range_compatible_p (r.type (),
+		   TREE_TYPE (name)));
+	  range_cast (r, TREE_TYPE (name));
+	}
+	  return true;
+	}
+}
   return false;
 }
 
@@ -1156,7 +1165,7 @@ bool
 logical_stmt_cache::cacheable_p (gimple *stmt, const irange *lhs_range) const
 {
   if (gimple_code (stmt) == GIMPLE_ASSIGN
-  && types_compatible_p (TREE_TYPE (gimple_assign_lhs (stmt)),
+  && range_compatible_p (TREE_TYPE (gimple_assign_lhs (stmt)),
 			 boolean_type_node)
   && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
 {
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 999d631c5ee..e4864ba60f6 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -392,8 +392,14 @@ gimple_ranger::calc_stmt (irange &r, gimple *s, tree name)
 {
   if (r.undefined_p ())
 	return true;
+  // We sometimes get compatible types copied from operands, make sure
+  // the correct type is being returned.
   if (name && TREE_TYPE (name) != r.type ())
-	range_cast (r, TREE_TYPE (name));
+	{
+	  gcc_checking_assert (range_compatible_p (r.type (),
+		   TREE_TYPE (name)));
+	  range_cast (r, TREE_TYPE (name));
+	}
   return true;
 }
   return false;
@@ -928,7 +934,7 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name)
   else
 gcc_assert (range_of_expr (r, name, s));
   gcc_checking_assert (r.undefined_p ()
-		   || types_compatible_p (r.type(), TREE_TYPE (name)));
+		   || range_compatible_p (r.type (), TREE_TYPE (name)));
 }
 
 // Calculate a range for NAME on edge E and return it in R.
@@ -948,7 +954,7 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name)
 
   range_on_exit (r, e->src, name);
   gcc_checking_assert  (r.undefined_p ()
-			|| types_compatible_p (r.type(), TREE_TYPE (name)));
+			|| range_compatible_p (r.type(), TREE_TYPE (name)));
 
   // Check to see if NAME is defined on edge e.
   if (m_cache.outgoing_edge_range_p (edge_range, e, name))
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 041dc7c2a97..a6e8793f284 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -115,6 +115,18 @@ gimple_range_ssa_p (

[PATCH 2/2] c++: Clean up constraint normalization routines

2020-10-19 Thread Patrick Palka via Gcc-patches
Many of the high-level constraint normalization routines allow the
caller to supply the initial template arguments for normalization, but
in practice all of the callers ultimately supply either NULL_TREE or a
set of generic template arguments (*).  Since the previous patch made
NULL_TREE act like a set of generic template arguments during
normalization, we can just make get_normalized_constraints pass
NULL_TREE to normalize_expression and remove the 'args' parameter from
the routines that wrap it.

(*): Except one of the overloads of normalize_constraint_expression uses
the template arguments of a concept check for normalizing the concept
check, which doesn't seem right, since if a substitution failure happens
during normalization then it will become a hard error instead of a
SFINAE error.  This patch does away with this overload.

Bootstrapped and regtested on x86_64-pc-linux-gnu and tested on the
cmcstl2 testsuite.  Also verified that the concepts diagnostics remain
unchanged across our testsuite.  Doest this look OK to commit?

gcc/cp/ChangeLog:

* constraint.cc (get_normalized_constraints): Remove 'args'
parameter.  Pass NULL_TREE as the initial template arguments to
normalize_expression.
(get_normalized_constraints_from_info): Remove 'args' parameter
and adjust the call to get_normalized_constraints.
(get_normalized_constraints_from_decl): Remove 'args' local
variable and adjust call to get_normalized_constraints_from_info.
(normalize_concept_definition): Remove 'args' local variable
and adjust call to get_normalized_constraints.
(normalize_constraint_expression): Remove the two-argument
overload.  Remove 'args' parameter from the three-argument
overload and update function comment accordingly.  Remove
default argument from 'diag' parameter. Adjust call to
get_normalized_constraints accordingly.
(finish_nested_requirement): Adjust call to
normalize_constraint_expression accordingly.
(strictly_subsumes): Remove 'args' parameter.  Adjust call to
get_normalized_constraints_from_info accordingly.
(weakly_subsumes): Likewise.
* cp-tree.h (strictly_subsumes): Remove 'args' parameter.
(weakly_subsumes): Likewise.
* pt.c (process_partial_specialization): Adjust call to
strictly_subsumes accordingly.
(is_compatible_template_arg): Adjust call to weakly_subsumes
accordingly.
---
 gcc/cp/constraint.cc | 69 +---
 gcc/cp/cp-tree.h |  4 +--
 gcc/cp/pt.c  |  5 ++--
 3 files changed, 24 insertions(+), 54 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 75457a2dd60..d6354edbe6f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -759,20 +759,18 @@ normalize_expression (tree t, tree args, norm_info info)
 static GTY((deletable)) hash_map *normalized_map;
 
 static tree
-get_normalized_constraints (tree t, tree args, norm_info info)
+get_normalized_constraints (tree t, norm_info info)
 {
   auto_timevar time (TV_CONSTRAINT_NORM);
-  return normalize_expression (t, args, info);
+  return normalize_expression (t, NULL_TREE, info);
 }
 
 /* Returns the normalized constraints from a constraint-info object
-   or NULL_TREE if the constraints are null. ARGS provide the initial
-   arguments for normalization and IN_DECL provides the declaration
-   to which the constraints belong.  */
+   or NULL_TREE if the constraints are null. IN_DECL provides the
+   declaration to which the constraints belong.  */
 
 static tree
-get_normalized_constraints_from_info (tree ci, tree args, tree in_decl,
- bool diag = false)
+get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
 {
   if (ci == NULL_TREE)
 return NULL_TREE;
@@ -780,8 +778,7 @@ get_normalized_constraints_from_info (tree ci, tree args, 
tree in_decl,
   /* Substitution errors during normalization are fatal.  */
   ++processing_template_decl;
   norm_info info (in_decl, diag ? tf_norm : tf_none);
-  tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci),
-  args, info);
+  tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci), info);
   --processing_template_decl;
 
   return t;
@@ -843,9 +840,8 @@ get_normalized_constraints_from_decl (tree d, bool diag = 
false)
 
   push_nested_class_guard pncs (DECL_CONTEXT (d));
 
-  tree args = generic_targs_for (tmpl);
   tree ci = get_constraints (decl);
-  tree norm = get_normalized_constraints_from_info (ci, args, tmpl, diag);
+  tree norm = get_normalized_constraints_from_info (ci, tmpl, diag);
 
   if (!diag)
 hash_map_safe_put (normalized_map, tmpl, norm);
@@ -866,11 +862,10 @@ normalize_concept_definition (tree tmpl, bool diag = 
false)
   if (OVL_P (tmpl))
 tmpl = OVL_FIRST (tmpl);
   gcc_assert (TREE_CODE (tmp

[PATCH 1/2] c++: Tolerate empty initial targs during normalization [PR97412]

2020-10-19 Thread Patrick Palka via Gcc-patches
When normalizing the constraint-expression of a nested-requirement, we
pass NULL_TREE as the initial template arguments for normalization, but
tsubst_argument_pack is not prepared to handle a NULL_TREE targ vector.
This causes us to ICE when normalizing a variadic concept as part of a
nested-requirement.

This patch fixes the ICE by guarding the call to tsubst_template_args in
normalize_concept_check appropriately.  This will also enables us to
simplify many of the normalization routines to pass NULL_TREE instead of
a set of generic template arguments as the initial template arguments,
which will be done in a subsequent patch.

gcc/cp/ChangeLog:

PR c++/97412
* constraint.cc (normalize_concept_check): Don't call
tsubst_template_args when args is NULL.

gcc/testsuite/ChangeLog:

PR c++/97412
* g++.dg/cpp2a/concepts-variadic2.C: New test.
---
 gcc/cp/constraint.cc|  3 ++-
 gcc/testsuite/g++.dg/cpp2a/concepts-variadic2.C | 12 
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-variadic2.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index f4f5174eff3..75457a2dd60 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -686,7 +686,8 @@ normalize_concept_check (tree check, tree args, norm_info 
info)
 }
 
   /* Substitute through the arguments of the concept check. */
-  targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
+  if (args)
+targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
   if (targs == error_mark_node)
 return error_mark_node;
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-variadic2.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-variadic2.C
new file mode 100644
index 000..ce61aef5481
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-variadic2.C
@@ -0,0 +1,12 @@
+// PR c++/97412
+// { dg-do compile { target c++20 } }
+
+template 
+concept call_bar_with = requires(T t, TArgs... args) {
+  t.bar(args...);
+};
+
+template 
+concept foo = requires {
+  requires call_bar_with;
+};
-- 
2.29.0.rc0



Re: using ENUM::V

2020-10-19 Thread Jason Merrill via Gcc-patches

On 11/15/19 12:07 PM, Nathan Sidwell wrote:

Jason,
using ENUM::v is proving rather tricky, when the memberness of the 
enumerator and the context of the using decl differ.


struct B
{
   enum E {e};
};

struct D
{
private:
   using B::e; // ok
   static inline const auto ok1 = e; // #1 accessible
};

struct F : D
{
   static inline const auto bad1 = e; // #2 inaccessible
}

The CONST_DECL is what gets injected into the binding level -- not the 
USING_DECL.  the access checking machinery expects that the context of 
any member it's checking is within the inheritance graph.  That's not 
true and if ICEs at #1 and #2.  Simply bailing out if the thing being 
checked is not in the graph, fixes #1, but then we miss #2 as we can't 
tell the difference -- all we have is the CONST_DECL with no separate 
scope information.


I'm considering 2 ways around this:

1) push the USING_DECL, not the CONST_DECL, into the binding.  I think 
we do this for some other cases, but I'm not sure exactly why/where. I'm 
concerned strip_using_decls will trigger too early, and we'll be back to 
the above scenario.


Our do_class_using_decl does normally build USING_DECLs for class-scope 
using-declarations.  Are you not using that code?


2) clone the CONST_DECL, giving it a fake DECL_CONTEXT of the 
using-decl's scope.  We can still get to the correct context via the 
CONST_DECL's type.  There's probably a DECL_LANG flag we can use to mark 
it as fake -- perhaps DECL_ARTIFICIAL suffices.


That could work if the normal path doesn't for some reason.

Are you going to have a chance to look at this any more in stage 1, or 
should I take a crack at it?


Jason



Re: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems

2020-10-19 Thread Segher Boessenkool
On Mon, Oct 19, 2020 at 03:12:13PM -0400, Michael Meissner wrote:
> On Fri, Oct 16, 2020 at 02:14:04PM -0500, Segher Boessenkool wrote:
> > On Thu, Sep 24, 2020 at 04:20:36PM -0400, Michael Meissner wrote:
> > > You will need a new enough GLIBC in order to do this configuration.
> > 
> > What happens if you glibc is older, and you try?
> 
> You get linker errors due to the older GLIBC not using -mno-gnu-attribute in
> all of the appropriate places, and and not all of the names that are renamed
> will be present.
> 
> -marlin-> ./xgcc -B./ -O2 -g foo.c -lm -mabi=ieeelongdouble -Wno-psabi && 
> ./a.out
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
> /opt/at13.0/lib/../lib64/libm.so uses IBM long double, 
> /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses 
> IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
> /opt/at13.0/lib/../lib64/libc.so.6 uses IBM long double, 
> /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses 
> IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
> /home/meissner/tmp/gcc-tmp/ccvzdRyj.o: in function `main':
> /home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined 
> reference to `__sinieee128'
> /home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
> /home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined 
> reference to `__printfieee128'
> collect2: error: ld returned 1 exit status

So this requirement needs to be put in the release notes.  It also is a
regression, but I guess we will just have to live with that :-(


Segher


Re: [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double.

2020-10-19 Thread Michael Meissner via Gcc-patches
On Fri, Oct 16, 2020 at 03:30:56PM -0500, Segher Boessenkool wrote:
> > + if (len >= printf_len
> > + && strcmp (name + len - printf_len, "printf") == 0)
> 
> Thew first test is unnecessary.

Actually no, it is necessary.  If you are looking at a builtin function with 4
or fewer characters, if you don't check if len is at least 5 (i.e. >=
printf_len), the expression:

name + len - printf_len

would be before the beginning of the name pointer.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


[committed] libstdc++: Implement std::make_unique_for_overwrite

2020-10-19 Thread Jonathan Wakely via Gcc-patches
This is the std::unique_ptr part of P1020R1 (as amended by P1973R1) for
C++20. The std::shared_ptr part still needs to be done.

libstdc++-v3/ChangeLog:

* include/bits/unique_ptr.h (make_unique_for_overwrite): Define
for C++20.
* testsuite/20_util/unique_ptr/creation/array_neg.cc: Remove
unused header. Adjust standard reference.
* testsuite/20_util/unique_ptr/creation/for_overwrite.cc: New test.
* testsuite/20_util/unique_ptr/creation/for_overwrite__neg.cc: New test.

Tested powerpc64le-linux. Committed to trunk.

commit e7a0af84d68f50b65dffa1af462d10bd4bf03939
Author: Jonathan Wakely 
Date:   Mon Oct 19 22:11:39 2020

libstdc++: Implement std::make_unique_for_overwrite

This is the std::unique_ptr part of P1020R1 (as amended by P1973R1) for
C++20. The std::shared_ptr part still needs to be done.

libstdc++-v3/ChangeLog:

* include/bits/unique_ptr.h (make_unique_for_overwrite): Define
for C++20.
* testsuite/20_util/unique_ptr/creation/array_neg.cc: Remove
unused header. Adjust standard reference.
* testsuite/20_util/unique_ptr/creation/for_overwrite.cc: New test.
* testsuite/20_util/unique_ptr/creation/for_overwrite__neg.cc: New 
test.

diff --git a/libstdc++-v3/include/bits/unique_ptr.h 
b/libstdc++-v3/include/bits/unique_ptr.h
index d0e4cefadd7..252ea89917b 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -969,8 +969,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// Disable std::make_unique for arrays of known bound
   template
-inline typename _MakeUniq<_Tp>::__invalid_type
+typename _MakeUniq<_Tp>::__invalid_type
 make_unique(_Args&&...) = delete;
+
+#if __cplusplus > 201703L
+  /// std::make_unique_for_overwrite for single objects
+  template
+inline typename _MakeUniq<_Tp>::__single_object
+make_unique_for_overwrite()
+{ return unique_ptr<_Tp>(new _Tp); }
+
+  /// std::make_unique_for_overwrite for arrays of unknown bound
+  template
+inline typename _MakeUniq<_Tp>::__array
+make_unique_for_overwrite(size_t __n)
+{ return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__n]); }
+
+  /// Disable std::make_unique_for_overwrite for arrays of known bound
+  template
+typename _MakeUniq<_Tp>::__invalid_type
+make_unique_for_overwrite(_Args&&...) = delete;
+#endif // C++20
+
   // @} relates unique_ptr
 #endif // C++14
 
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/creation/array_neg.cc 
b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/array_neg.cc
index 928080d9161..a76cacb1031 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/creation/array_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/array_neg.cc
@@ -17,10 +17,9 @@
 // with this library; see the file COPYING3.  If not see
 // .
 
-// 20.9.1.4 unique_ptr creation [unique.ptr.create]
+// C++14 20.8.1.4 unique_ptr creation [unique.ptr.create]
 
 #include 
-#include 
 
 struct A { };
 
diff --git 
a/libstdc++-v3/testsuite/20_util/unique_ptr/creation/for_overwrite.cc 
b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/for_overwrite.cc
new file mode 100644
index 000..e7231c2ac95
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/for_overwrite.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do run { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+
+// This library 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 this library; see the file COPYING3.  If not see
+// .
+
+// C++20 20.11.1.5 unique_ptr creation [unique.ptr.create]
+
+#include 
+#include 
+#include 
+#include 
+
+void* operator new(std::size_t n)
+{
+  void* p = std::malloc(n);
+  std::memset(p, 0xaa, n);
+  return p;
+}
+
+void operator delete(void* p) { std::free(p); }
+void operator delete(void* p, std::size_t) { std::free(p); }
+
+void
+test01()
+{
+  std::unique_ptr a = std::make_unique_for_overwrite();
+  VERIFY( a != nullptr );
+  unsigned char buf[sizeof(int)];
+  std::memcpy(buf, a.get(), sizeof(buf));
+  for (unsigned char c : buf)
+VERIFY( c == 0xaa );
+}
+
+void
+test02()
+{
+  std::unique_ptr a = std::make_unique_for_overwrite(3);
+  VERIFY( a != nullptr );
+  unsigned char buf[3 * sizeof(int)];
+  std::memcpy(buf, a.get(), sizeo

Re: Extend builtin fnspecs

2020-10-19 Thread Jan Hubicka
> > +  /* True if memory reached by the argument is read.
> > + Valid only if all loads are known.  */
> > +  bool
> > +  arg_read_p (unsigned int i)
> > +  {
> > +unsigned int idx = arg_idx (i);
> > +gcc_checking_assert (arg_specified_p (i));
> > +gcc_checking_assert (loads_known_p ());
> 
> I see loads_known_p () is 'const' (introducing new terminology
> as alias for sth else is IMHO bad).  So what do you think
> arg_read_p () guarantees?  Even on a not 'const' function
> 'r' or 'R' or 'w' or 'W' means the argument could be read??!

Original intention was !arg_read_p to guarantee that argument is not
read from (and for that you need const), but I updated it.
> 
> > +return str[idx] == 'r' || str[idx] == 'R'
> > +  || str[idx] == 'w' || str[idx] == 'W';
> > +  }
> > +
> > +  /* True if memory reached by the argument is read.
> > + Valid only if all loads are known.  */
> > +  bool
> > +  arg_written_p (unsigned int i)
> > +  {
> > +unsigned int idx = arg_idx (i);
> > +gcc_checking_assert (arg_specified_p (i));
> > +gcc_checking_assert (stores_known_p ());
> 
> Likewise.  IMHO those will cause lots of confusion.  For example
> arg_readonly_p doesn't imply arg_read_p.
> 
> Please keep the number of core predicates at a minimum!

Well, my intention is/was that while fnspec strings themselves are
necessarily bit ad-hoc (trying to pack multiple things into 2 characters
and choosing just few special cases we care about) we should abstract
this and have predicates for individual properties we care about.

Indeed I did not name them very well, hopefully things are better now :)
In future modref can detect those properties of functions and provide
symetric API for testing them without need to go to fnspec limitations.
Similarly I would like to decouple logic around const/pure functions
better as well (since they pack multiple things together - presence of
side effects, whether function is deterministic and info about global
memory accesses).

Concerning arg_read_p and arg_written_p I introduced the while I was
still intending to make 'w' and 'W' mean what 'o' and 'O' does.
With original predicates the code handling loads

if (fnspec.loads_known_p ())
  for each argument i
if (fnspec.arg_readonly_p (i))
  argument is read from
else
  argument is not read, ignore it.
else
 ask pta if base is local

Which looked like odd re-use of readonly_p predicate intended for
something else.  I think main confussion is that I interpreted the specs
with cCpP bit weirdly. In particular:

 ". W . R "
means
 - arg 1 is written&read directly and noescapes,
 - arg 2 is written, read directly or indirectly and escapes,
 - arg 3 is read only directly, not written to and odes not escape.

With previus patch 
 ".cW . R "
means:
 - arg 1 is written&read directly and noescapes
 - arg 2 is used only as pointer value (i.e. for NULL check)
 - arg 3 is read only directly, not written to and does not escape.

With current patch is means:
 - arg 1 is written&read directly and noescapes
 - arg 2 is written&read directly or indirectly and may escape (in other stores 
allowed by the function)
 - arg 3 is read only directly, not written to and does not escape.

With current patch the loop is:
if (!fnspec.global_memory_read_p ())
  for each argument i
if (POINTER_TYPE_P (TREE_TYPE (arg))
&& fnspec.arg_maybe_read_p (i))
  argument is read from
else
  argument is not read.
else
  ask pta if base is local

Which seems better and follows what we did before.
However the extra POINTER_TYPE_P test is needed since we do not want to
disambiguate non-pointer parameters that also have '.' specifier. I am
not sure that this is safe/feasible with gimple type system.

I think it should be:

for each argument i
  if (POINTER_TYPE_P (TREE_TYPE (arg))
  && fnspec.arg_maybe_read_p (i))
argument is read from
  else
argument is not read.
if (fnspec.global_memory_read_p ())
  give up if pta thinks this is not local.

Because if I have function with spec say
 ". R "
and cal it with foo (&localvar) I think it should end up non-escaping
and thus not alias with function calls except when it is an parameter.

We do not have builtins like this right now though.
> 
> > +return str[idx] == 'w' || str[idx] == 'W'
> > +  || str[idx] == 'o' || str[idx] == 'O';
> > +  }
> > +
> > +  /* Return true if load of memory pointed to by argument I is specified
> > + by another argument.  In this case set ARG.  */
> > +  bool
> > +  arg_access_size_given_by_arg_p (unsigned int i, unsigned int *arg)
> 
> I think we need to document that this and all the other predicates are
> _may_ predicates, thus strncat "1cW R3" means src is _possibly_
> accessed from offset 0 to what argument 3 specifies.  That's important
> for stores I think.  While memcpy has "1cW3R3" the fnspec can _not_
> be used to DSE a previous write to the destination covering [0, n].
> 
> That is, those are all may_ predicates 

Re: [PATCH][middle-end][i386][version 3]Add -fzero-call-used-regs=[skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all]

2020-10-19 Thread Uros Bizjak via Gcc-patches
On Tue, Oct 6, 2020 at 4:02 PM Qing Zhao  wrote:
>
> Hi, Gcc team,
>
> This is the 3rd version of the implementation of patch -fzero-call-used-regs.
>
> We will provide a new feature into GCC:
>
> Add 
> -fzero-call-used-regs=[skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all]
>  command-line option
> and
> zero_call_used_regs("skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all")
>  function attribues:
>
>1. -fzero-call-used-regs=skip and zero_call_used_regs("skip")
>
>Don't zero call-used registers upon function return. This is the default 
> behavior.
>
>2. -fzero-call-used-regs=used-gpr-arg and 
> zero_call_used_regs("used-gpr-arg")
>
>Zero used call-used general purpose registers that are used to pass 
> parameters upon function return.
>
>3. -fzero-call-used-regs=used-arg and zero_call_used_regs("used-arg")
>
>Zero used call-used registers that are used to pass parameters upon 
> function return.
>
>4. -fzero-call-used-regs=all-arg and zero_call_used_regs("all-arg")
>
>Zero all call-used registers that are used to pass parameters upon 
> function return.
>
>5. -fzero-call-used-regs=used-gpr and zero_call_used_regs("used-gpr")
>
>Zero used call-used general purpose registers upon function return.
>
>6. -fzero-call-used-regs=all-gpr and zero_call_used_regs("all-gpr")
>
>Zero all call-used general purpose registers upon function return.
>
>7. -fzero-call-used-regs=used and zero_call_used_regs("used")
>
>Zero used call-used registers upon function return.
>
>8. -fzero-call-used-regs=all and zero_call_used_regs("all")
>
>Zero all call-used registers upon function return.
>
> Zero call-used registers at function return to increase the program
> security by either mitigating Return-Oriented Programming (ROP) or
> preventing information leak through registers.
>
> {skip}, which is the default, doesn't zero call-used registers.
>
> {used-arg-gpr} zeros used call-used general purpose registers that
> pass parameters. {used-arg} zeros used call-used registers that
> pass parameters. {arg} zeros all call-used registers that pass
> parameters. These 3 choices are used for ROP mitigation.
>
> {used-gpr} zeros call-used general purpose registers
> which are used in function.  {all-gpr} zeros all
> call-used registers.  {used} zeros call-used registers which
> are used in function.  {all} zeros all call-used registers.
> These 4 choices are used for preventing information leak through
> registers.
>
> You can control this behavior for a specific function by using the function
> attribute {zero_call_used_regs}.
>
> **Tests be done:
> 1. Gcc bootstrap on x86, aarch64 and rs6000.
> 2. Regression test on x86, aarch64 and rs6000.
> (X86, aarch64 have no any issue, rs6000 failed at the new testing case in 
> middle end which is expected)
>
> 3. Cpu2017 on x86, -O2 
> -fzero-call-used-regs=used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all
>
> **runtime performance data of CPU2017 on x86
> https://gitlab.com/x86-gcc/gcc/-/wikis/uploads/e9c5bedba6e387586364571f2eae3b8d/zero_call_used_regs_runtime_New.csv
>
> **The major changes compared to the previous version are:
>
> 1. Add 3 new sub-options and corresponding function attributes:
>   used-gpr-arg, used-arg, all-arg
>   for ROP mitigation purpose;
> 2. Updated user manual;
> 3. Re-design of the implementation:
>
>   3.1 data flow change to reflect the newly added zeroing insns to avoid
>   these insns been deleted, moved, or merged by later passes:
>
>   3.1.1.
>   abstract EPILOGUE_USES into a new target-independent wrapper function that
>   (a) returns true if EPILOGUE_USES itself returns true and (b) returns
>   true for registers that need to be zero on return, if the zeroing
>   instructions have already been inserted.  The places that currently
>   test EPILOGUE_USES should then test this new wrapper function instead.
>
>   Add this new wrapper function to df.h and df-scan.c.
>
>   3.1.2.
>   add a new utility routine "expand_asm_reg_clobber_mem_blockage" to generate
>   a volatile asm insn that clobbers all the hard registers that are zeroed.
>
>   emit this volatile asm in the very beginning of the zeroing sequence.
>
>   3.2 new pass:
>   add a new pass in the beginning of "late_compilation", before
>   "pass_compute_alignment", called "pass_zero_call_used_regs".
>
>   in this new pass,
>   * compute the data flow information; (df_analyze ());
>   * scan the exit block from backward to look for "return":
> A. for each return, compute the "need_zeroed_hardregs" based on
> the user request, and data flow information, and function ABI info.
> B. pass this need_zeroed_hardregs set to target hook "zero_call_used_regs"
> to generate the instruction sequnce that zero the regs.
> C. Data flow maintenance.
> 4.Use "lookup_attribute" to get the attribute information instead of setting
>   the attribute information into "tree_decl_with_vis" in tree-core.h.

Re: [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double.

2020-10-19 Thread Michael Meissner via Gcc-patches
On Fri, Oct 16, 2020 at 03:30:56PM -0500, Segher Boessenkool wrote:
> On Fri, Oct 09, 2020 at 12:35:44AM -0400, Michael Meissner wrote:
> > This patch is revised from the first version of the patch posted.
> 
> In the future, please send a NEW series, in a NEW thread, when you have
> a new series.  I was waiting for a new series (because you needed
> changes), and I missed that you posted it in the old thread.
> 
> If you do not want to because the patches are independent (and not
> actually a series), you can send them as independent patches as well
> (and that is easier to handle, independent things become much more
> obviously independent!)

In this case, they are grouped together because various people (Tulio, Jonathan
Wakely) need to know all of the patches that they need to apply to get their
various work (GLIBC, Libstc++, etc.) to work before the patches are installed.

> > Normally the mapping is done in the math.h and stdio.h files.  However, not
> > everybody uses these files, which means we also need to change the external
> > name for the built-in function within the compiler.
> 
> Because those are *not* defined in those headers.  So those headers are
> completely irrelevant to this.

The current glibc stdio.h and math.h takes care of the mapping for the
functions without having the compiler do the mapping.  But not everybody uses
those headers (there are a few test cases for instance that do not include
math.h).

But more importantly, we need the mapping for Fortran to access the right
functions for the math library, since they do not have an equivalent of math.h.

> 
> > --- a/gcc/config/rs6000/rs6000.c
> > +++ b/gcc/config/rs6000/rs6000.c
> > @@ -26897,56 +26897,156 @@ rs6000_globalize_decl_name (FILE * stream, tree 
> > decl)
> > library before you can switch the real*16 type at compile time.
> >  
> > We use the TARGET_MANGLE_DECL_ASSEMBLER_NAME hook to change this name.  
> > We
> > -   only do this if the default is that long double is IBM extended double, 
> > and
> > -   the user asked for IEEE 128-bit.  */
> > +   only do this transformation if the __float128 type is enabled.  This
> > +   prevents us from doing the transformation on older 32-bit ports that 
> > might
> > +   have enabled using IEEE 128-bit floating point as the default long 
> > double
> > +   type.  */
> 
> But that is just as broken then?

I'm not sure what you mean is broken.  We currently do not provide the float128
emulation functions on any system other than little endian PowerPC.  If
somebody goes through and adds the work, then obviously, we can change the
code.

> 
> > +   default:
> > + break;
> 
> Please don't invert the natural order, leave the default at the bottom.
> Just like you should not write "0 == x".

Ok.

> 
> > +   case BUILT_IN_NEXTTOWARD:
> > + newname = "__nexttoward_to_ieee128";
> > + break;
> > +
> > +   case BUILT_IN_NEXTTOWARDF:
> > + newname = "__nexttowardf_to_ieee128";
> > + break;
> 
> Why the "_to_" in those?  How irregular.

No idea.  I was just using the names that are in glibc.

> > +   case BUILT_IN_SCALBL:
> > + newname = "__scalbnieee128";
> > + break;
> 
> Should that be __scalbieee128?

Yes, thanks.

> > +  /* Update the __builtin_*printf && __builtin_*scanf functions.  */
> > +  if (!newname)
> > +   {
> > + const size_t printf_len = sizeof ("printf") - 1;
> 
> The "const" here has no function; the compiler *knows* this is a
> constant number.
> 
> Please use strlen, and no - 1.

Ok.

> > + if (len >= printf_len
> > + && strcmp (name + len - printf_len, "printf") == 0)
> 
> Thew first test is unnecessary.
> 
> > +   {
> > + char *name2 = (char *) alloca (len + 1 + printf_extra);
> > + strcpy (name2, "__");
> > + memcpy (name2 + 2, name, len);
> > + strcpy (name2 + 2 + len, "ieee128");
> > + newname = (const char *) name2;
> > +   }
> 
> Maybe just use asprintf and simplify all of this massively?  It's not
> like a malloc here or there will be measurably slower (if it was, you
> need to do all of this differently anyway, with some caching etc.)

Ok.

> > + /* See if the function passes a IEEE 128-bit floating point 
> > type
> > +or complex type.  */
> > + FOREACH_FUNCTION_ARGS (type, arg, args_iter)
> > {
> > - uses_ieee128_p = true;
> > - break;
> > + machine_mode arg_mode = TYPE_MODE (arg);
> > + if (arg_mode == TFmode || arg_mode == TCmode)
> > +   {
> > + uses_ieee128_p = true;
> > + break;
> > +   }
> 
> I don't see why TFmode would mean it is IEEE?  TFmode can be IBM128 as
> well?

The whole section is inside of the test:

  if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
  && TREE_CODE (decl) == FUNCTION_DECL
  && fndecl_built_in_p (decl, BUI

[r11-4072 Regression] FAIL: gcc.dg/cpp/endif.c (test for excess errors) on Linux/x86_64

2020-10-19 Thread sunil.k.pandey via Gcc-patches
On Linux/x86_64,

5abe05b4331250b6a7798ce87c0a82adc2bd70f3 is the first bad commit
commit 5abe05b4331250b6a7798ce87c0a82adc2bd70f3
Author: Nathan Sidwell 
Date:   Mon Oct 19 07:57:50 2020 -0700

preprocessor: Fix non-fn fn-like macro at EOF [PR97471]

caused

FAIL: gcc.dg/cpp/endif.c (test for excess errors)

with GCC configured with

Configured with: ../../gcc/configure 
--prefix=/local/skpandey/gccwork/toolwork/gcc-bisect-master/master/r11-4072/usr 
--enable-clocale=gnu --with-system-zlib --with-demangler-in-ld 
--with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl 
--enable-libmpx x86_64-linux --disable-bootstrap

To reproduce:

$ cd {build_dir}/gcc && make check RUNTESTFLAGS="cpp.exp=gcc.dg/cpp/endif.c 
--target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="cpp.exp=gcc.dg/cpp/endif.c 
--target_board='unix{-m32\ -march=cascadelake}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="cpp.exp=gcc.dg/cpp/endif.c 
--target_board='unix{-m64}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="cpp.exp=gcc.dg/cpp/endif.c 
--target_board='unix{-m64\ -march=cascadelake}'"

(Please do not reply to this email, for question about this report, contact me 
at skpgkp2 at gmail dot com)


Re: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems

2020-10-19 Thread Michael Meissner via Gcc-patches
On Fri, Oct 16, 2020 at 02:14:04PM -0500, Segher Boessenkool wrote:
> On Thu, Sep 24, 2020 at 04:20:36PM -0400, Michael Meissner wrote:
> > This series of 9 patches is an attempt to gather together all of the patches
> > that are needed to be able to configure and build a little endian 64-bit
> > PowerPC Linux GCC compiler where the defualt long double format uses the 
> > IEEE
> > 128-bit representation.
> > 
> > I have created an IBM vendor branch that includes these patches (along the
> > other outstanding patches that I have for IEEE 128-bit min/max/cmove on
> > power10, and power10 PCREL_OPT support):
> > 
> > vendors/ibm/ieee-longdouble-001
> > 
> > You will need a new enough GLIBC in order to do this configuration.
> 
> What happens if you glibc is older, and you try?

You get linker errors due to the older GLIBC not using -mno-gnu-attribute in
all of the appropriate places, and and not all of the names that are renamed
will be present.

-marlin-> ./xgcc -B./ -O2 -g foo.c -lm -mabi=ieeelongdouble -Wno-psabi && 
./a.out
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
/opt/at13.0/lib/../lib64/libm.so uses IBM long double, 
/home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses 
IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
/opt/at13.0/lib/../lib64/libc.so.6 uses IBM long double, 
/home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: ./libgcc_s.so.1 uses 
IBM long double, /home/meissner/tmp/gcc-tmp/ccvzdRyj.o uses IEEE long double
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
/home/meissner/tmp/gcc-tmp/ccvzdRyj.o: in function `main':
/home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined 
reference to `__sinieee128'
/home3/meissner/fsf-install-ppc64le/binutils-gdb/bin/ld: 
/home3/meissner/fsf-build-ppc64le/work020-at13.0/gcc/foo.c:8: undefined 
reference to `__printfieee128'
collect2: error: ld returned 1 exit status

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


[r11-4070 Regression] FAIL: gcc.dg/pr97488.c (test for excess errors) on Linux/x86_64

2020-10-19 Thread sunil.k.pandey via Gcc-patches
On Linux/x86_64,

2d2f4ffc97a8510e72a99ee106159aeae2627a42 is the first bad commit
commit 2d2f4ffc97a8510e72a99ee106159aeae2627a42
Author: Aldy Hernandez 
Date:   Mon Oct 19 06:18:46 2020 -0400

Gracefully handle right shifts larger than the precision.

caused

FAIL: gcc.dg/pr97488.c (test for excess errors)

with GCC configured with

Configured with: ../../gcc/configure 
--prefix=/local/skpandey/gccwork/toolwork/gcc-bisect-master/master/r11-4070/usr 
--enable-clocale=gnu --with-system-zlib --with-demangler-in-ld 
--with-fpmath=sse --enable-languages=c,c++,fortran --enable-cet --without-isl 
--enable-libmpx x86_64-linux --disable-bootstrap

To reproduce:

$ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr97488.c 
--target_board='unix{-m32}'"
$ cd {build_dir}/gcc && make check RUNTESTFLAGS="dg.exp=gcc.dg/pr97488.c 
--target_board='unix{-m32\ -march=cascadelake}'"

(Please do not reply to this email, for question about this report, contact me 
at skpgkp2 at gmail dot com)


Re: [PATCH] openmp: Implement support for OMP_TARGET_OFFLOAD

2020-10-19 Thread Jakub Jelinek via Gcc-patches
On Mon, Oct 19, 2020 at 06:57:49PM +0100, Kwok Cheung Yeung wrote:
> --- a/libgomp/env.c
> +++ b/libgomp/env.c
> @@ -75,6 +75,7 @@ struct gomp_task_icv gomp_global_icv = {
>  
>  unsigned long gomp_max_active_levels_var = gomp_supported_active_levels;
>  bool gomp_cancel_var = false;
> +enum gomp_target_offload_t gomp_target_offload_var = 
> GOMP_TARGET_OFFLOAD_DEFAULT;

Too long line.

> --- a/libgomp/target.c
> +++ b/libgomp/target.c
> @@ -116,7 +116,13 @@ resolve_device (int device_id)
>  }
>  
>if (device_id < 0 || device_id >= gomp_get_num_devices ())
> -return NULL;
> +{
> +  if (gomp_target_offload_var == GOMP_TARGET_OFFLOAD_MANDATORY
> +   && device_id != GOMP_DEVICE_HOST_FALLBACK)
> + gomp_fatal ("OMP_TARGET_OFFLOAD is set to MANDATORY, but device not 
> found.");

No full stop at the end of gomp_fatal messages (everywhere in your patch)
for consistency with other gomp_fatal calls.  Also, too long line (similarly
other gomp_fatal calls).  Just use
gomp_fatal (" .   ... "
"..");

Otherwise LGTM.

Jakub



Re: [PATCH] openmp: Implement support for OMP_TARGET_OFFLOAD

2020-10-19 Thread Kwok Cheung Yeung

On 15/10/2020 12:02 pm, Jakub Jelinek wrote:

On Thu, Oct 15, 2020 at 12:50:18PM +0200, Jakub Jelinek via Gcc-patches wrote:
Ok, the first response indicates that both if (false) and
omp_get_initial_device () are valid.
Therefore, I think until omp_get_initial_device () value is changed, we
want in resolve_device:
   if (device_id < 0 || device_id >= gomp_get_num_devices ())
 {
   if (device_id != GOMP_DEVICE_HOST_FALLBACK)
gomp_fatal (...);
   return NULL;
 }
and do gomp_fatal also for further return NULLs in the function.
And then in
   if (devicep == NULL
   || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
   /* All shared memory devices should use the GOMP_target_ext function.  */
   || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM
   || !(fn_addr = gomp_get_target_fn_addr (devicep, fn)))
 return gomp_target_fallback (fn, hostaddrs);
and similar do gomp_fatal before the gomp_target_fallback call
if target-offload-var ICV is mandatory and devicep != NULL.



Instead of doing a gomp_fatal before every call to 
gomp_target_fallback/gomp_target_data_fallback, I think it would be tidier to 
pass devicep into the fallback instead and keep the gomp_fatals in the fallback 
functions? Although it is kind of odd to pass the device to the fallback 
function to be used if the device in question does not work, but at least the 
fallback functions are static to target.c.


Is this version okay for trunk?

Thanks

Kwok
commit 82555f50d2930f973ab20782ebcb836b719bce96
Author: Kwok Cheung Yeung 
Date:   Mon Oct 19 10:47:42 2020 -0700

openmp: Implement support for OMP_TARGET_OFFLOAD environment variable

This implements support for the OMP_TARGET_OFFLOAD environment variable
introduced in the OpenMP 5.0 standard, which controls how offloading
is handled.  It may be set to MANDATORY (abort if offloading cannot be
performed), DISABLED (no offloading to devices) or DEFAULT (offload to
device if possible, fall back to host if not).

2020-10-19  Kwok Cheung Yeung  

libgomp/
* env.c (gomp_target_offload_var): New.
(parse_target_offload): New.
(handle_omp_display_env): Print value of OMP_TARGET_OFFLOAD.
(initialize_env): Parse OMP_TARGET_OFFLOAD.
* libgomp.h (gomp_target_offload_t): New.
(gomp_target_offload_var): New.
* libgomp.texi (OMP_TARGET_OFFLOAD): New section.
* target.c (resolve_device): Generate error if device not found and
offloading is mandatory.
(gomp_target_fallback): Generate error if offloading is mandatory.
(GOMP_target): Add argument in call to gomp_target_fallback.
(GOMP_target_ext): Likewise.
(gomp_target_data_fallback): Generate error if offloading is mandatory.
(GOMP_target_data): Add argument in call to gomp_target_data_fallback.
(GOMP_target_data_ext): Likewise.
(gomp_target_task_fn): Add argument in call to gomp_target_fallback.
(gomp_target_init): Return early if offloading is disabled.

diff --git a/libgomp/env.c b/libgomp/env.c
index d730c48..d0eae8d 100644
--- a/libgomp/env.c
+++ b/libgomp/env.c
@@ -75,6 +75,7 @@ struct gomp_task_icv gomp_global_icv = {
 
 unsigned long gomp_max_active_levels_var = gomp_supported_active_levels;
 bool gomp_cancel_var = false;
+enum gomp_target_offload_t gomp_target_offload_var = 
GOMP_TARGET_OFFLOAD_DEFAULT;
 int gomp_max_task_priority_var = 0;
 #ifndef HAVE_SYNC_BUILTINS
 gomp_mutex_t gomp_managed_threads_lock;
@@ -374,6 +375,48 @@ parse_unsigned_long_list (const char *name, unsigned long 
*p1stvalue,
   return false;
 }
 
+static void
+parse_target_offload (const char *name, enum gomp_target_offload_t *offload)
+{
+  const char *env;
+  bool found = false;
+  enum gomp_target_offload_t new_offload;
+
+  env = getenv (name);
+  if (env == NULL)
+return;
+
+  while (isspace ((unsigned char) *env))
+++env;
+  if (strncasecmp (env, "default", 7) == 0)
+{
+  env += 7;
+  found = true;
+  new_offload = GOMP_TARGET_OFFLOAD_DEFAULT;
+}
+  else if (strncasecmp (env, "mandatory", 9) == 0)
+{
+  env += 9;
+  found = true;
+  new_offload = GOMP_TARGET_OFFLOAD_MANDATORY;
+}
+  else if (strncasecmp (env, "disabled", 8) == 0)
+{
+  env += 8;
+  found = true;
+  new_offload = GOMP_TARGET_OFFLOAD_DISABLED;
+}
+  while (isspace ((unsigned char) *env))
+++env;
+  if (found && *env == '\0')
+{
+  *offload = new_offload;
+  return;
+}
+
+  gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
+}
+
 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
enum values.  Return true if one was present and it was successfully
parsed.  */
@@ -1334,6 +1377,21 @@ handle_omp_display_env (unsigned long stacksize, int 
wait_policy)
 }
   fputs ("'\n", stderr);
 
+  fputs ("  OMP_TARGET_OFFLOAD = '", stderr);
+  switch 

PING: [PATCH] Convert -Wrestrict pass to ranger.

2020-10-19 Thread Aldy Hernandez via Gcc-patches
Rebased on current trunk.

There is one adjustment to a C++ test which now gives a false positive.
After talking with Martin Sebor, we've concluded this is expected.  There
is no way to communicate that libstdc++ allocated objects are always
less than PTRDIFF_MAX.

OK?

gcc/ChangeLog:

* calls.c (get_size_range): Adjust to work with ranger.
* calls.h (get_size_range): Add ranger argument to prototype.
* gimple-ssa-warn-restrict.c (class wrestrict_dom_walker): Remove.
(check_call): Pull out of wrestrict_dom_walker into a
static function.
(wrestrict_dom_walker::before_dom_children): Rename to...
(wrestrict_walk): ...this.
(pass_wrestrict::execute): Instantiate ranger.
(class builtin_memref): Add stmt and query fields.
(builtin_access::builtin_access): Add range_query field.
(builtin_memref::builtin_memref): Same.
(builtin_memref::extend_offset_range): Same.
(builtin_access::builtin_access): Make work with ranger.
(wrestrict_dom_walker::check_call): Pull out into...
(check_call): ...here.
(check_bounds_or_overlap): Add range_query argument.
* gimple-ssa-warn-restrict.h (check_bounds_or_overlap):
Add range_query and gimple stmt arguments.

gcc/testsuite/ChangeLog:

* gcc.dg/Wrestrict-22.c: New test.
* g++.dg/torture/pr92421.C: Adjust for ranger.

libstdc++-v3/ChangeLog:

* testsuite/21_strings/basic_string/capacity/1.cc: Pass
-Wno-stringop-overflow to test.
---
 gcc/calls.c   | 26 -
 gcc/calls.h   |  2 +
 gcc/gimple-ssa-warn-restrict.c| 99 +++
 gcc/gimple-ssa-warn-restrict.h|  3 +
 gcc/testsuite/g++.dg/torture/pr92421.C|  4 +
 gcc/testsuite/gcc.dg/Wrestrict-22.c   |  9 ++
 .../21_strings/basic_string/capacity/1.cc |  2 +
 7 files changed, 104 insertions(+), 41 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wrestrict-22.c

diff --git a/gcc/calls.c b/gcc/calls.c
index d3120b23f60..a12b84744c0 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "gimple-fold.h"
 #include "attr-fnspec.h"
+#include "value-query.h"
 
 #include "tree-pretty-print.h"
 
@@ -1244,7 +1245,8 @@ alloc_max_size (void)
in a multi-range, otherwise to the smallest valid subrange.  */
 
 bool
-get_size_range (tree exp, tree range[2], int flags /* = 0 */)
+get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2],
+   int flags /* = 0 */)
 {
   if (!exp)
 return false;
@@ -1263,7 +1265,21 @@ get_size_range (tree exp, tree range[2], int flags /* = 
0 */)
   enum value_range_kind range_type;
 
   if (integral)
-range_type = determine_value_range (exp, &min, &max);
+{
+  value_range vr;
+  if (query && query->range_of_expr (vr, exp, stmt))
+   {
+ range_type = vr.kind ();
+ if (!vr.undefined_p ())
+   {
+ min = wi::to_wide (vr.min ());
+ max = wi::to_wide (vr.max ());
+   }
+   }
+  else
+   range_type = determine_value_range (exp, &min, &max);
+
+}
   else
 range_type = VR_VARYING;
 
@@ -1369,6 +1385,12 @@ get_size_range (tree exp, tree range[2], int flags /* = 
0 */)
   return true;
 }
 
+bool
+get_size_range (tree exp, tree range[2], int flags /* = 0 */)
+{
+  return get_size_range (/*query=*/NULL, exp, /*stmt=*/NULL, range, flags);
+}
+
 /* Diagnose a call EXP to function FN decorated with attribute alloc_size
whose argument numbers given by IDX with values given by ARGS exceed
the maximum object size or cause an unsigned oveflow (wrapping) when
diff --git a/gcc/calls.h b/gcc/calls.h
index 644ec45d92c..f32b6308b58 100644
--- a/gcc/calls.h
+++ b/gcc/calls.h
@@ -142,6 +142,8 @@ enum size_range_flags
SR_USE_LARGEST = 2
   };
 extern bool get_size_range (tree, tree[2], int = 0);
+extern bool get_size_range (class range_query *, tree, gimple *,
+   tree[2], int = 0);
 extern rtx rtx_for_static_chain (const_tree, bool);
 extern bool cxx17_empty_base_field_p (const_tree);
 
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index e2734c81456..3a79e7240f9 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -25,7 +25,6 @@
 #include "backend.h"
 #include "tree.h"
 #include "gimple.h"
-#include "domwalk.h"
 #include "tree-pass.h"
 #include "builtins.h"
 #include "ssa.h"
@@ -41,6 +40,7 @@
 #include "calls.h"
 #include "cfgloop.h"
 #include "intl.h"
+#include "gimple-range.h"
 
 namespace {
 
@@ -77,21 +77,10 @@ pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED)
   return warn_array_bounds || warn_restrict || warn_stringop_overflow;
 }
 
-/* Class

PING: [PATCH] Convert -Walloca pass to ranger.

2020-10-19 Thread Aldy Hernandez via Gcc-patches
Rebased on current trunk.

FWIW, we finally get rid of the Walloca-6.c XFAIL.  This has been a long time
in coming:

-/* { dg-xfail-if "Currently broken but Andrew's work should fix this" { *-*-* 
} } */

:-)

OK?
Aldy

gcc/ChangeLog:

* gimple-ssa-warn-alloca.c (enum alloca_type): Remove
ALLOCA_BOUND_UNKNOWN and ALLOCA_CAST_FROM_SIGNED.
(warn_limit_specified_p): New.
(alloca_call_type_by_arg): Remove.
(cast_from_signed_p): Remove.
(is_max): Remove.
(alloca_call_type): Remove heuristics and replace with call into
ranger.
(pass_walloca::execute): Instantiate ranger.

gcc/testsuite/ChangeLog:

* gcc.dg/Walloca-1.c: Adjust for ranger.
* gcc.dg/Walloca-12.c: Same.
* gcc.dg/Walloca-13.c: Same.
* gcc.dg/Walloca-2.c: Same.
* gcc.dg/Walloca-3.c: Same.
* gcc.dg/Walloca-6.c: Same.
---
 gcc/gimple-ssa-warn-alloca.c  | 351 +++---
 gcc/testsuite/gcc.dg/Walloca-1.c  |   3 +-
 gcc/testsuite/gcc.dg/Walloca-12.c |   2 +-
 gcc/testsuite/gcc.dg/Walloca-13.c |   2 +-
 gcc/testsuite/gcc.dg/Walloca-2.c  |   6 +-
 gcc/testsuite/gcc.dg/Walloca-3.c  |   4 +-
 gcc/testsuite/gcc.dg/Walloca-6.c  |   1 -
 gcc/testsuite/gcc.dg/Wvla-larger-than-2.c |   1 -
 8 files changed, 51 insertions(+), 319 deletions(-)

diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index 9e80e5dbbd9..33824a7a091 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "calls.h"
 #include "cfgloop.h"
 #include "intl.h"
+#include "gimple-range.h"
 
 static unsigned HOST_WIDE_INT adjusted_warn_limit (bool);
 
@@ -99,12 +100,6 @@ enum alloca_type {
   // Alloca argument may be too large.
   ALLOCA_BOUND_MAYBE_LARGE,
 
-  // Alloca argument is bounded but of an indeterminate size.
-  ALLOCA_BOUND_UNKNOWN,
-
-  // Alloca argument was casted from a signed integer.
-  ALLOCA_CAST_FROM_SIGNED,
-
   // Alloca appears in a loop.
   ALLOCA_IN_LOOP,
 
@@ -135,6 +130,15 @@ public:
   }
 };
 
+/* Return TRUE if the user specified a limit for either VLAs or ALLOCAs.  */
+
+static bool
+warn_limit_specified_p (bool is_vla)
+{
+  unsigned HOST_WIDE_INT max = is_vla ? warn_vla_limit : warn_alloca_limit;
+  return max != HOST_WIDE_INT_MAX;
+}
+
 /* Return the value of the argument N to -Walloca-larger-than= or
-Wvla-larger-than= adjusted for the target data model so that
when N == HOST_WIDE_INT_MAX, the adjusted value is set to
@@ -158,183 +162,15 @@ adjusted_warn_limit (bool idx)
   return limits[idx];
 }
 
-
-// NOTE: When we get better range info, this entire function becomes
-// irrelevant, as it should be possible to get range info for an SSA
-// name at any point in the program.
-//
-// We have a few heuristics up our sleeve to determine if a call to
-// alloca() is within bounds.  Try them out and return the type of
-// alloca call with its assumed limit (if applicable).
-//
-// Given a known argument (ARG) to alloca() and an EDGE (E)
-// calculating said argument, verify that the last statement in the BB
-// in E->SRC is a gate comparing ARG to an acceptable bound for
-// alloca().  See examples below.
-//
-// If set, ARG_CASTED is the possible unsigned argument to which ARG
-// was casted to.  This is to handle cases where the controlling
-// predicate is looking at a casted value, not the argument itself.
-//arg_casted = (size_t) arg;
-//if (arg_casted < N)
-//  goto bb3;
-//else
-//  goto bb5;
-//
-// MAX_SIZE is WARN_ALLOCA= adjusted for VLAs.  It is the maximum size
-// in bytes we allow for arg.
-
-static class alloca_type_and_limit
-alloca_call_type_by_arg (tree arg, tree arg_casted, edge e,
-unsigned HOST_WIDE_INT max_size)
-{
-  basic_block bb = e->src;
-  gimple_stmt_iterator gsi = gsi_last_bb (bb);
-  gimple *last = gsi_stmt (gsi);
-
-  const offset_int maxobjsize = tree_to_shwi (max_object_size ());
-
-  /* When MAX_SIZE is greater than or equal to PTRDIFF_MAX treat
- allocations that aren't visibly constrained as OK, otherwise
- report them as (potentially) unbounded.  */
-  alloca_type unbounded_result = (max_size < maxobjsize.to_uhwi ()
- ? ALLOCA_UNBOUNDED : ALLOCA_OK);
-
-  if (!last || gimple_code (last) != GIMPLE_COND)
-{
-  return alloca_type_and_limit (unbounded_result);
-}
-
-  enum tree_code cond_code = gimple_cond_code (last);
-  if (e->flags & EDGE_TRUE_VALUE)
-;
-  else if (e->flags & EDGE_FALSE_VALUE)
-cond_code = invert_tree_comparison (cond_code, false);
-  else
-  return alloca_type_and_limit (unbounded_result);
-
-  // Check for:
-  //   if (ARG .COND. N)
-  // goto ;
-  //   else
-  // goto ;
-  //   :
-  //   alloca(ARG);
-  if ((cond_code

[committed] libstdc++: Use reserved name for C++20 attribute

2020-10-19 Thread Jonathan Wakely via Gcc-patches
Although the compiler supports the [[no_unique_address]] attribute, it's
not a reserved name prior to C++20, so we can't use it in std::tuple.
Use [[__no_unique_address__]] instead.

libstdc++-v3/ChangeLog:

* include/std/tuple (_Head_base): Use reserved
form of __no_unique_address__ attribute because
no_unique_address is not reserved prior to C++20.

Tested powerpc64le-linux. Committed to trunk.

commit fc77484c4a4feb308c64371233cb65b280333953
Author: Jonathan Wakely 
Date:   Mon Oct 19 17:57:14 2020

libstdc++: Use reserved name for C++20 attribute

Although the compiler supports the [[no_unique_address]] attribute, it's
not a reserved name prior to C++20, so we can't use it in std::tuple.
Use [[__no_unique_address__]] instead.

libstdc++-v3/ChangeLog:

* include/std/tuple (_Head_base): Use reserved
form of __no_unique_address__ attribute because
no_unique_address is not reserved prior to C++20.

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 11ad1991108..adfd6213a14 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -122,7 +122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   static constexpr const _Head&
   _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
 
-  [[no_unique_address]] _Head _M_head_impl;
+  [[__no_unique_address__]] _Head _M_head_impl;
 };
 #else
   template


[committed] libstdc++: Optimize container node-handle type for size

2020-10-19 Thread Jonathan Wakely via Gcc-patches
The use of std::optional in _Node_handle makes the node handle types for
associative and unordered containers larger than necessary. It also
greatly increases the amount of code included, as  is quite
large.

The boolean flag that records whether the std::optional contains a value
is redundant, because the _Node_handle::_M_ptr member provides the same
information. If the node handle has a non-null pointer it also has an
allocator, and not otherwise. By replacing std::optional with a custom
union type (and using _M_ptr to tell which union member is active) all
node handle sizes can be reduced by sizeof(allocator_type::pointer).

This makes the node handle types incompatible with previous releases, so
must be done before the C++17 ABI is fixed for GCC 11.

libstdc++-v3/ChangeLog:

* include/bits/node_handle.h (_Node_handle_common): Replace
std::optional with custom type.
* testsuite/20_util/variant/exception_safety.cc: Add missing
header include.

Tested powerpc64le-linux. Committed to trunk.

commit aa6d2be1e3455a5f0818d5bd6a44b15a55a39df5
Author: Jonathan Wakely 
Date:   Mon Oct 19 17:56:54 2020

libstdc++: Optimize container node-handle type for size

The use of std::optional in _Node_handle makes the node handle types for
associative and unordered containers larger than necessary. It also
greatly increases the amount of code included, as  is quite
large.

The boolean flag that records whether the std::optional contains a value
is redundant, because the _Node_handle::_M_ptr member provides the same
information. If the node handle has a non-null pointer it also has an
allocator, and not otherwise. By replacing std::optional with a custom
union type (and using _M_ptr to tell which union member is active) all
node handle sizes can be reduced by sizeof(allocator_type::pointer).

This makes the node handle types incompatible with previous releases, so
must be done before the C++17 ABI is fixed for GCC 11.

libstdc++-v3/ChangeLog:

* include/bits/node_handle.h (_Node_handle_common): Replace
std::optional with custom type.
* testsuite/20_util/variant/exception_safety.cc: Add missing
header include.

diff --git a/libstdc++-v3/include/bits/node_handle.h 
b/libstdc++-v3/include/bits/node_handle.h
index fc96937665a..82b702426d1 100644
--- a/libstdc++-v3/include/bits/node_handle.h
+++ b/libstdc++-v3/include/bits/node_handle.h
@@ -33,10 +33,10 @@
 
 #pragma GCC system_header
 
-#if __cplusplus > 201402L
+#if __cplusplus >= 201703L
 # define __cpp_lib_node_extract 201606
 
-#include 
+#include 
 #include 
 #include 
 
@@ -57,7 +57,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   get_allocator() const noexcept
   {
__glibcxx_assert(!this->empty());
-   return allocator_type(*_M_alloc);
+   return allocator_type(_M_alloc._M_alloc);
   }
 
   explicit operator bool() const noexcept { return _M_ptr != nullptr; }
@@ -65,76 +65,151 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   [[nodiscard]] bool empty() const noexcept { return _M_ptr == nullptr; }
 
 protected:
-  constexpr _Node_handle_common() noexcept : _M_ptr(), _M_alloc() {}
+  constexpr _Node_handle_common() noexcept : _M_ptr() { }
 
-  ~_Node_handle_common() { _M_destroy(); }
+  ~_Node_handle_common()
+  {
+   if (!empty())
+ _M_reset();
+  }
 
   _Node_handle_common(_Node_handle_common&& __nh) noexcept
-  : _M_ptr(__nh._M_ptr), _M_alloc(std::move(__nh._M_alloc))
+  : _M_ptr(__nh._M_ptr)
   {
-   __nh._M_ptr = nullptr;
-   __nh._M_alloc = nullopt;
+   if (_M_ptr)
+ _M_move(std::move(__nh));
   }
 
   _Node_handle_common&
   operator=(_Node_handle_common&& __nh) noexcept
   {
-   _M_destroy();
-   _M_ptr = __nh._M_ptr;
-   if constexpr (is_move_assignable_v<_NodeAlloc>)
+   if (empty())
  {
-   if (_AllocTraits::propagate_on_container_move_assignment::value
-   || !this->_M_alloc)
- this->_M_alloc = std::move(__nh._M_alloc);
-   else
- {
-   __glibcxx_assert(this->_M_alloc == __nh._M_alloc);
- }
+   if (!__nh.empty())
+ _M_move(std::move(__nh));
  }
+   else if (__nh.empty())
+ _M_reset();
else
  {
-   __glibcxx_assert(_M_alloc);
+   // Free the current node before replacing the allocator.
+   _AllocTraits::destroy(*_M_alloc, _M_ptr->_M_valptr());
+   _AllocTraits::deallocate(*_M_alloc, _M_ptr, 1);
+
+   _M_alloc = __nh._M_alloc.release(); // assigns if POCMA
+   _M_ptr = __nh._M_ptr;
+   __nh._M_ptr = nullptr;
  }
-   __nh._M_ptr = nullptr;
-   __nh._M_alloc = nullopt;
return *this;
   }
 
   _Node_handle_common(typename _AllocTraits::pointer __ptr,
   

Re: [PATCH] IBM Z: Emit vector alignment hints for strlen

2020-10-19 Thread Andreas Krebbel via Gcc-patches
On 18.10.20 20:32, Stefan Schulze Frielinghaus wrote:
> In case the vectorized version of strlen is used, then each memory
> access inside the loop is 16-byte aligned.  Thus add this kind of
> information so that vector alignment hints can later on be emitted.
> 
> Bootstrapped and regtested on IBM Z.  Ok for master?
> 
> gcc/ChangeLog:
> 
>   * config/s390/s390.c (s390_expand_vec_strlen): Add alignment
>   for memory access inside loop.

Ok. Thanks!

Andreas

> ---
>  gcc/config/s390/s390.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
> index dbb541bbea7..f9b27f96fd7 100644
> --- a/gcc/config/s390/s390.c
> +++ b/gcc/config/s390/s390.c
> @@ -5955,6 +5955,7 @@ s390_expand_vec_strlen (rtx target, rtx string, rtx 
> alignment)
>rtx temp;
>rtx len = gen_reg_rtx (QImode);
>rtx cond;
> +  rtx mem;
>  
>s390_load_address (str_addr_base_reg, XEXP (string, 0));
>emit_move_insn (str_idx_reg, const0_rtx);
> @@ -5996,10 +5997,10 @@ s390_expand_vec_strlen (rtx target, rtx string, rtx 
> alignment)
>LABEL_NUSES (loop_start_label) = 1;
>  
>/* Load 16 bytes of the string into VR.  */
> -  emit_move_insn (str_reg,
> -   gen_rtx_MEM (V16QImode,
> -gen_rtx_PLUS (Pmode, str_idx_reg,
> -  str_addr_base_reg)));
> +  mem = gen_rtx_MEM (V16QImode,
> +  gen_rtx_PLUS (Pmode, str_idx_reg, str_addr_base_reg));
> +  set_mem_align (mem, 128);
> +  emit_move_insn (str_reg, mem);
>if (into_loop_label != NULL_RTX)
>  {
>emit_label (into_loop_label);
> 



Re: [PATCH] arm: Fix multiple inheritance thunks for thumb-1 with -mpure-code

2020-10-19 Thread Christophe Lyon via Gcc-patches
On Mon, 19 Oct 2020 at 16:39, Richard Earnshaw
 wrote:
>
> On 12/10/2020 08:59, Christophe Lyon via Gcc-patches wrote:
> > On Thu, 8 Oct 2020 at 11:58, Richard Earnshaw
> >  wrote:
> >>
> >> On 08/10/2020 10:07, Christophe Lyon via Gcc-patches wrote:
> >>> On Tue, 6 Oct 2020 at 18:02, Richard Earnshaw
> >>>  wrote:
> 
>  On 29/09/2020 20:50, Christophe Lyon via Gcc-patches wrote:
> > When mi_delta is > 255 and -mpure-code is used, we cannot load delta
> > from code memory (like we do without -mpure-code).
> >
> > This patch builds the value of mi_delta into r3 with a series of
> > movs/adds/lsls.
> >
> > We also do some cleanup by not emitting the function address and delta
> > via .word directives at the end of the thunk since we don't use them
> > with -mpure-code.
> >
> > No need for new testcases, this bug was already identified by
> > eg. pr46287-3.C
> >
> > 2020-09-29  Christophe Lyon  
> >
> >   gcc/
> >   * config/arm/arm.c (arm_thumb1_mi_thunk): Build mi_delta in r3 and
> >   do not emit function address and delta when -mpure-code is used.
> 
> >>> Hi Richard,
> >>>
> >>> Thanks for your comments.
> >>>
>  There are some optimizations you can make to this code.
> 
>  Firstly, for values between 256 and 510 (inclusive), it would be better
>  to just expand a mov of 255 followed by an add.
> >>> I now see the splitted for the "Pe" constraint which I hadn't noticed
> >>> before, so I can write something similar indeed.
> >>>
> >>> However, I'm note quite sure to understand the benefit in the split
> >>> when -mpure-code is NOT used.
> >>> Consider:
> >>> int f3_1 (void) { return 510; }
> >>> int f3_2 (void) { return 511; }
> >>> Compile with -O2 -mcpu=cortex-m0:
> >>> f3_1:
> >>> movsr0, #255
> >>> lslsr0, r0, #1
> >>> bx  lr
> >>> f3_2:
> >>> ldr r0, .L4
> >>> bx  lr
> >>>
> >>> The splitter makes the code bigger, does it "compensate" for this by
> >>> not having to load the constant?
> >>> Actually the constant uses 4 more bytes, which should be taken into
> >>> account when comparing code size,
> >>
> >> Yes, the size of the literal pool entry needs to be taken into account.
> >>  It might happen that the entry could be shared with another use of that
> >> literal, but in general that's rare.
> >>
> >>> so f3_1 uses 6 bytes, and f3_2 uses 8, so as you say below three
> >>> thumb1 instructions would be equivalent in size compared to loading
> >>> from the literal pool. Should the 256-510 range be extended?
> >>
> >> It's a bit borderline at three instructions when literal pools are not
> >> expensive to use, but in thumb1 literal pools tend to be quite small due
> >> to the limited pc offsets we can use.  I think on balance we probably
> >> want to use the instruction sequence unless optimizing for size.
> >>
> >>>
> >>>
>  This is also true for
>  the literal pools alternative as well, so should be handled before all
>  this.
> >>> I am not sure what you mean: with -mpure-code, the above sample is 
> >>> compiled as:
> >>> f3_1:
> >>> movsr0, #255
> >>> lslsr0, r0, #1
> >>> bx  lr
> >>> f3_2:
> >>> movsr0, #1
> >>> lslsr0, r0, #8
> >>> addsr0, r0, #255
> >>> bx  lr
> >>>
> >>> so the "return 510" case is already handled as without -mpure-code.
> >>
> >> I was thinking specifically of the thunk sequence where you seem to be
> >> emitting instructions directly rather than generating RTL.  The examples
> >> you show here are not thunks.
> >>
> > OK thanks for the clarification.
> >
> > Here is an updated version, split into 3 patches to hopefully make
> > review easier.
> > They apply on top of my other mpure-code patches for PR96967 and PR96770:
> > https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554956.html
> > https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554957.html
> >
> > I kept it this way to make incremental changes easier to understand.
> >
> > Patch 1: With the hope to avoid confusion and make maintenance easier,
> > I have updated thumb1_gen_const_int() so that it can generate either RTL or
> > asm. This way, all the code used to build thumb-1 constants is in the
> > same place,
> >  in case we need to improve/fix it later. We now generate shorter sequences 
> > in
> > several cases matching your comments.
> >
> > Patch 2: Removes the equivalent loop from thumb1_movsi_insn pattern and
> > calls thumb1_gen_const_int.
> >
> > Patch 3: Update of the original patch in this thread, now calls
> > thumb1_gen_const_int.
>
> Yuk!  Those changes to thumb1_gen_const_int are horrible.
>
> I think we should be able to leverage the fact that the compiler can use
> C++ now to do much better than that, for example by making that function
> a template.  For example (and this is just a sketch):
>

Indeed! I didn't think abou

[Patch] testsuite: Avoid TCL errors when rootme or ASAN/TSAN/UBSAN is not available (was: Re: [Patch] testsuite: Avoid TCL errors when ASAN/TSAN/UBSAN is not available)

2020-10-19 Thread Tobias Burnus

Thomas Schwinge and Joseph convinced me that 'rootme' only makes sense
for in-tree testing and, hence, does not need (or: should not) be set in
site.exp.

Thus, if it is not set, we have to check its existence before using it –
to avoid similar TCL errors.
Hence, I updated the patch to check also for 'rootme'.

OK?

Tobias

On 10/19/20 11:46 AM, Tobias Burnus wrote:

In a --disable-libsanitizer build, I see errors such as:
  g++.sum:ERROR: can't read "asan_saved_library_path": no such variable

I believe the following patch is the right way to solve this.
OK?

Tobias


-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
testsuite: Avoid TCL errors when rootme or ASAN/TSAN/UBSAN is not avail

	* g++.dg/guality/guality.exp:
	* gcc.dg/guality/guality.exp:
	* gfortran.dg/guality/guality.exp:
	* lib/asan-dg.exp:
	* lib/tsan-dg.exp:
	* lib/ubsan-dg.exp:

 gcc/testsuite/g++.dg/guality/guality.exp  | 2 +-
 gcc/testsuite/gcc.dg/guality/guality.exp  | 2 +-
 gcc/testsuite/gfortran.dg/guality/guality.exp | 2 +-
 gcc/testsuite/lib/asan-dg.exp | 6 --
 gcc/testsuite/lib/tsan-dg.exp | 6 --
 gcc/testsuite/lib/ubsan-dg.exp| 6 --
 6 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/g++.dg/guality/guality.exp b/gcc/testsuite/g++.dg/guality/guality.exp
index 33571f1f28f..1d5b65fef57 100644
--- a/gcc/testsuite/g++.dg/guality/guality.exp
+++ b/gcc/testsuite/g++.dg/guality/guality.exp
@@ -38,7 +38,7 @@ global GDB
 if ![info exists ::env(GUALITY_GDB_NAME)] {
 if [info exists GDB] {
 	set guality_gdb_name "$GDB"
-} elseif [file exists $rootme/../gdb/gdb] {
+} elseif { [info exists rootme] && [file exists $rootme/../gdb/gdb] } {
 	# If we're doing a combined build, and gdb is available, use it.
 	set guality_gdb_name "$rootme/../gdb/gdb"
 } else {
diff --git a/gcc/testsuite/gcc.dg/guality/guality.exp b/gcc/testsuite/gcc.dg/guality/guality.exp
index 89cd896d05c..ba87132aef2 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.exp
+++ b/gcc/testsuite/gcc.dg/guality/guality.exp
@@ -38,7 +38,7 @@ global GDB
 if ![info exists ::env(GUALITY_GDB_NAME)] {
 if [info exists GDB] {
 	set guality_gdb_name "$GDB"
-} elseif [file exists $rootme/../gdb/gdb] {
+} elseif { [info exists rootme] && [file exists $rootme/../gdb/gdb] } {
 	# If we're doing a combined build, and gdb is available, use it.
 	set guality_gdb_name "$rootme/../gdb/gdb"
 } else {
diff --git a/gcc/testsuite/gfortran.dg/guality/guality.exp b/gcc/testsuite/gfortran.dg/guality/guality.exp
index eaa7ae770d6..0375edfffe4 100644
--- a/gcc/testsuite/gfortran.dg/guality/guality.exp
+++ b/gcc/testsuite/gfortran.dg/guality/guality.exp
@@ -19,7 +19,7 @@ global GDB
 if ![info exists ::env(GUALITY_GDB_NAME)] {
 if [info exists GDB] {
 	set guality_gdb_name "$GDB"
-} elseif [file exists $rootme/../gdb/gdb] {
+} elseif { [info exists rootme] && [file exists $rootme/../gdb/gdb] } {
 	# If we're doing a combined build, and gdb is available, use it.
 	set guality_gdb_name "$rootme/../gdb/gdb"
 } else {
diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 2124607245e..ce745dfdf8d 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -151,8 +151,10 @@ proc asan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-set ld_library_path $asan_saved_library_path
-set_ld_library_path_env_vars
+if [info exists asan_saved_library_path ] {
+	set ld_library_path $asan_saved_library_path
+	set_ld_library_path_env_vars
+}
 clear_effective_target_cache
 }
 
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index b5631a79bcf..6dcfd0a2f83 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -150,7 +150,9 @@ proc tsan_finish { args } {
 } else {
 	unset dg-do-what-default
 }
-set ld_library_path $tsan_saved_library_path
-set_ld_library_path_env_vars
+if [info exists tsan_saved_library_path ] {
+	set ld_library_path $tsan_saved_library_path
+	set_ld_library_path_env_vars
+}
 clear_effective_target_cache
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index f4ab29e2add..31740e02ab4 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -141,7 +141,9 @@ proc ubsan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-set ld_library_path $ubsan_saved_library_path
-set_ld_library_path_env_vars
+if [info exists ubsan_saved_library_path ] {
+	set ld_library_path $ubsan_saved_library_path
+	set_ld_library_path_env_vars
+}
 clear_effective_target_cache
 }


Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-10-19 Thread Marek Polacek via Gcc-patches
Ping.

On Thu, Oct 08, 2020 at 11:04:40AM -0400, Marek Polacek via Gcc-patches wrote:
> Ping for the C parts.
> 
> On Mon, Sep 28, 2020 at 02:15:41PM -0400, Marek Polacek via Gcc-patches wrote:
> > On Tue, Sep 22, 2020 at 04:07:41PM -0400, Jason Merrill wrote:
> > > On 9/22/20 1:29 PM, Marek Polacek wrote:
> > > > Ping.
> > > 
> > > The C++ change is OK.
> > 
> > Ping for the C parts.
> > 
> > > > On Tue, Sep 15, 2020 at 04:33:05PM -0400, Marek Polacek via Gcc-patches 
> > > > wrote:
> > > > > On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via 
> > > > > Gcc-patches wrote:
> > > > > > On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via 
> > > > > > Gcc-patches wrote:
> > > > > > > --- a/gcc/c/c-tree.h
> > > > > > > +++ b/gcc/c/c-tree.h
> > > > > > > @@ -147,6 +147,11 @@ struct c_expr
> > > > > > >etc), so we stash a copy here.  */
> > > > > > > source_range src_range;
> > > > > > > +  /* True iff the sizeof expression was enclosed in parentheses.
> > > > > > > + NB: This member is currently only initialized when 
> > > > > > > .original_code
> > > > > > > + is a SIZEOF_EXPR.  ??? Add a default constructor to this 
> > > > > > > class.  */
> > > > > > > +  bool parenthesized_p;
> > > > > > > +
> > > > > > > /* Access to the first and last locations within the source 
> > > > > > > spelling
> > > > > > >of this expression.  */
> > > > > > > location_t get_start () const { return src_range.m_start; }
> > > > > > 
> > > > > > I think a magic tree code would be better, c_expr is used in too 
> > > > > > many places
> > > > > > and returned by many functions, so it is copied over and over.
> > > > > > Even if you must add it, it would be better to change the struct 
> > > > > > layout,
> > > > > > because right now there are fields: tree, location_t, tree, 
> > > > > > 2xlocation_t,
> > > > > > which means 32-bit gap on 64-bit hosts before the second tree, so 
> > > > > > the new
> > > > > > field would fit in there.  But, if it is mostly uninitialized, it 
> > > > > > is kind of
> > > > > > unclean.
> > > > > 
> > > > > Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require 
> > > > > changes to
> > > > > c_expr, but adding a new tree code is always a pain...
> > > > > 
> > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > > 
> > > > > -- >8 --
> > > > > This patch implements a new warning, -Wsizeof-array-div.  It warns 
> > > > > about
> > > > > code like
> > > > > 
> > > > >int arr[10];
> > > > >sizeof (arr) / sizeof (short);
> > > > > 
> > > > > where we have a division of two sizeof expressions, where the first
> > > > > argument is an array, and the second sizeof does not equal the size
> > > > > of the array element.  See e.g. 
> > > > > .
> > > > > 
> > > > > Clang makes it possible to suppress the warning by parenthesizing the
> > > > > second sizeof like this:
> > > > > 
> > > > >sizeof (arr) / (sizeof (short));
> > > > > 
> > > > > so I followed suit.  In the C++ FE this was rather easy, because
> > > > > finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
> > > > > I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
> > > > > non-() and () versions.
> > > > > 
> > > > > This warning is enabled by -Wall.  An example of the output:
> > > > > 
> > > > > x.c:5:23: warning: expression does not compute the number of elements 
> > > > > in this array; element type is ‘int’, not ‘short int’ 
> > > > > [-Wsizeof-array-div]
> > > > >  5 |   return sizeof (arr) / sizeof (short);
> > > > >|  ~^~~~
> > > > > x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to 
> > > > > silence this warning
> > > > >  5 |   return sizeof (arr) / sizeof (short);
> > > > >| ^~
> > > > >| ( )
> > > > > x.c:4:7: note: array ‘arr’ declared here
> > > > >  4 |   int arr[10];
> > > > >|   ^~~
> > > > > 
> > > > > gcc/c-family/ChangeLog:
> > > > > 
> > > > >   PR c++/91741
> > > > >   * c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
> > > > >   (c_common_init_ts): Likewise.
> > > > >   * c-common.def (PAREN_SIZEOF_EXPR): New tree code.
> > > > >   * c-common.h (maybe_warn_sizeof_array_div): Declare.
> > > > >   * c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
> > > > >   (maybe_warn_sizeof_array_div): New function.
> > > > >   * c.opt (Wsizeof-array-div): New option.
> > > > > 
> > > > > gcc/c/ChangeLog:
> > > > > 
> > > > >   PR c++/91741
> > > > >   * c-parser.c (c_parser_binary_expression): Implement 
> > > > > -Wsizeof-array-div.
> > > > >   (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
> > > > >   (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
> > > > >   * c-tree.h (char_type_p): Declare.
> > > > >

Re: [PATCH 1/2] [target 87767] Refactor AVX512 broadcast patterns with speical memory constraint.

2020-10-19 Thread Vladimir Makarov via Gcc-patches



On 2020-10-11 8:58 p.m., Hongtao Liu wrote:

Hi:
   This is done in 2 steps:
   1. Extend special memory constraint to handle non MEM_P cases, i.e.
(vec_duplicate:V4SF (mem:SF (addr)))
   2. Refactor implementation of *_bcst{_1,_2,_3} patterns. Add new
predicate bcst_mem_operand and corresponding constraint "Br" to merge
"$(pattern)_bcst{_1,_2,_3}" into "$(pattern)", also delete those
separate "*_bcst{_1,_2,_3}" patterns.

   Bootstrap is ok, regression test on i386 backend is ok.

gcc/ChangeLog:

 PR target/87767
 * ira-costs.c (record_operand_costs): Extract memory operand
 from recog_data.operand[i] for record_address_regs.
 (record_reg_classes): Extract memory operand from OP for
 conditional judgement MEM_P.
 * ira.c (ira_setup_alts): Ditto.
 * lra-constraints.c (extract_mem_from_operand): New function.
 (satisfies_memory_constraint_p): Extract memory operand from
 OP for decompose_mem_address, return false when there's no
 memory operand inside OP.
 (process_alt_operands): Remove MEM_P (op) since it would be
 judged in satisfies_memory_constraint_p.
 * recog.c (asm_operand_ok): Extract memory operand from OP for
 judgement of memory_operand (OP, VOIDmode).
 (constrain_operands): Don't unwrapper unary operator when
 there's memory operand inside.
 * rtl.h (extract_mem_from_operand): New decl.



Thank you for working on the PR.  In general patch is ok for me. The 
only thing is


+/* For special_memory_operand, it could be false for MEM_P (op),
+   i.e. bcst_mem_operand in i386 backend.
+   Extract and return real memory operand or op.  */
+rtx
+extract_mem_from_operand (rtx op)
+{
+  if (MEM_P (op))
+return op;
+  /* Only allow one memory_operand inside special memory operand.  */

The comment contradicts to the below code which returns the first memory 
operand (not the only one).

+  subrtx_var_iterator::array_type array;
+  FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
+{
+  rtx x = *iter;
+  if (MEM_P (x))
+   return x;
+}
+
+  return op;
+}
+

I think the code should look like

/* For special_memory_operand, it could be false for MEM_P (op),
   i.e. bcst_mem_operand in i386 backend.
   Extract and return real memory operand or op.  */
rtx
extract_mem_from_operand (rtx op)
{
  if (MEM_P (op))
return op;
  /* Only allow one memory_operand inside special memory operand.  */
  subrtx_var_iterator::array_type array;
  rtx res = op;
  FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
{
  rtx x = *iter;
  if (!MEM_P (x) || res != op)
return op;
  res = op;
}

  return res;
}


With this change, the patch is ok for me and can be committed into the trunk.



[PATCH][RFC] SLP vectorize across PHI nodes

2020-10-19 Thread Richard Biener
This enables SLP build to handle PHI nodes in full, continuing
the SLP build to non-backedges.  For loop vectorization this
enables outer loop vectorization of nested SLP cycles and for
BB vectorization this enables vectorization of PHIs at CFG merges.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

The patch needs some final polishing and eventually I'm going
to split it into BB and loop vect parts (not sure, only if
easily possible).

Comments welcome.  The various !child checks are a bit iffy
and a more clever way to do pre/postorder walks of the SLP
graph would be nice to have I guess - but the SLP graph
changes quite often :/

There's still one (serious?) wart in how we represent
SLP reduction chains - the SLP node for the PHI
has the single scalar stmt repeated N times and obviously
we cannot find the backedge def for this.  I suppose more
manual frobbing should be done here - I'll see to this
as followup.

2020-10-19  Richard Biener  

* gimple.h ():
* tree-vect-loop.c ():
* tree-vect-slp.c ():
* tree-vect-stmts.c ():

* gcc.dg/vect/vect-outer-slp-1.c: New testcase.
* gcc.dg/vect/bb-slp-54.c: Likewise.
---
 gcc/gimple.h |   2 +
 gcc/testsuite/gcc.dg/vect/bb-slp-54.c|  23 ++
 gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c |  31 +++
 gcc/tree-vect-loop.c |  98 ++-
 gcc/tree-vect-slp.c  | 273 +--
 gcc/tree-vect-stmts.c|  11 +-
 gcc/tree-vectorizer.c|   3 +-
 gcc/tree-vectorizer.h|   3 +
 8 files changed, 354 insertions(+), 90 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-54.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c

diff --git a/gcc/gimple.h b/gcc/gimple.h
index 3c9b9965f5a..87c90be9a6a 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -6598,6 +6598,8 @@ gimple_expr_type (const gimple *stmt)
 }
   else if (code == GIMPLE_COND)
 return boolean_type_node;
+  else if (code == GIMPLE_PHI)
+return TREE_TYPE (gimple_phi_result (stmt));
   else
 return void_type_node;
 }
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-54.c 
b/gcc/testsuite/gcc.dg/vect/bb-slp-54.c
new file mode 100644
index 000..d05ce33310d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-54.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_double } */
+
+double a[2], b[2], c[2];
+
+void foo(int flag)
+{
+  double tem1, tem2;
+  if (flag)
+{
+  tem1 = a[0];
+  tem2 = a[1];
+}
+  else
+{
+  tem1 = b[0];
+  tem2 = b[1];
+}
+  c[0] = tem1;
+  c[1] = tem2;
+}
+
+/* { dg-final { scan-tree-dump-times "transform load" 2 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c 
b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
new file mode 100644
index 000..62b18bd5764
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+int a[1024];
+
+void foo (void)
+{
+  for (int i = 0; i < 1020; i += 4)
+{
+  int suma = a[i];
+  int sumb = a[i+1];
+  int sumc = a[i+2];
+  int sumd = a[i+3];
+  for (unsigned j = 0; j < 77; ++j)
+{
+  suma = (suma ^ i) + 1;
+  sumb = (sumb ^ i) + 2;
+  sumc = (sumc ^ i) + 3;
+  sumd = (sumd ^ i) + 4;
+}
+  a[i] = suma;
+  a[i+1] = sumb;
+  a[i+2] = sumc;
+  a[i+3] = sumd;
+}
+}
+
+/* We should vectorize this outer loop with SLP.  */
+/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" } } */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "vect" } } */
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 991fd457229..952a6878447 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -7375,15 +7375,24 @@ vect_transform_cycle_phi (loop_vec_info loop_vinfo,
   if (slp_node)
 {
   vec_initial_defs.reserve (vec_num);
-  gcc_assert (slp_node == slp_node_instance->reduc_phis);
-  stmt_vec_info first = REDUC_GROUP_FIRST_ELEMENT (reduc_stmt_info);
-  tree neutral_op
-   = neutral_op_for_slp_reduction (slp_node, vectype_out,
-   STMT_VINFO_REDUC_CODE (reduc_info),
-   first != NULL);
-  get_initial_defs_for_reduction (loop_vinfo, 
slp_node_instance->reduc_phis,
- &vec_initial_defs, vec_num,
- first != NULL, neutral_op);
+  if (nested_cycle)
+   {
+ unsigned phi_idx = loop_preheader_edge (loop)->dest_idx;
+ vect_get_slp_defs (SLP_TREE_CHILDREN (slp_node)[phi_idx],
+&vec_initial_defs);
+   }
+  else
+   {
+ gcc_as

Re: [PATCH] [PR rtl-optimization/97249]Simplify vec_select of paradoxical subreg.

2020-10-19 Thread Richard Sandiford via Gcc-patches
Hongtao Liu  writes:
> On Thu, Oct 15, 2020 at 8:38 PM Richard Sandiford
>  wrote:
>>
>> Hongtao Liu via Gcc-patches  writes:
>> > +   /* Simplify vec_select of a subreg of X to just a vec_select of X
>> > +  when X has same component mode as vec_select.  */
>> > +   int l2;
>> > +   if (GET_CODE (trueop0) == SUBREG
>> > +   && GET_MODE_INNER (mode)
>> > +  == GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
>>
>> Better to use SUBREG_REG here and below.
>>
>
> Yes and changed.
>
>> > +   && (GET_MODE_NUNITS (GET_MODE (trueop0))).is_constant (&l0)
>> > +   && (GET_MODE_NUNITS (mode)).is_constant (&l1)
>> > +   && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0
>> > +   .is_constant (&l2)
>> > +   && known_le (l1, l2))
>> > + {
>> > +   unsigned HOST_WIDE_INT subreg_offset = 0;
>> > +   gcc_assert (known_eq (XVECLEN (trueop1, 0), l1));
>> > +   gcc_assert (can_div_trunc_p (exact_div (subreg_lsb (trueop0), 
>> > BITS_PER_UNIT),
>> > +GET_MODE_SIZE (GET_MODE_INNER 
>> > (mode)),
>> > +&subreg_offset));
>>
>> can_div_trunc_p discards the remainder, whereas it looks like here
>> you want an exact multiple.
>>
>> I don't think it's absolutely guaranteed that the “if” condition makes
>> the division by GET_MODE_SIZE exact.  E.g. in principle you could have
>> a subreg of a vector of TIs in which the subreg offset is misaligned by
>> a DI offset.
>>
>> I'm not sure the subreg_lsb conversion is correct though.  On big-endian
>> targets, lane numbering follows memory layout, just like subreg byte
>> offsets do.  So ISTM that using SUBREG_BYTE (as per the earlier patch)
>> was correct.
>>
>> In summary, I think the "if” condition should include something like:
>>
>>   constant_mulitple_p (SUBREG_BYTE (trueop0),
>>GET_MODE_UNIT_BITSIZE (mode),
>>&subreg_offset)
>>
>
> Changed.
>
>> Thanks,
>> Richard
>
>
> Update patch.
>
> -- 
> BR,
> Hongtao
>
> From 8d154067963e453c337e6dc2c4f3f19bf0d6e11b Mon Sep 17 00:00:00 2001
> From: liuhongt 
> Date: Tue, 13 Oct 2020 15:35:29 +0800
> Subject: [PATCH] Simplify vec_select of a subreg of X to just a vec_select of
>  X.
>
> gcc/ChangeLog
>   PR rtl-optimization/97249
>   * simplify-rtx.c (simplify_binary_operation_1): Simplify
>   vec_select of a subreg of X to a vec_select of X.
>
> gcc/testsuite/ChangeLog
>
>   * gcc.target/i386/pr97249-1.c: New test.
> ---
>  gcc/simplify-rtx.c| 44 +++
>  gcc/testsuite/gcc.target/i386/pr97249-1.c | 30 
>  2 files changed, 74 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr97249-1.c
>
> diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
> index 869f0d11b2e..b1009837b2b 100644
> --- a/gcc/simplify-rtx.c
> +++ b/gcc/simplify-rtx.c
> @@ -4170,6 +4170,50 @@ simplify_binary_operation_1 (enum rtx_code code, 
> machine_mode mode,
>   return subop1;
>   }
>   }
> +
> +   /* Simplify vec_select of a subreg of X to just a vec_select of X
> +  when X has same component mode as vec_select.  */
> +   int l2;
> +   unsigned HOST_WIDE_INT subreg_offset = 0;
> +   if (GET_CODE (trueop0) == SUBREG
> +   && GET_MODE_INNER (mode)
> +  == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
> +   && (GET_MODE_NUNITS (GET_MODE (trueop0))).is_constant (&l0)

Nothing really relies on this last line, and nothing uses l0, so better
to drop it.

> +   && (GET_MODE_NUNITS (mode)).is_constant (&l1)
> +   && (GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0
> +   .is_constant (&l2)
> +   && known_le (l1, l2)

I'm not sure the last two &&s are really the important condition.
I think we should drop them for the suggestion below.

> +   && constant_multiple_p (SUBREG_BYTE (trueop0),
> +   GET_MODE_UNIT_BITSIZE (mode),
> +   &subreg_offset))
> + {
> +

Excess blank line.

> +   gcc_assert (known_eq (XVECLEN (trueop1, 0), l1));

This can just use ==.

> +   bool success = true;
> +   for (int i = 0; i != l1; i++)
> + {
> +   rtx idx  = XVECEXP (trueop1, 0, i);

Excess space.

> +   if (!CONST_INT_P (idx))

Here I think we should check:

  || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))

where:

   poly_uint64 nunits
 = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0.

This makes sure that all indices are in range.  In particular, it's
valid for the SUBREG_REG to be narrower than mode, for appropriate
vec_select indices

Thanks,
Richard


preprocessor: Fix non-fn fn-like macro at EOF [PR97471]

2020-10-19 Thread Nathan Sidwell

We inject EOF tokens between macro argument lists, but had
confused/stale logic in the non-fn invocation.  Renamed the magic
'eof' token, as it's now only used for macro argument termination.
Always rewind the non-OPEN_PAREN token.

libcpp/
* internal.h (struct cpp_reader): Rename 'eof' field to 'endarg'.
* init.c (cpp_create_reader): Adjust.
* macro.c (collect_args): Use endarg for separator.  Always rewind
in the not-fn case.
gcc/testsuite/
* c-c++-common/cpp/pr97471.c: New.

pushing to trunk,

nathan

--
Nathan Sidwell
diff --git c/gcc/testsuite/c-c++-common/cpp/pr97471.c w/gcc/testsuite/c-c++-common/cpp/pr97471.c
new file mode 100644
index 000..f1e512ea331
--- /dev/null
+++ w/gcc/testsuite/c-c++-common/cpp/pr97471.c
@@ -0,0 +1,10 @@
+/* PR preprocessor/97471 */
+/* { dg-do compile } */
+
+/* ICE with non-fn use of fn-like macro at EOF  */
+
+#define a() b
+
+/* { dg-error "expected" "" { target c } .+2 } */
+/* { dg-error "does not name" "" { target c++ } .+1 } */
+a
diff --git c/libcpp/init.c w/libcpp/init.c
index 84c0a9efa74..454a183134a 100644
--- c/libcpp/init.c
+++ w/libcpp/init.c
@@ -248,8 +248,10 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
   /* Set up static tokens.  */
   pfile->avoid_paste.type = CPP_PADDING;
   pfile->avoid_paste.val.source = NULL;
-  pfile->eof.type = CPP_EOF;
-  pfile->eof.flags = 0;
+  pfile->avoid_paste.src_loc = 0;
+  pfile->endarg.type = CPP_EOF;
+  pfile->endarg.flags = 0;
+  pfile->endarg.src_loc = 0;
 
   /* Create a token buffer for the lexer.  */
   _cpp_init_tokenrun (&pfile->base_run, 250);
diff --git c/libcpp/internal.h w/libcpp/internal.h
index b728df74562..b1a2a996ef6 100644
--- c/libcpp/internal.h
+++ w/libcpp/internal.h
@@ -517,9 +517,9 @@ struct cpp_reader
  set to -1 to disable it or to a non-negative value to enable it.  */
   time_t source_date_epoch;
 
-  /* EOF token, and a token forcing paste avoidance.  */
+  /* A token forcing paste avoidance, and one demarking macro arguments.  */
   cpp_token avoid_paste;
-  cpp_token eof;
+  cpp_token endarg;
 
   /* Opaque handle to the dependencies of mkdeps.c.  */
   class mkdeps *deps;
diff --git c/libcpp/macro.c w/libcpp/macro.c
index 2c7d7322e09..9cb3b10a9a0 100644
--- c/libcpp/macro.c
+++ w/libcpp/macro.c
@@ -1241,7 +1241,8 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node,
 	ntokens--;
 
   arg->count = ntokens;
-  set_arg_token (arg, &pfile->eof, pfile->eof.src_loc,
+  /* Append an EOF to mark end-of-argument.  */
+  set_arg_token (arg, &pfile->endarg, token->src_loc,
 		 ntokens, MACRO_ARG_TOKEN_NORMAL,
 		 CPP_OPTION (pfile, track_macro_expansion));
 
@@ -1328,17 +1329,12 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
   return collect_args (pfile, node, pragma_buff, num_args);
 }
 
-  /* CPP_EOF can be the end of macro arguments, or the end of the
- file.  We mustn't back up over the latter.  Ugh.  */
-  if (token->type != CPP_EOF || token == &pfile->eof)
-{
-  /* Back up.  We may have skipped padding, in which case backing
-	 up more than one token when expanding macros is in general
-	 too difficult.  We re-insert it in its own context.  */
-  _cpp_backup_tokens (pfile, 1);
-  if (padding)
-	_cpp_push_token_context (pfile, NULL, padding, 1);
-}
+  /* Back up.  We may have skipped padding, in which case backing
+ up more than one token when expanding macros is in general
+ too difficult.  We re-insert it in its own context.  */
+  _cpp_backup_tokens (pfile, 1);
+  if (padding)
+_cpp_push_token_context (pfile, NULL, padding, 1);
 
   return NULL;
 }


Re: [PATCH] cplxlower: Avoid a transform when looking at a default definition

2020-10-19 Thread Martin Jambor
Hi,

On Sat, Oct 17 2020, Richard Biener wrote:
> On October 16, 2020 8:46:39 PM GMT+02:00, Martin Jambor  
> wrote:
>>Hi,
>>
>>in PR 97456, IPA-SRA triggers a bug in tree-complex.c where it
>>converts:
>>
>> 
>>   a$_M_value_21 = COMPLEX_EXPR ;
>>
>>(where ISRA.18 is IPA-SRA created PARM_DECL with DECL_IGNORED_P set,
>>which is why it only happens with IPA-SRA) into:
>>
>>  
>>a$_M_value_21 = COMPLEX_EXPR >a$_M_value$real_10(D)>;
>>
>>i.e. it replaces two uses of the parameter default-def with two
>>uninitialized default-defs of a new variable - all in hope to produce
>>code with better debug info.
>>
>>This patch fixes it by avoiding the transform when the SSA_NAME to be
>>replaced is a default definition.  Bootstrapped and tested on
>>x86_64-linux.  OK for trunk and the gcc-10 branch?
>
> It's never OK to replace SSA_NAME_VAR of a default Def so may I suggest to 
> put this restriction first, independent of any other predicate?
>

OK, I've rebased the following on the current master and will commit it
after the final round of testing.

Thanks,

Martin


gcc/ChangeLog:

2020-10-19  Martin Jambor  

PR tree-optimization/97456
* tree-complex.c (set_component_ssa_name): Do not replace ignored decl
default definitions with new component vars.

gcc/testsuite/ChangeLog:

2020-10-19  Martin Jambor  

PR tree-optimization/97456
* gcc.dg/tree-ssa/pr97456.c: New test.
---
 gcc/testsuite/gcc.dg/tree-ssa/pr97456.c | 40 +
 gcc/tree-complex.c  |  3 +-
 2 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr97456.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97456.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr97456.c
new file mode 100644
index 000..5171c9b4577
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97456.c
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fwhole-program" } */
+
+
+float val2 = 1.710780f;
+float val3;
+volatile float vf;
+
+int __attribute__((noipa))
+get_bool (void)
+{
+  return 1;
+}
+
+int __attribute__((noinline))
+wrong (float *pos)
+{
+  _Complex float a;
+
+  __real__ a = *pos;
+  __imag__ a = *pos;
+
+  _Complex float b = 0 + 0i;
+
+  b = b + a;
+
+  if (b == 0.0f)
+return 1;
+
+  vf = __imag__ b;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  float val = get_bool () == 1 ? val2 : val3;
+
+  if ((wrong(&val), wrong(&val)))
+__builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 2e54bbb917c..f132e0f41c7 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -569,7 +569,8 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree 
value)
 {
   /* Replace an anonymous base value with the variable from cvc_lookup.
 This should result in better debug info.  */
-  if (SSA_NAME_VAR (ssa_name)
+  if (!SSA_NAME_IS_DEFAULT_DEF (value)
+ && SSA_NAME_VAR (ssa_name)
  && (!SSA_NAME_VAR (value) || DECL_IGNORED_P (SSA_NAME_VAR (value)))
  && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name)))
{
-- 
2.28.0



Re: [PATCH] arm: Fix multiple inheritance thunks for thumb-1 with -mpure-code

2020-10-19 Thread Richard Earnshaw via Gcc-patches
On 12/10/2020 08:59, Christophe Lyon via Gcc-patches wrote:
> On Thu, 8 Oct 2020 at 11:58, Richard Earnshaw
>  wrote:
>>
>> On 08/10/2020 10:07, Christophe Lyon via Gcc-patches wrote:
>>> On Tue, 6 Oct 2020 at 18:02, Richard Earnshaw
>>>  wrote:

 On 29/09/2020 20:50, Christophe Lyon via Gcc-patches wrote:
> When mi_delta is > 255 and -mpure-code is used, we cannot load delta
> from code memory (like we do without -mpure-code).
>
> This patch builds the value of mi_delta into r3 with a series of
> movs/adds/lsls.
>
> We also do some cleanup by not emitting the function address and delta
> via .word directives at the end of the thunk since we don't use them
> with -mpure-code.
>
> No need for new testcases, this bug was already identified by
> eg. pr46287-3.C
>
> 2020-09-29  Christophe Lyon  
>
>   gcc/
>   * config/arm/arm.c (arm_thumb1_mi_thunk): Build mi_delta in r3 and
>   do not emit function address and delta when -mpure-code is used.

>>> Hi Richard,
>>>
>>> Thanks for your comments.
>>>
 There are some optimizations you can make to this code.

 Firstly, for values between 256 and 510 (inclusive), it would be better
 to just expand a mov of 255 followed by an add.
>>> I now see the splitted for the "Pe" constraint which I hadn't noticed
>>> before, so I can write something similar indeed.
>>>
>>> However, I'm note quite sure to understand the benefit in the split
>>> when -mpure-code is NOT used.
>>> Consider:
>>> int f3_1 (void) { return 510; }
>>> int f3_2 (void) { return 511; }
>>> Compile with -O2 -mcpu=cortex-m0:
>>> f3_1:
>>> movsr0, #255
>>> lslsr0, r0, #1
>>> bx  lr
>>> f3_2:
>>> ldr r0, .L4
>>> bx  lr
>>>
>>> The splitter makes the code bigger, does it "compensate" for this by
>>> not having to load the constant?
>>> Actually the constant uses 4 more bytes, which should be taken into
>>> account when comparing code size,
>>
>> Yes, the size of the literal pool entry needs to be taken into account.
>>  It might happen that the entry could be shared with another use of that
>> literal, but in general that's rare.
>>
>>> so f3_1 uses 6 bytes, and f3_2 uses 8, so as you say below three
>>> thumb1 instructions would be equivalent in size compared to loading
>>> from the literal pool. Should the 256-510 range be extended?
>>
>> It's a bit borderline at three instructions when literal pools are not
>> expensive to use, but in thumb1 literal pools tend to be quite small due
>> to the limited pc offsets we can use.  I think on balance we probably
>> want to use the instruction sequence unless optimizing for size.
>>
>>>
>>>
 This is also true for
 the literal pools alternative as well, so should be handled before all
 this.
>>> I am not sure what you mean: with -mpure-code, the above sample is compiled 
>>> as:
>>> f3_1:
>>> movsr0, #255
>>> lslsr0, r0, #1
>>> bx  lr
>>> f3_2:
>>> movsr0, #1
>>> lslsr0, r0, #8
>>> addsr0, r0, #255
>>> bx  lr
>>>
>>> so the "return 510" case is already handled as without -mpure-code.
>>
>> I was thinking specifically of the thunk sequence where you seem to be
>> emitting instructions directly rather than generating RTL.  The examples
>> you show here are not thunks.
>>
> OK thanks for the clarification.
> 
> Here is an updated version, split into 3 patches to hopefully make
> review easier.
> They apply on top of my other mpure-code patches for PR96967 and PR96770:
> https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554956.html
> https://gcc.gnu.org/pipermail/gcc-patches/2020-September/554957.html
> 
> I kept it this way to make incremental changes easier to understand.
> 
> Patch 1: With the hope to avoid confusion and make maintenance easier,
> I have updated thumb1_gen_const_int() so that it can generate either RTL or
> asm. This way, all the code used to build thumb-1 constants is in the
> same place,
>  in case we need to improve/fix it later. We now generate shorter sequences in
> several cases matching your comments.
> 
> Patch 2: Removes the equivalent loop from thumb1_movsi_insn pattern and
> calls thumb1_gen_const_int.
> 
> Patch 3: Update of the original patch in this thread, now calls
> thumb1_gen_const_int.

Yuk!  Those changes to thumb1_gen_const_int are horrible.

I think we should be able to leverage the fact that the compiler can use
C++ now to do much better than that, for example by making that function
a template.  For example (and this is just a sketch):

class t1_rtl
{
 public:
  void ashift(int a) { gen_rtx_ASHIFT(a); }
  void rshift(int b) { gen_rtx_SHIFTRT(b); }
};

class t1_print
{
 public:
  t1_print (FILE *f) : t_file(f) {}
  void ashift (int a) { fprintf (t_file, "a shift %d\n", a); }
  void rshift (int b) { fprintf (t_file, "r shift %d\n", b); }
 private:
  FILE *t_fil

Re: [PATCH] Handle right shifts by zero in range-ops.

2020-10-19 Thread Jakub Jelinek via Gcc-patches
On Mon, Oct 19, 2020 at 10:19:48AM -0400, Andrew MacLeod via Gcc-patches wrote:
> On 10/19/20 5:38 AM, Aldy Hernandez wrote:
> > If the shift amount in operator_lshift::op1_range was zero, an invalid range
> > of [1, 0] was being created.
> 
> Should we do the same thing with rshift::op1_range?     ie, return the LHS
> if the shift is 0 instead of trying to figure it out

Shift by 0 is a noop, so yes, for all of left/right shifts and rotates
the result range should be the range of the first operand.

> > gcc/ChangeLog:
> > 
> > PR tree-optimization/97467
> > * range-op.cc (operator_lshift::op1_range): Handle shifts by 0.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * gcc.dg/pr97467.c: New test.
> > ---
> >   gcc/range-op.cc|  5 +
> >   gcc/testsuite/gcc.dg/pr97467.c | 16 
> >   2 files changed, 21 insertions(+)
> >   create mode 100644 gcc/testsuite/gcc.dg/pr97467.c
> > 
> > diff --git a/gcc/range-op.cc b/gcc/range-op.cc
> > index 0efa00186e8..30d2a4d3987 100644
> > --- a/gcc/range-op.cc
> > +++ b/gcc/range-op.cc
> > @@ -1579,6 +1579,11 @@ operator_lshift::op1_range (irange &r,
> > wide_int shift = wi::to_wide (shift_amount);
> > if (wi::lt_p (shift, 0, SIGNED))
> > return false;
> > +  if (shift == 0)
> > +   {
> > + r = lhs;
> > + return true;
> > +   }
> > // Work completely in unsigned mode to start.
> > tree utype = type;
> > diff --git a/gcc/testsuite/gcc.dg/pr97467.c b/gcc/testsuite/gcc.dg/pr97467.c
> > new file mode 100644
> > index 000..dcbd218f733
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr97467.c
> > @@ -0,0 +1,16 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-Os" } */
> > +
> > +int a;
> > +long b;
> > +unsigned int c = 1;
> > +
> > +int main () {
> > +  int e;
> > +  for (; c <= 0; c++) {
> > +int f = 0;
> > +b = e;
> > +a = f || b << c;
> > +  }
> > +  return 0;
> > +}

Jakub



Re: [PATCH] Handle right shifts by zero in range-ops.

2020-10-19 Thread Andrew MacLeod via Gcc-patches

On 10/19/20 5:38 AM, Aldy Hernandez wrote:

If the shift amount in operator_lshift::op1_range was zero, an invalid range
of [1, 0] was being created.


Should we do the same thing with rshift::op1_range? ie, return the 
LHS if the shift is 0 instead of trying to figure it out




Pushed.

gcc/ChangeLog:

PR tree-optimization/97467
* range-op.cc (operator_lshift::op1_range): Handle shifts by 0.

gcc/testsuite/ChangeLog:

* gcc.dg/pr97467.c: New test.
---
  gcc/range-op.cc|  5 +
  gcc/testsuite/gcc.dg/pr97467.c | 16 
  2 files changed, 21 insertions(+)
  create mode 100644 gcc/testsuite/gcc.dg/pr97467.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 0efa00186e8..30d2a4d3987 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1579,6 +1579,11 @@ operator_lshift::op1_range (irange &r,
wide_int shift = wi::to_wide (shift_amount);
if (wi::lt_p (shift, 0, SIGNED))
return false;
+  if (shift == 0)
+   {
+ r = lhs;
+ return true;
+   }
  
// Work completely in unsigned mode to start.

tree utype = type;
diff --git a/gcc/testsuite/gcc.dg/pr97467.c b/gcc/testsuite/gcc.dg/pr97467.c
new file mode 100644
index 000..dcbd218f733
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97467.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+int a;
+long b;
+unsigned int c = 1;
+
+int main () {
+  int e;
+  for (; c <= 0; c++) {
+int f = 0;
+b = e;
+a = f || b << c;
+  }
+  return 0;
+}




Re: [PATCH][middle-end][i386][version 3]Add -fzero-call-used-regs=[skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all]

2020-10-19 Thread Qing Zhao via Gcc-patches
Ping.

Richard and Uros,

Could you please review the patch and let me know whether it’s Okay for gcc 11?

Thanks a lot.


Qing

> On Oct 6, 2020, at 9:01 AM, Qing Zhao via Gcc-patches 
>  wrote:
> 
> Hi, Gcc team,
> 
> This is the 3rd version of the implementation of patch -fzero-call-used-regs.
> 
> We will provide a new feature into GCC:
> 
> Add 
> -fzero-call-used-regs=[skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all]
>  command-line option
> and
> zero_call_used_regs("skip|used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all")
>  function attribues:
> 
>   1. -fzero-call-used-regs=skip and zero_call_used_regs("skip")
> 
>   Don't zero call-used registers upon function return. This is the default 
> behavior.
> 
>   2. -fzero-call-used-regs=used-gpr-arg and 
> zero_call_used_regs("used-gpr-arg")
> 
>   Zero used call-used general purpose registers that are used to pass 
> parameters upon function return.
> 
>   3. -fzero-call-used-regs=used-arg and zero_call_used_regs("used-arg")
> 
>   Zero used call-used registers that are used to pass parameters upon 
> function return.
> 
>   4. -fzero-call-used-regs=all-arg and zero_call_used_regs("all-arg")
> 
>   Zero all call-used registers that are used to pass parameters upon function 
> return.
> 
>   5. -fzero-call-used-regs=used-gpr and zero_call_used_regs("used-gpr")
> 
>   Zero used call-used general purpose registers upon function return.
> 
>   6. -fzero-call-used-regs=all-gpr and zero_call_used_regs("all-gpr")
> 
>   Zero all call-used general purpose registers upon function return.
> 
>   7. -fzero-call-used-regs=used and zero_call_used_regs("used")
> 
>   Zero used call-used registers upon function return.
> 
>   8. -fzero-call-used-regs=all and zero_call_used_regs("all")
> 
>   Zero all call-used registers upon function return.
> 
> Zero call-used registers at function return to increase the program
> security by either mitigating Return-Oriented Programming (ROP) or
> preventing information leak through registers.
> 
> {skip}, which is the default, doesn't zero call-used registers.
> 
> {used-arg-gpr} zeros used call-used general purpose registers that
> pass parameters. {used-arg} zeros used call-used registers that
> pass parameters. {arg} zeros all call-used registers that pass
> parameters. These 3 choices are used for ROP mitigation.
> 
> {used-gpr} zeros call-used general purpose registers
> which are used in function.  {all-gpr} zeros all
> call-used registers.  {used} zeros call-used registers which
> are used in function.  {all} zeros all call-used registers.
> These 4 choices are used for preventing information leak through
> registers.
> 
> You can control this behavior for a specific function by using the function
> attribute {zero_call_used_regs}.
> 
> **Tests be done:
> 1. Gcc bootstrap on x86, aarch64 and rs6000.
> 2. Regression test on x86, aarch64 and rs6000.
> (X86, aarch64 have no any issue, rs6000 failed at the new testing case in 
> middle end which is expected)
> 
> 3. Cpu2017 on x86, -O2 
> -fzero-call-used-regs=used-gpr-arg|used-arg|all-arg|used-gpr|all-gpr|used|all
> 
> **runtime performance data of CPU2017 on x86
> https://urldefense.com/v3/__https://gitlab.com/x86-gcc/gcc/-/wikis/uploads/e9c5bedba6e387586364571f2eae3b8d/zero_call_used_regs_runtime_New.csv__;!!GqivPVa7Brio!KabFawXf4waV8v6RfHHKO5ZoFbei3YVhbR9Pquv8AVICgBHpjAkuEb5mfVbaNozS$
>   
>   >
> 
> **The major changes compared to the previous version are:
> 
> 1. Add 3 new sub-options and corresponding function attributes:
>  used-gpr-arg, used-arg, all-arg
>  for ROP mitigation purpose;
> 2. Updated user manual;
> 3. Re-design of the implementation:
> 
>  3.1 data flow change to reflect the newly added zeroing insns to avoid
>  these insns been deleted, moved, or merged by later passes:
> 
>  3.1.1.
>  abstract EPILOGUE_USES into a new target-independent wrapper function that
>  (a) returns true if EPILOGUE_USES itself returns true and (b) returns
>  true for registers that need to be zero on return, if the zeroing
>  instructions have already been inserted.  The places that currently
>  test EPILOGUE_USES should then test this new wrapper function instead.
> 
>  Add this new wrapper function to df.h and df-scan.c.
> 
>  3.1.2.
>  add a new utility routine "expand_asm_reg_clobber_mem_blockage" to generate
>  a volatile asm insn that clobbers all the hard registers that are zeroed.
> 
>  emit this volatile asm in the very beginning of the zeroing sequence.
> 
>  3.2 new pass:
>  add a new pass in the beginning of "late_compilation", before
>  "pass_compute_alignment", called "pass_zero_call_used_regs".
> 
>  in this new pass,
>  * compute the data flow information; (df_analyze ());
>  * scan the exit block from ba

Re: [PATCH] coroutines: Emit error for invalid promise return types [PR97438].

2020-10-19 Thread Nathan Sidwell

On 10/18/20 4:13 PM, Iain Sandoe wrote:

Hi,

At one stage, use cases were proposed for allowing the promise
type to contain both return_value and return_void.  That was
not accepted into C++20; so we should reject it as per the PR.

Tested on x86_64-darwin, x86_64-linux-gnu,
OK for master?

(although this is technically an ‘accepts invalid’ not sure it’s serious
  enough to backport to 10.x - but I’m happy to do so if anyone thinks
  it should be).


ok.  I don;t think it worth a speculative backport

nathan

--
Nathan Sidwell


Re: [PATCH] Gracefully handle right shifts larger than the precision.

2020-10-19 Thread Andrew MacLeod via Gcc-patches

On 10/19/20 6:36 AM, Aldy Hernandez wrote:

The test is trying to shift by 129, but the underlying type is 128 bits.
This causes low_bits to wrap around to -1 and things go bad really
quick.

Attached is my proposed solution.

Andrew, do you have a preference on how to fix this?


If we know we are shifting by the precision of the object, or more,   we 
cant tell anything about the operand...    So just return varying I think.
The code is eventually  just going to create a mask over all the bits 
and come up with varying anyway.


Andrew




[PATCH] rs6000: correct BE vextract_fp_from_short[hl] vperm mask

2020-10-19 Thread David Edelsohn via Gcc-patches
xvcvhpsp instruction converts a vector of bfloat16 half precision to single
precision.  The intrinsics vextract_fp_from_shorth and
vextract_fp_from_shortl select the high or low four elements of a
half precision vector to convert.  The intrinsics use vperm to select
the appropriate portion of the half precision vector and redistribute
the values for the xvcvhpsp instruction.  The big endian versions of the
masks for the intrinsics were initialized wrong.  This patch replaces the
masks with the correct values.  This corrects the failure of
builtins-3-p9-runnable.c testcase on big endian systems.

Bootstrapped powerpc-ibm-aix7.2.3.0 Power9.  Committed.

gcc/ChangeLog:

* config/rs6000/vsx.md (vextract_fp_from_shorth):  Fix vals_be.
(vextract_fp_from_shortl) Same.

diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 4ff52455fd3..c023bc0baaa 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -5659,7 +5659,7 @@ (define_expand "vextract_fp_from_shorth"
 {
   int i;
   int vals_le[16] = {15, 14, 0, 0, 13, 12, 0, 0, 11, 10, 0, 0, 9, 8, 0, 0};
-  int vals_be[16] = {7, 6, 0, 0, 5, 4, 0, 0, 3, 2, 0, 0, 1, 0, 0, 0};
+  int vals_be[16] = {0, 0, 0, 1, 0, 0, 2, 3, 0, 0, 4, 5, 0, 0, 6, 7};

   rtx rvals[16];
   rtx mask = gen_reg_rtx (V16QImode);
@@ -5693,7 +5693,7 @@ (define_expand "vextract_fp_from_shortl"
   "TARGET_P9_VECTOR"
 {
   int vals_le[16] = {7, 6, 0, 0, 5, 4, 0, 0, 3, 2, 0, 0, 1, 0, 0, 0};
-  int vals_be[16] = {15, 14, 0, 0, 13, 12, 0, 0, 11, 10, 0, 0, 9, 8, 0, 0};
+  int vals_be[16] = {0, 0, 8, 9, 0, 0, 10, 11, 0, 0, 12, 13, 0, 0, 14, 15};

   int i;
   rtx rvals[16];


Re: [PATCH] Gracefully handle right shifts larger than the precision.

2020-10-19 Thread Aldy Hernandez via Gcc-patches




On 10/19/20 1:01 PM, Jakub Jelinek wrote:

On Mon, Oct 19, 2020 at 12:55:38PM +0200, Aldy Hernandez wrote:

Shifts are undefined already when the shift count is equal to the precision.
And arbitrarily choosing one of the values as the shift count seems risky to
me (and even when used, the most natural would be truncating the excess bits
rather than saturating), can't it just punt (return VARYING) for the UB
shifts?


Good point.  It looks cleaner too.

How about this?

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 30d2a4d3987..0ab5e62be7f 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1579,6 +1579,9 @@ operator_lshift::op1_range (irange &r,
wide_int shift = wi::to_wide (shift_amount);
if (wi::lt_p (shift, 0, SIGNED))
 return false;
+  if (wi::gt_p (shift, wi::uhwi (TYPE_PRECISION (type),
+TYPE_PRECISION (op2.type ()
+   return false;


If you use wi::ge_p instead, then LGTM.


Thanks.

Pushed.



Re: [PATCH][pushed] IPA: fix one more UBSAN error

2020-10-19 Thread Jan Hubicka
> It fixes:
> 
> /home/marxin/Programming/gcc2/gcc/ipa-modref-tree.h:482:22: runtime error: 
> load of value 255, which is not a valid value for type 'bool'
> #0 0x18e5df3 in modref_tree::merge(modref_tree*, 
> vec*) 
> /home/marxin/Programming/gcc2/gcc/ipa-modref-tree.h:482
> #1 0x18dc180 in ipa_merge_modref_summary_after_inlining(cgraph_edge*) 
> /home/marxin/Programming/gcc2/gcc/ipa-modref.c:1779
> #2 0x18c1c72 in inline_call(cgraph_edge*, bool, vec va_heap, vl_ptr>*, int*, bool, bool*) 
> /home/marxin/Programming/gcc2/gcc/ipa-inline-transform.c:492
> #3 0x4a3589c in inline_small_functions 
> /home/marxin/Programming/gcc2/gcc/ipa-inline.c:2216
> #4 0x4a3b230 in ipa_inline 
> /home/marxin/Programming/gcc2/gcc/ipa-inline.c:2697
> #5 0x4a3d902 in execute 
> /home/marxin/Programming/gcc2/gcc/ipa-inline.c:3096
> #6 0x1edf831 in execute_one_pass(opt_pass*) 
> /home/marxin/Programming/gcc2/gcc/passes.c:2509
> #7 0x1ee26af in execute_ipa_pass_list(opt_pass*) 
> /home/marxin/Programming/gcc2/gcc/passes.c:2936
> #8 0x103f31b in ipa_passes 
> /home/marxin/Programming/gcc2/gcc/cgraphunit.c:2700
> #9 0x103fb40 in symbol_table::compile() 
> /home/marxin/Programming/gcc2/gcc/cgraphunit.c:2777
> #10 0x104092b in symbol_table::finalize_compilation_unit() 
> /home/marxin/Programming/gcc2/gcc/cgraphunit.c:3022
> #11 0x235723b in compile_file 
> /home/marxin/Programming/gcc2/gcc/toplev.c:485
> #12 0x235fff9 in do_compile 
> /home/marxin/Programming/gcc2/gcc/toplev.c:2321
> #13 0x23605fc in toplev::main(int, char**) 
> /home/marxin/Programming/gcc2/gcc/toplev.c:2460
> #14 0x4e2b93b in main /home/marxin/Programming/gcc2/gcc/main.c:39
> #15 0x76f0ae09 in __libc_start_main ../csu/libc-start.c:314
> #16 0x9a0be9 in _start 
> (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x9a0be9)
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> I'm going to install it as it's very similar to what I installed 2 weeks ago.

Yes, this is OK - again the undefined memory is harmless because we only
copy it and never going to use it.

Thanks,
Honza
> 
> Thanks,
> Martin
> 
> gcc/ChangeLog:
> 
>   * ipa-modref.c (compute_parm_map): Clear vector.
> ---
>  gcc/ipa-modref.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
> index 8e6a87643ec..3a70965d156 100644
> --- a/gcc/ipa-modref.c
> +++ b/gcc/ipa-modref.c
> @@ -1654,7 +1654,7 @@ compute_parm_map (cgraph_edge *callee_edge, 
> vec *parm_map)
>   : callee_edge->caller);
>callee_pi = IPA_NODE_REF (callee);
> -  (*parm_map).safe_grow (count);
> +  (*parm_map).safe_grow_cleared (count);
>for (i = 0; i < count; i++)
>   {
> -- 
> 2.28.0
> 


[PATCH][GCC-10 backport][COMMITTED] arm: Fix the warning -mcpu=cortex-m55 conflicting with -march=armv8.1-m.main (pr97327).

2020-10-19 Thread Srinath Parvathaneni via Gcc-patches
As this patch is approved here 
https://gcc.gnu.org/pipermail/gcc-patches/2020-October/556387.html ,
committed to releases/gcc-10 branch.

This patch fixes (PR97327) the warning -mcpu=cortex-m55 conflicts with 
-march=armv8.1-m.main
for -mfloat-abi=soft by adding the isa_bit_mve_float to clearing FP bit list.

The following combination are fixed with this patch:
$ cat bug.c
int main(){
return 0;
}

$ arm-none-eabi-gcc -mcpu=cortex-m55 -mfloat-abi=soft bug.c -c
$ arm-none-eabi-gcc -mcpu=cortex-m55 -mfloat-abi=soft -march=armv8.1-m.main+mve 
bug.c -c

Before this patch for above combinations:
cc1: warning: switch '-mcpu=cortex-m55' conflicts with '-march=armv8.1-m.main' 
switch

After this patch for above combinations no warning/errors.

gcc/ChangeLog:

2020-10-16  Srinath Parvathaneni  

PR target/97327
* config/arm/arm.c (fp_bitlist): Add isa_bit_mve_float to FP bits array.

gcc/testsuite/ChangeLog:

PR target/97327
* gcc.target/arm/mve/intrinsics/pr97327.c: New test.

(cherry picked from commit 90042c43a92c452a5f9f3afbfcdad511ea09a54f)


### Attachment also inlined for ease of reply###


diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
11292c2658c866d22962f2534b64ec13246346e6..99b1e926dc3025f8547e4bb5b98cdba02a6abe86
 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3445,8 +3445,9 @@ arm_option_override (void)
 {
   static const enum isa_feature fpu_bitlist_internal[]
 = { ISA_ALL_FPU_INTERNAL, isa_nobit };
+  /* isa_bit_mve_float is also part of FP bit list for arch v8.1-m.main.  */
   static const enum isa_feature fp_bitlist[]
-= { ISA_ALL_FP, isa_nobit };
+= { ISA_ALL_FP, isa_bit_mve_float, isa_nobit };
   static const enum isa_feature quirk_bitlist[] = { ISA_ALL_QUIRKS, isa_nobit};
   cl_target_option opts;
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
new file mode 100644
index 
..8f6d36063811607623048c0a95920b29e43f4c39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
@@ -0,0 +1,8 @@
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=hard" } { "" 
} } */
+/* { dg-additional-options "-mcpu=cortex-m55 -mfloat-abi=soft -mfpu=auto 
-Werror" } */
+
+int main ()
+{
+  return 0;
+}

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
11292c2658c866d22962f2534b64ec13246346e6..99b1e926dc3025f8547e4bb5b98cdba02a6abe86
 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3445,8 +3445,9 @@ arm_option_override (void)
 {
   static const enum isa_feature fpu_bitlist_internal[]
 = { ISA_ALL_FPU_INTERNAL, isa_nobit };
+  /* isa_bit_mve_float is also part of FP bit list for arch v8.1-m.main.  */
   static const enum isa_feature fp_bitlist[]
-= { ISA_ALL_FP, isa_nobit };
+= { ISA_ALL_FP, isa_bit_mve_float, isa_nobit };
   static const enum isa_feature quirk_bitlist[] = { ISA_ALL_QUIRKS, isa_nobit};
   cl_target_option opts;
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
new file mode 100644
index 
..8f6d36063811607623048c0a95920b29e43f4c39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr97327.c
@@ -0,0 +1,8 @@
+/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
+/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=hard" } { "" 
} } */
+/* { dg-additional-options "-mcpu=cortex-m55 -mfloat-abi=soft -mfpu=auto 
-Werror" } */
+
+int main ()
+{
+  return 0;
+}



[PATCH][pushed] IPA: fix one more UBSAN error

2020-10-19 Thread Martin Liška

It fixes:

/home/marxin/Programming/gcc2/gcc/ipa-modref-tree.h:482:22: runtime error: load 
of value 255, which is not a valid value for type 'bool'
#0 0x18e5df3 in modref_tree::merge(modref_tree*, 
vec*) 
/home/marxin/Programming/gcc2/gcc/ipa-modref-tree.h:482
#1 0x18dc180 in ipa_merge_modref_summary_after_inlining(cgraph_edge*) 
/home/marxin/Programming/gcc2/gcc/ipa-modref.c:1779
#2 0x18c1c72 in inline_call(cgraph_edge*, bool, vec*, int*, bool, bool*) 
/home/marxin/Programming/gcc2/gcc/ipa-inline-transform.c:492
#3 0x4a3589c in inline_small_functions 
/home/marxin/Programming/gcc2/gcc/ipa-inline.c:2216
#4 0x4a3b230 in ipa_inline 
/home/marxin/Programming/gcc2/gcc/ipa-inline.c:2697
#5 0x4a3d902 in execute /home/marxin/Programming/gcc2/gcc/ipa-inline.c:3096
#6 0x1edf831 in execute_one_pass(opt_pass*) 
/home/marxin/Programming/gcc2/gcc/passes.c:2509
#7 0x1ee26af in execute_ipa_pass_list(opt_pass*) 
/home/marxin/Programming/gcc2/gcc/passes.c:2936
#8 0x103f31b in ipa_passes 
/home/marxin/Programming/gcc2/gcc/cgraphunit.c:2700
#9 0x103fb40 in symbol_table::compile() 
/home/marxin/Programming/gcc2/gcc/cgraphunit.c:2777
#10 0x104092b in symbol_table::finalize_compilation_unit() 
/home/marxin/Programming/gcc2/gcc/cgraphunit.c:3022
#11 0x235723b in compile_file /home/marxin/Programming/gcc2/gcc/toplev.c:485
#12 0x235fff9 in do_compile /home/marxin/Programming/gcc2/gcc/toplev.c:2321
#13 0x23605fc in toplev::main(int, char**) 
/home/marxin/Programming/gcc2/gcc/toplev.c:2460
#14 0x4e2b93b in main /home/marxin/Programming/gcc2/gcc/main.c:39
#15 0x76f0ae09 in __libc_start_main ../csu/libc-start.c:314
#16 0x9a0be9 in _start 
(/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x9a0be9)

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
I'm going to install it as it's very similar to what I installed 2 weeks ago.

Thanks,
Martin

gcc/ChangeLog:

* ipa-modref.c (compute_parm_map): Clear vector.
---
 gcc/ipa-modref.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 8e6a87643ec..3a70965d156 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -1654,7 +1654,7 @@ compute_parm_map (cgraph_edge *callee_edge, 
vec *parm_map)
: callee_edge->caller);
   callee_pi = IPA_NODE_REF (callee);
 
-  (*parm_map).safe_grow (count);

+  (*parm_map).safe_grow_cleared (count);
 
   for (i = 0; i < count; i++)

{
--
2.28.0



Re: [Ada,FYI] revamp ada.numerics.aux

2020-10-19 Thread Alexandre Oliva
Hello, Andreas,

On Oct 19, 2020, Andreas Schwab  wrote:

> -nostdinc a-nallfl.ads -o a-nallfl.o
> a-nallfl.ads:48:13: warning: intrinsic binding type mismatch on return value
> a-nallfl.ads:48:13: warning: intrinsic binding type mismatch on argument 1
> a-nallfl.ads:48:13: warning: profile of "Sin" doesn't match the builtin it 
> binds

Thanks for the report.  Ada's Standard.Long_Long_Float is mapped to C
double rather than long double on this target.

Here's a workaround, for aarch64-* and ppc*-linux-gnu, where I've
observed the mismatch so far.

I'm not sure whether we're going to use something like this, or a fix
for the mismatch; I'm yet to figure out how to implement the latter.


aarch64-* and ppc*-linux-gnu long long float/long double mismatch

---
 gcc/ada/Makefile.rtl |6 ++
 gcc/ada/libgnat/a-nallfl__wraplf.ads |   87 ++
 2 files changed, 93 insertions(+)
 create mode 100644 gcc/ada/libgnat/a-nallfl__wraplf.ads

diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 2bc95db..6a83371e 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -1298,6 +1298,7 @@ ifeq ($(strip $(filter-out aarch64 arm% coff wrs 
vx%,$(target_cpu) $(target_vend
 VX=vxworks7
 EH_MECHANISM=-gcc
 SIGTRAMP_OBJ=sigtramp-vxworks.o
+LIBGNAT_TARGET_PAIRS += a-nallfl.adshttp://www.gnu.org/licenses/>.  --
+--  --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.  --
+--  --
+--
+
+--  This package provides the basic computational interface for the
+--  generic elementary functions. The functions in this unit are
+--  wrappers for those in the Long Float package.
+
+with Ada.Numerics.Aux_Long_Float;
+
+package Ada.Numerics.Aux_Long_Long_Float is
+   pragma Pure;
+
+   subtype T is Long_Long_Float;
+   package Aux renames Ada.Numerics.Aux_Long_Float;
+   subtype W is Aux.T;
+
+   --  Use the Aux implementation.
+
+   function Sin (X : T) return T
+   is (T (Aux.Sin (W (X;
+
+   function Cos (X : T) return T
+   is (T (Aux.Cos (W (X;
+
+   function Tan (X : T) return T
+   is (T (Aux.Tan (W (X;
+
+   function Exp (X : T) return T
+   is (T (Aux.Exp (W (X;
+
+   function Sqrt (X : T) return T
+   is (T (Aux.Sqrt (W (X;
+
+   function Log (X : T) return T
+   is (T (Aux.Log (W (X;
+
+   function Acos (X : T) return T
+   is (T (Aux.Acos (W (X;
+
+   function Asin (X : T) return T
+   is (T (Aux.Asin (W (X;
+
+   function Atan (X : T) return T
+   is (T (Aux.Atan (W (X;
+
+   function Sinh (X : T) return T
+   is (T (Aux.Sinh (W (X;
+
+   function Cosh (X : T) return T
+   is (T (Aux.Cosh (W (X;
+
+   function Tanh (X : T) return T
+   is (T (Aux.Tanh (W (X;
+
+   function Pow (X, Y : T) return T
+   is (T (Aux.Pow (W (X), W (Y;
+
+end Ada.Numerics.Aux_Long_Long_Float;


-- 
Alexandre Oliva, happy hacker
https://FSFLA.org/blogs/lxo/
Free Software Activist
GNU Toolchain Engineer


Re: /home/rguenther/Mail/tem

2020-10-19 Thread Richard Biener
> Sender: "Gcc-patches" 
> 
> > > @@ -122,7 +201,8 @@ public:
> > >  unsigned int idx = arg_idx (i);
> > >  gcc_checking_assert (arg_specified_p (i));
> > >  return str[idx] == 'w' || str[idx] == 'W'
> > > -|| str[idx] == 'R' || str[idx] == 'r';
> > > +|| str[idx] == 'r' || str[idx] == 'R'
> > > +|| str[idx] == 'o' || str[idx] == 'o';
> > 
> > Did you mean 
> > 
> >   || str[idx] == 'o' || str[idx] == 'O';
> > 
> > here?
> Yes, thank you!  It is a lot of ascii-art that is easy to get wrong :(
> I also re-checked the new specs and noticed wrong return value of
> mempcpy.  Here is updated patch I am re-testing.
> 
> 2020-10-16  Jan Hubicka  
> 
>   * attr-fnspec.h: Update toplevel comment.
>   (attr_fnspec::attr_fnspec): New constructor.
>   (attr_fnspec::arg_read_p,
>   attr_fnspec::arg_written_p,
>   attr_fnspec::arg_access_size_given_by_arg_p,
>   attr_fnspec::arg_single_access_p
>   attr_fnspec::loads_known_p
>   attr_fnspec::stores_known_p,
>   attr_fnspec::clobbers_errno_p): New member functions.
>   (gimple_call_fnspec): Declare.
>   (builtin_fnspec): Declare.
>   * builtins.c: Include attr-fnspec.h
>   (builtin_fnspec): New function.
>   * builtins.def (BUILT_IN_MEMCPY): Do not specify RET1 fnspec.
>   (BUILT_IN_MEMMOVE): Do not specify RET1 fnspec.
>   (BUILT_IN_MEMSET): Do not specify RET1 fnspec.
>   (BUILT_IN_STRCAT): Do not specify RET1 fnspec.
>   (BUILT_IN_STRCPY): Do not specify RET1 fnspec.
>   (BUILT_IN_STRNCAT): Do not specify RET1 fnspec.
>   (BUILT_IN_STRNCPY): Do not specify RET1 fnspec.
>   (BUILT_IN_MEMCPY_CHK): Do not specify RET1 fnspec.
>   (BUILT_IN_MEMMOVE_CHK): Do not specify RET1 fnspec.
>   (BUILT_IN_MEMSET_CHK): Do not specify RET1 fnspec.
>   (BUILT_IN_STRCAT_CHK): Do not specify RET1 fnspec.
>   (BUILT_IN_STRCPY_CHK): Do not specify RET1 fnspec.
>   (BUILT_IN_STRNCAT_CHK): Do not specify RET1 fnspec.
>   (BUILT_IN_STRNCPY_CHK): Do not specify RET1 fnspec.
>   * gimple.c (gimple_call_fnspec): Return attr_fnspec.
>   (gimple_call_arg_flags): Update.
>   (gimple_call_return_flags): Update.
>   * tree-ssa-alias.c (check_fnspec): New function.
>   (ref_maybe_used_by_call_p_1): Use fnspec for builtin handling.
>   (call_may_clobber_ref_p_1): Likewise.
>   (attr_fnspec::verify): Update verifier.
>   * calls.c (decl_fnspec): New function.
>   (decl_return_flags): Use it.
> 
> diff --git a/gcc/attr-fnspec.h b/gcc/attr-fnspec.h
> index d38b84a969e..c9421a60095 100644
> --- a/gcc/attr-fnspec.h
> +++ b/gcc/attr-fnspec.h
> @@ -27,11 +27,19 @@
>   '.' specifies that nothing is known.
> character 1  specifies additional function properties
>   ' 'specifies that nothing is known
> + 'p' or 'P' specifies that function is pure except for described side
> + effects.
> + 'c' or 'C' specifies that function is const except for described side
> + effects.
> + 'b' specifies that functions is a memory barrier.
> +   The uppercase letter in addition specifies that function clobbers errno.
>

What does 'b' actually guarantee?

> character 2+2i specifies properties of argument number i as follows:
>   'x' or 'X' specifies that parameter is unused.
>   'r' or 'R' specifies that the memory pointed to by the parameter is only
>   read and does not escape
> + 'o' or 'O' specifies that the memory pointed to by the parameter is only
> + written and does not escape
>   'w' or 'W' specifies that the memory pointed to by the parameter does 
> not
>   escape
>   '.' specifies that nothing is known.
> @@ -42,6 +50,10 @@
> character 3+2i specifies additional properties of argument number i
> as follows:
>   ' 'nothing is known
> + 't' the size of value written/read corresponds to the size of
> + of the pointed-to type of the argument type
> + '1'...'9'  the size of value written/read is given by the specified
> + argument
>   */
>  
>  #ifndef ATTR_FNSPEC_H
> @@ -72,6 +84,12 @@ public:
>  if (flag_checking)
>verify ();
>}
> +  attr_fnspec (const char *str)
> +  : str (str), len (strlen (str))
> +  {
> +if (flag_checking)
> +  verify ();
> +  }
>attr_fnspec (const_tree identifier)
>: str (TREE_STRING_POINTER (identifier)),
>  len (TREE_STRING_LENGTH (identifier))
> @@ -79,6 +97,17 @@ public:
>  if (flag_checking)
>verify ();
>}
> +  attr_fnspec ()
> +  : str (NULL), len (0)
> +  {
> +  }
> +
> +  /* Return true if fn spec is known.  */
> +  bool
> +  known_p ()
> +  {
> +return len;
> +  }
>  
>/* Return true if arg I is specified.  */
>bool
> @@ -94,7 +123,7 @@ public:
>{
>  unsigned int idx = arg_idx (i);
>  gcc_checking_assert (arg_specified_p (i));
> -return str[idx] == 'R' || str[idx] 

Re: [PATCH] Gracefully handle right shifts larger than the precision.

2020-10-19 Thread Jakub Jelinek via Gcc-patches
On Mon, Oct 19, 2020 at 12:55:38PM +0200, Aldy Hernandez wrote:
> > Shifts are undefined already when the shift count is equal to the precision.
> > And arbitrarily choosing one of the values as the shift count seems risky to
> > me (and even when used, the most natural would be truncating the excess bits
> > rather than saturating), can't it just punt (return VARYING) for the UB
> > shifts?
> 
> Good point.  It looks cleaner too.
> 
> How about this?
> 
> diff --git a/gcc/range-op.cc b/gcc/range-op.cc
> index 30d2a4d3987..0ab5e62be7f 100644
> --- a/gcc/range-op.cc
> +++ b/gcc/range-op.cc
> @@ -1579,6 +1579,9 @@ operator_lshift::op1_range (irange &r,
>wide_int shift = wi::to_wide (shift_amount);
>if (wi::lt_p (shift, 0, SIGNED))
> return false;
> +  if (wi::gt_p (shift, wi::uhwi (TYPE_PRECISION (type),
> +TYPE_PRECISION (op2.type ()
> +   return false;

If you use wi::ge_p instead, then LGTM.

Jakub



Re: [PATCH] Gracefully handle right shifts larger than the precision.

2020-10-19 Thread Aldy Hernandez via Gcc-patches
On Mon, Oct 19, 2020 at 12:44 PM Jakub Jelinek  wrote:
>
> On Mon, Oct 19, 2020 at 12:36:24PM +0200, Aldy Hernandez via Gcc-patches 
> wrote:
> > The test is trying to shift by 129, but the underlying type is 128 bits.
> > This causes low_bits to wrap around to -1 and things go bad really
> > quick.
> >
> > Attached is my proposed solution.
> >
> > Andrew, do you have a preference on how to fix this?
>
> Shifts are undefined already when the shift count is equal to the precision.
> And arbitrarily choosing one of the values as the shift count seems risky to
> me (and even when used, the most natural would be truncating the excess bits
> rather than saturating), can't it just punt (return VARYING) for the UB
> shifts?

Good point.  It looks cleaner too.

How about this?

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 30d2a4d3987..0ab5e62be7f 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1579,6 +1579,9 @@ operator_lshift::op1_range (irange &r,
   wide_int shift = wi::to_wide (shift_amount);
   if (wi::lt_p (shift, 0, SIGNED))
return false;
+  if (wi::gt_p (shift, wi::uhwi (TYPE_PRECISION (type),
+TYPE_PRECISION (op2.type ()
+   return false;
   if (shift == 0)
{
  r = lhs;



Re: [PATCH] Gracefully handle right shifts larger than the precision.

2020-10-19 Thread Jakub Jelinek via Gcc-patches
On Mon, Oct 19, 2020 at 12:36:24PM +0200, Aldy Hernandez via Gcc-patches wrote:
> The test is trying to shift by 129, but the underlying type is 128 bits.
> This causes low_bits to wrap around to -1 and things go bad really
> quick.
> 
> Attached is my proposed solution.
> 
> Andrew, do you have a preference on how to fix this?

Shifts are undefined already when the shift count is equal to the precision.
And arbitrarily choosing one of the values as the shift count seems risky to
me (and even when used, the most natural would be truncating the excess bits
rather than saturating), can't it just punt (return VARYING) for the UB
shifts?
> 
> gcc/ChangeLog:
> 
>   PR tree-optimization/97488
>   * range-op.cc (operator_lshift::op1_range): Handle large right shifts.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/pr97488.c: New test.

Jakub



Re: [RFC] Remove include/precompiled/expc++.h

2020-10-19 Thread Jonathan Wakely via Gcc-patches

On 16/10/20 14:36 -0400, Ed Smith-Rowland wrote:

On 10/15/20 7:21 PM, Jonathan Wakely wrote:

Ed,

In commit r232377 (aka 2be75957b80b640c0aac4356ab861edd0c2f1b9d in the
git repo) you added a new header to the include/precompiled directory.
That wasn't mentioned in the ChangeLog, wasn't in the patch posted to
https://gcc.gnu.org/legacy-ml/libstdc++/2016-01/msg00016.html and
wasn't added to include/Makefile.am, which means it never gets
precompiled, and never gets installed.

I don't think it was meant to be committed, so I think we should
remove it. Any objection?

We *could* add it to the build so it gets installed ... but meh.


Jonathan,

Go ahead and remove that header. Sorry for the noise.


Committed, thanks.



[PATCH] Gracefully handle right shifts larger than the precision.

2020-10-19 Thread Aldy Hernandez via Gcc-patches
The test is trying to shift by 129, but the underlying type is 128 bits.
This causes low_bits to wrap around to -1 and things go bad really
quick.

Attached is my proposed solution.

Andrew, do you have a preference on how to fix this?

gcc/ChangeLog:

PR tree-optimization/97488
* range-op.cc (operator_lshift::op1_range): Handle large right shifts.

gcc/testsuite/ChangeLog:

* gcc.dg/pr97488.c: New test.
---
 gcc/range-op.cc|  6 --
 gcc/testsuite/gcc.dg/pr97488.c | 11 +++
 2 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr97488.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 30d2a4d3987..13a0ee37feb 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1608,8 +1608,10 @@ operator_lshift::op1_range (irange &r,
   // This would be [0x42, 0xFC] aka [0110, 1100].
 
   // Ideally we do this for each subrange, but just lump them all for now.
-  unsigned low_bits = TYPE_PRECISION (utype)
- - TREE_INT_CST_LOW (shift_amount);
+  unsigned saturated_shift_amount = TREE_INT_CST_LOW (shift_amount);
+  if (saturated_shift_amount > TYPE_PRECISION (utype))
+   saturated_shift_amount = TYPE_PRECISION (utype);
+  unsigned low_bits = TYPE_PRECISION (utype) - saturated_shift_amount;
   wide_int up_mask = wi::mask (low_bits, true, TYPE_PRECISION (utype));
   wide_int new_ub = wi::bit_or (up_mask, r.upper_bound ());
   wide_int new_lb = wi::set_bit (r.lower_bound (), low_bits);
diff --git a/gcc/testsuite/gcc.dg/pr97488.c b/gcc/testsuite/gcc.dg/pr97488.c
new file mode 100644
index 000..96dc33cf258
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97488.c
@@ -0,0 +1,11 @@
+// { dg-do compile }
+// { dg-options "-O1 -ftree-vrp" }
+
+__int128
+ef (__int128 ms)
+{
+  int dh = 129;
+  int *hj = &dh;
+
+  return ms << *hj ? ms : 0;
+}
-- 
2.25.4



[committed] doc: Add closing parenthesis to -ffat-lto-objects docs

2020-10-19 Thread Jonathan Wakely via Gcc-patches
gcc/ChangeLog:

* doc/invoke.texi (OPptimize Options): Add missing closing
parenthesis.

Committed to trunk.

commit 2c6565d168204be5e99d960af727447c02f3a13f
Author: Jonathan Wakely 
Date:   Mon Oct 19 10:24:03 2020

doc: Add closing parenthesis to -ffat-lto-objects docs

gcc/ChangeLog:

* doc/invoke.texi (OPptimize Options): Add missing closing
parenthesis.

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 631a119181c..b3418b43a34 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11774,7 +11774,7 @@ to more aggressive optimization decisions.
 When a file is compiled with @option{-flto} without
 @option{-fuse-linker-plugin}, the generated object file is larger than
 a regular object file because it contains GIMPLE bytecodes and the usual
-final code (see @option{-ffat-lto-objects}.  This means that
+final code (see @option{-ffat-lto-objects}).  This means that
 object files with LTO information can be linked as normal object
 files; if @option{-fno-lto} is passed to the linker, no
 interprocedural optimizations are applied.  Note that when


PING: Fwd: [PATCH] Refactor range handling of builtins in vr_values and ranger.

2020-10-19 Thread Aldy Hernandez via Gcc-patches





 Forwarded Message 
Subject: [PATCH] Refactor range handling of builtins in vr_values and 
ranger.

Date: Fri,  9 Oct 2020 14:32:05 +0200
From: Aldy Hernandez 
To: GCC patches , Jakub Jelinek 
CC: Andrew MacLeod , Aldy Hernandez 

Hi Jakub.

As the last known expert in this area, would you review this, please? :)

This sets things up so we can share range handling of builtins between
vr_values and ranger.  It is meant to refactor the code so that we can
verify that both implementations yield the same results.

First, we abstract out gimple_ranger::range_of_builtin_call into an 
externally

visible counterpart that can be called from vr_values.  It will take a
range_query since both ranger and vr_values inherit from this base class.

Then we abstract out all the builtin handling in vr_values into a separate
method that is easier to compare against.

Finally, we call the ranger version from vr_values and compare it with the
vr_values version.  Since this proves both versions return the same,
we can remove vr_values::extract_range_builtin in a follow-up patch.

The vr_values::range_of_expr change brings the vr_values version up to par
with the ranger version.  It should've handled non-SSA's.  This was
a small oversight that went unnoticed because the vr_value version isn't
stressed nearly as much as the ranger version.  The change is needed because
the ranger code handling builtins calls, may call it for integer arguments
in range_of_builtin_ubsan_call.

There should be no change in functionality.

Tested on x86_64, with aarch64 tests still going.

OK provided aarch64 tests finish this century?

gcc/ChangeLog:

* gimple-range.cc (gimple_ranger::range_of_builtin_ubsan_call):
Make externally visble...
(range_of_builtin_ubsan_call): ...here.  Add range_query argument.
(gimple_ranger::range_of_builtin_call): Make externally visible...
(range_of_builtin_call): ...here.  Add range_query argument.
* gimple-range.h (range_of_builtin_call): Move out from class and
make externally visible.
* vr-values.c (vr_values::extract_range_basic): Abstract out
builtin handling to...
(vr_values::range_of_expr): Handle non SSAs.
(vr_values::extract_range_builtin): ...here.
* vr-values.h (class vr_values): Add extract_range_builtin.
(range_of_expr): Rename NAME to EXPR.
---
 gcc/gimple-range.cc |  36 ++--
 gcc/gimple-range.h  |   4 +-
 gcc/vr-values.c | 508 +++-
 gcc/vr-values.h |   3 +-
 4 files changed, 293 insertions(+), 258 deletions(-)

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 2ca86ed0e4c..a72919fc6c5 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -546,10 +546,13 @@ gimple_ranger::range_of_call (irange &r, gcall *call)
   return true;
 }
 +// Return the range of a __builtin_ubsan* in CALL and set it in R.
+// CODE is the type of ubsan call (PLUS_EXPR, MINUS_EXPR or
+// MULT_EXPR).
 -void
-gimple_ranger::range_of_builtin_ubsan_call (irange &r, gcall *call,
-   tree_code code)
+static void
+range_of_builtin_ubsan_call (range_query &query, irange &r, gcall *call,
+tree_code code)
 {
   gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR
   || code == MULT_EXPR);
@@ -559,8 +562,8 @@ gimple_ranger::range_of_builtin_ubsan_call (irange 
&r, gcall *call,

   int_range_max ir0, ir1;
   tree arg0 = gimple_call_arg (call, 0);
   tree arg1 = gimple_call_arg (call, 1);
-  gcc_assert (range_of_expr (ir0, arg0, call));
-  gcc_assert (range_of_expr (ir1, arg1, call));
+  gcc_assert (query.range_of_expr (ir0, arg0, call));
+  gcc_assert (query.range_of_expr (ir1, arg1, call));
bool saved_flag_wrapv = flag_wrapv;
   // Pretend the arithmetic is wrapping.  If there is any overflow,
@@ -576,9 +579,11 @@ gimple_ranger::range_of_builtin_ubsan_call (irange 
&r, gcall *call,

 r.set_varying (type);
 }
 +// For a builtin in CALL, return a range in R if known and return
+// TRUE.  Otherwise return FALSE.
  bool
-gimple_ranger::range_of_builtin_call (irange &r, gcall *call)
+range_of_builtin_call (range_query &query, irange &r, gcall *call)
 {
   combined_fn func = gimple_call_combined_fn (call);
   if (func == CFN_LAST)
@@ -599,7 +604,7 @@ gimple_ranger::range_of_builtin_call (irange &r, 
gcall *call)

  return true;
}
   arg = gimple_call_arg (call, 0);
-  if (range_of_expr (r, arg, call) && r.singleton_p ())
+  if (query.range_of_expr (r, arg, call) && r.singleton_p ())
{
  r.set (build_one_cst (type), build_one_cst (type));
  return true;
@@ -613,7 +618,7 @@ gimple_ranger::range_of_builtin_call (irange &r, 
gcall *call)

   prec = TYPE_PRECISION (TREE_TYPE (arg));
   mini = 0;
   maxi = prec;
-  gcc_assert (range_of_expr (r, arg, call));
+  gcc_assert (query.range_of_expr 

[Ada] Expanded names in ghost assignments

2020-10-19 Thread Pierre-Marie de Rodat
If the left-hand side of an assignment statement denotes a ghost
entity, then the assignment statement is a ghost assignment.
This patch fixes a bug in which ghost assignments were not
recognized in some cases. In particular, for an assignment
of the form "P.R.C := ...;", where P is a nonghost package,
R is a ghost record object, and C is a component, the assignment
was not recognized as ghost. This could cause compiler crashes
and undefined linker symbols in ghost-ignored mode.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* ghost.adb (Whole_Object_Ref): New function to compute the name
of the whole object.
(Mark_And_Set_Ghost_Assignment): Rewrite to use
Whole_Object_Ref.  We need to partly analyze the left-hand side
in order to distinguish expanded names and record components.
* lib-xref.ads, lib-xref.adb (Deferred_References): Move table
to body, and add Defer_Reference to update the table, avoiding
duplicates.
(Generate_Reference): Avoid duplicates.
* sem_ch8.ads, sem_ch8.adb (Find_Direct_Name): Remove _OK
parameters, which are no longer needed. Ignore errors in
Ignore_Errors mode.
* sem_util.ads, sem_util.adb (Preanalyze_Without_Errors): Make
this public, so we can call it from Ghost.
* errout.ads, scng.adb, sem_prag.adb: Minor.diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -112,8 +112,8 @@ package Errout is
--already placed an error (not warning) message at that location,
--then we assume this is cascaded junk and delete the message.
 
-   --  This normal suppression action may be overridden in cases 2-5 (but not
-   --  in case 1 or 7 by setting All_Errors mode, or by setting the special
+   --  This normal suppression action may be overridden in cases 2-5 (but
+   --  not in case 1 or 7) by setting All_Errors mode, or by setting the
--  unconditional message insertion character (!) as described below.
 
-


diff --git a/gcc/ada/ghost.adb b/gcc/ada/ghost.adb
--- a/gcc/ada/ghost.adb
+++ b/gcc/ada/ghost.adb
@@ -34,7 +34,6 @@ with Nlists;   use Nlists;
 with Nmake;use Nmake;
 with Sem;  use Sem;
 with Sem_Aux;  use Sem_Aux;
-with Sem_Ch8;  use Sem_Ch8;
 with Sem_Disp; use Sem_Disp;
 with Sem_Eval; use Sem_Eval;
 with Sem_Prag; use Sem_Prag;
@@ -65,6 +64,12 @@ package body Ghost is
-- Local subprograms --
---
 
+   function Whole_Object_Ref (Ref : Node_Id) return Node_Id;
+   --  For a name that denotes an object, returns a name that denotes the whole
+   --  object, declared by an object declaration, formal parameter declaration,
+   --  etc. For example, for P.X.Comp (J), if P is a package X is a record
+   --  object, this returns P.X.
+
function Ghost_Entity (Ref : Node_Id) return Entity_Id;
pragma Inline (Ghost_Entity);
--  Obtain the entity of a Ghost entity from reference Ref. Return Empty if
@@ -1009,10 +1014,8 @@ package body Ghost is
   
 
   function Ultimate_Original_Node (Nod : Node_Id) return Node_Id is
- Res : Node_Id;
-
+ Res : Node_Id := Nod;
   begin
- Res := Nod;
  while Original_Node (Res) /= Res loop
 Res := Original_Node (Res);
  end loop;
@@ -1176,61 +1179,73 @@ package body Ghost is
---
 
procedure Mark_And_Set_Ghost_Assignment (N : Node_Id) is
-  Orig_Lhs : constant Node_Id := Name (N);
-  Orig_Ref : constant Node_Id := Ultimate_Prefix (Orig_Lhs);
-
-  Id  : Entity_Id;
-  Ref : Node_Id;
+  --  A ghost assignment is an assignment whose left-hand side denotes a
+  --  ghost object. Subcomponents are not marked "ghost", so we need to
+  --  find the containing "whole" object. So, for "P.X.Comp (J) := ...",
+  --  where P is a package, X is a record, and Comp is an array, we need
+  --  to check the ghost flags of X.
 
+  Orig_Lhs : constant Node_Id := Name (N);
begin
-  --  A reference to a whole Ghost object (SPARK RM 6.9(1)) appears as an
-  --  identifier. If the reference has not been analyzed yet, preanalyze a
-  --  copy of the reference to discover the nature of its entity.
-
-  if Nkind (Orig_Ref) = N_Identifier and then not Analyzed (Orig_Ref) then
- Ref := New_Copy_Tree (Orig_Ref);
-
- --  Alter the assignment statement by setting its left-hand side to
- --  the copy.
-
- Set_Name   (N, Ref);
- Set_Parent (Ref, N);
-
- --  Preanalysis is carried out by looking for a Ghost entity while
- --  suppressing all possible side effects.
-
- Find_Direct_Name
-   (N=> Ref,
-Errors_OK=> False,
-Marker_OK=> False,
-Reference_OK => False);
-
-   

[Ada] Missing check on array concatenation

2020-10-19 Thread Pierre-Marie de Rodat
The expansion of array concatenation disables checks too much, so
reenable checks that are needed on the relevant internal subtype
declaration.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch4.adb (Expand_Concatenate): Enable needed range checks.diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -3524,12 +3524,13 @@ package body Exp_Ch4 is
  --  Note that we have arranged that the result will not be treated as
  --  a static constant, so we won't get an illegality during this
  --  insertion.
+ --  We also enable checks (in particular range checks) in case the
+ --  bounds of Subtyp_Ind are out of range.
 
  Insert_Action (Cnode,
Make_Object_Declaration (Loc,
  Defining_Identifier => Ent,
- Object_Definition   => Subtyp_Ind),
-   Suppress => All_Checks);
+ Object_Definition   => Subtyp_Ind));
   end if;
 
   --  If the result of the concatenation appears as the initializing




Re: [PATCH] [PR target/97194] [AVX2] Support variable index vec_set.

2020-10-19 Thread Richard Biener via Gcc-patches
On Mon, Oct 19, 2020 at 11:37 AM Hongtao Liu  wrote:
>
> On Mon, Oct 19, 2020 at 5:07 PM Richard Biener
>  wrote:
> >
> > On Mon, Oct 19, 2020 at 10:21 AM Hongtao Liu  wrote:
> > >
> > > Hi:
> > >   It's implemented as below:
> > > V setg (V v, int idx, T val)
> > >
> > > {
> > >   V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
> > >   V valv = (V){val, val, val, val, val, val, val, val};
> > >   V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
> > >   v = (v & ~mask) | (valv & mask);
> > >   return v;
> > > }
> > >
> > > Bootstrap is fine, regression test for i386/x86-64 backend is ok.
> > > Ok for trunk?
> >
> > Hmm, I guess you're trying to keep the code for !AVX512BW simple
> > but isn't just splitting the compare into
> >
> >  clow = {0, 1, 2, 3 ... } == idxv
> >  chigh = {16, 17, 18, ... } == idxv;
> >  cmp = {clow, chigh}
> >
>
> We also don't have 512-bits byte/word blend instructions without
> TARGET_AVX512W, so how to use 512-bits cmp?

Oh, I see.  Guess two back-to-back vpternlog could emulate
the blend?  Not sure if important - I recall only knl didn't have bw?

> cut from i386-expand.c:
> in ix86_expand_sse_movcc
>  3682case E_V64QImode:
>  3683  gen = gen_avx512bw_blendmv64qi; ---> TARGET_AVX512BW needed
>  3684  break;
>  3685case E_V32HImode:
>  3686  gen = gen_avx512bw_blendmv32hi; --> TARGET_AVX512BW needed
>  3687  break;
>  3688case E_V16SImode:
>  3689  gen = gen_avx512f_blendmv16si;
>  3690  break;
>  3691case E_V8DImode:
>  3692  gen = gen_avx512f_blendmv8di;
>  3693  break;
>  3694case E_V8DFmode:
>
> > faster, smaller and eventually even easier during expansion?
> >
> > +  gcc_assert (ix86_expand_vector_init_duplicate (false, mode, valv, val));
> > +  gcc_assert (ix86_expand_vector_init_duplicate (false, cmp_mode,
> > idxv, idx_tmp));
> >
> > side-effects in gcc_assert is considered bad style, use
> >
> >   ok = ix86_expand_vector_init_duplicate (false, mode, valv, val);
> >   gcc_assert (ok);
> >
> > +  vec[5] = constv;
> > +  ix86_expand_int_vcond (vec);
> >
> > this also returns a bool you probably should assert true.
> >
>
> Yes, will change.
>
> > Otherwise thanks for tackling this.
> >
> > Richard.
> >
> > > gcc/ChangeLog:
> > >
> > > PR target/97194
> > > * config/i386/i386-expand.c (ix86_expand_vector_set_var): New 
> > > function.
> > > * config/i386/i386-protos.h (ix86_expand_vector_set_var): New 
> > > Decl.
> > > * config/i386/predicates.md (vec_setm_operand): New predicate,
> > > true for const_int_operand or register_operand under TARGET_AVX2.
> > > * config/i386/sse.md (vec_set): Support both constant
> > > and variable index vec_set.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/i386/avx2-vec-set-1.c: New test.
> > > * gcc.target/i386/avx2-vec-set-2.c: New test.
> > > * gcc.target/i386/avx512bw-vec-set-1.c: New test.
> > > * gcc.target/i386/avx512bw-vec-set-2.c: New test.
> > > * gcc.target/i386/avx512f-vec-set-2.c: New test.
> > > * gcc.target/i386/avx512vl-vec-set-2.c: New test.
> > >
> > > --
> > > BR,
> > > Hongtao
>
>
>
> --
> BR,
> Hongtao


[Ada] Alternative display of multi-line messages for GNATprove

2020-10-19 Thread Pierre-Marie de Rodat
GNATprove now supports better display of multi-line messages on the
command-line, where additional information for a given check is issued
on separate lines that are clearly associated to the main message, both
by prefixing such lines with space characters, and by separating a block
of lines corresponding to one message from the next with a newline.

For example:

after_tax.adb:7:22: medium: range check might fail
  e.g. when Before_Tax = 101
and Rate = 2
  reason for check: returned value must fit in the result type ...
  possible fix: precondition of subprogram at after_tax.ads:3 should ...

This is made possible by implementing an alternative display of
continuation messages under debug switch -gnatdF.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* debug.adb: Use debug switch -gnatdF for this alternative
display of messages.
* errout.adb (Output_Messages): Alternative display when -gnatdF
is used.
* erroutc.adb (Output_Msg_Text): Likewise.diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -69,7 +69,7 @@ package body Debug is
--  dC   Output debugging information on check suppression
--  dD   Delete elaboration checks in inner level routines
--  dE   Apply elaboration checks to predefined units
-   --  dF
+   --  dF   Alternative display for messages over multiple lines
--  dG   Generate all warnings including those normally suppressed
--  dH   Hold (kill) call to gigi
--  dI   Inhibit internal name numbering in gnatG listing


diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -2052,24 +2052,41 @@ package body Errout is
  E := First_Error_Msg;
  while E /= No_Error_Msg loop
 if not Errors.Table (E).Deleted and then not Debug_Flag_KK then
-   if Full_Path_Name_For_Brief_Errors then
-  Write_Name (Full_Ref_Name (Errors.Table (E).Sfile));
-   else
-  Write_Name (Reference_Name (Errors.Table (E).Sfile));
+
+   --  If -gnatdF is used, separate main messages from previous
+   --  messages with a newline and make continuation messages
+   --  follow the main message with only an indentation of two
+   --  space characters, without repeating file:line:col: prefix.
+
+   if Debug_Flag_FF then
+  if Errors.Table (E).Msg_Cont then
+ Write_Str ("  ");
+  else
+ Write_Eol;
+  end if;
end if;
 
-   Write_Char (':');
-   Write_Int (Int (Physical_To_Logical
-(Errors.Table (E).Line,
- Errors.Table (E).Sfile)));
-   Write_Char (':');
+   if not (Debug_Flag_FF and then Errors.Table (E).Msg_Cont) then
+  if Full_Path_Name_For_Brief_Errors then
+ Write_Name (Full_Ref_Name (Errors.Table (E).Sfile));
+  else
+ Write_Name (Reference_Name (Errors.Table (E).Sfile));
+  end if;
+
+  Write_Char (':');
+  Write_Int (Int (Physical_To_Logical
+ (Errors.Table (E).Line,
+Errors.Table (E).Sfile)));
+  Write_Char (':');
+
+  if Errors.Table (E).Col < 10 then
+ Write_Char ('0');
+  end if;
 
-   if Errors.Table (E).Col < 10 then
-  Write_Char ('0');
+  Write_Int (Int (Errors.Table (E).Col));
+  Write_Str (": ");
end if;
 
-   Write_Int (Int (Errors.Table (E).Col));
-   Write_Str (": ");
Output_Msg_Text (E);
Write_Eol;
 end if;


diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -689,9 +689,16 @@ package body Erroutc is
  Txt := Text;
   end if;
 
+  --  If -gnatdF is used, continuation messages follow the main message
+  --  with only an indentation of two space characters, without repeating
+  --  any prefix.
+
+  if Debug_Flag_FF and then E_Msg.Msg_Cont then
+ null;
+
   --  For info messages, prefix message with "info: "
 
-  if E_Msg.Info then
+  elsif E_Msg.Info then
  Txt := new String'("info: " & Txt.all);
 
   --  Warning treated as error




[Ada] Ada_2020: Implement Key_Expression for named container aggregates

2020-10-19 Thread Pierre-Marie de Rodat
This patch implements the Key_Expression mechanism for container
aggregates. A Key_Expression specifies a mapping between the loop
variable in an iterated element association, and the value of the key
to be used for insertion of successive components into the container
being populated. The parser creates an Iterated_Element_Association only
when the key_expression appears, as indicated by the presence of a "use"
keyword. If the key_expression is not present, the parser generates
an Iterated_Component_Association.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* par-ch4.adb: (P_Aggregate_Or_Paren_Expr): Recognize
Iterated_Element_Component.
(P_Iterated_Component_Association): Rebuild node as an Iterated_
Element_Association when Key_Expression is present, and attach
either the Loop_Parameter_Specification or the
Iterator_Specification to the new node.
* sem_aggr.adb: (Resolve_Container_Aggregate):
Resolve_Iterated_Association handles bota Iterated_Component_
and Iterated_Element_Associations, in which case it analyzes and
resoles the orresponding Key_Expression.
* exp_aggr.adb (Expand_Iterated_Component): If a Key_Expression
is present, use it as the required parameter in the call to the
insertion routine for the destination container aggregate. Call
this routine for both kinds of Iterated_Associations.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6899,23 +6899,62 @@ package body Exp_Aggr is
 
   procedure Expand_Iterated_Component (Comp : Node_Id) is
  Expr: constant Node_Id := Expression (Comp);
- Loop_Id : constant Entity_Id :=
-Make_Defining_Identifier (Loc,
-  Chars => Chars (Defining_Identifier (Comp)));
 
+ Key_Expr   : Node_Id := Empty;
+ Loop_Id: Entity_Id;
  L_Range: Node_Id;
  L_Iteration_Scheme : Node_Id;
  Loop_Stat  : Node_Id;
  Stats  : List_Id;
 
   begin
- if Present (Iterator_Specification (Comp)) then
+ if Nkind (Comp) = N_Iterated_Element_Association then
+Key_Expr := Key_Expression (Comp);
+
+--  We create a new entity as loop identifier in all cases,
+--  as is done for generated loops elsewhere, as the loop
+--  structure has been previously analyzed.
+
+if Present (Iterator_Specification (Comp)) then
+
+   --  Either an Iterator_Specification of a Loop_Parameter_
+   --  Specification is present.
+
+   L_Iteration_Scheme :=
+ Make_Iteration_Scheme (Loc,
+   Iterator_Specification => Iterator_Specification (Comp));
+   Loop_Id :=
+  Make_Defining_Identifier (Loc,
+Chars => Chars (Defining_Identifier
+   (Iterator_Specification (Comp;
+   Set_Defining_Identifier
+  (Iterator_Specification (L_Iteration_Scheme), Loop_Id);
+
+else
+   L_Iteration_Scheme :=
+ Make_Iteration_Scheme (Loc,
+   Loop_Parameter_Specification =>
+ Loop_Parameter_Specification (Comp));
+   Loop_Id :=
+  Make_Defining_Identifier (Loc,
+Chars => Chars (Defining_Identifier
+   (Loop_Parameter_Specification (Comp;
+   Set_Defining_Identifier
+  (Loop_Parameter_Specification
+ (L_Iteration_Scheme), Loop_Id);
+end if;
+
+ elsif Present (Iterator_Specification (Comp)) then
 L_Iteration_Scheme :=
   Make_Iteration_Scheme (Loc,
 Iterator_Specification => Iterator_Specification (Comp));
 
  else
 L_Range := Relocate_Node (First (Discrete_Choices (Comp)));
+Loop_Id :=
+  Make_Defining_Identifier (Loc,
+Chars => Chars (Defining_Identifier (Comp)));
+
 L_Iteration_Scheme :=
   Make_Iteration_Scheme (Loc,
 Loop_Parameter_Specification =>
@@ -6928,6 +6967,9 @@ package body Exp_Aggr is
  --  expression is needed. For a named aggregate, the loop variable,
  --  whose type is that of the key, is an additional parameter for
  --  the insertion operation.
+ --  If a Key_Expression is present, it serves as the additional
+ --  parameter. Otherwise the key is given by the loop parameter
+ --  itself.
 
  if Present (Add_Unnamed_Subp) then
 Stats := New_List
@@ -6937,13 +6979,27 @@ package body Exp_Aggr is
New_List (New_Occurrence_Of (Temp, Loc),
  New_Copy_Tree (Expr;
  el

[Ada] No range check on fixed point to integer conversion

2020-10-19 Thread Pierre-Marie de Rodat
In some cases, range checks are missing when converting fixed point
values to integer.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* checks.adb (Apply_Type_Conversion_Checks): Minor code clean
up.
* exp_ch4.adb (Discrete_Range_Check): Optimize range checks.
Update comments.
(Expand_N_Type_Conversion): Generate range check when rewriting
a type conversion if needed. Add assertion.
* exp_ch6.adb (Expand_Simple_Function_Return): Minor code clean
up.
* sem_res.adb (Resolve_Type_Conversion): Apply range check when
needed.  Update comments.diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -3646,14 +3646,10 @@ package body Checks is
 (Entity (High_Bound (Scalar_Range (Enum_T;
  end if;
 
- if Last_E <= Last_I then
-null;
-
- else
+ if Last_E > Last_I then
 Activate_Overflow_Check (N);
  end if;
   end;
-
else
   Activate_Overflow_Check (N);
end if;
@@ -3666,7 +3662,6 @@ package body Checks is
  and then not GNATprove_Mode
then
   Apply_Float_Conversion_Check (Expr, Target_Type);
-
else
   --  Conversions involving fixed-point types are expanded
   --  separately, and do not need a Range_Check flag, except


diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -11447,7 +11447,12 @@ package body Exp_Ch4 is
   --  Start of processing for Discrete_Range_Check
 
   begin
- --  Nothing to do if conversion was rewritten
+ --  Clear the Do_Range_Check flag on N if needed: this can occur when
+ --  e.g. a trivial type conversion is rewritten by its expression.
+
+ Set_Do_Range_Check (N, False);
+
+ --  Nothing more to do if conversion was rewritten
 
  if Nkind (N) /= N_Type_Conversion then
 return;
@@ -11455,6 +11460,16 @@ package body Exp_Ch4 is
 
  Expr := Expression (N);
 
+ --  Nothing to do if no range check flag set
+
+ if not Do_Range_Check (Expr) then
+return;
+ end if;
+
+ --  Clear the Do_Range_Check flag on Expr
+
+ Set_Do_Range_Check (Expr, False);
+
  --  Nothing to do if range checks suppressed
 
  if Range_Checks_Suppressed (Target_Type) then
@@ -11473,23 +11488,20 @@ package body Exp_Ch4 is
  --  Before we do a range check, we have to deal with treating
  --  a fixed-point operand as an integer. The way we do this
  --  is simply to do an unchecked conversion to an appropriate
- --  integer type large enough to hold the result.
+ --  integer type with the smallest size, so that we can suppress
+ --  trivial checks.
 
  if Is_Fixed_Point_Type (Etype (Expr)) then
-if Esize (Base_Type (Etype (Expr))) > Standard_Integer_Size then
-   Ityp := Standard_Long_Long_Integer;
-else
-   Ityp := Standard_Integer;
-end if;
+Ityp := Small_Integer_Type_For
+  (Esize (Base_Type (Etype (Expr))), False);
 
---  Generate a temporary with the large type to facilitate in the C
---  backend the code generation for the unchecked conversion.
+--  Generate a temporary with the integer type to facilitate in the
+--  C backend the code generation for the unchecked conversion.
 
 if Modify_Tree_For_C then
Generate_Temporary;
 end if;
 
-Set_Do_Range_Check (Expr, False);
 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
  end if;
 
@@ -11726,7 +11738,12 @@ package body Exp_Ch4 is
  Tnn: Entity_Id;
 
   begin
- --  Nothing to do if conversion was rewritten
+ --  Clear the Do_Range_Check flag on N if needed: this can occur when
+ --  e.g. a trivial type conversion is rewritten by its expression.
+
+ Set_Do_Range_Check (N, False);
+
+ --  Nothing more to do if conversion was rewritten
 
  if Nkind (N) /= N_Type_Conversion then
 return;
@@ -11734,7 +11751,7 @@ package body Exp_Ch4 is
 
  Expr := Expression (N);
 
- --  Clear the flag once for all
+ --  Clear the Do_Range_Check flag on Expr
 
  Set_Do_Range_Check (Expr, False);
 
@@ -12009,7 +12026,8 @@ package body Exp_Ch4 is
 
   --  Nothing at all to do if conversion is to the identical type so remove
   --  the conversion completely, it is useless, except that it may carry
-  --  an Assignment_OK attribute, which must be 

[Ada] Compiler abort on in_out function parameter with type invariant

2020-10-19 Thread Pierre-Marie de Rodat
Compiler crashes on a function call when function profile includes
an in_out parameter, the parameter type has an inherited type
invariant, and the actual is a view conversion to an ancestor type.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch6.adb (Add_View_Conversion_Invariants): Do not insert
generated invariant checks when the call is a function call.
These tests are properly inserted in the code in procedure
Insert_Post_Call_Actions, which takes care of finding the proper
insertion point for the checks.
(Insert_Post_Call_Actions): Add question marks to indicate
possible gap in handling function calls that appear as aggregate
components.diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2943,7 +2943,12 @@ package body Exp_Ch6 is
 Par_Typ := Base_Type (Etype (Curr_Typ));
  end loop;
 
- if not Is_Empty_List (Inv_Checks) then
+ --  If the node is a function call the generated tests have been
+ --  already handled in Insert_Post_Call_Actions.
+
+ if not Is_Empty_List (Inv_Checks)
+   and then Nkind (Call_Node) = N_Procedure_Call_Statement
+ then
 Insert_Actions_After (Call_Node, Inv_Checks);
  end if;
   end Add_View_Conversion_Invariants;
@@ -8388,6 +8393,7 @@ package body Exp_Ch6 is
   --  The only exception is when the function call acts as an actual in a
   --  procedure call. In this case the function call is in a list, but the
   --  post-call actions must be inserted after the procedure call.
+  --  What if the function call is an aggregate component ???
 
   elsif Nkind (Context) = N_Procedure_Call_Statement then
  Insert_Actions_After (Context, Post_Call);




[Ada] Do not replace bounds for packed arrays that depend on discriminants

2020-10-19 Thread Pierre-Marie de Rodat
When generating constraint checks for types whose size depend on a
discriminant, the frontend would generate a reference to the
discriminant. This would result in a crash as the backend actually needs
a reference to the object itself.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_attr.adb (Expand_N_Attribute_Reference): Check if type
depends on discriminant.diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -3456,8 +3456,12 @@ package body Exp_Attr is
  --  replace this attribute with a direct reference to the attribute of
  --  the appropriate index subtype (since otherwise the back end will
  --  try to give us the value of 'First for this implementation type).
+ --  Do not do this if Ptyp depends on a discriminant as its bounds
+ --  are only available through N.
 
- if Is_Constrained_Packed_Array (Ptyp) then
+ if Is_Constrained_Packed_Array (Ptyp)
+   and then not Size_Depends_On_Discriminant (Ptyp)
+ then
 Rewrite (N,
   Make_Attribute_Reference (Loc,
 Attribute_Name => Attribute_Name (N),




[Ada] Reject use of Relaxed_Initialization on scalar/access param or result

2020-10-19 Thread Pierre-Marie de Rodat
The rules for Relaxed_Initialization have been tightened in SPARK RM, to
reject meaningless uses. This is implemented here.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch13.adb (Analyze_Aspect_Relaxed_Initialization): Fix bug
where a call to Error_Msg_N leads to crash due to
Error_Msg_Name_1 being removed by the call, while a subsequent
call to Error_Msg_N tries to use it. The variable
Error_Msg_Name_1 should be restored prior to the next call. Also
add checking for the new rules.diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -2165,6 +2165,9 @@ package body Sem_Ch13 is
   Seen: in out Elist_Id)
is
begin
+  --  Set name of the aspect for error messages
+  Error_Msg_Name_1 := Nam;
+
   --  The relaxed parameter is a formal parameter
 
   if Nkind (Param) in N_Identifier | N_Expanded_Name then
@@ -2179,6 +2182,14 @@ package body Sem_Ch13 is
 
pragma Assert (Is_Formal (Item));
 
+   --  It must not have scalar or access type
+
+   if Is_Elementary_Type (Etype (Item)) then
+  Error_Msg_N ("illegal aspect % item", Param);
+  Error_Msg_N
+("\item must not have elementary type", Param);
+   end if;
+
--  Detect duplicated items
 
if Contains (Seen, Item) then
@@ -2205,6 +2216,16 @@ package body Sem_Ch13 is
   and then
 Entity (Pref) = Subp_Id
 then
+   --  Function result must not have scalar or access
+   --  type.
+
+   if Is_Elementary_Type (Etype (Pref)) then
+  Error_Msg_N ("illegal aspect % item", Param);
+  Error_Msg_N
+("\function result must not have elementary"
+ & " type", Param);
+   end if;
+
--  Detect duplicated items
 
if Contains (Seen, Subp_Id) then
@@ -2345,12 +2366,14 @@ package body Sem_Ch13 is
 if not Is_OK_Static_Expression
   (Expression (Assoc))
 then
+   Error_Msg_Name_1 := Nam;
Error_Msg_N
  ("expression of aspect %" &
   "must be static", Aspect);
 end if;
 
  else
+Error_Msg_Name_1 := Nam;
 Error_Msg_N
   ("illegal aspect % expression", Expr);
  end if;




[Ada] Remove excessive guards in building predicate functions

2020-10-19 Thread Pierre-Marie de Rodat
When calling routine Add_Call, which extends the type predicate function
with a call to its ancestor's type predicate function, we checked that
the ancestor type is present twice: in the Add_Call itself and at its
only call site.

Also, when the ancestor type has a predicate function, this routine was
setting Has_Predicates flag on the derived type. However, this flag is
already propagated as part of the type derivation. Setting it while
building the predicate function was redundant (and felt to be done much
too late).

Code cleanup only.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch13.adb (Add_Call): Remove excessive condition and
unnecessary call to Set_Has_Predicates.diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -9583,8 +9583,8 @@ package body Sem_Ch13 is
   --  Predicate_Function of the parent type, using Add_Call above.
 
   procedure Add_Call (T : Entity_Id);
-  --  Includes a call to the predicate function for type T in Expr if T
-  --  has predicates and Predicate_Function (T) is non-empty.
+  --  Includes a call to the predicate function for type T in Expr if
+  --  Predicate_Function (T) is non-empty.
 
   function Process_RE (N : Node_Id) return Traverse_Result;
   --  Used in Process REs, tests if node N is a raise expression, and if
@@ -9608,8 +9608,8 @@ package body Sem_Ch13 is
  Exp : Node_Id;
 
   begin
- if Present (T) and then Present (Predicate_Function (T)) then
-Set_Has_Predicates (Typ);
+ if Present (Predicate_Function (T)) then
+pragma Assert (Has_Predicates (Typ));
 
 --  Build the call to the predicate function of T. The type may be
 --  derived, so use an unchecked conversion for the actual.




[Ada] Use alternate stack for signal handling on PowerPC/Linux

2020-10-19 Thread Pierre-Marie de Rodat
This is necessary because the stack checking method has been changed
on this platform and now requires an alternate stack to propagate the
stack overflow exception.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* Makefile.rtl (PowerPC/Linux): Use s-taspri__posix.ads instead
of s-taspri__posix-noaltstack.ads for s-taspri.ads.diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2112,7 +2112,7 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(target_cpu) $(target_os))),)
 s-taprop.adb

[Ada] Ada2020: matching parentheses and brackets

2020-10-19 Thread Pierre-Marie de Rodat
This patch fixes a bug where the compiler allowed mismatched brackets
and parentheses in aggregates in -gnatX mode, as in (...] and [...).

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* par-ch4.adb (P_Aggregate_Or_Paren_Expr): Require matching
parens or brackets.
* par.adb, par-tchk.adb (T_Right_Bracket): New procedure to give
an error on missing ].diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -1391,6 +1391,9 @@ package body Ch4 is
  return Maybe;
   end Is_Quantified_Expression;
 
+  Start_Token : constant Token_Type := Token;
+  --  Used to prevent mismatches (...] and [...)
+
--  Start of processing for P_Aggregate_Or_Paren_Expr
 
begin
@@ -1697,23 +1700,26 @@ package body Ch4 is
  end if;
   end loop;
 
-  --  All component associations (positional and named) have been scanned
+  --  All component associations (positional and named) have been scanned.
+  --  Scan ] or ) based on Start_Token.
 
-  if Token = Tok_Right_Bracket and then Ada_Version >= Ada_2020 then
- Set_Component_Associations (Aggregate_Node, Assoc_List);
- Set_Is_Homogeneous_Aggregate (Aggregate_Node);
- Scan;  --  past right bracket
+  case Start_Token is
+ when Tok_Left_Bracket =>
+Set_Component_Associations (Aggregate_Node, Assoc_List);
+Set_Is_Homogeneous_Aggregate (Aggregate_Node);
+T_Right_Bracket;
 
- if Token = Tok_Apostrophe then
-Scan;
+if Token = Tok_Apostrophe then
+   Scan;
 
-if Token = Tok_Identifier then
-   return P_Reduction_Attribute_Reference (Aggregate_Node);
+   if Token = Tok_Identifier then
+  return P_Reduction_Attribute_Reference (Aggregate_Node);
+   end if;
 end if;
- end if;
-  else
- T_Right_Paren;
-  end if;
+ when Tok_Left_Paren =>
+T_Right_Paren;
+ when others => raise Program_Error;
+  end case;
 
   if Nkind (Aggregate_Node) /= N_Delta_Aggregate then
  Set_Expressions (Aggregate_Node, Expr_List);


diff --git a/gcc/ada/par-tchk.adb b/gcc/ada/par-tchk.adb
--- a/gcc/ada/par-tchk.adb
+++ b/gcc/ada/par-tchk.adb
@@ -402,6 +402,20 @@ package body Tchk is
   Check_Token (Tok_Record, AP);
end T_Record;
 
+   -
+   -- T_Right_Bracket --
+   -
+
+   procedure T_Right_Bracket is
+   begin
+  if Token = Tok_Right_Bracket then
+ Scan;
+  else
+ Error_Msg_AP -- CODEFIX
+   ("|missing ""']'""");
+  end if;
+   end T_Right_Bracket;
+
---
-- T_Right_Paren --
---


diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -1212,6 +1212,7 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
   procedure T_Private;
   procedure T_Range;
   procedure T_Record;
+  procedure T_Right_Bracket;
   procedure T_Right_Paren;
   procedure T_Semicolon;
   procedure T_Then;




[Ada] Ada2020: AI12-0304 Put_Image attrs of lang-def types

2020-10-19 Thread Pierre-Marie de Rodat
This patch implements AI12-0304. In particular, Put_Image (and
therefore 'Image) is provided for the containers and for unbounded
strings.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_put_image.adb (Build_Elementary_Put_Image_Call): Use the
base type to recognize various cases of access types.
* libgnat/a-cbdlli.adb, libgnat/a-cbdlli.ads, libgnat/a-cbhama.adb,
libgnat/a-cbhama.ads, libgnat/a-cbhase.adb, libgnat/a-cbhase.ads,
libgnat/a-cbmutr.adb, libgnat/a-cbmutr.ads, libgnat/a-cborma.adb,
libgnat/a-cborma.ads, libgnat/a-cborse.adb, libgnat/a-cborse.ads,
libgnat/a-cdlili.adb, libgnat/a-cdlili.ads, libgnat/a-cidlli.adb,
libgnat/a-cidlli.ads, libgnat/a-cihama.adb, libgnat/a-cihama.ads,
libgnat/a-cihase.adb, libgnat/a-cihase.ads, libgnat/a-cimutr.adb,
libgnat/a-cimutr.ads, libgnat/a-ciorma.adb, libgnat/a-ciorma.ads,
libgnat/a-ciormu.adb, libgnat/a-ciormu.ads, libgnat/a-ciorse.adb,
libgnat/a-ciorse.ads, libgnat/a-coboho.adb, libgnat/a-coboho.ads,
libgnat/a-cobove.adb, libgnat/a-cobove.ads, libgnat/a-cohama.adb,
libgnat/a-cohama.ads, libgnat/a-cohase.adb, libgnat/a-cohase.ads,
libgnat/a-coinho.adb, libgnat/a-coinho.ads,
libgnat/a-coinho__shared.adb, libgnat/a-coinho__shared.ads,
libgnat/a-coinve.adb, libgnat/a-coinve.ads, libgnat/a-comutr.adb,
libgnat/a-comutr.ads, libgnat/a-coorma.adb, libgnat/a-coorma.ads,
libgnat/a-coormu.adb, libgnat/a-coormu.ads, libgnat/a-coorse.adb,
libgnat/a-coorse.ads, libgnat/a-strunb.adb, libgnat/a-strunb.ads,
libgnat/a-strunb__shared.adb, libgnat/a-strunb__shared.ads:
Implement Put_Image attibute.
* libgnat/a-stteou.ads, libgnat/s-putima.ads,
libgnat/a-stouut.ads, libgnat/a-stoubu.adb: Make
Ada.Strings.Text_Output, Ada.Strings.Text_Output.Utils, and
System.Put_Images Pure, so they can be with'ed by Pure units
that should have Put_Image defined.
* libgnat/a-stouut.adb: Add missing column adjustments, and
remove a redundant one.
* libgnat/s-putima.adb (Put_Arrow): New routine to print an
arrow. Avoids adding a with clause to some containers.

patch.diff.gz
Description: application/gzip


[Ada] AI12-0352: Early derivation and equality of untagged types

2020-10-19 Thread Pierre-Marie de Rodat
This AI clarifies that declaring a user-defined primitive equality
operation for a record type T is illegal if it occurs after a type has
been derived from T.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch6.adb (Check_Untagged_Equality): Check for AI12-0352.diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -9118,10 +9118,27 @@ package body Sem_Ch6 is
   ("equality operator appears too late (Ada 2012)?y?", Eq_Op);
  end if;
 
-  --  No error detected
+  --  Finally check for AI12-0352: declaration of a user-defined primitive
+  --  equality operation for a record type T is illegal if it occurs after
+  --  a type has been derived from T.
 
   else
- return;
+ Obj_Decl := Next (Parent (Typ));
+
+ while Present (Obj_Decl) and then Obj_Decl /= Decl loop
+if Nkind (Obj_Decl) = N_Full_Type_Declaration
+  and then Etype (Defining_Identifier (Obj_Decl)) = Typ
+then
+   Error_Msg_N
+ ("equality operator cannot appear after derivation", Eq_Op);
+   Error_Msg_NE
+ ("an equality operator for& cannot be declared after "
+  & "this point??",
+  Obj_Decl, Typ);
+end if;
+
+Next (Obj_Decl);
+ end loop;
   end if;
end Check_Untagged_Equality;
 




[Ada] ACATS 4.1R - Exception missed

2020-10-19 Thread Pierre-Marie de Rodat
This new ACATS test shows that we are not taking the subtype constraint
into account when a Default_Value (via a box notation) is used in an
aggregate, e.g: B_Rec : Bad_Rec := (Cnt => <>);

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_aggr.adb (Resolve_Record_Aggregate): Properly apply
subtype constraints when using a Default_Value.
* freeze.adb: Fix typo.diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -6830,7 +6830,7 @@ package body Freeze is
  end if;
 
  --  If the type has a Defaut_Value/Default_Component_Value aspect,
- --  this is where we analye the expression (after the type is frozen,
+ --  this is where we analyze the expression (after the type is frozen,
  --  since in the case of Default_Value, we are analyzing with the
  --  type itself, and we treat Default_Component_Value similarly for
  --  the sake of uniformity).


diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -5033,16 +5033,28 @@ package body Sem_Aggr is
   end if;
 
--  Ada 2012: If component is scalar with default value, use it
+   --  by converting it to Ctyp, so that subtype constraints are
+   --  checked.
 
elsif Is_Scalar_Type (Ctyp)
  and then Has_Default_Aspect (Ctyp)
then
-  Add_Association
-(Component  => Component,
- Expr   =>
-   Default_Aspect_Value
- (First_Subtype (Underlying_Type (Ctyp))),
- Assoc_List => New_Assoc_List);
+  declare
+ Conv : constant Node_Id :=
+   Convert_To
+ (Typ  => Ctyp,
+  Expr =>
+New_Copy_Tree
+  (Default_Aspect_Value
+ (First_Subtype (Underlying_Type (Ctyp);
+
+  begin
+ Analyze_And_Resolve (Conv, Ctyp);
+ Add_Association
+   (Component  => Component,
+Expr   => Conv,
+Assoc_List => New_Assoc_List);
+  end;
 
elsif Has_Non_Null_Base_Init_Proc (Ctyp)
  or else not Expander_Active




[Ada] Ada2020: AI12-0304 Put_Image attrs of lang-def types

2020-10-19 Thread Pierre-Marie de Rodat
More work on this AI. Replace the Put_Image procedures in
Ada.Containers.Indefinite_Vectors and Indefinite_Doubly_Linked_Lists
with versions that call procedure Iterate, rather than using a
"for ... of" loop, because the "for ... of" loop causes regressions.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/a-coinve.adb, libgnat/a-cidlli.adb (Put_Image): Call
Iterate.diff --git a/gcc/ada/libgnat/a-cidlli.adb b/gcc/ada/libgnat/a-cidlli.adb
--- a/gcc/ada/libgnat/a-cidlli.adb
+++ b/gcc/ada/libgnat/a-cidlli.adb
@@ -1307,19 +1307,22 @@ is
is
   First_Time : Boolean := True;
   use System.Put_Images;
-   begin
-  Array_Before (S);
 
-  for X of V loop
+  procedure Put_Elem (Position : Cursor);
+  procedure Put_Elem (Position : Cursor) is
+  begin
  if First_Time then
 First_Time := False;
  else
 Simple_Array_Between (S);
  end if;
 
- Element_Type'Put_Image (S, X);
-  end loop;
+ Element_Type'Put_Image (S, Element (Position));
+  end Put_Elem;
 
+   begin
+  Array_Before (S);
+  Iterate (V, Put_Elem'Access);
   Array_After (S);
end Put_Image;
 


diff --git a/gcc/ada/libgnat/a-coinve.adb b/gcc/ada/libgnat/a-coinve.adb
--- a/gcc/ada/libgnat/a-coinve.adb
+++ b/gcc/ada/libgnat/a-coinve.adb
@@ -2659,19 +2659,22 @@ is
is
   First_Time : Boolean := True;
   use System.Put_Images;
-   begin
-  Array_Before (S);
 
-  for X of V loop
+  procedure Put_Elem (Position : Cursor);
+  procedure Put_Elem (Position : Cursor) is
+  begin
  if First_Time then
 First_Time := False;
  else
 Simple_Array_Between (S);
  end if;
 
- Element_Type'Put_Image (S, X);
-  end loop;
+ Element_Type'Put_Image (S, Element (Position));
+  end Put_Elem;
 
+   begin
+  Array_Before (S);
+  Iterate (V, Put_Elem'Access);
   Array_After (S);
end Put_Image;
 




[Ada] Implement initialization of CUDA runtime

2020-10-19 Thread Pierre-Marie de Rodat
Executing CUDA kernels requires registering the kernel with the CUDA
runtime beforehand. This is achieved by keeping track of procedures
marked with CUDA_Global when analyzing packages and then registering
each of the procedures with a fat binary created by the CUDA toolchain.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* debug.adb: Document -gnatd_c flag as being used for CUDA.
* gnat_cuda.ads: New file.
* gnat_cuda.adb: New file.
* rtsfind.ads: Add Interfaces_C_Strings package and
RE_Fatbin_Wrapper, RE_Register_Fat_Binary,
RE_Register_Fat_Binary_End, RE_Register_Function, RE_Chars_Ptr,
RE_New_Char_Array entities.
* rtsfind.adb: Create new Interfaces_C_Descendant subtype,
handle it.
* sem_ch7.adb (Analyze_Package_Body_Helper): Call CUDA init
procedure.
* sem_prag.adb (Analyze_Pragma): Call Add_Cuda_Kernel procedure.
* gcc-interface/Make-lang.in (GNAT_ADA_OBJS): Add gnat_cuda.o.

patch.diff.gz
Description: application/gzip


[Ada] Refine type of a local variable

2020-10-19 Thread Pierre-Marie de Rodat
Formal parameters, while iterated with First_Formal/Next_Formal, are
entities and not just nodes.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch6.adb (Is_Direct_Deep_Call): Refine type from Node_Id to
Entity_Id.diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -3215,7 +3215,7 @@ package body Exp_Ch6 is
  then
 declare
Actual : Node_Id;
-   Formal : Node_Id;
+   Formal : Entity_Id;
 
 begin
Actual := First (Parameter_Associations (Call_Node));




[Ada] Clarify current design of Errout wrt global variable usage

2020-10-19 Thread Pierre-Marie de Rodat
Current design of Errout mandates that the global variables defining
its input state for issuing messages is restored when needed by multiple
successive calls. This is surprising, and deserves proper documenting.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* errout.ads: Add comment regarding lack of preservation of
Errout state across successive calls to the API.diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -453,6 +453,15 @@ package Errout is
--  Note that is mandatory that the caller ensure that global variables
--  are set before the Error_Msg call, otherwise the result is undefined.
 
+   --  Also note that calls to Error_Msg and its variants destroy the value of
+   --  these global variables, as a way to support the inclusion of multiple
+   --  insertion characters of the same type. For example, support for
+   --  multiple characters % for a name in the message (up to 3) is
+   --  implemented by unconditionally shifting the value for Error_Msg_Nam_2
+   --  to Error_Msg_Nam_1 and from Error_Msg_Nam_3 to Error_Msg_Nam_2 after
+   --  dealing with insertion character %. The caller should ensure that all
+   --  global variables are restored if needed prior to calling Error_Msg.
+
Error_Msg_Col : Column_Number renames Err_Vars.Error_Msg_Col;
--  Column for @ insertion character in message
 




[Ada] Clarify protection offered by preconditions on Ada.Text_IO units

2020-10-19 Thread Pierre-Marie de Rodat
These preconditions are used in particular for analysis by SPARK tools.
It is thus important that they precisely convey which errors they allow
detecting, in callers of Ada.Text_IO. Here, Layout_Error cannot be
detected in a number of cases.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/a-textio.ads: Update top-level comment.diff --git a/gcc/ada/libgnat/a-textio.ads b/gcc/ada/libgnat/a-textio.ads
--- a/gcc/ada/libgnat/a-textio.ads
+++ b/gcc/ada/libgnat/a-textio.ads
@@ -36,8 +36,9 @@
 --  Preconditions in this unit are meant for analysis only, not for run-time
 --  checking, so that the expected exceptions are raised. This is enforced by
 --  setting the corresponding assertion policy to Ignore. These preconditions
---  are partial and protect against Status_Error, Mode_Error, and Layout_Error,
---  but not against other types of errors.
+--  are partial. They protect fully against Status_Error and Mode_Error,
+--  partially against Layout_Error (see SPARK User's Guide for details), and
+--  not against other types of errors.
 
 pragma Assertion_Policy (Pre => Ignore);
 




[Ada] Private type unexpectedly visible

2020-10-19 Thread Pierre-Marie de Rodat
The frontend erroneously allows referencing a subtype declaration
of a private type defined in the private part of a package.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch7.adb (Uninstall_Declarations): Uninstall the
declaration of a subtype declaration defined in the private part
of a package.diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -3185,6 +3185,25 @@ package body Sem_Ch7 is
end loop;
 end;
 
+ --  For subtypes of private types the frontend generates two entities:
+ --  one associated with the partial view and the other associated with
+ --  the full view. When the subtype declaration is public the frontend
+ --  places the former entity in the list of public entities of the
+ --  package and the latter entity in the private part of the package.
+ --  When the subtype declaration is private it generates these two
+ --  entities but both are placed in the private part of the package
+ --  (and the full view has the same source location as the partial
+ --  view and no parent; see Prepare_Private_Subtype_Completion).
+
+ elsif Ekind (Id) in E_Private_Subtype
+   | E_Limited_Private_Subtype
+   and then Present (Full_View (Id))
+   and then Sloc (Id) = Sloc (Full_View (Id))
+   and then No (Parent (Full_View (Id)))
+ then
+Set_Is_Hidden (Id);
+Set_Is_Potentially_Use_Visible (Id, False);
+
  elsif not Is_Child_Unit (Id)
and then (not Is_Private_Type (Id) or else No (Full_View (Id)))
  then




[Ada] Clean up support of square brackets

2020-10-19 Thread Pierre-Marie de Rodat
We cannot support at the same time [] aggregate notation and the
[""] wide character notation, and there's no agreement yet on the
proper syntax for [] aggregates, so resolve this temporarily by
supporting only [] as an aggregate under -gnatX and only the wide chars
legacy notation otherwise.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* par-ch4.adb (P_Aggregate_Or_Paren_Expr): Simplify code since
we are always under -gnatX if we encounter a Tok_Left_Bracket.
* scng.adb (Scan): [] is an aggregate under -gnatX and a wide
character otherwise.diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -1395,7 +1395,7 @@ package body Ch4 is
 
begin
   Lparen_Sloc := Token_Ptr;
-  if Token = Tok_Left_Bracket and then Ada_Version >= Ada_2020 then
+  if Token = Tok_Left_Bracket then
  Scan;
 
  --  Special case for null aggregate in Ada 2020


diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -1378,14 +1378,19 @@ package body Scng is
  --  Left bracket
 
  when '[' =>
-if Source (Scan_Ptr + 1) = '"' then
-   goto Scan_Wide_Character;
 
-elsif Ada_Version >= Ada_2020 then
+--  [] under -gnatX is an aggregate notation and the special
+--  wide character notation becomes unsupported since the two
+--  are ambiguous.
+
+if Extensions_Allowed then
Scan_Ptr := Scan_Ptr + 1;
Token := Tok_Left_Bracket;
return;
 
+elsif Source (Scan_Ptr + 1) = '"' then
+   goto Scan_Wide_Character;
+
 else
Error_Msg_S ("illegal character, replaced by ""(""");
Scan_Ptr := Scan_Ptr + 1;




[Ada] AI12-0170: Abstract subprogram calls in class-wide precond exprs

2020-10-19 Thread Pierre-Marie de Rodat
As specified in AI12-0170, calls to abstract subprograms within pre-
and postcondition expressions of an abstract subprogram of type T
are allowed in some cases, and references to a formal parameter of
the controlling type are reinterpreted as though they had a (notional)
nonabstract type NT that is a formal derived type whose ancestor type
is T. The compiler was properly allowing such abstract calls, but was
also allowing cases that are still illegal, such as when the abstract
call within the aspect is tag-indeterminate, and such a call is now
properly rejected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_disp.adb (Check_Dispatching_Context): When the enclosing
subprogram is abstract, bypass early return if the call is
tag-indeterminate, to continue with the later error checking.diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -575,12 +575,16 @@ package body Sem_Disp is
 --  Similarly, if this is a pre/postcondition for an abstract
 --  subprogram, it may call another abstract function which is
 --  a primitive of an abstract type. The call is non-dispatching
---  but will be legal in overridings of the operation.
+--  but will be legal in overridings of the operation. However,
+--  if the call is tag-indeterminate we want to continue with
+--  with the error checking below, as this case is illegal even
+--  for abstract subprograms (see AI12-0170).
 
 elsif (Is_Subprogram (Scop)
 or else Chars (Scop) = Name_Postcondition)
   and then
-(Is_Abstract_Subprogram (Scop)
+((Is_Abstract_Subprogram (Scop)
+   and then not Is_Tag_Indeterminate (N))
   or else
 (Nkind (Parent (Scop)) = N_Procedure_Specification
   and then Null_Present (Parent (Scop




[Ada] Crash in expression function defined in protected object

2020-10-19 Thread Pierre-Marie de Rodat
The frontend crashes processing an expression function defined
in the body of protected type that depends on discriminants.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch8.adb (Find_Direct_Name): Do not trust in the decoration
of the Entity attribute in constants associated with
discriminals of protected types.diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -5627,6 +5627,21 @@ package body Sem_Ch8 is
  if Is_Type (Entity (N)) then
 Set_Etype (N, Entity (N));
 
+ --  The exception to this general rule are constants associated with
+ --  discriminals of protected types because for each protected op
+ --  a new set of discriminals is internally created by the frontend
+ --  (see Exp_Ch9.Set_Discriminals), and the current decoration of the
+ --  entity pointer may have been set as part of a preanalysis, where
+ --  discriminals still reference the first subprogram or entry to be
+ --  expanded (see Expand_Protected_Body_Declarations).
+
+ elsif Full_Analysis
+   and then Ekind (Entity (N)) = E_Constant
+   and then Present (Discriminal_Link (Entity (N)))
+   and then Is_Protected_Type (Scope (Discriminal_Link (Entity (N
+ then
+goto Find_Name;
+
  else
 declare
Entyp : constant Entity_Id := Etype (Entity (N));
@@ -5667,6 +5682,8 @@ package body Sem_Ch8 is
  return;
   end if;
 
+  <>
+
   --  Preserve relevant elaboration-related attributes of the context which
   --  are no longer available or very expensive to recompute once analysis,
   --  resolution, and expansion are over.




[Ada] Remove useless initialization and refine type of a local variable

2020-10-19 Thread Pierre-Marie de Rodat
A local variable Param_Count is only accessed after being initialized to
1 and then is only incremented, so it only takes positive values. There
is no complex control flow involved, so code checkers like CodePeer
should have no trouble with the new code.

Semantics is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch6.adb (Expand_Call_Helper): Cleanup.diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -3259,7 +3259,7 @@ package body Exp_Ch6 is
   Actual: Node_Id;
   Formal: Entity_Id;
   Orig_Subp : Entity_Id := Empty;
-  Param_Count   : Natural := 0;
+  Param_Count   : Positive;
   Parent_Formal : Entity_Id;
   Parent_Subp   : Entity_Id;
   Prev_Ult  : Node_Id;




[Patch] testsuite: Avoid TCL errors when ASAN/TSAN/UBSAN is not available

2020-10-19 Thread Tobias Burnus

In a --disable-libsanitizer build, I see errors such as:
  g++.sum:ERROR: can't read "asan_saved_library_path": no such variable

I believe the following patch is the right way to solve this.
OK?

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
testsuite: Avoid TCL errors when ASAN/TSAN/UBSAN is not available

gcc/testsuite/ChangeLog:

	* lib/asan-dg.ex (asan_finish): Only reset ld_library_path if
	saved-path variable exists.
	* lib/tsan-dg.exp (tsan_finish): Likewise.
	* lib/ubsan-dg.ex (ubsan_finish): Likewise.

diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 2124607245e..ce745dfdf8d 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -151,8 +151,10 @@ proc asan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-set ld_library_path $asan_saved_library_path
-set_ld_library_path_env_vars
+if [info exists asan_saved_library_path ] {
+	set ld_library_path $asan_saved_library_path
+	set_ld_library_path_env_vars
+}
 clear_effective_target_cache
 }
 
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index b5631a79bcf..6dcfd0a2f83 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -150,7 +150,9 @@ proc tsan_finish { args } {
 } else {
 	unset dg-do-what-default
 }
-set ld_library_path $tsan_saved_library_path
-set_ld_library_path_env_vars
+if [info exists tsan_saved_library_path ] {
+	set ld_library_path $tsan_saved_library_path
+	set_ld_library_path_env_vars
+}
 clear_effective_target_cache
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index f4ab29e2add..31740e02ab4 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -141,7 +141,9 @@ proc ubsan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-set ld_library_path $ubsan_saved_library_path
-set_ld_library_path_env_vars
+if [info exists ubsan_saved_library_path ] {
+	set ld_library_path $ubsan_saved_library_path
+	set_ld_library_path_env_vars
+}
 clear_effective_target_cache
 }


Re: [Ada,FYI] revamp ada.numerics.aux

2020-10-19 Thread Andreas Schwab
/opt/gcc/gcc-20201019/Build/./gcc/xgcc -B/opt/gcc/gcc-20201019/Build/./gcc/ 
-B/usr/aarch64-suse-linux/bin/ -B/usr/aarch64-suse-linux/lib/ -isystem 
/usr/aarch64-suse-linux/include -isystem /usr/aarch64-suse-linux/sys-include
-c -g -O2  -fPIC  -W -Wall -gnatpg -nostdinc   a-nallfl.ads -o a-nallfl.o
a-nallfl.ads:48:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:48:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:48:13: warning: profile of "Sin" doesn't match the builtin it binds
a-nallfl.ads:51:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:51:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:51:13: warning: profile of "Cos" doesn't match the builtin it binds
a-nallfl.ads:54:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:54:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:54:13: warning: profile of "Tan" doesn't match the builtin it binds
a-nallfl.ads:57:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:57:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:57:13: warning: profile of "Exp" doesn't match the builtin it binds
a-nallfl.ads:60:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:60:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:60:13: warning: profile of "Sqrt" doesn't match the builtin it 
binds
a-nallfl.ads:63:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:63:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:63:13: warning: profile of "Log" doesn't match the builtin it binds
a-nallfl.ads:66:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:66:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:66:13: warning: profile of "Acos" doesn't match the builtin it 
binds
a-nallfl.ads:69:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:69:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:69:13: warning: profile of "Asin" doesn't match the builtin it 
binds
a-nallfl.ads:72:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:72:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:72:13: warning: profile of "Atan" doesn't match the builtin it 
binds
a-nallfl.ads:75:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:75:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:75:13: warning: profile of "Sinh" doesn't match the builtin it 
binds
a-nallfl.ads:78:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:78:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:78:13: warning: profile of "Cosh" doesn't match the builtin it 
binds
a-nallfl.ads:81:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:81:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:81:13: warning: profile of "Tanh" doesn't match the builtin it 
binds
a-nallfl.ads:84:13: warning: intrinsic binding type mismatch on return value
a-nallfl.ads:84:13: warning: intrinsic binding type mismatch on argument 1
a-nallfl.ads:84:13: warning: profile of "Pow" doesn't match the builtin it binds
make[7]: *** [../gcc-interface/Makefile:302: a-nallfl.o] Error 1

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


[PATCH] Handle right shifts by zero in range-ops.

2020-10-19 Thread Aldy Hernandez via Gcc-patches
If the shift amount in operator_lshift::op1_range was zero, an invalid range
of [1, 0] was being created.

Pushed.

gcc/ChangeLog:

PR tree-optimization/97467
* range-op.cc (operator_lshift::op1_range): Handle shifts by 0.

gcc/testsuite/ChangeLog:

* gcc.dg/pr97467.c: New test.
---
 gcc/range-op.cc|  5 +
 gcc/testsuite/gcc.dg/pr97467.c | 16 
 2 files changed, 21 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr97467.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 0efa00186e8..30d2a4d3987 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1579,6 +1579,11 @@ operator_lshift::op1_range (irange &r,
   wide_int shift = wi::to_wide (shift_amount);
   if (wi::lt_p (shift, 0, SIGNED))
return false;
+  if (shift == 0)
+   {
+ r = lhs;
+ return true;
+   }
 
   // Work completely in unsigned mode to start.
   tree utype = type;
diff --git a/gcc/testsuite/gcc.dg/pr97467.c b/gcc/testsuite/gcc.dg/pr97467.c
new file mode 100644
index 000..dcbd218f733
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97467.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+int a;
+long b;
+unsigned int c = 1;
+
+int main () {
+  int e;
+  for (; c <= 0; c++) {
+int f = 0;
+b = e;
+a = f || b << c;
+  }
+  return 0;
+}
-- 
2.26.2



Re: [PATCH] [PR target/97194] [AVX2] Support variable index vec_set.

2020-10-19 Thread Hongtao Liu via Gcc-patches
On Mon, Oct 19, 2020 at 5:07 PM Richard Biener
 wrote:
>
> On Mon, Oct 19, 2020 at 10:21 AM Hongtao Liu  wrote:
> >
> > Hi:
> >   It's implemented as below:
> > V setg (V v, int idx, T val)
> >
> > {
> >   V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
> >   V valv = (V){val, val, val, val, val, val, val, val};
> >   V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
> >   v = (v & ~mask) | (valv & mask);
> >   return v;
> > }
> >
> > Bootstrap is fine, regression test for i386/x86-64 backend is ok.
> > Ok for trunk?
>
> Hmm, I guess you're trying to keep the code for !AVX512BW simple
> but isn't just splitting the compare into
>
>  clow = {0, 1, 2, 3 ... } == idxv
>  chigh = {16, 17, 18, ... } == idxv;
>  cmp = {clow, chigh}
>

We also don't have 512-bits byte/word blend instructions without
TARGET_AVX512W, so how to use 512-bits cmp?
cut from i386-expand.c:
in ix86_expand_sse_movcc
 3682case E_V64QImode:
 3683  gen = gen_avx512bw_blendmv64qi; ---> TARGET_AVX512BW needed
 3684  break;
 3685case E_V32HImode:
 3686  gen = gen_avx512bw_blendmv32hi; --> TARGET_AVX512BW needed
 3687  break;
 3688case E_V16SImode:
 3689  gen = gen_avx512f_blendmv16si;
 3690  break;
 3691case E_V8DImode:
 3692  gen = gen_avx512f_blendmv8di;
 3693  break;
 3694case E_V8DFmode:

> faster, smaller and eventually even easier during expansion?
>
> +  gcc_assert (ix86_expand_vector_init_duplicate (false, mode, valv, val));
> +  gcc_assert (ix86_expand_vector_init_duplicate (false, cmp_mode,
> idxv, idx_tmp));
>
> side-effects in gcc_assert is considered bad style, use
>
>   ok = ix86_expand_vector_init_duplicate (false, mode, valv, val);
>   gcc_assert (ok);
>
> +  vec[5] = constv;
> +  ix86_expand_int_vcond (vec);
>
> this also returns a bool you probably should assert true.
>

Yes, will change.

> Otherwise thanks for tackling this.
>
> Richard.
>
> > gcc/ChangeLog:
> >
> > PR target/97194
> > * config/i386/i386-expand.c (ix86_expand_vector_set_var): New 
> > function.
> > * config/i386/i386-protos.h (ix86_expand_vector_set_var): New Decl.
> > * config/i386/predicates.md (vec_setm_operand): New predicate,
> > true for const_int_operand or register_operand under TARGET_AVX2.
> > * config/i386/sse.md (vec_set): Support both constant
> > and variable index vec_set.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/i386/avx2-vec-set-1.c: New test.
> > * gcc.target/i386/avx2-vec-set-2.c: New test.
> > * gcc.target/i386/avx512bw-vec-set-1.c: New test.
> > * gcc.target/i386/avx512bw-vec-set-2.c: New test.
> > * gcc.target/i386/avx512f-vec-set-2.c: New test.
> > * gcc.target/i386/avx512vl-vec-set-2.c: New test.
> >
> > --
> > BR,
> > Hongtao



-- 
BR,
Hongtao


Re: [PATCH] dwarf: Multi-register CFI address support

2020-10-19 Thread Jakub Jelinek via Gcc-patches
On Fri, Aug 28, 2020 at 01:04:51PM +0100, Andrew Stubbs wrote:
> This patch introduces DWARF CFI support for architectures that require
> multiple registers to hold pointers, such as the stack pointer, frame
> pointer, and return address. The motivating case is the AMD GCN architecture
> which has 64-bit address pointers, but 32-bit registers.
> 
> The current implementation permits program variables to span as many
> registers as they need, but assumes that CFI expressions will only need a
> single register for each frame value.
> 
> To be fair, the DWARF standard makes a similar assumption; the engineers
> working on LLVM and GDB, at AMD, have therefore invented some new DWARF
> operators that they plan to propose for a future standard. Only one is
> relevant here, however: DW_OP_LLVM_piece_end. (Unfortunately this clashes
> with an AArch64 extension, but I think we can cope using an alias -- only
> GCC dumps will be confusing.)

First of all, in GCC it definitely should not be called DW_OP_LLVM_*, either
we adopt it also as a GNU extension and then we should call it DW_OP_GNU_*,
or we don't and then we shouldn't emit it.

For the beginning, it would help if you posted some examples of how
the CFI info would look like on typical functions.

I fear the piece_end is just a sign of misunderstanding of the DWARF
expression vs. DWARF location description differences on the AMD side.
Because all of DW_CFA_def_cfa_expression, DW_CFA_expression and
DW_CFA_val_expression take as one of their operands a DWARF expression
rather than DWARF location description, so e.g. DW_OP_piece can't appear in
those.

And, if GCN DWARF uses 64-bit addresses, it isn't clear why one can't use
existing
DW_CFA_def_cfa_expression 
or similar (assuming you want CFA of (reg4 << 32) + reg5 + 16.

Jakub



[PATCH v2] RISC-V: Add configure option: --with-multilib-config to flexible config multi-lib settings.

2020-10-19 Thread Kito Cheng
 - Able to configure complex multi-lib rule in configure time, without modify
   any in-tree source.

 - I was consider to implmenet this into `--with-multilib-list` option,
   but I am not sure who will using that with riscv*-*-elf*, so I decide to
   using another option name for that.

 - --with-multilib-config will pass arguments to multilib-generator, and
   then using the generated multi-lib config file to build the toolchain.

  e.g. Build riscv gcc, default arch/abi is rv64gc/lp64, and build multilib
   for rv32imafd/ilp32 and rv32i/ilp32; rv32ic/ilp32 will reuse
   rv32i/ilp32.
$ /configure \
   --target=riscv64-elf \
   --with-arch=rv64gc --with-abi=lp64 \
   --with-multilib-config=rv32i-ilp32--c;rv32imafd-ilp32--

V2 Changes:

 - Fix --with-multilib-config hanling on non riscv*-*-elf* triple.

gcc/ChangeLog:

* config.gcc (riscv*-*-*): Handle --with-multilib-config.
* configure: Regen.
* configure.ac: Add --with-multilib-config.
* config/riscv/multilib-generator: Exit when parsing arch string error.
* config/riscv/t-withmultilib-config: New.
* doc/install.texi: Document --with-multilib-config.
---
 gcc/config.gcc | 32 ++
 gcc/config/riscv/multilib-generator|  9 +++-
 gcc/config/riscv/t-withmultilib-config |  2 ++
 gcc/configure  | 15 ++--
 gcc/configure.ac   |  5 
 gcc/doc/install.texi   | 30 
 6 files changed, 85 insertions(+), 8 deletions(-)
 create mode 100644 gcc/config/riscv/t-withmultilib-config

diff --git a/gcc/config.gcc b/gcc/config.gcc
index b79c544c9fa4..881e78cf84b1 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2436,11 +2436,13 @@ riscv*-*-elf* | riscv*-*-rtems*)
  tmake_file="${tmake_file} riscv/t-rtems"
  ;;
*)
- case "x${enable_multilib}" in
- xno) ;;
- xyes) tmake_file="${tmake_file} riscv/t-elf-multilib" ;;
- *) echo "Unknown value for enable_multilib"; exit 1
- esac
+ if test "x${with_multilib_config}" == xdefault; then
+ case "x${enable_multilib}" in
+ xno) ;;
+ xyes) tmake_file="${tmake_file} riscv/t-elf-multilib" ;;
+ *) echo "Unknown value for enable_multilib"; exit 1
+ esac
+ fi
esac
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
@@ -4575,6 +4577,26 @@ case "${target}" in
exit 1
;;
esac
+   # Handle --with-multilib-config.
+   if test "x${with_multilib_config}" != xdefault; then
+   case "${target}" in
+   riscv*-*-elf*)
+   if ${srcdir}/config/riscv/multilib-generator \
+   `echo ${with_multilib_config} | sed 
's/;/ /g'`\
+   > t-multilib-config;
+   then
+   tmake_file="${tmake_file} 
riscv/t-withmultilib-config"
+   else
+   echo "invalid option for 
--with-multilib-config" 1>&2
+   exit 1
+   fi
+   ;;
+   *)
+   echo "--with-multilib-config= is not supported 
for ${target}, only supported for riscv*-*-elf*" 1>&2
+   exit 1
+   ;;
+   esac
+   fi
 
# Handle --with-multilib-list.
if test "x${with_multilib_list}" != xdefault; then
diff --git a/gcc/config/riscv/multilib-generator 
b/gcc/config/riscv/multilib-generator
index f444d0ebc746..9bc3a8fbb1f4 100755
--- a/gcc/config/riscv/multilib-generator
+++ b/gcc/config/riscv/multilib-generator
@@ -103,7 +103,14 @@ def arch_canonicalize(arch):
   return new_arch
 
 for cfg in sys.argv[1:]:
-  (arch, abi, extra, ext) = cfg.split('-')
+  try:
+(arch, abi, extra, ext) = cfg.split('-')
+  except:
+print ("Invalid configure string %s, ---\n"
+   " and  can be empty, "
+   "e.g. rv32imafd-ilp32--" % cfg)
+sys.exit(1)
+
   arch = arch_canonicalize (arch)
   arches[arch] = 1
   abis[abi] = 1
diff --git a/gcc/config/riscv/t-withmultilib-config 
b/gcc/config/riscv/t-withmultilib-config
new file mode 100644
index ..1a35cc0bc655
--- /dev/null
+++ b/gcc/config/riscv/t-withmultilib-config
@@ -0,0 +1,2 @@
+# t-multilib-config will generated in build folder by configure script.
+include t-multilib-config
diff --git a/gcc/configure b/gcc/configure
index abff47d30eb9..eab70192bf46 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -972,6 +972,7 @@ with_documentation_root_url
 with_changes_

[PATCH] tree-optimization/97486 - avoid edge insertion in SLP vectorizing

2020-10-19 Thread Richard Biener
This avoids edge inserting and eventual splitting during BB SLP
vectorization for now.

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

2020-10-19  Richard Biener  

PR tree-optimization/97486
* tree-vect-slp.c (vect_slp_function): Split after stmts
ending a BB.

* gcc.dg/vect/bb-slp-pr97486.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/bb-slp-pr97486.c | 27 ++
 gcc/tree-vect-slp.c|  9 
 2 files changed, 36 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr97486.c

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr97486.c 
b/gcc/testsuite/gcc.dg/vect/bb-slp-pr97486.c
new file mode 100644
index 000..17d48a7fe69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr97486.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+struct {
+  int *end_info;
+  int *fp;
+} png_load_body_c;
+
+int *png_set_longjmp_fn();
+
+void setjmp();
+
+void png_load_body()
+{
+  int *fp;
+  int png_ptr, info_ptr, *end_info;
+  if (!fp)
+return;
+  if (png_ptr) {
+info_ptr = 0;
+end_info = png_set_longjmp_fn();
+  }
+  png_load_body_c.end_info = end_info;
+  png_load_body_c.fp = fp;
+  if (png_ptr)
+png_set_longjmp_fn();
+  setjmp(info_ptr);
+}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 20a109b5347..0f9185e6c55 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -4285,6 +4285,15 @@ vect_slp_function (function *fun)
}
   else
bbs.safe_push (bb);
+
+  /* When we have a stmt ending this block we have to insert on
+edges when inserting after it.  Avoid this for now.  */
+  if (gimple *last = last_stmt (bb))
+   if (stmt_ends_bb_p (last))
+ {
+   r |= vect_slp_bbs (bbs);
+   bbs.truncate (0);
+ }
 }
 
   if (!bbs.is_empty ())
-- 
2.26.2


RE: [PATCH PR94442] [AArch64] Redundant ldp/stp instructions emitted at -O3

2020-10-19 Thread xiezhiheng
> -Original Message-
> From: Richard Sandiford [mailto:richard.sandif...@arm.com]
> Sent: Tuesday, October 13, 2020 4:08 PM
> To: xiezhiheng 
> Cc: Richard Biener ; gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH PR94442] [AArch64] Redundant ldp/stp instructions
> emitted at -O3
> 

Cut ...

> 
> Thanks, LGTM.  Pushed to trunk.
> 

I made two separate patches for these two groups, get/set register intrinsics 
and store intrinsics.

Note: It does not matter which patch is applied first.

Bootstrapped and tested on aarch64 Linux platform.

Thanks,
Xie Zhiheng


diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d1ce634eb2b..8828cc5929d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-10-19  Zhiheng Xie  
+   Nannan Zheng  
+
+   * config/aarch64/aarch64-simd-builtins.def: Add proper FLAG
+   for get/set reg intrinsics.
+

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d1ce634eb2b..bab5c1faf3c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-10-19  Zhiheng Xie  
+   Nannan Zheng  
+
+   * config/aarch64/aarch64-simd-builtins.def: Add proper FLAG
+   for store intrinsics.
+


get_set-reg-v1.patch
Description: get_set-reg-v1.patch


store-v1.patch
Description: store-v1.patch


[PATCH] tree-optimization/97466 - remove spurious assert

2020-10-19 Thread Richard Biener
This removes an assertion that was supposed to be only for temporary
debugging.  I've also re-indented the code which I missed as well.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

2020-10-19  Richard Biener  

PR tree-optimization/97466
* tree-vect-slp.c (vect_get_and_check_slp_defs): Remove
spurious assert, re-indent.
---
 gcc/tree-vect-slp.c | 128 +---
 1 file changed, 62 insertions(+), 66 deletions(-)

diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index c3e6d67067c..a2fbbc56bcc 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -531,78 +531,74 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned 
char swap,
   oprnd = oprnd_info->ops[stmt_num];
   tree type = TREE_TYPE (oprnd);
 
- if (!types_compatible_p (oprnd_info->first_op_type, type))
+  if (!types_compatible_p (oprnd_info->first_op_type, type))
+   {
+ if (dump_enabled_p ())
+   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+"Build SLP failed: different operand types\n");
+ return 1;
+   }
+
+  /* Not first stmt of the group, check that the def-stmt/s match
+the def-stmt/s of the first stmt.  Allow different definition
+types for reduction chains: the first stmt must be a
+vect_reduction_def (a phi node), and the rest
+end in the reduction chain.  */
+  if ((!vect_def_types_match (oprnd_info->first_dt, dt)
+  && !(oprnd_info->first_dt == vect_reduction_def
+   && !STMT_VINFO_DATA_REF (stmt_info)
+   && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
+   && def_stmt_info
+   && !STMT_VINFO_DATA_REF (def_stmt_info)
+   && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
+   == REDUC_GROUP_FIRST_ELEMENT (stmt_info
+ || (!STMT_VINFO_DATA_REF (stmt_info)
+ && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
+ && ((!def_stmt_info
+  || STMT_VINFO_DATA_REF (def_stmt_info)
+  || (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
+  != REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
+ != (oprnd_info->first_dt != vect_reduction_def
+   {
+ /* Try swapping operands if we got a mismatch.  For BB
+vectorization only in case it will clearly improve things.  */
+ if (i == commutative_op && !swapped
+ && (!is_a  (vinfo)
+ || (!vect_def_types_match ((*oprnds_info)[i+1]->first_dt,
+dts[i+1])
+ && (vect_def_types_match (oprnd_info->first_dt, dts[i+1])
+ || vect_def_types_match
+  ((*oprnds_info)[i+1]->first_dt, dts[i])
{
- gcc_assert ((i != commutative_op
-  && (commutative_op == -1U
-  || i != commutative_op + 1)));
  if (dump_enabled_p ())
-   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-"Build SLP failed: different operand types\n");
- return 1;
+   dump_printf_loc (MSG_NOTE, vect_location,
+"trying swapped operands\n");
+ std::swap (dts[i], dts[i+1]);
+ std::swap ((*oprnds_info)[i]->def_stmts[stmt_num],
+(*oprnds_info)[i+1]->def_stmts[stmt_num]);
+ std::swap ((*oprnds_info)[i]->ops[stmt_num],
+(*oprnds_info)[i+1]->ops[stmt_num]);
+ swapped = true;
+ continue;
}
 
- /* Not first stmt of the group, check that the def-stmt/s match
-the def-stmt/s of the first stmt.  Allow different definition
-types for reduction chains: the first stmt must be a
-vect_reduction_def (a phi node), and the rest
-end in the reduction chain.  */
- if ((!vect_def_types_match (oprnd_info->first_dt, dt)
-  && !(oprnd_info->first_dt == vect_reduction_def
-   && !STMT_VINFO_DATA_REF (stmt_info)
-   && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
-   && def_stmt_info
-   && !STMT_VINFO_DATA_REF (def_stmt_info)
-   && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
-   == REDUC_GROUP_FIRST_ELEMENT (stmt_info
- || (!STMT_VINFO_DATA_REF (stmt_info)
- && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
- && ((!def_stmt_info
-  || STMT_VINFO_DATA_REF (def_stmt_info)
-  || (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
-  != REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
- != (oprnd_info->first_dt != vect_reduction_def
+ if (is_a  (vinfo))

Re: [PATCH] [PR target/97194] [AVX2] Support variable index vec_set.

2020-10-19 Thread Richard Biener via Gcc-patches
On Mon, Oct 19, 2020 at 10:21 AM Hongtao Liu  wrote:
>
> Hi:
>   It's implemented as below:
> V setg (V v, int idx, T val)
>
> {
>   V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
>   V valv = (V){val, val, val, val, val, val, val, val};
>   V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
>   v = (v & ~mask) | (valv & mask);
>   return v;
> }
>
> Bootstrap is fine, regression test for i386/x86-64 backend is ok.
> Ok for trunk?

Hmm, I guess you're trying to keep the code for !AVX512BW simple
but isn't just splitting the compare into

 clow = {0, 1, 2, 3 ... } == idxv
 chigh = {16, 17, 18, ... } == idxv;
 cmp = {clow, chigh}

faster, smaller and eventually even easier during expansion?

+  gcc_assert (ix86_expand_vector_init_duplicate (false, mode, valv, val));
+  gcc_assert (ix86_expand_vector_init_duplicate (false, cmp_mode,
idxv, idx_tmp));

side-effects in gcc_assert is considered bad style, use

  ok = ix86_expand_vector_init_duplicate (false, mode, valv, val);
  gcc_assert (ok);

+  vec[5] = constv;
+  ix86_expand_int_vcond (vec);

this also returns a bool you probably should assert true.

Otherwise thanks for tackling this.

Richard.

> gcc/ChangeLog:
>
> PR target/97194
> * config/i386/i386-expand.c (ix86_expand_vector_set_var): New 
> function.
> * config/i386/i386-protos.h (ix86_expand_vector_set_var): New Decl.
> * config/i386/predicates.md (vec_setm_operand): New predicate,
> true for const_int_operand or register_operand under TARGET_AVX2.
> * config/i386/sse.md (vec_set): Support both constant
> and variable index vec_set.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/avx2-vec-set-1.c: New test.
> * gcc.target/i386/avx2-vec-set-2.c: New test.
> * gcc.target/i386/avx512bw-vec-set-1.c: New test.
> * gcc.target/i386/avx512bw-vec-set-2.c: New test.
> * gcc.target/i386/avx512f-vec-set-2.c: New test.
> * gcc.target/i386/avx512vl-vec-set-2.c: New test.
>
> --
> BR,
> Hongtao


[PATCH] Simplify comparison GIMPLE IL verification

2020-10-19 Thread Richard Biener
There's an old extra allowance for same-mode pointer comparison
for which I don't see any good reason today where the only special-case
of pointers in useless_type_conversion_p is that of function/method
pointers vs. non-function/method pointers.

Bootstrapped / tested on x86_64-unknown-linux-gnu, pushed.

2020-10-19  Richard Biener  

* tree-cfg.c (verify_gimple_comparison): Drop special-case
for pointer comparison.
---
 gcc/tree-cfg.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 002560d9370..3d825c20212 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3489,14 +3489,9 @@ verify_gimple_comparison (tree type, tree op0, tree op1, 
enum tree_code code)
   /* For comparisons we do not have the operations type as the
  effective type the comparison is carried out in.  Instead
  we require that either the first operand is trivially
- convertible into the second, or the other way around.
- Because we special-case pointers to void we allow
- comparisons of pointers with the same mode as well.  */
+ convertible into the second, or the other way around.  */
   if (!useless_type_conversion_p (op0_type, op1_type)
-  && !useless_type_conversion_p (op1_type, op0_type)
-  && (!POINTER_TYPE_P (op0_type)
- || !POINTER_TYPE_P (op1_type)
- || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
+  && !useless_type_conversion_p (op1_type, op0_type))
 {
   error ("mismatching comparison operand types");
   debug_generic_expr (op0_type);
-- 
2.26.2


[PATCH] [PR target/97194] [AVX2] Support variable index vec_set.

2020-10-19 Thread Hongtao Liu via Gcc-patches
Hi:
  It's implemented as below:
V setg (V v, int idx, T val)

{
  V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
  V valv = (V){val, val, val, val, val, val, val, val};
  V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
  v = (v & ~mask) | (valv & mask);
  return v;
}

Bootstrap is fine, regression test for i386/x86-64 backend is ok.
Ok for trunk?

gcc/ChangeLog:

PR target/97194
* config/i386/i386-expand.c (ix86_expand_vector_set_var): New function.
* config/i386/i386-protos.h (ix86_expand_vector_set_var): New Decl.
* config/i386/predicates.md (vec_setm_operand): New predicate,
true for const_int_operand or register_operand under TARGET_AVX2.
* config/i386/sse.md (vec_set): Support both constant
and variable index vec_set.

gcc/testsuite/ChangeLog:

* gcc.target/i386/avx2-vec-set-1.c: New test.
* gcc.target/i386/avx2-vec-set-2.c: New test.
* gcc.target/i386/avx512bw-vec-set-1.c: New test.
* gcc.target/i386/avx512bw-vec-set-2.c: New test.
* gcc.target/i386/avx512f-vec-set-2.c: New test.
* gcc.target/i386/avx512vl-vec-set-2.c: New test.

-- 
BR,
Hongtao
From d00b6ada0fc420da7cf1e91ccbf12ee0a923d8a3 Mon Sep 17 00:00:00 2001
From: liuhongt 
Date: Mon, 19 Oct 2020 16:04:39 +0800
Subject: [PATCH] Support variable index vec_set.

gcc/ChangeLog:

	PR target/97194
	* config/i386/i386-expand.c (ix86_expand_vector_set_var): New function.
	* config/i386/i386-protos.h (ix86_expand_vector_set_var): New Decl.
	* config/i386/predicates.md (vec_setm_operand): New predicate,
	true for const_int_operand or register_operand under TARGET_AVX2.
	* config/i386/sse.md (vec_set): Support both constant
	and variable index vec_set.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/avx2-vec-set-1.c: New test.
	* gcc.target/i386/avx2-vec-set-2.c: New test.
	* gcc.target/i386/avx512bw-vec-set-1.c: New test.
	* gcc.target/i386/avx512bw-vec-set-2.c: New test.
	* gcc.target/i386/avx512f-vec-set-2.c: New test.
	* gcc.target/i386/avx512vl-vec-set-2.c: New test.
---
 gcc/config/i386/i386-expand.c | 102 ++
 gcc/config/i386/i386-protos.h |   1 +
 gcc/config/i386/predicates.md |   6 ++
 gcc/config/i386/sse.md|   9 +-
 .../gcc.target/i386/avx2-vec-set-1.c  |  49 +
 .../gcc.target/i386/avx2-vec-set-2.c  |  50 +
 .../gcc.target/i386/avx512bw-vec-set-1.c  |  20 
 .../gcc.target/i386/avx512bw-vec-set-2.c  |  44 
 .../gcc.target/i386/avx512f-vec-set-2.c   |  42 
 .../gcc.target/i386/avx512vl-vec-set-2.c  |  55 ++
 10 files changed, 375 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/avx2-vec-set-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx2-vec-set-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512bw-vec-set-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512bw-vec-set-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-vec-set-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-vec-set-2.c

diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index e6f8b314f18..63b11e5f945 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -14201,6 +14201,108 @@ ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals)
   ix86_expand_vector_init_general (mmx_ok, mode, target, vals);
 }
 
+/* Implemented as
+   V setg (V v, int idx, T val)
+   {
+ V idxv = (V){idx, idx, idx, idx, idx, idx, idx, idx};
+ V valv = (V){val, val, val, val, val, val, val, val};
+ V mask = ((V){0, 1, 2, 3, 4, 5, 6, 7} == idxv);
+ v = (v & ~mask) | (valv & mask);
+ return v;
+   }.  */
+void
+ix86_expand_vector_set_var (rtx target, rtx val, rtx idx)
+{
+  rtx vec[64];
+  machine_mode mode = GET_MODE (target);
+  machine_mode cmp_mode = mode;
+  int n_elts = GET_MODE_NUNITS (mode);
+  rtx valv,idxv,constv,idx_tmp;
+
+  /* 512-bits vector byte/word broadcast and comparison only available
+ under TARGET_AVX512BW, break 512-bits vector into two 256-bits vector
+ when without TARGET_AVX512BW.  */
+  if ((mode == V32HImode || mode == V64QImode) && !TARGET_AVX512BW)
+{
+  gcc_assert (TARGET_AVX512F);
+  rtx vhi, vlo, idx_hi;
+  machine_mode half_mode;
+  rtx (*extract_hi)(rtx, rtx);
+  rtx (*extract_lo)(rtx, rtx);
+
+  if (mode == V32HImode)
+	{
+	  half_mode = V16HImode;
+	  extract_hi = gen_vec_extract_hi_v32hi;
+	  extract_lo = gen_vec_extract_lo_v32hi;
+	}
+  else
+	{
+	  half_mode = V32QImode;
+	  extract_hi = gen_vec_extract_hi_v64qi;
+	  extract_lo = gen_vec_extract_lo_v64qi;
+	}
+
+  vhi = gen_reg_rtx (half_mode);
+  vlo = gen_reg_rtx (half_mode);
+  idx_hi = gen_reg_rtx (GET_MODE (idx));
+  emit_insn (extract_hi (vhi, target));
+  emit_insn (extract_lo (vlo, target));
+  vec[0] = idx_hi;
+  vec[1] =

PING – Re: [Patch] collect-utils.c, lto-wrapper + mkoffload: Improve -save-temps filename

2020-10-19 Thread Tobias Burnus

PING.

Attached patch has a minor change: the renamed suffixes for nvptx as
suggested by Tom
(and for considency, 'ltrans.args' → 'ltrans_args').

OK?

Tobias

On 10/13/20 9:37 PM, Tobias Burnus wrote:

This patch avoids putting some [...] files to /tmp/cc* when
-save-temps has been specified.

For my testcase, it now generates:
a.lto_wrapper_args
a.offload_args
a.xnvptx-none.args
a.xnvptx-none.gcc_args
a.xamdgcn-amdhsa.gcc_args
a.xamdgcn-amdhsa.gccnative_args
a.xamdgcn-amdhsa.ld_args


This patch adds an additional argument to collect-utils.c's
collect_execute (and is wrapper fork_execute) which, if not NULL,
it is used in 'concat (dumppfx, atsuffix, NULL);'.

This patch adds a suffix to gcc/config/gcn/mkoffload.c,
gcc/config/nvptx/mkoffload.c and gcc/lto-wrapper.c.

It does not (yet) add a suffix to gcc/collect2.c and
gcc/config/i386/intelmic-mkoffload.c but just passes
NULL; for intelmic it is not a work item as it does
not use '@' files at all.

Hopefully, there is no file which is written twice
with the same name (or otherwise overridden) and
the files names do make sense.

OK?

Tobias

PS: There is still cceBdzZk.ofldlist (via lto-plugin/lto-plugin.c),
and @/tmp/cc* in calls to lto1 and collect2. And collect2.c
passes NULL also when use_atfile is true.

-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
collect-utils.c, lto-wrapper + mkoffload: Improve -save-temps filename

gcc/ChangeLog:

	* collect-utils.c (collect_execute, fork_execute): Add at-file suffix
	argument.
	* collect-utils.h (collect_execute, fork_execute): Update prototype.
	* collect2.c (maybe_run_lto_and_relink, do_link, main, do_dsymutil):
	Update calls by passing NULL.
	* config/i386/intelmic-mkoffload.c (compile_for_target,
	generate_host_descr_file, prepare_target_image, main): Likewise.
	* config/gcn/mkoffload.c (compile_native, main): Pass at-file suffix.
	* config/nvptx/mkoffload.c (compile_native, main): Likewise.
	* lto-wrapper.c (compile_offload_image): Likewise.

 gcc/collect-utils.c  | 13 +
 gcc/collect-utils.h  |  4 ++--
 gcc/collect2.c   | 17 +
 gcc/config/gcn/mkoffload.c   |  7 ---
 gcc/config/i386/intelmic-mkoffload.c | 12 ++--
 gcc/config/nvptx/mkoffload.c |  6 --
 gcc/lto-wrapper.c| 13 +
 7 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/gcc/collect-utils.c b/gcc/collect-utils.c
index d4fa2c3d345..095db8d7547 100644
--- a/gcc/collect-utils.c
+++ b/gcc/collect-utils.c
@@ -104,7 +104,8 @@ do_wait (const char *prog, struct pex_obj *pex)
 
 struct pex_obj *
 collect_execute (const char *prog, char **argv, const char *outname,
-		 const char *errname, int flags, bool use_atfile)
+		 const char *errname, int flags, bool use_atfile,
+		 const char *atsuffix)
 {
   struct pex_obj *pex;
   const char *errmsg;
@@ -126,7 +127,10 @@ collect_execute (const char *prog, char **argv, const char *outname,
   /* Note: we assume argv contains at least one element; this is
  checked above.  */
 
-  response_file = make_temp_file ("");
+  if (!save_temps || !atsuffix)
+	response_file = make_temp_file ("");
+  else
+	response_file = concat (dumppfx, atsuffix, NULL);
 
   f = fopen (response_file, "w");
 
@@ -202,12 +206,13 @@ collect_execute (const char *prog, char **argv, const char *outname,
 }
 
 void
-fork_execute (const char *prog, char **argv, bool use_atfile)
+fork_execute (const char *prog, char **argv, bool use_atfile,
+	  const char *atsuffix)
 {
   struct pex_obj *pex;
 
   pex = collect_execute (prog, argv, NULL, NULL,
-			 PEX_LAST | PEX_SEARCH, use_atfile);
+			 PEX_LAST | PEX_SEARCH, use_atfile, atsuffix);
   do_wait (prog, pex);
 }
 
diff --git a/gcc/collect-utils.h b/gcc/collect-utils.h
index 6ff7d9d96df..482225764a9 100644
--- a/gcc/collect-utils.h
+++ b/gcc/collect-utils.h
@@ -27,10 +27,10 @@ extern void fatal_signal (int);
 
 extern struct pex_obj *collect_execute (const char *, char **,
 	const char *, const char *,
-	int, bool);
+	int, bool, const char *);
 extern int collect_wait (const char *, struct pex_obj *);
 extern void do_wait (const char *, struct pex_obj *);
-extern void fork_execute (const char *, char **, bool);
+extern void fork_execute (const char *, char **, bool, const char *);
 extern void utils_cleanup (bool);
 
 
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 6d074a79e91..3a43a5a61aa 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -644,7 +644,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
 
   /* Run the LTO back end.  */
   pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH,
-			 at_file_supplied);
+			 at_file_supplied, NULL);
   {
 	int c;
 	FILE *stream;
@@ -727,7 +727,8 @@ maybe_run_lto_and_relink (c

Re: [PATCH] Libsanitizer: merge from master.

2020-10-19 Thread Tobias Burnus

On 10/19/20 9:11 AM, Martin Liška wrote:


The change was introduced in the upstream commit:
https://github.com/llvm/llvm-project/commit/5813fca1076089c835de737834955a0fe7eb3898


Please create a LLVM bugzilla entry where you can mention that


Filled as https://bugs.llvm.org/show_bug.cgi?id=47896

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter


Re: [PATCH] Libsanitizer: merge from master.

2020-10-19 Thread Martin Liška

On 10/19/20 9:04 AM, Tobias Burnus wrote:

Hi Martin,


Hello.



this patch caused here a build fail:

gcc-mainline/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp:490:39:
 error: 'NT_X86_XSTATE' was not declared in this scope

It turned out that the used GLIBC of the cross build is 2.11.1.
And that one does not contain this #define in 'elf.h'.


Thanks for the heads up.




I wonder whether we should do something like the following – what do you think?

--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
@@ -490 +490,5 @@ typedef user_regs_struct regs_struct;
-static constexpr uptr kExtraRegs[] = {NT_X86_XSTATE, NT_FPREGSET};
+static constexpr uptr kExtraRegs[] = {
+#ifdef NT_X86_XSTATE
+ NT_X86_XSTATE,
+#endif
+ DNT_FPREGSET};

Tobias


The change was introduced in the upstream commit:
https://github.com/llvm/llvm-project/commit/5813fca1076089c835de737834955a0fe7eb3898

Please create a LLVM bugzilla entry where you can mention that and they will
hopefully merge the change. We usually upstream the changes first.

Thanks,
Martin


Re: [pushed] libsanitizer, Darwin, Bootstrap : Fix bootstrap on Darwin <= 15.

2020-10-19 Thread Martin Liška

On 10/18/20 10:00 PM, Iain Sandoe wrote:

Hi


Hello.



The latest upstream merge for libsanitizer introduces code that makes
use of some macro values that are not available in SDKs for versions
of Darwin <= 15 (macOS 10.11).

[TBH, I am a bit surprised by this, I was under the impression that upstream
  supported versions back to Darwin11 / macOS 10.7]

Add definitions for these where they are not present.


Thank you for the fix. However, I've just checked the upstream changes, and I 
can't
find a commit that would touch the mentioned macros.



tested on Darwin9 -> Darwin19 and x86_64-linux
pushed to master
thanks
Iain

P.S. I will also add this change to LOCAL_PATCHES.


I've just done that.

Thanks,
Martin



libsanitizer/ChangeLog:

* sanitizer_common/sanitizer_mac.h: Ensure that TARGET_OS_
macros are defined where the macOS SDK does not contain
them.
(TARGET_OS_OSX, TARGET_OS_IOS, TARGET_OS_TV, TARGET_OS_WATCH):
Define where needed.
---
  libsanitizer/sanitizer_common/sanitizer_mac.h | 20 +++
  1 file changed, 20 insertions(+)

diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h 
b/libsanitizer/sanitizer_common/sanitizer_mac.h
index 023071e4f11..a2c42b3bf4f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.h
+++ b/libsanitizer/sanitizer_common/sanitizer_mac.h
@@ -14,6 +14,26 @@
  
  #include "sanitizer_common.h"

  #include "sanitizer_platform.h"
+
+/* TARGET_OS_OSX is not present in SDKs before Darwin16 (macOS 10.12) use
+   TARGET_OS_MAC (we have no support for iOS in any form for these versions,
+   so there's no ambiguity).  */
+#if !defined(TARGET_OS_OSX) && TARGET_OS_MAC
+# define TARGET_OS_OSX 1
+#endif
+
+/* Other TARGET_OS_xxx are not present on earlier versions, define them to
+   0 (we have no support for them; they are not valid targets anyway).  */
+#ifndef TARGET_OS_IOS
+#define TARGET_OS_IOS 0
+#endif
+#ifndef TARGET_OS_TV
+#define TARGET_OS_TV 0
+#endif
+#ifndef TARGET_OS_WATCH
+#define TARGET_OS_WATCH 0
+#endif
+
  #if SANITIZER_MAC
  #include "sanitizer_posix.h"