Re: [PATCH] df: Don't set bbs dirty because of debug insn moves [PR104459]

2022-02-11 Thread Richard Biener via Gcc-patches
On Thu, 10 Feb 2022, Jakub Jelinek wrote:

> Hi!
> 
> As mentioned in the PR, we get -fcompare-debug failure, which is caused by
> cfg_layout_merge_blocks successfully merging two bbs where both bbs
> contained just CODE_LABEL, NOTE_INSN_BASIC_BLOCK and in the -g case both
> some debug insns at the end.  cfg_layout_merge_blocks calls
> update_bb_for_insn_chain which for the post-label insns in the second block
> (except for BARRIERs) calls df_insn_change_bb.  This function changes
> the bb of the insns and for notes just punts, but for other insns calls
> df_set_bb_dirty.  Now the problem is that because there were only debug
> insns and notes in the second block, df_set_bb_dirty is called on both
> only in the -g case and not with -g0.  df_set_bb_dirty these days
> sets both the BB_MODIFIED flag and marks the bb as dirty, and the former
> is what 6 spots in cfgcleanup.cc use in code-generation decisions,
> in this case
>   may_thread |= (target->flags & BB_MODIFIED) != 0;
> in particular.  So, with -g may_thread is true while with -g0 it is not
> and we diverge from that point onwards.
> I've thought about introducing df_set_bb_dirty_nondebug that wouldn't
> set BB_MODIFIED but would mark the bb dirty, but then I went through
> history and found changes like:
> https://gcc.gnu.org/legacy-ml/gcc-patches/2010-10/msg00059.html
> so I've also tried just not calling df_set_bb_dirty for debug insns
> at all and it passed x86_64-linux and i686-linux
> --enable-checking=yes,rtl,extra,df bootstraps/regtests, so perhaps
> that works too.
> Now that I look at it again, if we don't need those from %d to %d messages
> for debug insns in the dump files, another way to fix it would be just to
> change the very first line in the hunk from
>   if (!INSN_P (insn))
> to
>   if (!DEBUG_INSN_P (insn))
> Though, df_set_bb_dirty_nondebug which will do everything but
> set bb->flags |= BB_MODIFIED is yet another option I can test.
> Perhaps even that PR42889 was solely about those 6 decisions in cfgcleanup
> (at that point it used df_get_bb_dirty) and not about actually the
> recomputation of some of the problems causing different code generations.

OK.

Thanks,
Richard.

> 2022-02-10  Jakub Jelinek  
> 
>   PR rtl-optimization/104459
>   * df-scan.cc (df_insn_change_bb): Don't call df_set_bb_dirty when
>   moving DEBUG_INSNs between bbs.
> 
>   * gcc.dg/pr104459.c: New test.
> 
> --- gcc/df-scan.cc.jj 2022-01-18 00:18:02.720744815 +0100
> +++ gcc/df-scan.cc2022-02-10 11:10:54.039135547 +0100
> @@ -1769,13 +1769,15 @@ df_insn_change_bb (rtx_insn *insn, basic
>if (!INSN_P (insn))
>  return;
>  
> -  df_set_bb_dirty (new_bb);
> +  if (!DEBUG_INSN_P (insn))
> +df_set_bb_dirty (new_bb);
>if (old_bb)
>  {
>if (dump_file)
>   fprintf (dump_file, "  from %d to %d\n",
>old_bb->index, new_bb->index);
> -  df_set_bb_dirty (old_bb);
> +  if (!DEBUG_INSN_P (insn))
> + df_set_bb_dirty (old_bb);
>  }
>else
>  if (dump_file)
> --- gcc/testsuite/gcc.dg/pr104459.c.jj2022-02-10 11:09:38.397181836 
> +0100
> +++ gcc/testsuite/gcc.dg/pr104459.c   2022-02-10 11:09:16.049490953 +0100
> @@ -0,0 +1,38 @@
> +/* PR rtl-optimization/104459 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -funswitch-loops -fno-tree-dce -fcompare-debug -w" } */
> +
> +void
> +foo (int x, int y)
> +{
> +  unsigned int a;
> +
> +  for (;;)
> +{
> +  short int *p = (short int *) &x;
> +  unsigned int q = 0;
> +
> +  a /= 2;
> +  if (a)
> + {
> +   q -= y;
> +   while (q)
> + ;
> + }
> +
> +  if (x)
> + {
> +   for (q = 0; q != 1; q += 2)
> + {
> +   unsigned int n;
> +
> +   n = *p ? 0 : q;
> +   y += n < 1;
> +
> +   n = a || *p;
> +   if (n % x == 0)
> + y /= x;
> + }
> + }
> +}
> +}
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)


Re: [PATCH] [PATCH,v4,1/1,AARCH64][PR102768] aarch64: Add compiler support for Shadow Call Stack

2022-02-11 Thread Dan Li via Gcc-patches




On 2/10/22 01:55, Richard Sandiford wrote:


There might be a little difference:

- Using push candidates means that a register to be ignored in pop
candidates will not be emitted again during the "restore" (pop_candidates
should always be a subset of push_candidates, since popping a register
without a push might not make sense).


The push candidates are simply a subset of the saved registers though.
Similarly, the pop candidates are simply a subset of the restored registers.
So I think the requirement operates at that level: the restored registers
must be a subset of the saved registers.

In other circumstances it could have been the other way around:
there might have been a change that stopped us from saving two
registers during the allocation, but we wanted to carry on restoring
two registers during the deallocation.  I don't think there's a
reason that the push candidates *have* to be a superset of the
pop candidates (even though they are with the current change).



Oh yeah, that sounds more reasonable.


When we use "pop_candidate[12]", one more insn is emitted:

00400604 :
 400604:   a9bf53f3stp x19, x20, [sp, #-16]!
 400608:   5280mov w0, #0x0
+  40060c:   f94007f4ldr x20, [sp, #8]
 400610:   f84107f3ldr x19, [sp], #16
 400614:   d65f03c0ret

But in the case of ignoring a specific register (like scs ignores x30),
there is no difference between the two (because we always need
to explicitly specify which registers to ignore in the parameter of
aarch64_restore_callee_saves).


I think this is the correct behaviour.  If we don't want to restore
a register at all then it should be excluded from the restore list
somehow.  In your case you're doing that be using a limit of
X29_REGNUM instead of X30_REGNUM.



Got it, I'll use pop candidates in the next version.


FWIW, I did wonder whether aarch64_restore_callee_saves should be
doing the scs pop, rather than aarch64_expand_epilogue, and in an
earlier draft of the previous review I'd asked for that.  It does
seem conceptually cleaner, but in practice, it would probably have
been awkward to implement.  E.g. we'd need to explicitly stop an
LDP being formed with X30 as the second register.



Well, then I think I should keep it the same here :).


But treating scs push and scs pop as part of the register save and
restore sequences would have one advantage: it would allow the
scs push and scs pop to be shrink-wrapped.



Sorry for my limited knowledge of shrink warping, I don't think I get
it here (I tried to find a case when compiling the kernel and some
gcc test cases but I still don't have a clue.).

I see that the bitmap of LR_REGNUM is cleared in
aarch64_get_separate_components and scs push/pop are x18 based operations.

If we handle them in aarch64_restore/save_callee_saves,
could scs push/pop be shrink-wrapped in some cases?

Thanks,
Dan


Re: [PATCH] [PATCH, v4, 1/1, AARCH64][PR102768] aarch64: Add compiler support for Shadow Call Stack

2022-02-11 Thread Richard Sandiford via Gcc-patches
Dan Li  writes:
> On 2/10/22 01:55, Richard Sandiford wrote:
>>>
>>> There might be a little difference:
>>>
>>> - Using push candidates means that a register to be ignored in pop
>>> candidates will not be emitted again during the "restore" (pop_candidates
>>> should always be a subset of push_candidates, since popping a register
>>> without a push might not make sense).
>> 
>> The push candidates are simply a subset of the saved registers though.
>> Similarly, the pop candidates are simply a subset of the restored registers.
>> So I think the requirement operates at that level: the restored registers
>> must be a subset of the saved registers.
>> 
>> In other circumstances it could have been the other way around:
>> there might have been a change that stopped us from saving two
>> registers during the allocation, but we wanted to carry on restoring
>> two registers during the deallocation.  I don't think there's a
>> reason that the push candidates *have* to be a superset of the
>> pop candidates (even though they are with the current change).
>> 
>
> Oh yeah, that sounds more reasonable.
>
>>> When we use "pop_candidate[12]", one more insn is emitted:
>>>
>>> 00400604 :
>>>  400604:   a9bf53f3stp x19, x20, [sp, #-16]!
>>>  400608:   5280mov w0, #0x0
>>> +  40060c:   f94007f4ldr x20, [sp, #8]
>>>  400610:   f84107f3ldr x19, [sp], #16
>>>  400614:   d65f03c0ret
>>>
>>> But in the case of ignoring a specific register (like scs ignores x30),
>>> there is no difference between the two (because we always need
>>> to explicitly specify which registers to ignore in the parameter of
>>> aarch64_restore_callee_saves).
>> 
>> I think this is the correct behaviour.  If we don't want to restore
>> a register at all then it should be excluded from the restore list
>> somehow.  In your case you're doing that be using a limit of
>> X29_REGNUM instead of X30_REGNUM.
>> 
>
> Got it, I'll use pop candidates in the next version.
>
>> FWIW, I did wonder whether aarch64_restore_callee_saves should be
>> doing the scs pop, rather than aarch64_expand_epilogue, and in an
>> earlier draft of the previous review I'd asked for that.  It does
>> seem conceptually cleaner, but in practice, it would probably have
>> been awkward to implement.  E.g. we'd need to explicitly stop an
>> LDP being formed with X30 as the second register.
>> 
>
> Well, then I think I should keep it the same here :).
>
>> But treating scs push and scs pop as part of the register save and
>> restore sequences would have one advantage: it would allow the
>> scs push and scs pop to be shrink-wrapped.
>> 
>
> Sorry for my limited knowledge of shrink warping, I don't think I get
> it here (I tried to find a case when compiling the kernel and some
> gcc test cases but I still don't have a clue.).
>
> I see that the bitmap of LR_REGNUM is cleared in
> aarch64_get_separate_components and scs push/pop are x18 based operations.
>
> If we handle them in aarch64_restore/save_callee_saves,
> could scs push/pop be shrink-wrapped in some cases?

Yeah, I think so.  E.g. for:

void f();
int g(int x) {
if (x == 0)
return 1;
f();
return 2;
}

shrink wrapping would allow the scs push and pop to move along with the
x30 save:

g:
cbnzw0, .L9
mov w0, 1
ret
.L9:
stp x29, x30, [sp, -16]!
mov x29, sp
bl  f
mov w0, 2
ldp x29, x30, [sp], 16
ret

The idea is that aarch64_save_callee_saves would treat the scs push
as part of saving x30 (along with the normal store to the frame chain,
when used).  aarch64_restore_callee_saves would similarly treat the scs
pop as the way of restoring x30 (instead of loading from the frame chain).
This is in contrast to the current patch, where the scs push and pop are
treated as fixed parts of the prologue and epilogue instead, and where
aarch64_restore_callee_saves tries to avoid doing anything for x30.

If shrink-wrapping decides to treat x30 as a separate “component”, as it
does in the example above, then the scs push and pop would be emitted
by aarch64_process_components instead.

It would be more complex, but it would give better code.

Thanks,
Richard


[PATCH] c++: Fix up constant expression __builtin_convertvector folding [PR104472]

2022-02-11 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase ICEs, because due to the -frounding-math
fold_const_call fails, which is it returns NULL, and returning NULL from
cxx_eval* is wrong, all the callers rely on them to either return folded
value or original with *non_constant_p = true.

The following patch does that, and additionally falls through into the
default case where there is diagnostics for the !ctx->quiet case too.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2022-02-11  Jakub Jelinek  

PR c++/104472
* constexpr.cc (cxx_eval_internal_function) :
Only return fold_const_call result if it is non-NULL.  Otherwise
fall through into the default: case to return t, set *non_constant_p
and emit diagnostics if needed.

* g++.dg/cpp0x/constexpr-104472.C: New test.

--- gcc/cp/constexpr.cc.jj  2022-02-08 20:15:33.997295271 +0100
+++ gcc/cp/constexpr.cc 2022-02-10 12:33:48.243321592 +0100
@@ -1840,13 +1840,10 @@ cxx_eval_internal_function (const conste
 false, non_constant_p,
 overflow_p);
if (TREE_CODE (arg) == VECTOR_CST)
- return fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg);
-   else
- {
-   *non_constant_p = true;
-   return t;
- }
+ if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
+   return r;
   }
+  /* FALLTHRU */
 
 default:
   if (!ctx->quiet)
--- gcc/testsuite/g++.dg/cpp0x/constexpr-104472.C.jj2022-02-10 
12:44:09.869720657 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-104472.C   2022-02-10 
12:46:25.881838766 +0100
@@ -0,0 +1,9 @@
+// PR c++/104472
+// { dg-options "-O2 -frounding-math" }
+// { dg-add-options float16 }
+// { dg-require-effective-target float16 }
+
+typedef short __attribute__((__vector_size__ (16))) V;
+typedef _Float16 __attribute__((__vector_size__ (16))) F;
+
+V v = __builtin_convertvector (__builtin_convertvector ((V){5534}, F), V) < 8;

Jakub



[PATCH] middle-end/104496 - fix vectorized_internal_fn_supported_p

2022-02-11 Thread Richard Biener via Gcc-patches
This fixes vectorized_internal_fn_supported_p behavior when
facing vector types with an integer mode.

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

2022-02-11  Richard Biener  

PR middle-end/104496
* internal-fn.cc (vectorized_internal_fn_supported_p):
Bail out for integer mode vector types.

* gcc.target/i386/pr104496.c: New testcase.
---
 gcc/internal-fn.cc   |  3 ++-
 gcc/testsuite/gcc.target/i386/pr104496.c | 12 
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr104496.c

diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index 71ac483f88a..3f1fbc6c91a 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -4392,7 +4392,8 @@ vectorized_internal_fn_supported_p (internal_fn ifn, tree 
type)
 return direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED);
 
   scalar_mode smode;
-  if (!is_a  (TYPE_MODE (type), &smode))
+  if (VECTOR_TYPE_P (type)
+  || !is_a  (TYPE_MODE (type), &smode))
 return false;
 
   machine_mode vmode = targetm.vectorize.preferred_simd_mode (smode);
diff --git a/gcc/testsuite/gcc.target/i386/pr104496.c 
b/gcc/testsuite/gcc.target/i386/pr104496.c
new file mode 100644
index 000..62d3bc60281
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104496.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mgeneral-regs-only -msse" } */
+
+typedef int __attribute__((__vector_size__ (8))) V;
+V a, b;
+int c;
+
+void
+foo (void)
+{
+  b = 0 != a | b << c;
+}
-- 
2.34.1


[PATCH] nvptx: Back-end portion of a fix for PR target/104489.

2022-02-11 Thread Roger Sayle
 

This one line fix/tweak is the back-end specific change for a fix for

PR target/104489, that allows the ISA for GCC's nvptx backend to be bumped

to sm_53.  The machine-independent middle-end pieces were posted here:

https://gcc.gnu.org/pipermail/gcc-patches/2022-February/590139.html

 

This patch has been tested on nvptx-none hosted on x86_64-pc-linux-gnu,

together with the above middle-end patch and changes identical to those

described by Tom de Vries in the PR, with make and make -k check, where

the build now completes, and there are no regressions in the testsuite.

Ok for mainline?

 

 

2022-02-11  Roger Sayle  

 

gcc/ChangeLog

PR target/104489

* config/nvptx/nvptx.md (*movhf_insn): Add subregs_ok attribute.

 

 

Thanks in advance,

Roger

--

 

diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
index 92768dd..3f1a4a6 100644
--- a/gcc/config/nvptx/nvptx.md
+++ b/gcc/config/nvptx/nvptx.md
@@ -285,7 +285,8 @@
   "@
%.\\tmov.b16\\t%0, %1;
%.\\tld.b16\\t%0, %1;
-   %.\\tst.b16\\t%0, %1;")
+   %.\\tst.b16\\t%0, %1;"
+  [(set_attr "subregs_ok" "true")])
 
 (define_expand "movhf"
   [(set (match_operand:HF 0 "nonimmediate_operand" "")


[PATCH] middle-end/104497 - gimplification of vector indexing

2022-02-11 Thread Richard Biener via Gcc-patches
The following attempts to address gimplification of

   ... = VIEW_CONVERT_EXPR((i & 1) != 0 ? inv : src)[i];

which is problematic since gimplifying the base object
? inv : src produces a register temporary but GIMPLE does not
really support a register as a base for an ARRAY_REF (even
though that's not strictly validated it seems as can be seen
at -O0).  Interestingly the C++ frontend avoids this issue
by emitting the following GENERIC instead:

   ... = (i & 1) != 0 ? VIEW_CONVERT_EXPR(inv)[i] : 
VIEW_CONVERT_EXPR(src)[i];

The proposed patch below fixes things up when using an rvalue
as the base is OK by emitting a copy from a register base to a
non-register one.  The ?: as lvalue extension seems to be gone
for C, C++ again unwraps the COND_EXPR in that case.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

2022-02-11  Richard Biener  

PR middle-end/104497
* gimplify.cc (gimplify_compound_lval): Make sure the
base is a non-register if needed and possible.

* c-c++-common/torture/pr104497.c: New testcase.
---
 gcc/gimplify.cc   | 17 ++---
 gcc/testsuite/c-c++-common/torture/pr104497.c | 12 
 2 files changed, 26 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/torture/pr104497.c

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 8d676fb96c8..cdf1ccbe48b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -250,6 +250,7 @@ static enum gimplify_status gimplify_compound_expr (tree *, 
gimple_seq *, bool);
 static hash_map *oacc_declare_returns;
 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
   bool (*) (tree), fallback_t, bool);
+static void prepare_gimple_addressable (tree *, gimple_seq *);
 
 /* Shorter alias name for the above function for use in gimplify.cc
only.  */
@@ -3126,10 +3127,12 @@ gimplify_compound_lval (tree *expr_p, gimple_seq 
*pre_p, gimple_seq *post_p,
  gimplified before gimplifying the size expressions.
 
  So we do this in three steps.  First we deal with variable
- bounds, sizes, and positions, then we gimplify the base,
- then we deal with the annotations for any variables in the
- components and any indices, from left to right.  */
+ bounds, sizes, and positions, then we gimplify the base and
+ ensure it is memory if needed, then we deal with the annotations
+ for any variables in the components and any indices, from left
+ to right.  */
 
+  bool need_non_reg = false;
   for (i = expr_stack.length () - 1; i >= 0; i--)
 {
   tree t = expr_stack[i];
@@ -3165,6 +3168,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
  TREE_OPERAND (t, 3) = elmt_size;
}
}
+ need_non_reg = true;
}
   else if (TREE_CODE (t) == COMPONENT_REF)
{
@@ -3186,6 +3190,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
  TREE_OPERAND (t, 2) = offset;
}
}
+ need_non_reg = true;
}
 }
 
@@ -3196,6 +3201,12 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
fallback | fb_lvalue);
   ret = MIN (ret, tret);
 
+  /* Step 2a: if we have component references we do not support on
+ registers then make sure the base isn't a register.  Of course
+ we can only do so if an rvalue is OK.  */
+  if (need_non_reg && (fallback & fb_rvalue))
+prepare_gimple_addressable (p, pre_p);
+
   /* Step 3: gimplify size expressions and the indices and operands of
  ARRAY_REF.  During this loop we also remove any useless conversions.  */
 
diff --git a/gcc/testsuite/c-c++-common/torture/pr104497.c 
b/gcc/testsuite/c-c++-common/torture/pr104497.c
new file mode 100644
index 000..c63fc021e03
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/pr104497.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+typedef int __attribute__((vector_size(16))) vec_t;
+
+vec_t src, inv, res;
+
+void test(int i)
+{
+vec_t y={0};
+y[i] = (i & 1 ? inv : src)[i];
+res = y;
+}
-- 
2.34.1


[PATCH] middle-end: Small __builtin_clear_padding improvements

2022-02-11 Thread Jakub Jelinek via Gcc-patches
Hi!

When looking at __builtin_clear_padding today, I've noticed that
it is quite wasteful to extend the original user one argument to 3,
2 is enough.  We need to encode the original type of the first argument
because pointer conversions are useless in GIMPLE, and we need to record
a boolean whether it is for -ftrivial-auto-var-init=* or not.
But for recording the type we don't need the value (we've always used
zero) and for recording the boolean we don't need the type (we've always
used integer_type_node).
So, this patch merges the two into one.

Ok for trunk if it passes full bootstrap/regtest?

2022-02-11  Jakub Jelinek  

* tree.cc (build_common_builtin_nodes): Fix up formatting in
__builtin_clear_padding decl creation.
* gimplify.cc (gimple_add_padding_init_for_auto_var): Encode
for_auto_init in the value of 2nd BUILT_IN_CLEAR_PADDING
argument rather than in 3rd argument.
(gimplify_call_expr): Likewise.  Fix up comment formatting.
* gimple-fold.cc (gimple_fold_builtin_clear_padding): Expect
2 arguments instead of 3, take for_auto_init from the value
of 2nd argument.

--- gcc/tree.cc.jj  2022-02-11 00:19:22.436063200 +0100
+++ gcc/tree.cc 2022-02-11 12:15:00.929134203 +0100
@@ -9520,7 +9520,7 @@ build_common_builtin_nodes (void)
   local_define_builtin ("__builtin_clear_padding", ftype,
BUILT_IN_CLEAR_PADDING,
"__builtin_clear_padding",
- ECF_LEAF | ECF_NOTHROW);
+   ECF_LEAF | ECF_NOTHROW);
 }
 
   if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
--- gcc/gimplify.cc.jj  2022-02-11 00:19:22.305064981 +0100
+++ gcc/gimplify.cc 2022-02-11 12:17:22.679180223 +0100
@@ -1804,7 +1804,6 @@ gimple_add_padding_init_for_auto_var (tr
  gimple_seq *seq_p)
 {
   tree addr_of_decl = NULL_TREE;
-  bool for_auto_init = true;
   tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
 
   if (is_vla)
@@ -1821,11 +1820,8 @@ gimple_add_padding_init_for_auto_var (tr
   addr_of_decl = build_fold_addr_expr (decl);
 }
 
-  gimple *call = gimple_build_call (fn,
-   3, addr_of_decl,
-   build_zero_cst (TREE_TYPE (addr_of_decl)),
-   build_int_cst (integer_type_node,
-  (int) for_auto_init));
+  gimple *call = gimple_build_call (fn, 2, addr_of_decl,
+   build_one_cst (TREE_TYPE (addr_of_decl)));
   gimplify_seq_add_stmt (seq_p, call);
 }
 
@@ -3536,15 +3532,12 @@ gimplify_call_expr (tree *expr_p, gimple
  {
/* Remember the original type of the argument in an internal
   dummy second argument, as in GIMPLE pointer conversions are
-  useless. also mark this call as not for automatic initialization
-  in the internal dummy third argument.  */
+  useless.  Also mark this call as not for automatic
+  initialization in the internal dummy third argument.  */
p = CALL_EXPR_ARG (*expr_p, 0);
-   bool for_auto_init = false;
*expr_p
- = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
-build_zero_cst (TREE_TYPE (p)),
-build_int_cst (integer_type_node,
-   (int) for_auto_init));
+ = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
+build_zero_cst (TREE_TYPE (p)));
return GS_OK;
  }
break;
--- gcc/gimple-fold.cc.jj   2022-02-11 00:18:54.799439055 +0100
+++ gcc/gimple-fold.cc  2022-02-11 12:13:27.869417000 +0100
@@ -4879,10 +4879,10 @@ gimple_fold_builtin_clear_padding (gimpl
   gcc_assert (gimple_call_num_args (stmt) == 3);
   tree ptr = gimple_call_arg (stmt, 0);
   tree typearg = gimple_call_arg (stmt, 1);
-  /* the 3rd argument of __builtin_clear_padding is to distinguish whether
- this call is made by the user or by the compiler for automatic variable
- initialization.  */
-  bool for_auto_init = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
+  /* The 2nd argument of __builtin_clear_padding's value is used to
+ distinguish whether this call is made by the user or by the compiler
+ for automatic variable initialization.  */
+  bool for_auto_init = (bool) TREE_INT_CST_LOW (typearg);
   tree type = TREE_TYPE (TREE_TYPE (typearg));
   location_t loc = gimple_location (stmt);
   clear_padding_struct buf;

Jakub



Re: [PATCH] middle-end: Small __builtin_clear_padding improvements

2022-02-11 Thread Richard Biener via Gcc-patches
On Fri, 11 Feb 2022, Jakub Jelinek wrote:

> Hi!
> 
> When looking at __builtin_clear_padding today, I've noticed that
> it is quite wasteful to extend the original user one argument to 3,
> 2 is enough.  We need to encode the original type of the first argument
> because pointer conversions are useless in GIMPLE, and we need to record
> a boolean whether it is for -ftrivial-auto-var-init=* or not.
> But for recording the type we don't need the value (we've always used
> zero) and for recording the boolean we don't need the type (we've always
> used integer_type_node).
> So, this patch merges the two into one.
> 
> Ok for trunk if it passes full bootstrap/regtest?

OK.

Thanks,
Richard.

> 2022-02-11  Jakub Jelinek  
> 
>   * tree.cc (build_common_builtin_nodes): Fix up formatting in
>   __builtin_clear_padding decl creation.
>   * gimplify.cc (gimple_add_padding_init_for_auto_var): Encode
>   for_auto_init in the value of 2nd BUILT_IN_CLEAR_PADDING
>   argument rather than in 3rd argument.
>   (gimplify_call_expr): Likewise.  Fix up comment formatting.
>   * gimple-fold.cc (gimple_fold_builtin_clear_padding): Expect
>   2 arguments instead of 3, take for_auto_init from the value
>   of 2nd argument.
> 
> --- gcc/tree.cc.jj2022-02-11 00:19:22.436063200 +0100
> +++ gcc/tree.cc   2022-02-11 12:15:00.929134203 +0100
> @@ -9520,7 +9520,7 @@ build_common_builtin_nodes (void)
>local_define_builtin ("__builtin_clear_padding", ftype,
>   BUILT_IN_CLEAR_PADDING,
>   "__builtin_clear_padding",
> -   ECF_LEAF | ECF_NOTHROW);
> + ECF_LEAF | ECF_NOTHROW);
>  }
>  
>if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
> --- gcc/gimplify.cc.jj2022-02-11 00:19:22.305064981 +0100
> +++ gcc/gimplify.cc   2022-02-11 12:17:22.679180223 +0100
> @@ -1804,7 +1804,6 @@ gimple_add_padding_init_for_auto_var (tr
> gimple_seq *seq_p)
>  {
>tree addr_of_decl = NULL_TREE;
> -  bool for_auto_init = true;
>tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
>  
>if (is_vla)
> @@ -1821,11 +1820,8 @@ gimple_add_padding_init_for_auto_var (tr
>addr_of_decl = build_fold_addr_expr (decl);
>  }
>  
> -  gimple *call = gimple_build_call (fn,
> - 3, addr_of_decl,
> - build_zero_cst (TREE_TYPE (addr_of_decl)),
> - build_int_cst (integer_type_node,
> -(int) for_auto_init));
> +  gimple *call = gimple_build_call (fn, 2, addr_of_decl,
> + build_one_cst (TREE_TYPE (addr_of_decl)));
>gimplify_seq_add_stmt (seq_p, call);
>  }
>  
> @@ -3536,15 +3532,12 @@ gimplify_call_expr (tree *expr_p, gimple
> {
>   /* Remember the original type of the argument in an internal
>  dummy second argument, as in GIMPLE pointer conversions are
> -useless. also mark this call as not for automatic initialization
> -in the internal dummy third argument.  */
> +useless.  Also mark this call as not for automatic
> +initialization in the internal dummy third argument.  */
>   p = CALL_EXPR_ARG (*expr_p, 0);
> - bool for_auto_init = false;
>   *expr_p
> -   = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
> -  build_zero_cst (TREE_TYPE (p)),
> -  build_int_cst (integer_type_node,
> - (int) for_auto_init));
> +   = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
> +  build_zero_cst (TREE_TYPE (p)));
>   return GS_OK;
> }
>   break;
> --- gcc/gimple-fold.cc.jj 2022-02-11 00:18:54.799439055 +0100
> +++ gcc/gimple-fold.cc2022-02-11 12:13:27.869417000 +0100
> @@ -4879,10 +4879,10 @@ gimple_fold_builtin_clear_padding (gimpl
>gcc_assert (gimple_call_num_args (stmt) == 3);
>tree ptr = gimple_call_arg (stmt, 0);
>tree typearg = gimple_call_arg (stmt, 1);
> -  /* the 3rd argument of __builtin_clear_padding is to distinguish whether
> - this call is made by the user or by the compiler for automatic variable
> - initialization.  */
> -  bool for_auto_init = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
> +  /* The 2nd argument of __builtin_clear_padding's value is used to
> + distinguish whether this call is made by the user or by the compiler
> + for automatic variable initialization.  */
> +  bool for_auto_init = (bool) TREE_INT_CST_LOW (typearg);
>tree type = TREE_TYPE (TREE_TYPE (typearg));
>location_t loc = gimple_location (stmt);
>clear_padding_struct buf;
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Ger

Re: [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern.

2022-02-11 Thread Richard Biener via Gcc-patches
On Thu, Feb 10, 2022 at 7:59 AM liuhongt  wrote:
>
> >But in principle @2 or @3 could safely differ in sign, you'd then need to 
> >ensure
> >to insert sign conversions to @2/@3 to the signedness of @4/@5.
> Changed.
> >you are not testing for this anywhere?
> It's tested in vect_recog_cond_expr_convert_pattern, I've move it to match.pd
>
> >Btw, matching up the comments with the types is somewhat difficult,
> >maybe using TYPE_AB, TYPE_CD, TYPE_E instead of 1,2,3 will
> >make that easier ;)
> Changed.
> >I think the precision check should be part of the match.pd pattern.  You
> >do not check that the comparison operands are integral - I think float
> >comparisons would be OK in principle but the precision check will not
> >work there.
> Restricted to integeral type.
>
> Here's updated patch.
>
> gcc/ChangeLog:
>
> PR target/103771
> * match.pd (cond_expr_convert_p): New match.
> * tree-vect-patterns.cc (gimple_cond_expr_convert_p): Declare.
> (vect_recog_cond_expr_convert_pattern): New.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/i386/pr103771-2.c: New test.
> * gcc.target/i386/pr103771-3.c: New test.
> ---
>  gcc/match.pd   | 14 
>  gcc/testsuite/gcc.target/i386/pr103771-2.c |  8 ++
>  gcc/testsuite/gcc.target/i386/pr103771-3.c | 21 +
>  gcc/tree-vect-patterns.cc  | 96 ++
>  4 files changed, 139 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-3.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 7bbb80172fc..7386ee518a1 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -7683,3 +7683,17 @@ and,
> to the number of trailing zeroes.  */
>  (match (ctz_table_index @1 @2 @3)
>(rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3))
> +
> +(match (cond_expr_convert_p @0 @2 @3 @6)
> + (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
> +  (if (INTEGRAL_TYPE_P (type)
> +   && INTEGRAL_TYPE_P (TREE_TYPE (@2))
> +   && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +   && INTEGRAL_TYPE_P (TREE_TYPE (@3))
> +   && TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0))
> +   && TYPE_PRECISION (TREE_TYPE (@0))
> + == TYPE_PRECISION (TREE_TYPE (@2))
> +   && TYPE_PRECISION (TREE_TYPE (@0))
> + == TYPE_PRECISION (TREE_TYPE (@3))
> +   && single_use (@4)
> +   && single_use (@5
> diff --git a/gcc/testsuite/gcc.target/i386/pr103771-2.c 
> b/gcc/testsuite/gcc.target/i386/pr103771-2.c
> new file mode 100644
> index 000..962a3a74ecf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr103771-2.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=cascadelake -O3" } */
> +/* { dg-final { scan-assembler-not "kunpck" } } */
> +/* { dg-final { scan-assembler-not "kand" } } */
> +/* { dg-final { scan-assembler-not "kor" } } */
> +/* { dg-final { scan-assembler-not "kshift" } } */
> +
> +#include "pr103771.c"
> diff --git a/gcc/testsuite/gcc.target/i386/pr103771-3.c 
> b/gcc/testsuite/gcc.target/i386/pr103771-3.c
> new file mode 100644
> index 000..ef379b23b12
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr103771-3.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=cascadelake -O3" } */
> +/* { dg-final { scan-assembler-not "kunpck" } } */
> +/* { dg-final { scan-assembler-not "kand" } } */
> +/* { dg-final { scan-assembler-not "kor" } } */
> +/* { dg-final { scan-assembler-not "kshift" } } */
> +
> +typedef unsigned char uint8_t;
> +
> +static uint8_t x264_clip_uint8 (int x, unsigned int y)
> +{
> +  return x & (~255) ? (-x) >> 31 : y;
> +}
> +
> +void
> +mc_weight (uint8_t* __restrict dst, uint8_t* __restrict src,
> +  int i_width,int i_scale, unsigned int* __restrict y)
> +{
> +  for(int x = 0; x < i_width; x++)
> +dst[x] = x264_clip_uint8 (src[x] * i_scale, y[x]);
> +}
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index 2baf974627e..aa54bc8bf8b 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -924,6 +924,101 @@ vect_reassociating_reduction_p (vec_info *vinfo,
>return true;
>  }
>
> +/* match.pd function to match
> +   (cond (cmp@3 a b) (convert@1 c) (convert@2 d))
> +   with conditions:
> +   1) @1, @2, c, d, a, b are all integral type.
> +   2) There's single_use for both @1 and @2.
> +   3) a, c and d have same precision.
> +   4) c and @1 have different precision.
> +
> +   record a and c and d and @3.  */
> +
> +extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
> +
> +/* Function vect_recog_cond_expr_convert
> +
> +   Try to find the following pattern:
> +
> +   TYPE_AB A,B;
> +   TYPE_CD C,D;
> +   TYPE_E E;
> +   TYPE_E op_true = (TYPE_E) A;
> +   TYPE_E op_false = (TYPE_E) B;
> +
> +   E = C cmp D ? op_true : op_false;
> +
> +   where
> +   TYPE_PRECISION (TYPE_E)

[PATCH] [gimplefe] Add vector_mask attribute to get access to vector bools

2022-02-11 Thread Richard Biener via Gcc-patches
The following adds __attribute__((vector_mask)) to get access to
the corresponding mask type for a vector type.  The implementation
simply uses truth_type_for so creating a mask type that's not
what the target would choose as canonical, say a AVX2 style one
when AVX512VL is enabled, is not possible.  It might be possible
to provide access to that with an optional argument specifying
the precision of the bool element.  The syntax is as simple as

typedef vector_type mask_type __attribute__((vector_mask));

In theory this allows to create unit testcases for vector
lowering and ISEL.

Bootstrapped and tested on x86_64-unknown-linux-gnu, I've also
checked that it works with SVE and -msve-vector-bits=256 but
I'm unsure how to build the vector type for a variable size case.
Without -msve-vector-bits=256 the testcase is decomposed by
vector lowering (I suppose there's no good way to "decompose"
a fixed width vector to a variable length one without creating
a loop around each stmt...).

OK?

Thanks,
Richard.

2022-02-11  Richard Biener  

gcc/c-family/
* c-attribs.cc (c_common_attribute_table): Add entry for
vector_mask.
(handle_vector_mask_attribute): New.

gcc/c/
* gimple-fe.cc (c_parser_gimple_statement): Properly parse
VEC_COND_EXPRs.

gcc/testsuite/
* gcc.dg/gimplefe-48.c: New testcase.
---
 gcc/c-family/c-attribs.cc  | 36 ++
 gcc/c/gimple-parser.cc | 12 ++
 gcc/testsuite/gcc.dg/gimplefe-48.c | 19 
 3 files changed, 63 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gimplefe-48.c

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 4fb5dbd1409..3849dba90b2 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -129,6 +129,8 @@ static tree handle_unavailable_attribute (tree *, tree, 
tree, int,
  bool *);
 static tree handle_vector_size_attribute (tree *, tree, tree, int,
  bool *) ATTRIBUTE_NONNULL(3);
+static tree handle_vector_mask_attribute (tree *, tree, tree, int,
+ bool *) ATTRIBUTE_NONNULL(3);
 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
@@ -417,6 +419,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_unavailable_attribute, NULL },
   { "vector_size",   1, 1, false, true, false, true,
  handle_vector_size_attribute, NULL },
+  { "vector_mask",   0, 0, false, true, false, true,
+ handle_vector_mask_attribute, NULL },
   { "visibility",1, 1, false, false, false, false,
  handle_visibility_attribute, NULL },
   { "tls_model", 1, 1, true,  false, false, false,
@@ -4419,6 +4423,38 @@ handle_vector_size_attribute (tree *node, tree name, 
tree args,
   return NULL_TREE;
 }
 
+/* Handle a "vector_mask" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_vector_mask_attribute (tree *node, tree name, tree,
+ int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+  *no_add_attrs = true;
+  if (!flag_gimple)
+{
+  warning (OPT_Wattributes, "%qE attribute ignored", name);
+  return NULL_TREE;
+}
+
+  /* Determine the "base" type to apply the attribute to.  */
+  tree type = type_for_vector_size (*node);
+  if (!VECTOR_TYPE_P (type) || VECTOR_BOOLEAN_TYPE_P (type))
+{
+  warning (OPT_Wattributes, "%qE attribute only supported on "
+  "non-mask vector types", name);
+  return NULL_TREE;
+}
+
+  tree new_type = truth_type_for (type);
+
+  /* Build back pointers if needed.  */
+  *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
+
+  return NULL_TREE;
+}
+
 /* Handle the "nonnull" attribute.  */
 
 static tree
diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index 51ddd86f23a..31075237c98 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -860,9 +860,10 @@ c_parser_gimple_statement (gimple_parser &parser, 
gimple_seq *seq)
   if (lhs.value != error_mark_node
   && rhs.value != error_mark_node)
 {
-  /* If we parsed a comparison and the next token is a '?' then
- parse a conditional expression.  */
-  if (COMPARISON_CLASS_P (rhs.value)
+  /* If we parsed a comparison or an identifier and the next token
+is a '?' then parse a conditional expression.  */
+  if ((COMPARISON_CLASS_P (rhs.value)
+  || SSA_VAR_P (rhs.value))
  && c_parser_next_token_is (parser, CPP_QUERY))
{
  struct c_expr trueval, falseval;
@@ -874,7 +875,10 @@ c_parser_

Re: [PATCH] [gimplefe] Add vector_mask attribute to get access to vector bools

2022-02-11 Thread Richard Sandiford via Gcc-patches
Richard Biener  writes:
> The following adds __attribute__((vector_mask)) to get access to
> the corresponding mask type for a vector type.  The implementation
> simply uses truth_type_for so creating a mask type that's not
> what the target would choose as canonical, say a AVX2 style one
> when AVX512VL is enabled, is not possible.  It might be possible
> to provide access to that with an optional argument specifying
> the precision of the bool element.  The syntax is as simple as
>
> typedef vector_type mask_type __attribute__((vector_mask));
>
> In theory this allows to create unit testcases for vector
> lowering and ISEL.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, I've also
> checked that it works with SVE and -msve-vector-bits=256 but
> I'm unsure how to build the vector type for a variable size case.
> Without -msve-vector-bits=256 the testcase is decomposed by
> vector lowering (I suppose there's no good way to "decompose"
> a fixed width vector to a variable length one without creating
> a loop around each stmt...).
>
> OK?

LGTM.  As mentioned on IRC, it also seems to work for the
variable-length case.  E.g. (names now meaningless):

typedef __SVInt8_t v8si;
typedef v8si v8sib __attribute__((vector_mask));

v8si __GIMPLE (ssa) foo (v8si v1, v8si v2, v8si v3, v8si v4)
{
  v8sib tem;
  v8si resr;

__BB(2):
  tem_3 = v1_1(D) <= v2_2(D);
  resr_4 = tem_3 ? v3_5(D) : v4_6(D);
  return resr_4;
}

produces:

ptrue   p0.b, all
cmple   p0.b, p0/z, z0.b, z1.b
sel z0.b, p0, z2.b, z3.b
ret

Thanks,
Richard

>
> Thanks,
> Richard.
>
> 2022-02-11  Richard Biener  
>
> gcc/c-family/
>   * c-attribs.cc (c_common_attribute_table): Add entry for
>   vector_mask.
>   (handle_vector_mask_attribute): New.
>
> gcc/c/
>   * gimple-fe.cc (c_parser_gimple_statement): Properly parse
>   VEC_COND_EXPRs.
>
> gcc/testsuite/
>   * gcc.dg/gimplefe-48.c: New testcase.
> ---
>  gcc/c-family/c-attribs.cc  | 36 ++
>  gcc/c/gimple-parser.cc | 12 ++
>  gcc/testsuite/gcc.dg/gimplefe-48.c | 19 
>  3 files changed, 63 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/gimplefe-48.c
>
> diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
> index 4fb5dbd1409..3849dba90b2 100644
> --- a/gcc/c-family/c-attribs.cc
> +++ b/gcc/c-family/c-attribs.cc
> @@ -129,6 +129,8 @@ static tree handle_unavailable_attribute (tree *, tree, 
> tree, int,
> bool *);
>  static tree handle_vector_size_attribute (tree *, tree, tree, int,
> bool *) ATTRIBUTE_NONNULL(3);
> +static tree handle_vector_mask_attribute (tree *, tree, tree, int,
> +   bool *) ATTRIBUTE_NONNULL(3);
>  static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
> @@ -417,6 +419,8 @@ const struct attribute_spec c_common_attribute_table[] =
> handle_unavailable_attribute, NULL },
>{ "vector_size", 1, 1, false, true, false, true,
> handle_vector_size_attribute, NULL },
> +  { "vector_mask", 0, 0, false, true, false, true,
> +   handle_vector_mask_attribute, NULL },
>{ "visibility",  1, 1, false, false, false, false,
> handle_visibility_attribute, NULL },
>{ "tls_model",   1, 1, true,  false, false, false,
> @@ -4419,6 +4423,38 @@ handle_vector_size_attribute (tree *node, tree name, 
> tree args,
>return NULL_TREE;
>  }
>  
> +/* Handle a "vector_mask" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +
> +static tree
> +handle_vector_mask_attribute (tree *node, tree name, tree,
> +   int ARG_UNUSED (flags),
> +   bool *no_add_attrs)
> +{
> +  *no_add_attrs = true;
> +  if (!flag_gimple)
> +{
> +  warning (OPT_Wattributes, "%qE attribute ignored", name);
> +  return NULL_TREE;
> +}
> +
> +  /* Determine the "base" type to apply the attribute to.  */
> +  tree type = type_for_vector_size (*node);
> +  if (!VECTOR_TYPE_P (type) || VECTOR_BOOLEAN_TYPE_P (type))
> +{
> +  warning (OPT_Wattributes, "%qE attribute only supported on "
> +"non-mask vector types", name);
> +  return NULL_TREE;
> +}
> +
> +  tree new_type = truth_type_for (type);
> +
> +  /* Build back pointers if needed.  */
> +  *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
> +
> +  return NULL_TREE;
> +}
> +
>  /* Handle the "nonnull" attribute.  */
>  
>  static tree
> diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
> index 51ddd86f23a..31075237c98 100644
> --- a/gcc/c/gimple-par

Re: [PATCH] c: Add diagnostic when operator= is used as truth cond [PR25689]

2022-02-11 Thread Jason Merrill via Gcc-patches

On 2/10/22 23:01, Zhao Wei Liew wrote:

On Fri, 11 Feb 2022 at 00:14, Jason Merrill  wrote:


On 2/9/22 21:18, Zhao Wei Liew via Gcc-patches wrote:

Hi!

I wrote a patch for PR 25689, but I feel like it may not be the ideal
fix. Furthermore, there are some standing issues with the patch for
which I would like tips on how to fix them.
Specifically, there are 2 issues:
1. GCC warns about  if (a.operator=(0)). That said, this may not be a
major issue as I don't think such code is widely written.


Can you avoid this by checking CALL_EXPR_OPERATOR_SYNTAX?


Thanks! It worked. There is no longer a warning for `if (a.operator=(0))`.
The updated patch is at the bottom of this email.




2. GCC does not warn for `if (a = b)` where the default copy/move
assignment operator is used.


The code for trivial copy-assignment should be pretty recognizable, as a
MODIFY_EXPR of two MEM_REFs; it's built in build_over_call after the
comment "We must only copy the non-tail padding parts."


Ah, I see what you mean. Thanks! However, it seems like that's the case only
for non-empty classes. GCC already warns for MODIFY_EXPR, so there's
nothing we need to do there.

On the other hand, for empty classes, it seems that a COMPOUND_EXPR
is built in build_over_call under the is_really_empty_class guard (line 9791).
I don't understand the tree structure that I should identify though.
Could you give me any further explanations on that?


True, that's not very recognizable.  I suppose we could use a 
TREE_LANG_FLAG to mark that COMPOUND_EXPR, or we could leave empty 
classes alone; neither assignment nor comparison of empty classes should 
happen much in practice.



-  if (TREE_CODE (cond) == MODIFY_EXPR
+  /* Also check if this is a call to operator=().
+ Example: if (my_struct = 5) {...}
+  */
+  tree fndecl = NULL_TREE;
+  if (TREE_OPERAND_LENGTH(cond) >= 1) {
+fndecl = cp_get_callee_fndecl(TREE_OPERAND(cond, 0));


Let's use cp_get_callee_fndecl_nofold.

Please add a space before all (


Got it. May I know why it's better to use *_nofold here?


To avoid trying to do constexpr evaluation of the function operand when 
it's non-constant; in the interesting cases it won't be needed.


However, have you tested virtual operator=?


On an unrelated note, I adjusted the if condition to use INDIRECT_REF_P (cond)
instead of TREE_OPERAND_LENGTH (cond) >= 1.
I hope that's better for semantics.


Yes; REFERENCE_REF_P might be even better.


--Everything below is the updated patch-

When compiling the following code with g++ -Wparentheses, GCC does not
warn on the if statement:

struct A {
A& operator=(int);
operator bool();
};

void f(A a) {
if (a = 0); // no warning
}

This is because a = 0 is a call to operator=, which GCC does not check
for.

This patch fixes that by checking for calls to operator= when deciding
to warn.

v1: gcc:gnu.org/pipermail/gcc-patches/2022-February/590158.html
Changes since v1:
1. Use CALL_EXPR_OPERATOR_SYNTAX to avoid warnings for explicit
operator=() calls.
2. Use INDIRECT_REF_P to filter implicit operator=() calls.
3. Use cp_get_callee_fndecl_nofold.
4. Add spaces before (.

PR c/25689

gcc/cp/ChangeLog:

* semantics.cc (maybe_convert_cond): Handle the operator=() case
  as well.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wparentheses-31.C: New test.
---
  gcc/cp/semantics.cc | 18 +-
  gcc/testsuite/g++.dg/warn/Wparentheses-31.C | 11 +++
  2 files changed, 28 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/warn/Wparentheses-31.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 466d6b56871f4..b45903a6a6fde 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -836,7 +836,23 @@ maybe_convert_cond (tree cond)
/* Do the conversion.  */
cond = convert_from_reference (cond);

-  if (TREE_CODE (cond) == MODIFY_EXPR
+  /* Check for operator syntax calls to operator=().
+ Example: if (my_struct = 5) {...}
+  */
+  tree fndecl = NULL_TREE;
+  if (INDIRECT_REF_P (cond)) {


The { should go on the next line.


+tree fn = TREE_OPERAND (cond, 0);
+if (TREE_CODE (fn) == CALL_EXPR
+&& CALL_EXPR_OPERATOR_SYNTAX (fn)) {
+  fndecl = cp_get_callee_fndecl_nofold (fn);
+}
+  }
+
+  if ((TREE_CODE (cond) == MODIFY_EXPR
+|| (fndecl != NULL_TREE
+&& DECL_OVERLOADED_OPERATOR_P (fndecl)
+&& DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR)
+&& DECL_ASSIGNMENT_OPERATOR_P (fndecl)))
&& warn_parentheses
&& !warning_suppressed_p (cond, OPT_Wparentheses)
&& warning_at (cp_expr_loc_or_input_loc (cond),
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-31.C
b/gcc/testsuite/g++.dg/warn/Wparentheses-31.C
new file mode 100644
index 0..abd7476ccb461
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wparentheses-31.C
@@ -0,0 +1,11 @@
+/* PR c/25689 */
+/* { dg-options "-Wparentheses" }  */

Re: [PATCH] c++: Fix up constant expression __builtin_convertvector folding [PR104472]

2022-02-11 Thread Jason Merrill via Gcc-patches

On 2/11/22 05:13, Jakub Jelinek wrote:

Hi!

The following testcase ICEs, because due to the -frounding-math
fold_const_call fails, which is it returns NULL, and returning NULL from
cxx_eval* is wrong, all the callers rely on them to either return folded
value or original with *non_constant_p = true.

The following patch does that, and additionally falls through into the
default case where there is diagnostics for the !ctx->quiet case too.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?


OK.


2022-02-11  Jakub Jelinek  

PR c++/104472
* constexpr.cc (cxx_eval_internal_function) :
Only return fold_const_call result if it is non-NULL.  Otherwise
fall through into the default: case to return t, set *non_constant_p
and emit diagnostics if needed.

* g++.dg/cpp0x/constexpr-104472.C: New test.

--- gcc/cp/constexpr.cc.jj  2022-02-08 20:15:33.997295271 +0100
+++ gcc/cp/constexpr.cc 2022-02-10 12:33:48.243321592 +0100
@@ -1840,13 +1840,10 @@ cxx_eval_internal_function (const conste
 false, non_constant_p,
 overflow_p);
if (TREE_CODE (arg) == VECTOR_CST)
- return fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg);
-   else
- {
-   *non_constant_p = true;
-   return t;
- }
+ if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
+   return r;
}
+  /* FALLTHRU */
  
  default:

if (!ctx->quiet)
--- gcc/testsuite/g++.dg/cpp0x/constexpr-104472.C.jj2022-02-10 
12:44:09.869720657 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-104472.C   2022-02-10 
12:46:25.881838766 +0100
@@ -0,0 +1,9 @@
+// PR c++/104472
+// { dg-options "-O2 -frounding-math" }
+// { dg-add-options float16 }
+// { dg-require-effective-target float16 }
+
+typedef short __attribute__((__vector_size__ (16))) V;
+typedef _Float16 __attribute__((__vector_size__ (16))) F;
+
+V v = __builtin_convertvector (__builtin_convertvector ((V){5534}, F), V) < 8;

Jakub





Re: [PATCH 1/3, 11 backport] libstdc++: Implement P2325 changes to default-constructibility of views

2022-02-11 Thread Jonathan Wakely via Gcc-patches
On Thu, 10 Feb 2022 at 17:29, Patrick Palka via Libstdc++
 wrote:
>
> On Thu, 10 Feb 2022, Patrick Palka wrote:
>
> > Tested on x86_64-pc-linux-gnu, does this look OK for the 11 branch?
> > The backport to the 10 branch hasn't been started yet, I figured it'd
> > be good to first get the 11 backport right then base the 10 backport
> > on the 11 one.
> >
> > NB: This backport of r12-1606 to the 11 branch deliberately omits parts
> > of P2325R3 so as to maximize backward compatibility with pre-P2325R3 code.
> > In particular, we don't remove the default ctors for back_insert_iterator,
> > front_insert_iterator, ostream_iterator, ref_view and basic_istream_view.
[...]
> > @@ -670,8 +710,6 @@ namespace views
> >   using difference_type = ptrdiff_t;
> >   using value_type = _Val;
> >
> > - _Iterator() = default;
>
> Drat, this default ctor (for basic_istream_view::iterator) should not
> be removed in the backport.  Here's v2 which fixes this mistake (and
> thus the static_assert on line 77 of p2325.cc now fails as expected):


Good catch. This one's OK for gcc-11, and if it applies cleanly to
gcc-10 as-is, there too.



Re: [PATCH 2/3, 11 backport] libstdc++: Sync __cpp_lib_ranges macro defined in ranges_cmp.h

2022-02-11 Thread Jonathan Wakely via Gcc-patches
On Thu, 10 Feb 2022 at 17:01, Patrick Palka via Libstdc++
 wrote:
>
> r12-1606 bumped the value of __cpp_lib_ranges defined in ,
> but this macro is also defined in , so it needs to
> be updated there as well.
>
> PR libstdc++/103904
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/ranges_cmp.h (__cpp_lib_ranges): Adjust value.
>
> (cherry picked from commit 12bdd39755a25d237b7776153cbe03e171396fc5)

OK, thanks.


> ---
>  libstdc++-v3/include/bits/ranges_cmp.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/bits/ranges_cmp.h 
> b/libstdc++-v3/include/bits/ranges_cmp.h
> index f859a33b2c1..1d7da30dddf 100644
> --- a/libstdc++-v3/include/bits/ranges_cmp.h
> +++ b/libstdc++-v3/include/bits/ranges_cmp.h
> @@ -57,7 +57,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>  #ifdef __cpp_lib_concepts
>  // Define this here, included by all the headers that need to define it.
> -#define __cpp_lib_ranges 201911L
> +#define __cpp_lib_ranges 202106L
>
>  namespace ranges
>  {
> --
> 2.35.1.102.g2b9c120970
>



Re: [PATCH 3/3, 11 backport] libstdc++: invalid default init in _CachedPosition [PR101231]

2022-02-11 Thread Jonathan Wakely via Gcc-patches
On Thu, 10 Feb 2022 at 16:58, Patrick Palka via Libstdc++
 wrote:
>
> The primary template for _CachedPosition is a dummy implementation for
> non-forward ranges, the iterators for which generally can't be cached.
> Because this implementation doesn't actually cache anything, _M_has_value
> is defined to be false and so calls to _M_get (which are always guarded
> by _M_has_value) are unreachable.
>
> Still, to suppress a "control reaches end of non-void function" warning
> I made _M_get return {}, but after P2325 input iterators are no longer
> necessarily default constructible so this workaround now breaks valid
> programs.
>
> This patch fixes this by instead using __builtin_unreachable to squelch
> the warning.

OK

>
> PR libstdc++/103904
> PR libstdc++/101231
>
> libstdc++-v3/ChangeLog:
>
> * include/std/ranges (_CachedPosition::_M_get): For non-forward
> ranges, just call __builtin_unreachable.
> * testsuite/std/ranges/istream_view.cc (test05): New test.
>
> (cherry picked from commit 1af937eb6246ad7f63ebff03590e9eede33aca81)
> ---
>  libstdc++-v3/include/std/ranges   |  2 +-
>  libstdc++-v3/testsuite/std/ranges/istream_view.cc | 12 
>  2 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
> index bf6cfae2a6e..a4228ba9aa0 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -1221,7 +1221,7 @@ namespace views::__adaptor
> _M_get(const _Range&) const
> {
>   __glibcxx_assert(false);
> - return {};
> + __builtin_unreachable();
> }
>
> constexpr void
> diff --git a/libstdc++-v3/testsuite/std/ranges/istream_view.cc 
> b/libstdc++-v3/testsuite/std/ranges/istream_view.cc
> index af76a1ab39e..f5c0c2a6bb0 100644
> --- a/libstdc++-v3/testsuite/std/ranges/istream_view.cc
> +++ b/libstdc++-v3/testsuite/std/ranges/istream_view.cc
> @@ -83,6 +83,17 @@ test04()
>static_assert(!std::forward_iterator);
>  }
>
> +void
> +test05()
> +{
> +  // PR libstdc++/101231
> +  auto words = std::istringstream{"42"};
> +  auto is = ranges::istream_view(words);
> +  auto r = is | views::filter([](auto) { return true; });
> +  for (auto x : r)
> +;
> +}
> +
>  void
>  test06()
>  {
> @@ -99,5 +110,6 @@ main()
>test02();
>test03();
>test04();
> +  test05();
>test06();
>  }
> --
> 2.35.1.102.g2b9c120970
>



Re: [PATCH] [PATCH,v4,1/1,AARCH64][PR102768] aarch64: Add compiler support for Shadow Call Stack

2022-02-11 Thread Dan Li via Gcc-patches




On 2/11/22 01:53, Richard Sandiford wrote:

Dan Li  writes:

On 2/10/22 01:55, Richard Sandiford wrote:



But treating scs push and scs pop as part of the register save and
restore sequences would have one advantage: it would allow the
scs push and scs pop to be shrink-wrapped.



Sorry for my limited knowledge of shrink warping, I don't think I get
it here (I tried to find a case when compiling the kernel and some
gcc test cases but I still don't have a clue.).

I see that the bitmap of LR_REGNUM is cleared in
aarch64_get_separate_components and scs push/pop are x18 based operations.

If we handle them in aarch64_restore/save_callee_saves,
could scs push/pop be shrink-wrapped in some cases?


Yeah, I think so.  E.g. for:

void f();
int g(int x) {
 if (x == 0)
 return 1;
 f();
 return 2;
}

shrink wrapping would allow the scs push and pop to move along with the
x30 save:

g:
 cbnzw0, .L9
 mov w0, 1
 ret
.L9:
 stp x29, x30, [sp, -16]!
 mov x29, sp
 bl  f
 mov w0, 2
 ldp x29, x30, [sp], 16
 ret



Thanks Richard, (to make sure I understand correctly :)) I think
it means that the current patch could do a "shrink-wapping", but
the X30 could not be treat as a "component", now it could gen code
like:

g:
cbnzw0, .L9
mov w0, 1
ret
.L9:
str x30, [x18], 8
stp x29, x30, [sp, -16]!
mov x29, sp
bl  f
ldr x30, [x18, -8]!
mov w0, 2
ldr x29, [sp], 16
ret


The idea is that aarch64_save_callee_saves would treat the scs push
as part of saving x30 (along with the normal store to the frame chain,
when used).  aarch64_restore_callee_saves would similarly treat the scs
pop as the way of restoring x30 (instead of loading from the frame chain).
This is in contrast to the current patch, where the scs push and pop are
treated as fixed parts of the prologue and epilogue instead, and where
aarch64_restore_callee_saves tries to avoid doing anything for x30.

If shrink-wrapping decides to treat x30 as a separate “component”, as it
does in the example above, then the scs push and pop would be emitted
by aarch64_process_components instead.

It would be more complex, but it would give better code.



Following your idea, I made a poc to add x30 in component bitmap:

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 35f6f64f5b2..fc9b5e7af54 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -8359,7 +8359,7 @@ aarch64_get_separate_components (void)
   if (reg1 != INVALID_REGNUM)
 bitmap_clear_bit (components, reg1);
 
-  bitmap_clear_bit (components, LR_REGNUM);

   bitmap_clear_bit (components, SP_REGNUM);
 
   return components;

@@ -8396,7 +8396,7 @@ aarch64_components_for_bb (basic_block bb)
   /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets.  */
   for (unsigned regno = 0; regno <= LAST_SAVED_REGNUM; regno++)
 if (!fixed_regs[regno]
-   && !crtl->abi->clobbers_full_reg_p (regno)
+   && (!crtl->abi->clobbers_full_reg_p (regno) || regno == R30_REGNUM)
&& (TEST_HARD_REG_BIT (extra_caller_saves, regno)
|| bitmap_bit_p (in, regno)
|| bitmap_bit_p (gen, regno)

And with a test code compiled with -fno-omit-frame-pointer:

void f();
int g(int x) {
if (x == 0) {
__asm__ ("":::"x19", "x20");
return 1;
}
f();
return 2;
}

Then it seems X30 is treat as a "component" (the test
result of aarch64.exp also seems fine).

g:
stp x19, x20, [sp, -32]!
cbnzw0, .L2
mov w0, 1
ldp x19, x20, [sp], 32
ret
.L2:
str x30, [sp, 16]
bl  f
ldr x30, [sp, 16]
mov w0, 2
ldp x19, x20, [sp], 32
ret

And I think maybe we could handle this through three patches:
1.Keep current patch (a V5) unchanged for scs.
2.Add shrink-warpping for X30:
logically this might be a separate topic, and I think more testing
might be needed here (Well, I'm a little worried about if there might
be other effects, since I just read this part of the code roughly
yesterday).
3.Add scs push/pop to shrink-wrapping (and maybe we can do the same for
the PAC code in pro/epilogue, since it's also the operation of the X30).

Thanks,
Dan


[committed] analyzer: ignore uninitialized uses of empty types [PR104274]

2022-02-11 Thread David Malcolm via Gcc-patches
PR analyzer/104274 reports a false positive from
-Wanalyzer-use-of-uninitialized-value on hppa when passing
an empty struct as a function parameter.

pa_pass_by_reference returns true for empty structs, so the
call is turned into:

  struct empty arg.0;
  arg.0 = arg
  called_function (arg.0);

by gimplify_parameters.

However, gimplify_modify_expr discards assignments statments
of empty types, so that we end up with:

  struct empty arg.0;
  called_function (arg.0);

which the analyzer considers to be a use of uninitialized "arg.0";

Given that gimplify_modify_expr will discard any assignments to
such types, it seems simplest for -Wanalyzer-use-of-uninitialized-value
to ignore values of empty types.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-7199-gcc68ad87014a331399ccb2528db3bf47fabe6f72.

gcc/analyzer/ChangeLog:
PR analyzer/104274
* region-model.cc (region_model::check_for_poison): Ignore
uninitialized uses of empty types.

gcc/testsuite/ChangeLog:
PR analyzer/104274
* gcc.dg/analyzer/torture/empty-struct-1.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/region-model.cc   | 10 +-
 .../gcc.dg/analyzer/torture/empty-struct-1.c   | 18 ++
 2 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/empty-struct-1.c

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index f8f19769258..e659cf03a86 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -843,13 +843,21 @@ region_model::check_for_poison (const svalue *sval,
 
   if (const poisoned_svalue *poisoned_sval = sval->dyn_cast_poisoned_svalue ())
 {
+  enum poison_kind pkind = poisoned_sval->get_poison_kind ();
+
+  /* Ignore uninitialized uses of empty types; there's nothing
+to initialize.  */
+  if (pkind == POISON_KIND_UNINIT
+ && sval->get_type ()
+ && is_empty_type (sval->get_type ()))
+   return sval;
+
   /* If we have an SSA name for a temporary, we don't want to print
 ''.
 Poisoned values are shared by type, and so we can't reconstruct
 the tree other than via the def stmts, using
 fixup_tree_for_diagnostic.  */
   tree diag_arg = fixup_tree_for_diagnostic (expr);
-  enum poison_kind pkind = poisoned_sval->get_poison_kind ();
   const region *src_region = NULL;
   if (pkind == POISON_KIND_UNINIT)
src_region = get_region_for_poisoned_expr (expr);
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/empty-struct-1.c 
b/gcc/testsuite/gcc.dg/analyzer/torture/empty-struct-1.c
new file mode 100644
index 000..1f1c07a25f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/empty-struct-1.c
@@ -0,0 +1,18 @@
+struct empty {};
+
+struct empty g;
+
+extern void sink (struct empty e);
+
+void test_1 (struct empty a)
+{
+  sink (a); /* { dg-bogus "uninit" } */
+}
+void test_2 ()
+{
+  struct empty a, b;
+  b = a;
+  g = b;
+  sink (b); /* { dg-bogus "uninit" } */
+  /* ...as there's nothing to initialize.  */
+}
-- 
2.26.3



Re: [PATCH, 11 backport] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082]

2022-02-11 Thread Bill Schmidt via Gcc-patches
Fine.  I withdraw the patch request, and will remove my name from
the bugzilla.  Somebody else can deal with it.  I have more important
things to worry about.

Bill

On 2/11/22 1:31 AM, Segher Boessenkool wrote:
> Hi!
>
> On Thu, Feb 10, 2022 at 04:28:02PM -0600, Bill Schmidt wrote:
>> On 2/10/22 4:11 PM, Segher Boessenkool wrote:
 No, trunk has this, for example:

   const signed int __builtin_altivec_vclzlsbb_v16qi (vsc);
     VCLZLSBB_V16QI vctzlsbb_v16qi {endian}
>>> I see this on trunk:
>>>
>>>   const signed int __builtin_altivec_vclzlsbb_v16qi (vsc);
>>> VCLZLSBB_V16QI vclzlsbb_v16qi {}
>>>
>>> Oh, you changed it?  Please fix it, then.
>> In a patch you approved, yes.
> Yes, I missed it.  That is not an argument that it would be good or
> should not be change.
>
>> I don't really understand why you want
>> it changed now.
> Because it is wrong.
>
>> You must not be looking at the most recent trunk revision.
> Indeed I haven't been able to update master for a week or so, it does
> not bootstrap, as we have talked about.
>
 Throughout the new builtin infrastructure, the defaults are set for
 little-endian, and the "endian" flag changes behavior for big-endian.
>>> That is a big mistake.  There are many machine instructions  that are
>>> *always* big-endian (most even!), and none that are always
>>> little-endian.  So this should be fixed, sooner rather than later :-(
>> That does not seem like a good idea in stage 4 to me.  That requires
>> yet another patch to reverse a bunch of other things unnecessarily.
> Things that were added in stage 4, a few days ago even.  Things that are
> broken and wrong.  Things I do not want to have to release with and deal
> with all the pain of having broken released versions.
>
>> This is a purely arbitrary choice.
> No, it is not.  It flies in the face of consistency.
>
>> The endian flag is only used when
>> a built-in function must have one behavior for big-endian, and another
>> behavior for little-endian.  Which one is chosen as the default is
>> absolutely arbitrary.
> The one that corresponds to the name should be the default.  I don't see
> how you can argue otherwise.
>
>> When we expand the built-in we will either
>> accept the default or change to the other.  The existence of machine
>> instructions that are only big-endian has nothing to do with the case;
>> what matters is the existence of built-in functions that have two
>> behaviors.
> Everything in our backend is BE by default, just like everything in the
> architecture is.  Yes, LE works almost as well (or just as well) in most
> places, but everything is named assuming BE.  This consistency is hugely
> important, without it the reader will not understand things as well and
> as easily.
>
 That's something that should be fixed, I guess, but it's orthogonal
 to this patch.
>>> Fixing it later is more work :-(
>>>
>>> Please at least open a bug report for it.
>> I can do that.
> Thanks!
>
>>> The other things need fixing before the patch is okay.
>> I'd ask you to reconsider, as explained above.
> It is purely an implementation thing, and it is completely trivial to
> do.  If you truly are afraid of breaking things (you should not be), it
> is marginally acceptable to do this as the very first thing in stage 1.
>
> Consistency matters.  Naming matters.  These shape how we think about
> things.
>
>
> Segher


Re: [PATCH] [PATCH, v4, 1/1, AARCH64][PR102768] aarch64: Add compiler support for Shadow Call Stack

2022-02-11 Thread Richard Sandiford via Gcc-patches
Dan Li  writes:
> On 2/11/22 01:53, Richard Sandiford wrote:
>> Dan Li  writes:
>>> On 2/10/22 01:55, Richard Sandiford wrote:
>
 But treating scs push and scs pop as part of the register save and
 restore sequences would have one advantage: it would allow the
 scs push and scs pop to be shrink-wrapped.

>>>
>>> Sorry for my limited knowledge of shrink warping, I don't think I get
>>> it here (I tried to find a case when compiling the kernel and some
>>> gcc test cases but I still don't have a clue.).
>>>
>>> I see that the bitmap of LR_REGNUM is cleared in
>>> aarch64_get_separate_components and scs push/pop are x18 based operations.
>>>
>>> If we handle them in aarch64_restore/save_callee_saves,
>>> could scs push/pop be shrink-wrapped in some cases?
>> 
>> Yeah, I think so.  E.g. for:
>> 
>> void f();
>> int g(int x) {
>>  if (x == 0)
>>  return 1;
>>  f();
>>  return 2;
>> }
>> 
>> shrink wrapping would allow the scs push and pop to move along with the
>> x30 save:
>> 
>> g:
>>  cbnzw0, .L9
>>  mov w0, 1
>>  ret
>> .L9:
>>  stp x29, x30, [sp, -16]!
>>  mov x29, sp
>>  bl  f
>>  mov w0, 2
>>  ldp x29, x30, [sp], 16
>>  ret
>> 
>
> Thanks Richard, (to make sure I understand correctly :)) I think
> it means that the current patch could do a "shrink-wapping", but
> the X30 could not be treat as a "component", now it could gen code
> like:
>
> g:
>  cbnzw0, .L9
>  mov w0, 1
>  ret
> .L9:
>  str x30, [x18], 8
>  stp x29, x30, [sp, -16]!
>  mov x29, sp
>  bl  f
>  ldr x30, [x18, -8]!
>  mov w0, 2
>  ldr x29, [sp], 16
>  ret

Ah, right, sorry.  I'd forgotten that this happened independently
of the components stuff (and has to, since like you say, we don't
treat LR_REGNUM as a separable component).

>> The idea is that aarch64_save_callee_saves would treat the scs push
>> as part of saving x30 (along with the normal store to the frame chain,
>> when used).  aarch64_restore_callee_saves would similarly treat the scs
>> pop as the way of restoring x30 (instead of loading from the frame chain).
>> This is in contrast to the current patch, where the scs push and pop are
>> treated as fixed parts of the prologue and epilogue instead, and where
>> aarch64_restore_callee_saves tries to avoid doing anything for x30.
>> 
>> If shrink-wrapping decides to treat x30 as a separate “component”, as it
>> does in the example above, then the scs push and pop would be emitted
>> by aarch64_process_components instead.
>> 
>> It would be more complex, but it would give better code.
>> 
>
> Following your idea, I made a poc to add x30 in component bitmap:
>
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 35f6f64f5b2..fc9b5e7af54 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -8359,7 +8359,7 @@ aarch64_get_separate_components (void)
> if (reg1 != INVALID_REGNUM)
>   bitmap_clear_bit (components, reg1);
>   
> -  bitmap_clear_bit (components, LR_REGNUM);
> bitmap_clear_bit (components, SP_REGNUM);
>   
> return components;
> @@ -8396,7 +8396,7 @@ aarch64_components_for_bb (basic_block bb)
> /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets.  */
> for (unsigned regno = 0; regno <= LAST_SAVED_REGNUM; regno++)
>   if (!fixed_regs[regno]
> -   && !crtl->abi->clobbers_full_reg_p (regno)
> +   && (!crtl->abi->clobbers_full_reg_p (regno) || regno == R30_REGNUM)
>  && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
>  || bitmap_bit_p (in, regno)
>  || bitmap_bit_p (gen, regno)
>
> And with a test code compiled with -fno-omit-frame-pointer:
>
> void f();
> int g(int x) {
>  if (x == 0) {
>  __asm__ ("":::"x19", "x20");
>  return 1;
>  }
>  f();
>  return 2;
> }
>
> Then it seems X30 is treat as a "component" (the test
> result of aarch64.exp also seems fine).
>
> g:
>  stp x19, x20, [sp, -32]!
>  cbnzw0, .L2
>  mov w0, 1
>  ldp x19, x20, [sp], 32
>  ret
> .L2:
>  str x30, [sp, 16]
>  bl  f
>  ldr x30, [sp, 16]
>  mov w0, 2
>  ldp x19, x20, [sp], 32
>  ret
>
> And I think maybe we could handle this through three patches:
> 1.Keep current patch (a V5) unchanged for scs.
> 2.Add shrink-warpping for X30:
> logically this might be a separate topic, and I think more testing
> might be needed here (Well, I'm a little worried about if there might
> be other effects, since I just read this part of the code roughly
> yesterday).
> 3.Add scs push/pop to shrink-wrapping (and maybe we can do the same for
> the PAC code in pro/epilogue, since it's also the operation of the X30).

Yeah, 

[committed] [PR104400] LRA: Modify exclude start hard register calculation for insn alternative

2022-02-11 Thread Vladimir Makarov via Gcc-patches

The following patch solves

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104400

The patch was successfully tested and bootstrapped on x86-64 and aarch64.
commit 274a4d29421e73c9b40c1641986c6ed904e20184
Author: Vladimir N. Makarov 
Date:   Fri Feb 11 09:52:14 2022 -0500

[PR104400] LRA: Modify exclude start hard register calculation for insn alternative

v850 target has an interesting insn alternative constraint 'e!r' where e
denotes even general regs and e is a subset of r.  We cannot just make
union of exclude start hard registers for e and r and should use only
exclude start hard registers of r.  The following patch implements this.

gcc/ChangeLog:

PR rtl-optimization/104400
* lra-constraints.cc (process_alt_operands): Don't make union of
this_alternative_exclude_start_hard_regs when reg class in insn
alternative covers other reg classes in the same alternative.

gcc/testsuite/ChangeLog:

PR rtl-optimization/104400
* gcc.target/v850/pr104400.c: New.
* gcc.target/v850/v850.exp: New.

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 9cee17479ba..fdff9e0720a 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2498,9 +2498,15 @@ process_alt_operands (int only_alternative)
 		  if (mode == BLKmode)
 		break;
 		  this_alternative = reg_class_subunion[this_alternative][cl];
+		  if (hard_reg_set_subset_p (this_alternative_set,
+	 reg_class_contents[cl]))
+		this_alternative_exclude_start_hard_regs
+		  = ira_exclude_class_mode_regs[cl][mode];
+		  else if (!hard_reg_set_subset_p (reg_class_contents[cl],
+		   this_alternative_set))
+		this_alternative_exclude_start_hard_regs
+		  |= ira_exclude_class_mode_regs[cl][mode];
 		  this_alternative_set |= reg_class_contents[cl];
-		  this_alternative_exclude_start_hard_regs
-		|= ira_exclude_class_mode_regs[cl][mode];
 		  if (costly_p)
 		{
 		  this_costly_alternative
diff --git a/gcc/testsuite/gcc.target/v850/pr104400.c b/gcc/testsuite/gcc.target/v850/pr104400.c
new file mode 100644
index 000..5d78a77345c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/v850/pr104400.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mv850e3v5" } */
+
+double frob (double r)
+{
+r = -r;
+return r;
+}
diff --git a/gcc/testsuite/gcc.target/v850/v850.exp b/gcc/testsuite/gcc.target/v850/v850.exp
new file mode 100644
index 000..4e8c745a0b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/v850/v850.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# .
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an v850 target.
+if ![istarget v850*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish


Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Qing Zhao via Gcc-patches
Hi, Jason,

On Feb 9, 2022, at 3:01 PM, Qing Zhao via Gcc-patches 
mailto:gcc-patches@gcc.gnu.org>> wrote:



On Feb 9, 2022, at 12:23 PM, Jason Merrill 
mailto:ja...@redhat.com>> wrote:

On 2/9/22 10:51, Qing Zhao wrote:
On Feb 8, 2022, at 4:20 PM, Jason Merrill 
mailto:ja...@redhat.com>> wrote:

On 2/8/22 15:11, Qing Zhao wrote:
Hi,
This is the patch to fix PR101515 (ICE in pp_cxx_unqualified_id, at  
cp/cxx-pretty-print.c:128)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101515
It's possible that the TYPE_NAME of a record_type is NULL, therefore when
printing the TYPE_NAME, we should check and handle this special case.
Please see the comment of pr101515 for more details.
The fix is very simple, just check and special handle cases when TYPE_NAME is 
NULL.
Bootstrapped and regression tested on both x86 and aarch64, no issues.
Okay for commit?
Thanks.
Qing
=
From f37ee8d21b80cb77d8108cb97a487c84c530545b Mon Sep 17 00:00:00 2001
From: Qing Zhao 
Date: Tue, 8 Feb 2022 16:10:37 +
Subject: [PATCH] Fix PR 101515 ICE in pp_cxx_unqualified_id, at
cp/cxx-pretty-print.c:128.
It's possible that the TYPE_NAME of a record_type is NULL, therefore when
printing the TYPE_NAME, we should check and handle this special case.
gcc/cp/ChangeLog:
* cxx-pretty-print.cc (pp_cxx_unqualified_id): Check and handle
the case when TYPE_NAME is NULL.
gcc/testsuite/ChangeLog:
* g++.dg/pr101515.C: New test.
---
gcc/cp/cxx-pretty-print.cc  |  5 -
gcc/testsuite/g++.dg/pr101515.C | 25 +
2 files changed, 29 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/pr101515.C
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index 4f9a090e520d..744ed0add5ba 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -171,7 +171,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
case ENUMERAL_TYPE:
case TYPENAME_TYPE:
case UNBOUND_CLASS_TEMPLATE:
-  pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+  if (TYPE_NAME (t))
+ pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+  else
+ pp_string (pp, "");

Hmm, but it's not an unnamed class, it's a pointer to member function type, and 
it would be better to avoid dumping compiler internal representations like the 
__pfn field name.
Yes, It’s not an unnamed class, but the ICE happened when try to print the 
compiler generated member function type “__ptrmemfunc_type”, whose TYPE_NAME is 
NULLed during building this type in c++ FE and the c++ FE does not handle the 
case when TYPE_NAME is NULL correctly.
So, there are two levels of issues:
1. The first level issue is that the current C++ FE does not handle the case 
TYPE_NAME being NULL correctly, this is indeed a bug in the current code and 
should be fixed as in the current patch.

Sure, we might as well make this code more robust.  But we can do better than 
 if we check TYPE_PTRMEMFUNC_P.
Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? Print 
nothing or some special string?

2. The second level issue is what you suggested in the above, shall we print 
the “compiler generated internal type”  to the user? And I agree with you that 
it might not be a good idea to print such compiler internal names to the user.  
Are we do this right now in general? (i.e, check whether the current TYPE is a 
source level TYPE or a compiler internal TYPE, and then only print out the name 
of TYPE for the source level TYPE?) and is there a bit in the TYPE to 
distinguish whether a TYPE is user -level type or a compiler generated internal 
type?

I think the real problem comes sooner, when c_fold_indirect_ref_for_warn turns 
a MEM_REF with RECORD_TYPE into a COMPONENT_REF with POINTER_TYPE.

What’s the major issue for this transformation? (I will study this in more 
details).

We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a whole) and 
it gave us back a POINTER_TYPE instead (the __pmf member). Folding shouldn't 
change the type of an expression like that.

Yes, this is not correct transformation, will study in more detail and try to 
fix it.

After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which triggered the 
ICE and introduced the new routine “c_fold_indirect_ref_for_warn”), from my 
understanding,  the above transformation from a RECORD_TYPE (the PMF as a 
whole) to POINTER_TYPE (the __pmf member) is what the function intended to do 
as following:

1823 static tree
1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
1825   offset_int &off)
1826 {
…
1870   /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
1871   else if (TREE_CODE (optype) == RECORD_TYPE)
1872 {
1873   for (tree field = TYPE_FIELDS (optype);
1874field; field = DECL_CHAIN (field))
1875 if (TREE_CODE (field) == FIELD_DECL
…
1886 if (upos <= off && off < upos + el_sz)
1887   {
1888 tree cop = bu

[PATCH] libstdc++: Back out some changes in P2325R3 backport [PR103904]

2022-02-11 Thread Patrick Palka via Gcc-patches
In the P2325R3 backport r11-9555 the relaxation of the constraints on
the partial specialization of __box (which is semantically equivalent to
the primary template, only more space efficient) means some
specializations of __box will now use the partial specialization instead
of the primary template, which (IIUC) constitutes an ABI change unsuitable
for a release branch.  This patch reverts this constraint change, which
isn't needed for correctness anyway.

Similarly the change to use __non_propagating_cache for the data member
split_view::_M_current (so that it's always default-initializable) also
constitutes an unsuitable ABI change.  This patch reverts this change
too, and instead further constrains split_view's default constructor to
require that we can default-initialize _M_current.

PR libstdc++/103904

libstdc++-v3/ChangeLog:

* include/std/ranges (__detail::__box): Revert r11-9555 changes
to the constraints on the partial specialization and the
now-unnecessary member additions.
(__detail::__non_propagating_cache::operator=): Remove
now-unused overload added by r11-9555.
(split_view::_OuterIter::__current): Adjust after reverting the
r11-9555 change to the type of _M_current.
(split_view::_M_current): Revert r11-9555 change to its type.
(split_view::split_view): Constrain the default ctor further.
* testsuite/std/ranges/adaptors/detail/copyable_box.cc: Disable
now-irrelevant test for the r11-9555 changes to the partial
specialization of __box.
---
 libstdc++-v3/include/std/ranges   | 54 +++
 .../ranges/adaptors/detail/copyable_box.cc|  4 ++
 2 files changed, 10 insertions(+), 48 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 03c6275801f..bf31e4be500 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -144,8 +144,7 @@ namespace ranges
 // std::optional.  It provides just the subset of the primary template's
 // API that we currently use.
 template<__boxable _Tp>
-  requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
-&& is_nothrow_copy_constructible_v<_Tp>)
+  requires copyable<_Tp>
   struct __box<_Tp>
   {
   private:
@@ -174,38 +173,6 @@ namespace ranges
  : _M_value(std::forward<_Args>(__args)...)
  { }
 
-   __box(const __box&) = default;
-   __box(__box&&) = default;
-   __box& operator=(const __box&) requires copyable<_Tp> = default;
-   __box& operator=(__box&&) requires copyable<_Tp> = default;
-
-   // When _Tp is nothrow_copy_constructible but not copy_assignable,
-   // copy assignment is implemented via destroy-then-copy-construct.
-   constexpr __box&
-   operator=(const __box& __that) noexcept
-   {
- static_assert(is_nothrow_copy_constructible_v<_Tp>);
- if (this != std::__addressof(__that))
-   {
- _M_value.~_Tp();
- std::construct_at(std::__addressof(_M_value), *__that);
-   }
- return *this;
-   }
-
-   // Likewise for move assignment.
-   constexpr __box&
-   operator=(__box&& __that) noexcept
-   {
- static_assert(is_nothrow_move_constructible_v<_Tp>);
- if (this != std::__addressof(__that))
-   {
- _M_value.~_Tp();
- std::construct_at(std::__addressof(_M_value), std::move(*__that));
-   }
- return *this;
-   }
-
constexpr bool
has_value() const noexcept
{ return true; };
@@ -1180,16 +1147,6 @@ namespace views::__adaptor
  return *this;
}
 
-   constexpr __non_propagating_cache&
-   operator=(_Tp __val)
-   {
- this->_M_reset();
- std::construct_at(std::__addressof(this->_M_payload._M_payload),
-   std::in_place, std::move(__val));
- this->_M_payload._M_engaged = true;
- return *this;
-   }
-
constexpr _Tp&
operator*() noexcept
{ return this->_M_get(); }
@@ -2886,7 +2843,7 @@ namespace views::__adaptor
if constexpr (forward_range<_Vp>)
  return _M_current;
else
- return *_M_parent->_M_current;
+ return _M_parent->_M_current;
  }
 
  constexpr auto&
@@ -2895,7 +2852,7 @@ namespace views::__adaptor
if constexpr (forward_range<_Vp>)
  return _M_current;
else
- return *_M_parent->_M_current;
+ return _M_parent->_M_current;
  }
 
  _Parent* _M_parent = nullptr;
@@ -3143,13 +3100,14 @@ namespace views::__adaptor
   // XXX: _M_current is "present only if !forward_range"
   [[no_unique_address]]
__detail::__maybe_present_t,
- __detail::__non_propagating_cache>> _M_current;
+

Re: [PATCH] libstdc++: Back out some changes in P2325R3 backport [PR103904]

2022-02-11 Thread Patrick Palka via Gcc-patches
On Fri, 11 Feb 2022, Patrick Palka wrote:

> In the P2325R3 backport r11-9555 the relaxation of the constraints on
> the partial specialization of __box (which is semantically equivalent to
> the primary template, only more space efficient) means some
> specializations of __box will now use the partial specialization instead
> of the primary template, which (IIUC) constitutes an ABI change unsuitable
> for a release branch.  This patch reverts this constraint change, which
> isn't needed for correctness anyway.
> 
> Similarly the change to use __non_propagating_cache for the data member
> split_view::_M_current (so that it's always default-initializable) also
> constitutes an unsuitable ABI change.  This patch reverts this change
> too, and instead further constrains split_view's default constructor to
> require that we can default-initialize _M_current.

Forgot to clarify that this is for the 11 branch, tested on
x86_64-pc-linux-gnu.  Does this look reasonable?  I noticed these
issues while backporting r11-9555 to the 10 branch, which doesn't have
__non_propagating_cache or the partial specialization of __box.

> 
>   PR libstdc++/103904
> 
> libstdc++-v3/ChangeLog:
> 
>   * include/std/ranges (__detail::__box): Revert r11-9555 changes
>   to the constraints on the partial specialization and the
>   now-unnecessary member additions.
>   (__detail::__non_propagating_cache::operator=): Remove
>   now-unused overload added by r11-9555.
>   (split_view::_OuterIter::__current): Adjust after reverting the
>   r11-9555 change to the type of _M_current.
>   (split_view::_M_current): Revert r11-9555 change to its type.
>   (split_view::split_view): Constrain the default ctor further.
>   * testsuite/std/ranges/adaptors/detail/copyable_box.cc: Disable
>   now-irrelevant test for the r11-9555 changes to the partial
>   specialization of __box.
> ---
>  libstdc++-v3/include/std/ranges   | 54 +++
>  .../ranges/adaptors/detail/copyable_box.cc|  4 ++
>  2 files changed, 10 insertions(+), 48 deletions(-)
> 
> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
> index 03c6275801f..bf31e4be500 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -144,8 +144,7 @@ namespace ranges
>  // std::optional.  It provides just the subset of the primary template's
>  // API that we currently use.
>  template<__boxable _Tp>
> -  requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
> -  && is_nothrow_copy_constructible_v<_Tp>)
> +  requires copyable<_Tp>
>struct __box<_Tp>
>{
>private:
> @@ -174,38 +173,6 @@ namespace ranges
> : _M_value(std::forward<_Args>(__args)...)
> { }
>  
> - __box(const __box&) = default;
> - __box(__box&&) = default;
> - __box& operator=(const __box&) requires copyable<_Tp> = default;
> - __box& operator=(__box&&) requires copyable<_Tp> = default;
> -
> - // When _Tp is nothrow_copy_constructible but not copy_assignable,
> - // copy assignment is implemented via destroy-then-copy-construct.
> - constexpr __box&
> - operator=(const __box& __that) noexcept
> - {
> -   static_assert(is_nothrow_copy_constructible_v<_Tp>);
> -   if (this != std::__addressof(__that))
> - {
> -   _M_value.~_Tp();
> -   std::construct_at(std::__addressof(_M_value), *__that);
> - }
> -   return *this;
> - }
> -
> - // Likewise for move assignment.
> - constexpr __box&
> - operator=(__box&& __that) noexcept
> - {
> -   static_assert(is_nothrow_move_constructible_v<_Tp>);
> -   if (this != std::__addressof(__that))
> - {
> -   _M_value.~_Tp();
> -   std::construct_at(std::__addressof(_M_value), std::move(*__that));
> - }
> -   return *this;
> - }
> -
>   constexpr bool
>   has_value() const noexcept
>   { return true; };
> @@ -1180,16 +1147,6 @@ namespace views::__adaptor
> return *this;
>   }
>  
> - constexpr __non_propagating_cache&
> - operator=(_Tp __val)
> - {
> -   this->_M_reset();
> -   std::construct_at(std::__addressof(this->_M_payload._M_payload),
> - std::in_place, std::move(__val));
> -   this->_M_payload._M_engaged = true;
> -   return *this;
> - }
> -
>   constexpr _Tp&
>   operator*() noexcept
>   { return this->_M_get(); }
> @@ -2886,7 +2843,7 @@ namespace views::__adaptor
>   if constexpr (forward_range<_Vp>)
> return _M_current;
>   else
> -   return *_M_parent->_M_current;
> +   return _M_parent->_M_current;
> }
>  
> constexpr auto&
> @@ -2895,7 +2852,7 @@ namespace views::__adaptor
>   if constexpr (forward_range<_Vp>)
> return _M_current;
>   else

Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Jason Merrill via Gcc-patches

On 2/11/22 11:07, Qing Zhao wrote:

Hi, Jason,

On Feb 9, 2022, at 3:01 PM, Qing Zhao via Gcc-patches 
mailto:gcc-patches@gcc.gnu.org>> wrote:




On Feb 9, 2022, at 12:23 PM, Jason Merrill > wrote:


On 2/9/22 10:51, Qing Zhao wrote:
On Feb 8, 2022, at 4:20 PM, Jason Merrill > wrote:


On 2/8/22 15:11, Qing Zhao wrote:

Hi,
This is the patch to fix PR101515 (ICE in pp_cxx_unqualified_id, 
at  cp/cxx-pretty-print.c:128)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101515 

It's possible that the TYPE_NAME of a record_type is NULL, 
therefore when

printing the TYPE_NAME, we should check and handle this special case.
Please see the comment of pr101515 for more details.
The fix is very simple, just check and special handle cases when 
TYPE_NAME is NULL.

Bootstrapped and regression tested on both x86 and aarch64, no issues.
Okay for commit?
Thanks.
Qing
=
From f37ee8d21b80cb77d8108cb97a487c84c530545b Mon Sep 17 00:00:00 2001
From: Qing Zhao 
Date: Tue, 8 Feb 2022 16:10:37 +
Subject: [PATCH] Fix PR 101515 ICE in pp_cxx_unqualified_id, at
cp/cxx-pretty-print.c:128.
It's possible that the TYPE_NAME of a record_type is NULL, 
therefore when

printing the TYPE_NAME, we should check and handle this special case.
gcc/cp/ChangeLog:
* cxx-pretty-print.cc (pp_cxx_unqualified_id): Check and handle
the case when TYPE_NAME is NULL.
gcc/testsuite/ChangeLog:
* g++.dg/pr101515.C: New test.
---
gcc/cp/cxx-pretty-print.cc      |  5 -
gcc/testsuite/g++.dg/pr101515.C | 25 +
2 files changed, 29 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/pr101515.C
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index 4f9a090e520d..744ed0add5ba 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -171,7 +171,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer 
*pp, tree t)

    case ENUMERAL_TYPE:
    case TYPENAME_TYPE:
    case UNBOUND_CLASS_TEMPLATE:
-      pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+      if (TYPE_NAME (t))
+pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+      else
+pp_string (pp, "");


Hmm, but it's not an unnamed class, it's a pointer to member 
function type, and it would be better to avoid dumping compiler 
internal representations like the __pfn field name.
Yes, It’s not an unnamed class, but the ICE happened when try to 
print the compiler generated member function type 
“__ptrmemfunc_type”, whose TYPE_NAME is NULLed during building this 
type in c++ FE and the c++ FE does not handle the case when 
TYPE_NAME is NULL correctly.

So, there are two levels of issues:
1. The first level issue is that the current C++ FE does not handle 
the case TYPE_NAME being NULL correctly, this is indeed a bug in the 
current code and should be fixed as in the current patch.


Sure, we might as well make this code more robust.  But we can do 
better than  if we check TYPE_PTRMEMFUNC_P.
Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? 
Print nothing or some special string?


2. The second level issue is what you suggested in the above, shall 
we print the “compiler generated internal type”  to the user? And I 
agree with you that it might not be a good idea to print such 
compiler internal names to the user.  Are we do this right now in 
general? (i.e, check whether the current TYPE is a source level TYPE 
or a compiler internal TYPE, and then only print out the name of 
TYPE for the source level TYPE?) and is there a bit in the TYPE to 
distinguish whether a TYPE is user -level type or a compiler 
generated internal type?


I think the real problem comes sooner, when 
c_fold_indirect_ref_for_warn turns a MEM_REF with RECORD_TYPE into 
a COMPONENT_REF with POINTER_TYPE.


What’s the major issue for this transformation? (I will study this 
in more details).


We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a 
whole) and it gave us back a POINTER_TYPE instead (the __pmf member). 
Folding shouldn't change the type of an expression like that.


Yes, this is not correct transformation, will study in more detail and 
try to fix it.


After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which 
triggered the ICE and introduced the new routine 
“c_fold_indirect_ref_for_warn”), from my understanding,  the above 
transformation from a RECORD_TYPE (the PMF as a whole) to POINTER_TYPE 
(the __pmf member) is what the function intended to do as following:


1823 static tree
1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
1825                               offset_int &off)
1826 {
…
1870 */* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */*
1871   else if (TREE_CODE (optype) == RECORD_TYPE)
1872     {
1873       for (tree field = TYPE_FIELDS (optype);
1874            field; field = DECL_CHAIN (field))
1875         if (TREE_CODE (field) == FIELD_DECL

Re: [PATCH] middle-end/104497 - gimplification of vector indexing

2022-02-11 Thread Jason Merrill via Gcc-patches

On 2/11/22 06:26, Richard Biener wrote:

The following attempts to address gimplification of

... = VIEW_CONVERT_EXPR((i & 1) != 0 ? inv : src)[i];

which is problematic since gimplifying the base object
? inv : src produces a register temporary but GIMPLE does not
really support a register as a base for an ARRAY_REF (even
though that's not strictly validated it seems as can be seen
at -O0).


I suppose that isn't easy to fix?

And COMPONENT_REF has the same problem?


Interestingly the C++ frontend avoids this issue
by emitting the following GENERIC instead:

... = (i & 1) != 0 ? VIEW_CONVERT_EXPR(inv)[i] : 
VIEW_CONVERT_EXPR(src)[i];


Yes, because in C++ ?: of two lvalues is an lvalue.


The proposed patch below fixes things up when using an rvalue
as the base is OK by emitting a copy from a register base to a
non-register one.  The ?: as lvalue extension seems to be gone
for C, C++ again unwraps the COND_EXPR in that case.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?


OK, assuming "yes" answers to my questions above.


Thanks,
Richard.

2022-02-11  Richard Biener  

PR middle-end/104497
* gimplify.cc (gimplify_compound_lval): Make sure the
base is a non-register if needed and possible.

* c-c++-common/torture/pr104497.c: New testcase.
---
  gcc/gimplify.cc   | 17 ++---
  gcc/testsuite/c-c++-common/torture/pr104497.c | 12 
  2 files changed, 26 insertions(+), 3 deletions(-)
  create mode 100644 gcc/testsuite/c-c++-common/torture/pr104497.c

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 8d676fb96c8..cdf1ccbe48b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -250,6 +250,7 @@ static enum gimplify_status gimplify_compound_expr (tree *, 
gimple_seq *, bool);
  static hash_map *oacc_declare_returns;
  static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
   bool (*) (tree), fallback_t, bool);
+static void prepare_gimple_addressable (tree *, gimple_seq *);
  
  /* Shorter alias name for the above function for use in gimplify.cc

 only.  */
@@ -3126,10 +3127,12 @@ gimplify_compound_lval (tree *expr_p, gimple_seq 
*pre_p, gimple_seq *post_p,
   gimplified before gimplifying the size expressions.
  
   So we do this in three steps.  First we deal with variable

- bounds, sizes, and positions, then we gimplify the base,
- then we deal with the annotations for any variables in the
- components and any indices, from left to right.  */
+ bounds, sizes, and positions, then we gimplify the base and
+ ensure it is memory if needed, then we deal with the annotations
+ for any variables in the components and any indices, from left
+ to right.  */
  
+  bool need_non_reg = false;

for (i = expr_stack.length () - 1; i >= 0; i--)
  {
tree t = expr_stack[i];
@@ -3165,6 +3168,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
  TREE_OPERAND (t, 3) = elmt_size;
}
}
+ need_non_reg = true;
}
else if (TREE_CODE (t) == COMPONENT_REF)
{
@@ -3186,6 +3190,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
  TREE_OPERAND (t, 2) = offset;
}
}
+ need_non_reg = true;
}
  }
  
@@ -3196,6 +3201,12 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,

fallback | fb_lvalue);
ret = MIN (ret, tret);
  
+  /* Step 2a: if we have component references we do not support on

+ registers then make sure the base isn't a register.  Of course
+ we can only do so if an rvalue is OK.  */
+  if (need_non_reg && (fallback & fb_rvalue))
+prepare_gimple_addressable (p, pre_p);
+
/* Step 3: gimplify size expressions and the indices and operands of
   ARRAY_REF.  During this loop we also remove any useless conversions.  */
  
diff --git a/gcc/testsuite/c-c++-common/torture/pr104497.c b/gcc/testsuite/c-c++-common/torture/pr104497.c

new file mode 100644
index 000..c63fc021e03
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/pr104497.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+typedef int __attribute__((vector_size(16))) vec_t;
+
+vec_t src, inv, res;
+
+void test(int i)
+{
+vec_t y={0};
+y[i] = (i & 1 ? inv : src)[i];
+res = y;
+}




[PATCH] libstdc++: Make atomic notify_one and notify_all non-const

2022-02-11 Thread Thomas Rodgers via Gcc-patches

PR102994 "atomics: std::atomic::wait is not marked const" raises the
issue that the current libstdc++ implementation marks the notify members
const, the implementation strategy used by libstdc++, as well as libc++
and the Microsoft STL, do not require the atomic to be mutable (it is hard
to conceive of a desirable implementation approach that would require it).
The original paper proposing the wait/notify functionality for atomics
(p1185) also had these members marked const for the first three revisions,
but that was changed without explanation in r3 and subsequent revisions of
the paper.

After raising the issue to the authors of p1185 and the author of the
libc++ implementation, the consensus seems to be "meh, it's harmless" so
there seems little appetite for an LWG issue to revisit the subject.

This patch changes the libstdc++ implementation to be in agreement with
the standard by removing const from those notify_one/notify_all members.

libstdc++-v3/ChangeLog:
* include/bits/atomic_base.h (atomic_flag::notify_one,
notify_all): Remove const qualification.
(__atomic_base::notify_one, notify_all): Likewise.
* include/std/atomic (atomic::notify_one, notify_all):
Likewise.
(atomic::notify_one, notify_all): Likewise.
(atomic::notify_one, notify_all): Likewise.
(atomic_notify_one, atomic_notify_all): Likewise.
* testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test
to account for change in notify_one/notify_all signature.

Tested x86_64-pc-linux-gnu.
From 7ed6dfae5a0a7a9e56291d780e44f99d644847e0 Mon Sep 17 00:00:00 2001
From: Thomas Rodgers 
Date: Thu, 10 Feb 2022 18:55:16 -0800
Subject: [PATCH] libstdc++: Make atomic notify_one and notify_all non-const


PR102994 "atomics: std::atomic::wait is not marked const" raises the
issue that the current libstdc++ implementation marks the notify members
const, the implementation strategy used by libstdc++, as well as libc++
and the Microsoft STL, do not require the atomic to be mutable (it is hard
to conceive of a desirable implementation approach that would require it).
The original paper proposing the wait/notify functionality for atomics
(p1185) also had these members marked const for the first three revisions,
but that was changed without explanation in r3 and subsequent revisions of
the paper.

After raising the issue to the authors of p1185 and the author of the
libc++ implementation, the consensus seems to be "meh, it's harmless" so
there seems little appetite for an LWG issue to revisit the subject.

This patch changes the libstdc++ implementation to be in agreement with
the standard by removing const from those notify_one/notify_all members.

libstdc++-v3/ChangeLog:
	* include/bits/atomic_base.h (atomic_flag::notify_one,
	notify_all): Remove const qualification.
	(__atomic_base::notify_one, notify_all): Likewise.
	* include/std/atomic (atomic::notify_one, notify_all):
	Likewise.
	(atomic::notify_one, notify_all): Likewise.
	(atomic::notify_one, notify_all): Likewise.
	(atomic_notify_one, atomic_notify_all): Likewise.
	* testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test
	to account for change in notify_one/notify_all signature.
---
 libstdc++-v3/include/bits/atomic_base.h  |  8 
 libstdc++-v3/include/std/atomic  | 16 
 .../29_atomics/atomic/wait_notify/102994.cc  |  4 ++--
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index d86766cf39b..adfd9fa3027 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -252,13 +252,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 // TODO add const volatile overload
 
 _GLIBCXX_ALWAYS_INLINE void
-notify_one() const noexcept
+notify_one() noexcept
 { std::__atomic_notify_address(&_M_i, false); }
 
 // TODO add const volatile overload
 
 _GLIBCXX_ALWAYS_INLINE void
-notify_all() const noexcept
+notify_all() noexcept
 { std::__atomic_notify_address(&_M_i, true); }
 
 // TODO add const volatile overload
@@ -600,13 +600,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // TODO add const volatile overload
 
   _GLIBCXX_ALWAYS_INLINE void
-  notify_one() const noexcept
+  notify_one() noexcept
   { std::__atomic_notify_address(&_M_i, false); }
 
   // TODO add const volatile overload
 
   _GLIBCXX_ALWAYS_INLINE void
-  notify_all() const noexcept
+  notify_all() noexcept
   { std::__atomic_notify_address(&_M_i, true); }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index bc57659b6e7..d819b6bf41e 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -172,11 +172,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 // TODO add const volatile overload
 
 void
-noti

Ping: [PATCH], PR 104253, Fix __ibm128 conversions on IEEE 128-bit system

2022-02-11 Thread Michael Meissner via Gcc-patches
Ping patch to fix PR target/104253.  This patch fixes using the wrong names for
conversions between __ibm128 and integer types if the long double default is
IEEE 128-bit.

| Date: Fri, 28 Jan 2022 22:47:06 -0500
| From: Michael Meissner 
| Subject: [PATCH], PR 104253, Fix __ibm128 conversions on IEEE 128-bit system
| Message-ID: 

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


Ping: [PATCH] PR target/102059 Fix inline of target specific functions

2022-02-11 Thread Michael Meissner via Gcc-patches
Ping patch for PR target/102059 to ignore implicit -mpower8-fusion that
prevents a function targeting power9 or power10 from inlining a function that
declared it needed power8 via attribute/pragma target.

While we likely should revist this in GCC 13, this patch is fairly minimal in
that it fixes the specific problem Eigen ran into.  It will need to be back
ported to GCC 11 and 10 as well.

| Date: Tue, 8 Feb 2022 22:27:11 -0500
| From: Michael Meissner 
| Subject: [PATCH] PR target/102059 Fix inline of target specific functions
| Message-ID: 

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Qing Zhao via Gcc-patches
Hi, Jason,

> On Feb 11, 2022, at 11:27 AM, Jason Merrill  wrote:
 
 Sure, we might as well make this code more robust.  But we can do better 
 than  if we check TYPE_PTRMEMFUNC_P.
>>> Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? 
>>> Print nothing or some special string?
 
> 2. The second level issue is what you suggested in the above, shall we 
> print the “compiler generated internal type”  to the user? And I agree 
> with you that it might not be a good idea to print such compiler internal 
> names to the user.  Are we do this right now in general? (i.e, check 
> whether the current TYPE is a source level TYPE or a compiler internal 
> TYPE, and then only print out the name of TYPE for the source level 
> TYPE?) and is there a bit in the TYPE to distinguish whether a TYPE is 
> user -level type or a compiler generated internal type?
 
>> I think the real problem comes sooner, when c_fold_indirect_ref_for_warn 
>> turns a MEM_REF with RECORD_TYPE into a COMPONENT_REF with POINTER_TYPE.
 
> What’s the major issue for this transformation? (I will study this in 
> more details).
 
 We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a 
 whole) and it gave us back a POINTER_TYPE instead (the __pmf member). 
 Folding shouldn't change the type of an expression like that.
>>> 
>>> Yes, this is not correct transformation, will study in more detail and try 
>>> to fix it.
>> After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which triggered 
>> the ICE and introduced the new routine “c_fold_indirect_ref_for_warn”), from 
>> my understanding,  the above transformation from a RECORD_TYPE (the PMF as a 
>> whole) to POINTER_TYPE (the __pmf member) is what the function intended to 
>> do as following:
>> 1823 static tree
>> 1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
>> 1825   offset_int &off)
>> 1826 {
>> …
>> 1870 */* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */*
>> 1871   else if (TREE_CODE (optype) == RECORD_TYPE)
>> 1872 {
>> 1873   for (tree field = TYPE_FIELDS (optype);
>> 1874field; field = DECL_CHAIN (field))
>> 1875 if (TREE_CODE (field) == FIELD_DECL
>> …
>> 1886 if(upos <= off && off < upos + el_sz)
>> 1887   {
>> 1888 tree cop = build3_loc (loc, COMPONENT_REF, TREE_TYPE 
>> (field),
>> 1889   op, field, NULL_TREE);
>> 1890 off = off - upos;
>> The above code was used to transform a MEM_REF to a RECORD_TYPE to a 
>> COMPONENT_REF to the corresponding FIELD.
> 
> Yes, that's what the above code would correctly do if TYPE were the 
> pointer-to-method type.  It's wrong for this case because TYPE is unrelated 
> to TREE_TYPE (field).
> 
> I think the problem is just this line:
> 
>>if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
>> off))
>>  return ret;
>>return cop;
>  ^^
> 
> The recursive call does the proper type checking, but then the "return cop" 
> line returns the COMPONENT_REF even though the type check failed. The 
> parallel code in cxx_fold_indirect_ref_1 doesn't have this line,

Just compared the routine “cxx_fold_indirect_ref_1” and 
“c_fold_indirect_ref_for_warn”, looks like there are more places that have such 
difference, for example, 
In “cxx_fold_indirect_ref_1”:

  /* ((foo *)&fooarray)[x] => fooarray[x] */
  else if (TREE_CODE (optype) == ARRAY_TYPE
   && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
   && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
…
  if (tree_fits_uhwi_p (min_val))
{
  tree index = size_int (idx + tree_to_uhwi (min_val));
  op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
   NULL_TREE, NULL_TREE); 
  return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
  empty_base);
}
However, in “c_fold_indirect_ref_for_warn”, the corresponding part is:

  /* ((foo *)&fooarray)[x] => fooarray[x] */
  if (TREE_CODE (optype) == ARRAY_TYPE
  && TYPE_SIZE_UNIT (TREE_TYPE (optype))
  && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
  && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
…
  if (TREE_CODE (min_val) == INTEGER_CST)
{
  tree index
= wide_int_to_tree (sizetype, idx + wi::to_offset (min_val));
  op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
   NULL_TREE, NULL_TREE);
  off = rem;
  if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op, off))
return ret;
  return op;
}

The exactly same difference as fo

[PATCH] c++: Reject __builtin_clear_padding on non-trivially-copyable types with one exception [PR102586]

2022-02-11 Thread Jakub Jelinek via Gcc-patches
Hi!

As mentioned by Jason in the PR, non-trivially-copyable types (or non-POD
for purposes of layout?) types can be base classes of derived classes in
which the padding in those non-trivially-copyable types can be redused for
some real data members or even the layout can change and data members can
be moved to other positions.
__builtin_clear_padding is right now used for multiple purposes,
in  where it isn't used yet but was planned as the main spot
it can be used for trivially copyable types only, ditto for std::bit_cast
where we also use it.  It is used for OpenMP long double atomics too but
long double is trivially copyable, and lastly for -ftrivial-auto-var-init=.

The following patch restricts the builtin to pointers to trivially-copyable
types, with the exception when it is called directly on an address of a
variable, in that case already the FE can verify it is the complete object
type and so it is safe to clear all the paddings in it.

Bootstrapped/regtested on powerpc64le-linux, ok for trunk?

Something like the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586#c16
will still be needed with adjusted testcase from
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586#c15 such that
__builtin_clear_padding is called directly on var addresses rather than
in separate functions.

2022-02-11  Jakub Jelinek  

PR tree-optimization/102586
gcc/
* doc/extend.texi (__builtin_clear_padding): Clearify that for C++
argument type should be pointer to trivially-copyable type unless it
is address of a variable or parameter.
gcc/cp/
* call.cc (build_cxx_call): Diagnose __builtin_clear_padding where
first argument's type is pointer to non-trivially-copyable type unless
it is address of a variable or parameter.
gcc/testsuite/
* g++.dg/cpp2a/builtin-clear-padding1.C: New test.

--- gcc/doc/extend.texi.jj  2022-02-09 15:16:03.336783697 +0100
+++ gcc/doc/extend.texi 2022-02-11 13:22:39.846157538 +0100
@@ -13993,6 +13993,11 @@ bits that are padding bits for all the u
 This built-in-function is useful if the padding bits of an object might
 have intederminate values and the object representation needs to be
 bitwise compared to some other object, for example for atomic operations.
+
+For C++, @var{ptr} argument type should be pointer to trivially-copyable
+type, unless the argument is address of a variable or parameter, because
+otherwise it isn't known if the type isn't just a base class whose padding
+bits are reused or laid out differently in a derived class.
 @end deftypefn
 
 @deftypefn {Built-in Function} @var{type} __builtin_bit_cast (@var{type}, 
@var{arg})
--- gcc/cp/call.cc.jj   2022-02-09 20:13:51.523305107 +0100
+++ gcc/cp/call.cc  2022-02-11 12:58:19.168301395 +0100
@@ -10398,6 +10398,27 @@ build_cxx_call (tree fn, int nargs, tree
   if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl,
 orig_fndecl, nargs, argarray))
return error_mark_node;
+  else if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING))
+   {
+ tree arg0 = argarray[0];
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (arg0, 0))
+ && same_type_ignoring_top_level_qualifiers_p
+   (TREE_TYPE (TREE_TYPE (argarray[0])),
+TREE_TYPE (TREE_TYPE (arg0
+   /* For __builtin_clear_padding (&var) we know the type
+  is for a complete object, so there is no risk in clearing
+  padding that is reused in some derived class member.  */;
+ else if (!trivially_copyable_p (TREE_TYPE (TREE_TYPE (argarray[0]
+   {
+ error_at (EXPR_LOC_OR_LOC (argarray[0], input_location),
+   "argument %u in call to function %qE "
+   "has pointer to a non-trivially-copyable type (%qT)",
+   1, fndecl, TREE_TYPE (argarray[0]));
+ return error_mark_node;
+   }
+   }
 }
 
   if (VOID_TYPE_P (TREE_TYPE (fn)))
--- gcc/testsuite/g++.dg/cpp2a/builtin-clear-padding1.C.jj  2022-02-11 
13:13:49.125471991 +0100
+++ gcc/testsuite/g++.dg/cpp2a/builtin-clear-padding1.C 2022-02-11 
13:13:43.403550851 +0100
@@ -0,0 +1,50 @@
+// PR tree-optimization/102586
+// { dg-do compile }
+// { dg-options "-Wno-inaccessible-base" }
+
+struct C0 {};
+struct C1 {};
+struct C2 : C1, virtual C0 {};
+struct C3 : virtual C2, C1 {};
+struct C4 : virtual C3, C1 {};
+struct C5 : C4 {};
+struct C6 { char c; };
+struct C7 : virtual C6, virtual C3, C1 {};
+struct C8 : C7 {};
+
+void
+foo (C0 *c0, C1 *c1, C2 *c2, C3 *c3, C4 *c4, C5 *c5, C6 *c6, C7 *c7, C8 *c8)
+{
+  __builtin_clear_padding (c0);
+  __builtin_clear_padding (c1);
+  __builtin_clear_padding (c2);// { dg-error "argument 1 in call to 
function '__builtin_clear_padding' has pointer to a non-trivially-copyable type 

[PATCH] match.pd: Fix up (X & Y) CMP 0 -> X CMP2 ~Y simplifications [PR104499]

2022-02-11 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase ICEs on x86_64-linux, because match.pd emits
there a NOP_EXPR cast from int*8 vector type with BLKmode to
unsigned*8 vector type with BLKmode and vec-lowering isn't prepared
to handle such casts.

Fixed by using VIEW_CONVERT_EXPR instead.

Bootstrapped/regtested on powerpc64le-linux, ok for trunk?

2022-02-11  Jakub Jelinek  

PR tree-optimization/104499
* match.pd ((X & Y) CMP 0 -> X CMP2 ~Y): Use view_convert instead
of convert.

* gcc.c-torture/compile/pr104499.c: New test.

--- gcc/match.pd.jj 2022-02-11 11:20:24.272393155 +0100
+++ gcc/match.pd2022-02-11 13:45:02.612636452 +0100
@@ -5778,7 +5778,7 @@ (define_operator_list SYNC_FETCH_AND_AND
   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
(icmp @0 { csts; })
(with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
-(icmp (convert:utype @0) { csts; }
+(icmp (view_convert:utype @0) { csts; }
 
 /* When one argument is a constant, overflow detection can be simplified.
Currently restricted to single use so as not to interfere too much with
--- gcc/testsuite/gcc.c-torture/compile/pr104499.c.jj   2022-02-11 
13:47:03.819963924 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr104499.c  2022-02-11 
13:46:44.421231605 +0100
@@ -0,0 +1,11 @@
+/* PR tree-optimization/104499 */
+
+typedef int __attribute__((__vector_size__ (8 * sizeof (int V;
+
+V v;
+
+void
+foo (void)
+{
+  v = ((1 | v) != 1);
+}

Jakub



Re: [PATCH] match.pd: Fix up (X & Y) CMP 0 -> X CMP2 ~Y simplifications [PR104499]

2022-02-11 Thread Richard Biener via Gcc-patches



> Am 11.02.2022 um 20:00 schrieb Jakub Jelinek via Gcc-patches 
> :
> 
> Hi!
> 
> The following testcase ICEs on x86_64-linux, because match.pd emits
> there a NOP_EXPR cast from int*8 vector type with BLKmode to
> unsigned*8 vector type with BLKmode and vec-lowering isn't prepared
> to handle such casts.
> 
> Fixed by using VIEW_CONVERT_EXPR instead.
> 
> Bootstrapped/regtested on powerpc64le-linux, ok for trunk?

Ok

> 2022-02-11  Jakub Jelinek  
> 
>PR tree-optimization/104499
>* match.pd ((X & Y) CMP 0 -> X CMP2 ~Y): Use view_convert instead
>of convert.
> 
>* gcc.c-torture/compile/pr104499.c: New test.
> 
> --- gcc/match.pd.jj2022-02-11 11:20:24.272393155 +0100
> +++ gcc/match.pd2022-02-11 13:45:02.612636452 +0100
> @@ -5778,7 +5778,7 @@ (define_operator_list SYNC_FETCH_AND_AND
>   (if (TYPE_UNSIGNED (TREE_TYPE (@1)))
>(icmp @0 { csts; })
>(with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
> - (icmp (convert:utype @0) { csts; }
> + (icmp (view_convert:utype @0) { csts; }
> 
> /* When one argument is a constant, overflow detection can be simplified.
>Currently restricted to single use so as not to interfere too much with
> --- gcc/testsuite/gcc.c-torture/compile/pr104499.c.jj2022-02-11 
> 13:47:03.819963924 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr104499.c2022-02-11 
> 13:46:44.421231605 +0100
> @@ -0,0 +1,11 @@
> +/* PR tree-optimization/104499 */
> +
> +typedef int __attribute__((__vector_size__ (8 * sizeof (int V;
> +
> +V v;
> +
> +void
> +foo (void)
> +{
> +  v = ((1 | v) != 1);
> +}
> 
>Jakub
> 


[PATCH] libgomp: added OMPD support to libgomp and created libgompd

2022-02-11 Thread Mohamed Atef via Gcc-patches
This patch added OMPD support for libgomp and added some OMPD functions.
One of the guys is working on the gdb-plugin and two of them are trying to
get familiar with DejaGnu and some of us are working on the Graduation Book
which will contain everything about the project. (we will provide it if you
wish.).
by the next few days we will finish the testing stage of the current
functions.

clarifications:
which file should i include to use _OPENMP?
will you need the gdb-plugin so we take care  of GNU coding standards?


libgomp/ChangeLog

2022-02-11  Mohamed Atef  

* Makefile.am (toolexeclib_LTLIBRARIES): Add libgompd.la.
(libgompd_la_LDFLAGS, libgompd_la_DEPENDENCIES, libgompd_la_LINK,
libgompd_la_SOURCES, libgompd_version_dep, libgompd_version_script,
libgompd.ver-sun, libgompd.ver, libgompd_version_info): Defined.
* Makefile.in: Regenerate.
* aclocal.m4: Regenerate.
* config/darwin/plugin-suffix.h: Removed ().
* config/hpux/plugin-suffix.h: Removed ().
* config/posix/plugin-suffix.h: Removed ().
* configure: Regenerate.
* env.c: (#include "ompd-support.h") : Added.
(initialize_env) : Call ompd_load().
* parallel.c:(#include "ompd-support.h"): Added.
(GOMP_parallel) : Call ompd_bp_parallel_begin and
ompd_bp_parallel_end.
* libgomp.map: Add OMP_5.0.3 symobl versions.
* libgompd.map: New file.
* omp-tools.h : New file.
* omp-types.h : New file.
* ompd-support.h : New file.
* ompd-support.c : New file.
* ompd-helper.h : New file.
* ompd-helper.c: New file.
* ompd-init.c: New file.
* testsuite/Makfile.in: Regenerate.

**


 configure |  14 +-
 libgomp/Makefile.am   |  32 +++-
 libgomp/Makefile.in   | 292
+++---
 libgomp/aclocal.m4| 189 ++
 libgomp/config/darwin/plugin-suffix.h |   2 +-
 libgomp/config/hpux/plugin-suffix.h   |   2 +-
 libgomp/config/posix/plugin-suffix.h  |   2 +-
 libgomp/configure | 209 
 libgomp/env.c |   2 +
 libgomp/libgomp.map   |   8 +
 libgomp/libgompd.map  |  12 ++
 libgomp/omp-tools.h   | 282

 libgomp/ompd-helper.c |  45 ++
 libgomp/ompd-helper.h |  65 
 libgomp/ompd-init.c   | 154 ++
 libgomp/ompd-support.c| 111 +
 libgomp/ompd-support.h|  44 +
 libgomp/ompd-types.h  |  59 +++
 libgomp/parallel.c|   5 +
 libgomp/testsuite/Makefile.in |   9 +-
 20 files changed, 1265 insertions(+), 273 deletions(-)

diff --git a/configure b/configure
index 9c2d7df1bb2..c270ea34098 100755
--- a/configure
+++ b/configure
@@ -766,6 +766,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -936,6 +937,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE}'
@@ -1188,6 +1190,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
 silent=yes ;;

+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
 ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1325,7 +1336,7 @@ fi
 for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
  datadir sysconfdir sharedstatedir localstatedir includedir \
  oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1485,6 +1496,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIRread-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIRmodifiable architecture-independent data
[PREFIX/com]
   --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR   modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIRobject code libraries [EPREFIX/lib]
   --includedir=DIRC header files [PREFIX/include]
   --oldincludedir=DIR C header files for non-gcc [/usr/include]
diff --git a/libgomp/Makefile.am b/libgomp/Makef

Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Jason Merrill via Gcc-patches

On 2/11/22 13:11, Qing Zhao wrote:

Hi, Jason,


On Feb 11, 2022, at 11:27 AM, Jason Merrill  wrote:


Sure, we might as well make this code more robust.  But we can do better than 
 if we check TYPE_PTRMEMFUNC_P.

Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? Print 
nothing or some special string?



2. The second level issue is what you suggested in the above, shall we print 
the “compiler generated internal type”  to the user? And I agree with you that 
it might not be a good idea to print such compiler internal names to the user.  
Are we do this right now in general? (i.e, check whether the current TYPE is a 
source level TYPE or a compiler internal TYPE, and then only print out the name 
of TYPE for the source level TYPE?) and is there a bit in the TYPE to 
distinguish whether a TYPE is user -level type or a compiler generated internal 
type?



I think the real problem comes sooner, when c_fold_indirect_ref_for_warn turns 
a MEM_REF with RECORD_TYPE into a COMPONENT_REF with POINTER_TYPE.



What’s the major issue for this transformation? (I will study this in more 
details).


We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a whole) and 
it gave us back a POINTER_TYPE instead (the __pmf member). Folding shouldn't 
change the type of an expression like that.


Yes, this is not correct transformation, will study in more detail and try to 
fix it.

After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which triggered the 
ICE and introduced the new routine “c_fold_indirect_ref_for_warn”), from my 
understanding,  the above transformation from a RECORD_TYPE (the PMF as a 
whole) to POINTER_TYPE (the __pmf member) is what the function intended to do 
as following:
1823 static tree
1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
1825   offset_int &off)
1826 {
…
1870 */* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */*
1871   else if (TREE_CODE (optype) == RECORD_TYPE)
1872 {
1873   for (tree field = TYPE_FIELDS (optype);
1874field; field = DECL_CHAIN (field))
1875 if (TREE_CODE (field) == FIELD_DECL
…
1886 if(upos <= off && off < upos + el_sz)
1887   {
1888 tree cop = build3_loc (loc, COMPONENT_REF, TREE_TYPE 
(field),
1889   op, field, NULL_TREE);
1890 off = off - upos;
The above code was used to transform a MEM_REF to a RECORD_TYPE to a 
COMPONENT_REF to the corresponding FIELD.


Yes, that's what the above code would correctly do if TYPE were the 
pointer-to-method type.  It's wrong for this case because TYPE is unrelated to 
TREE_TYPE (field).

I think the problem is just this line:


if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
 off))
  return ret;
return cop;

  ^^

The recursive call does the proper type checking, but then the "return cop" 
line returns the COMPONENT_REF even though the type check failed. The parallel code in 
cxx_fold_indirect_ref_1 doesn't have this line,


Just compared the routine “cxx_fold_indirect_ref_1” and 
“c_fold_indirect_ref_for_warn”, looks like there are more places that have such 
difference, for example,
In “cxx_fold_indirect_ref_1”:

   /* ((foo *)&fooarray)[x] => fooarray[x] */
   else if (TREE_CODE (optype) == ARRAY_TYPE
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
&& !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
…
   if (tree_fits_uhwi_p (min_val))
 {
   tree index = size_int (idx + tree_to_uhwi (min_val));
   op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
NULL_TREE, NULL_TREE);
  return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
   empty_base);
}
However, in “c_fold_indirect_ref_for_warn”, the corresponding part is:

   /* ((foo *)&fooarray)[x] => fooarray[x] */
   if (TREE_CODE (optype) == ARRAY_TYPE
   && TYPE_SIZE_UNIT (TREE_TYPE (optype))
   && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
   && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
…
   if (TREE_CODE (min_val) == INTEGER_CST)
 {
   tree index
 = wide_int_to_tree (sizetype, idx + wi::to_offset (min_val));
   op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
NULL_TREE, NULL_TREE);
   off = rem;
   if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op, off))
 return ret;
   return op;
 }

The exactly same difference as for “RECORD_TYPE”. So, I suspect that it’s a 
typo for “RECORD_TYPE” in “c_fold_indirect_ref_for_warn”.


and removing it fixes the testcase, so I see

warning: ‘*(ptrmemfunc*)&x.ptrmem

Re: [PATCH] libstdc++: Back out some changes in P2325R3 backport [PR103904]

2022-02-11 Thread Jonathan Wakely via Gcc-patches
On Fri, 11 Feb 2022, 17:11 Patrick Palka via Libstdc++, <
libstd...@gcc.gnu.org> wrote:

> On Fri, 11 Feb 2022, Patrick Palka wrote:
>
> > In the P2325R3 backport r11-9555 the relaxation of the constraints on
> > the partial specialization of __box (which is semantically equivalent to
> > the primary template, only more space efficient) means some
> > specializations of __box will now use the partial specialization instead
> > of the primary template, which (IIUC) constitutes an ABI change
> unsuitable
> > for a release branch.  This patch reverts this constraint change, which
> > isn't needed for correctness anyway.
> >
> > Similarly the change to use __non_propagating_cache for the data member
> > split_view::_M_current (so that it's always default-initializable) also
> > constitutes an unsuitable ABI change.  This patch reverts this change
> > too, and instead further constrains split_view's default constructor to
> > require that we can default-initialize _M_current.
>
> Forgot to clarify that this is for the 11 branch, tested on
> x86_64-pc-linux-gnu.  Does this look reasonable?  I noticed these
> issues while backporting r11-9555 to the 10 branch, which doesn't have
> __non_propagating_cache or the partial specialization of __box.
>


Yes, thanks for spotting the problem. OK for gcc-11.


Re: [PATCH] libstdc++: Make atomic notify_one and notify_all non-const

2022-02-11 Thread Jonathan Wakely via Gcc-patches
On Fri, 11 Feb 2022 at 17:40, Thomas Rodgers via Libstdc++
 wrote:
>
> 
> PR102994 "atomics: std::atomic::wait is not marked const" raises the
> issue that the current libstdc++ implementation marks the notify members
> const, the implementation strategy used by libstdc++, as well as libc++
> and the Microsoft STL, do not require the atomic to be mutable (it is hard
> to conceive of a desirable implementation approach that would require it).
> The original paper proposing the wait/notify functionality for atomics
> (p1185) also had these members marked const for the first three revisions,
> but that was changed without explanation in r3 and subsequent revisions of
> the paper.
>
> After raising the issue to the authors of p1185 and the author of the
> libc++ implementation, the consensus seems to be "meh, it's harmless" so
> there seems little appetite for an LWG issue to revisit the subject.
>
> This patch changes the libstdc++ implementation to be in agreement with
> the standard by removing const from those notify_one/notify_all members.
>
> libstdc++-v3/ChangeLog:

Might as well add a "PR libstdc++/102994" here to the bug gets updated
automatically.

OK for trunk with that change.

> * include/bits/atomic_base.h (atomic_flag::notify_one,
> notify_all): Remove const qualification.
> (__atomic_base::notify_one, notify_all): Likewise.
> * include/std/atomic (atomic::notify_one, notify_all):
> Likewise.
> (atomic::notify_one, notify_all): Likewise.
> (atomic::notify_one, notify_all): Likewise.
> (atomic_notify_one, atomic_notify_all): Likewise.
> * testsuite/29_atomics/atomic/wait_notify/102994.cc: Adjust test
> to account for change in notify_one/notify_all signature.
>
> Tested x86_64-pc-linux-gnu.



Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Qing Zhao via Gcc-patches


> On Feb 11, 2022, at 1:39 PM, Jason Merrill  wrote:
> 
> On 2/11/22 13:11, Qing Zhao wrote:
>> Hi, Jason,
>>> On Feb 11, 2022, at 11:27 AM, Jason Merrill  wrote:
>> 
>> Sure, we might as well make this code more robust.  But we can do better 
>> than  if we check TYPE_PTRMEMFUNC_P.
> Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? 
> Print nothing or some special string?
>> 
>>> 2. The second level issue is what you suggested in the above, shall we 
>>> print the “compiler generated internal type”  to the user? And I agree 
>>> with you that it might not be a good idea to print such compiler 
>>> internal names to the user.  Are we do this right now in general? (i.e, 
>>> check whether the current TYPE is a source level TYPE or a compiler 
>>> internal TYPE, and then only print out the name of TYPE for the source 
>>> level TYPE?) and is there a bit in the TYPE to distinguish whether a 
>>> TYPE is user -level type or a compiler generated internal type?
>> 
 I think the real problem comes sooner, when 
 c_fold_indirect_ref_for_warn turns a MEM_REF with RECORD_TYPE into a 
 COMPONENT_REF with POINTER_TYPE.
>> 
>>> What’s the major issue for this transformation? (I will study this in 
>>> more details).
>> 
>> We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a 
>> whole) and it gave us back a POINTER_TYPE instead (the __pmf member). 
>> Folding shouldn't change the type of an expression like that.
> 
> Yes, this is not correct transformation, will study in more detail and 
> try to fix it.
 After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which 
 triggered the ICE and introduced the new routine 
 “c_fold_indirect_ref_for_warn”), from my understanding,  the above 
 transformation from a RECORD_TYPE (the PMF as a whole) to POINTER_TYPE 
 (the __pmf member) is what the function intended to do as following:
 1823 static tree
 1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
 1825   offset_int &off)
 1826 {
 …
 1870 */* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */*
 1871   else if (TREE_CODE (optype) == RECORD_TYPE)
 1872 {
 1873   for (tree field = TYPE_FIELDS (optype);
 1874field; field = DECL_CHAIN (field))
 1875 if (TREE_CODE (field) == FIELD_DECL
 …
 1886 if(upos <= off && off < upos + el_sz)
 1887   {
 1888 tree cop = build3_loc (loc, COMPONENT_REF, TREE_TYPE 
 (field),
 1889   op, field, NULL_TREE);
 1890 off = off - upos;
 The above code was used to transform a MEM_REF to a RECORD_TYPE to a 
 COMPONENT_REF to the corresponding FIELD.
>>> 
>>> Yes, that's what the above code would correctly do if TYPE were the 
>>> pointer-to-method type.  It's wrong for this case because TYPE is unrelated 
>>> to TREE_TYPE (field).
>>> 
>>> I think the problem is just this line:
>>> 
if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
 off))
  return ret;
return cop;
>>>  ^^
>>> 
>>> The recursive call does the proper type checking, but then the "return cop" 
>>> line returns the COMPONENT_REF even though the type check failed. The 
>>> parallel code in cxx_fold_indirect_ref_1 doesn't have this line,
>> Just compared the routine “cxx_fold_indirect_ref_1” and 
>> “c_fold_indirect_ref_for_warn”, looks like there are more places that have 
>> such difference, for example,
>> In “cxx_fold_indirect_ref_1”:
>>   /* ((foo *)&fooarray)[x] => fooarray[x] */
>>   else if (TREE_CODE (optype) == ARRAY_TYPE
>>&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
>>&& !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
>> …
>>   if (tree_fits_uhwi_p (min_val))
>> {
>>   tree index = size_int (idx + tree_to_uhwi (min_val));
>>   op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
>>NULL_TREE, NULL_TREE);
>>return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
>>   empty_base);
>>  }
>> However, in “c_fold_indirect_ref_for_warn”, the corresponding part is:
>>   /* ((foo *)&fooarray)[x] => fooarray[x] */
>>   if (TREE_CODE (optype) == ARRAY_TYPE
>>   && TYPE_SIZE_UNIT (TREE_TYPE (optype))
>>   && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
>>   && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
>> …
>>   if (TREE_CODE (min_val) == INTEGER_CST)
>> {
>>   tree index
>> = wide_int_to_tree (sizetype, idx + wi::to_offset (min_val));

Re: [PATCH], PR 104253, Fix __ibm128 conversions on IEEE 128-bit system

2022-02-11 Thread Segher Boessenkool
Hi!

On Fri, Jan 28, 2022 at 10:47:06PM -0500, Michael Meissner wrote:
> Use correct names for __ibm128 if long double is IEEE 128-bit.
> 
> If you are on a PowerPC system where the default long double is IEEE
> 128-bit, GCC will use the wrong names for some of the conversion functions
> for the __ibm128 type.

It uses the wrong functions, yes.

> What is happening is when the defult long double is IEEE 128-bit, the

(default)

> various convert, truncation, and extend functions did not specify a
> default name for the conversion.  The machine indepentent portions of the

(independent)

> compiler would construct a call with an 'if' name (IFmode being the mode
> for IBM 128-bit floating point).  This patch specifies to use the
> tradiational 'tf' name for these conversion functions.

(traditional)

> 2022-01-28  Michael Meissner  
> 
> gcc/
>   PR target/104253
>   * config/rs6000/rs6000.cc (init_float128_ibm): Use the TF names
>   for builtin conversions between __ibm128 and DImode when long
>   double uses the IEEE 128-bit format.

Please rephrase this?  It should say "*also* when long double is IEEE
QP".  And it is not about the names in the first place.

In the code it says
  /* Add various conversions for IFmode to use the traditional TFmode
 names.  */
which is both clearer and more correct :-)

> gcc/testsuite/
>   PR target/104253
>   * gcc.target/powerpc/pr104253.c: New test.

> +/* { require-effective-target ppc_float128_sw } */

The documentation for this selector is wrong, btw: it says it tests
whether this is emulated in software!  But instead it just tests if it
works, soft float, emulated, and hardware are all fine.

The patch is okay for trunk, and backports later.  Thanks!


Segher


Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Jason Merrill via Gcc-patches

On 2/11/22 15:29, Qing Zhao wrote:




On Feb 11, 2022, at 1:39 PM, Jason Merrill  wrote:

On 2/11/22 13:11, Qing Zhao wrote:

Hi, Jason,

On Feb 11, 2022, at 11:27 AM, Jason Merrill  wrote:


Sure, we might as well make this code more robust.  But we can do better than 
 if we check TYPE_PTRMEMFUNC_P.

Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? Print 
nothing or some special string?



2. The second level issue is what you suggested in the above, shall we print 
the “compiler generated internal type”  to the user? And I agree with you that 
it might not be a good idea to print such compiler internal names to the user.  
Are we do this right now in general? (i.e, check whether the current TYPE is a 
source level TYPE or a compiler internal TYPE, and then only print out the name 
of TYPE for the source level TYPE?) and is there a bit in the TYPE to 
distinguish whether a TYPE is user -level type or a compiler generated internal 
type?



I think the real problem comes sooner, when c_fold_indirect_ref_for_warn turns 
a MEM_REF with RECORD_TYPE into a COMPONENT_REF with POINTER_TYPE.



What’s the major issue for this transformation? (I will study this in more 
details).


We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a whole) and 
it gave us back a POINTER_TYPE instead (the __pmf member). Folding shouldn't 
change the type of an expression like that.


Yes, this is not correct transformation, will study in more detail and try to 
fix it.

After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which triggered the 
ICE and introduced the new routine “c_fold_indirect_ref_for_warn”), from my 
understanding,  the above transformation from a RECORD_TYPE (the PMF as a 
whole) to POINTER_TYPE (the __pmf member) is what the function intended to do 
as following:
1823 static tree
1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
1825   offset_int &off)
1826 {
…
1870 */* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */*
1871   else if (TREE_CODE (optype) == RECORD_TYPE)
1872 {
1873   for (tree field = TYPE_FIELDS (optype);
1874field; field = DECL_CHAIN (field))
1875 if (TREE_CODE (field) == FIELD_DECL
…
1886 if(upos <= off && off < upos + el_sz)
1887   {
1888 tree cop = build3_loc (loc, COMPONENT_REF, TREE_TYPE 
(field),
1889   op, field, NULL_TREE);
1890 off = off - upos;
The above code was used to transform a MEM_REF to a RECORD_TYPE to a 
COMPONENT_REF to the corresponding FIELD.


Yes, that's what the above code would correctly do if TYPE were the 
pointer-to-method type.  It's wrong for this case because TYPE is unrelated to 
TREE_TYPE (field).

I think the problem is just this line:


if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
 off))
  return ret;
return cop;

  ^^

The recursive call does the proper type checking, but then the "return cop" 
line returns the COMPONENT_REF even though the type check failed. The parallel code in 
cxx_fold_indirect_ref_1 doesn't have this line,

Just compared the routine “cxx_fold_indirect_ref_1” and 
“c_fold_indirect_ref_for_warn”, looks like there are more places that have such 
difference, for example,
In “cxx_fold_indirect_ref_1”:
   /* ((foo *)&fooarray)[x] => fooarray[x] */
   else if (TREE_CODE (optype) == ARRAY_TYPE
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
&& !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
…
   if (tree_fits_uhwi_p (min_val))
 {
   tree index = size_int (idx + tree_to_uhwi (min_val));
   op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
NULL_TREE, NULL_TREE);
  return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
   empty_base);
}
However, in “c_fold_indirect_ref_for_warn”, the corresponding part is:
   /* ((foo *)&fooarray)[x] => fooarray[x] */
   if (TREE_CODE (optype) == ARRAY_TYPE
   && TYPE_SIZE_UNIT (TREE_TYPE (optype))
   && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
   && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
…
   if (TREE_CODE (min_val) == INTEGER_CST)
 {
   tree index
 = wide_int_to_tree (sizetype, idx + wi::to_offset (min_val));
   op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
NULL_TREE, NULL_TREE);
   off = rem;
   if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op, off))
 return ret;
   return op;
 }
The exactly same difference as for “RECORD_TYPE”. So, I suspect that it’s a 
typo for “RECORD_TYPE” in “c_fold_indirect_ref_for_wa

[committed] libstdc++: Fix test failures at -O0

2022-02-11 Thread Jonathan Wakely via Gcc-patches
Tested x86_64-linux, pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* testsuite/20_util/monotonic_buffer_resource/allocate.cc:
Ignore -Walloc-larger-than warning.
* testsuite/20_util/unsynchronized_pool_resource/allocate.cc:
Likewise.
* testsuite/29_atomics/atomic/cons/user_pod.cc: Compile with -O1
to avoid linker error for __atomic_is_lock_free.
---
 .../testsuite/20_util/monotonic_buffer_resource/allocate.cc| 3 +++
 .../testsuite/20_util/unsynchronized_pool_resource/allocate.cc | 3 +++
 libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc  | 1 +
 3 files changed, 7 insertions(+)

diff --git 
a/libstdc++-v3/testsuite/20_util/monotonic_buffer_resource/allocate.cc 
b/libstdc++-v3/testsuite/20_util/monotonic_buffer_resource/allocate.cc
index 015c1a9e4dc..e7a0e97c9f9 100644
--- a/libstdc++-v3/testsuite/20_util/monotonic_buffer_resource/allocate.cc
+++ b/libstdc++-v3/testsuite/20_util/monotonic_buffer_resource/allocate.cc
@@ -238,8 +238,11 @@ test07()
   std::pmr::monotonic_buffer_resource mbr(&cr);
   try
   {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
 // Try to allocate a ridiculous size:
 void* p = mbr.allocate(std::size_t(-2), 1);
+#pragma GCC diagnostic pop
 // Should not reach here!
 VERIFY( !"attempt to allocate SIZE_MAX-1 should not have succeeded" );
 throw p;
diff --git 
a/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/allocate.cc 
b/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/allocate.cc
index c81344a20e4..25e5ce63b58 100644
--- a/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/allocate.cc
+++ b/libstdc++-v3/testsuite/20_util/unsynchronized_pool_resource/allocate.cc
@@ -281,10 +281,13 @@ test07()
   std::pmr::unsynchronized_pool_resource upr(&cr);
   try
   {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
 // Try to allocate a ridiculous size (and use a large extended alignment
 // so that careful_resource::do_allocate can distinguish this allocation
 // from any required for the pool resource's internal data structures):
 void* p = upr.allocate(std::size_t(-2), 1024);
+#pragma GCC distinguish pop
 // Should not reach here!
 VERIFY( !"attempt to allocate SIZE_MAX-1 should not have succeeded" );
 throw p;
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc
index c538ff370e1..285b420eef1 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc
@@ -1,3 +1,4 @@
+// { dg-options "-O1" }
 // { dg-do link { target c++11 } }
 
 // Copyright (C) 2009-2022 Free Software Foundation, Inc.
-- 
2.34.1



[committed] libstdc++: Fix FAIL: 20_util/temporary_buffer.cc for C++14

2022-02-11 Thread Jonathan Wakely via Gcc-patches
Tested x86_64-linux, pushed to trunk.

-- >8 --

The std::get_temporary_buffer function is deprecated since C++17, but
the test was expecting a warning for C++14 as well.

libstdc++-v3/ChangeLog:

* testsuite/20_util/temporary_buffer.cc: Fix dg-warning target
selector.
---
 libstdc++-v3/testsuite/20_util/temporary_buffer.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/20_util/temporary_buffer.cc 
b/libstdc++-v3/testsuite/20_util/temporary_buffer.cc
index 3f3625961b6..54b0edb00ee 100644
--- a/libstdc++-v3/testsuite/20_util/temporary_buffer.cc
+++ b/libstdc++-v3/testsuite/20_util/temporary_buffer.cc
@@ -27,7 +27,7 @@ struct junk { char j[12]; };
 int main(void)
 {
   typedef std::pair pair_type;
-  pair_type results = std::get_temporary_buffer(5); // { dg-warning 
"deprecated" "" { target c++14 } }
+  pair_type results = std::get_temporary_buffer(5); // { dg-warning 
"deprecated" "" { target c++17 } }
 
   if (results.second != 0)
   {
-- 
2.34.1



Re: [PATCH] Fix PR 101515 (ICE in pp_cxx_unqualified_id, at cp/cxx-pretty-print.c:128)

2022-02-11 Thread Qing Zhao via Gcc-patches


> On Feb 11, 2022, at 3:54 PM, Jason Merrill  wrote:
> 
> On 2/11/22 15:29, Qing Zhao wrote:
>>> On Feb 11, 2022, at 1:39 PM, Jason Merrill  wrote:
>>> 
>>> On 2/11/22 13:11, Qing Zhao wrote:
 Hi, Jason,
> On Feb 11, 2022, at 11:27 AM, Jason Merrill  wrote:
 
 Sure, we might as well make this code more robust.  But we can do 
 better than  if we check TYPE_PTRMEMFUNC_P.
>>> Okay, so what should we print to the user if it's “TYPE_PTRMEMFUNC_P”? 
>>> Print nothing or some special string?
 
> 2. The second level issue is what you suggested in the above, shall 
> we print the “compiler generated internal type”  to the user? And I 
> agree with you that it might not be a good idea to print such 
> compiler internal names to the user.  Are we do this right now in 
> general? (i.e, check whether the current TYPE is a source level TYPE 
> or a compiler internal TYPE, and then only print out the name of TYPE 
> for the source level TYPE?) and is there a bit in the TYPE to 
> distinguish whether a TYPE is user -level type or a compiler 
> generated internal type?
 
>> I think the real problem comes sooner, when 
>> c_fold_indirect_ref_for_warn turns a MEM_REF with RECORD_TYPE into a 
>> COMPONENT_REF with POINTER_TYPE.
 
> What’s the major issue for this transformation? (I will study this in 
> more details).
 
 We told c_fold_indirect_ref that we want a RECORD_TYPE (the PMF as a 
 whole) and it gave us back a POINTER_TYPE instead (the __pmf member). 
 Folding shouldn't change the type of an expression like that.
>>> 
>>> Yes, this is not correct transformation, will study in more detail and 
>>> try to fix it.
>> After a deeper study of commit  r11-6729-gadb520606ce3e1e1 (which 
>> triggered the ICE and introduced the new routine 
>> “c_fold_indirect_ref_for_warn”), from my understanding,  the above 
>> transformation from a RECORD_TYPE (the PMF as a whole) to POINTER_TYPE 
>> (the __pmf member) is what the function intended to do as following:
>> 1823 static tree
>> 1824 c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
>> 1825   offset_int &off)
>> 1826 {
>> …
>> 1870 */* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */*
>> 1871   else if (TREE_CODE (optype) == RECORD_TYPE)
>> 1872 {
>> 1873   for (tree field = TYPE_FIELDS (optype);
>> 1874field; field = DECL_CHAIN (field))
>> 1875 if (TREE_CODE (field) == FIELD_DECL
>> …
>> 1886 if(upos <= off && off < upos + el_sz)
>> 1887   {
>> 1888 tree cop = build3_loc (loc, COMPONENT_REF, 
>> TREE_TYPE (field),
>> 1889   op, field, NULL_TREE);
>> 1890 off = off - upos;
>> The above code was used to transform a MEM_REF to a RECORD_TYPE to a 
>> COMPONENT_REF to the corresponding FIELD.
> 
> Yes, that's what the above code would correctly do if TYPE were the 
> pointer-to-method type.  It's wrong for this case because TYPE is 
> unrelated to TREE_TYPE (field).
> 
> I think the problem is just this line:
> 
>>if (tree ret = c_fold_indirect_ref_for_warn (loc, type, 
>> cop,
>> off))
>>  return ret;
>>return cop;
>  ^^
> 
> The recursive call does the proper type checking, but then the "return 
> cop" line returns the COMPONENT_REF even though the type check failed. 
> The parallel code in cxx_fold_indirect_ref_1 doesn't have this line,
 Just compared the routine “cxx_fold_indirect_ref_1” and 
 “c_fold_indirect_ref_for_warn”, looks like there are more places that have 
 such difference, for example,
 In “cxx_fold_indirect_ref_1”:
   /* ((foo *)&fooarray)[x] => fooarray[x] */
   else if (TREE_CODE (optype) == ARRAY_TYPE
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
&& !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype
 …
   if (tree_fits_uhwi_p (min_val))
 {
   tree index = size_int (idx + tree_to_uhwi (min_val));
   op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
NULL_TREE, NULL_TREE);
  return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
   empty_base);
}
 However, in “c_fold_indirect_ref_for_warn”, the corresponding part is:
   /* ((foo *)&fooarray)[x] => fooarray[x] */
   if (TREE_CODE (optype) == ARRAY_TYPE
   && TYPE_SIZE_UNIT (TREE_TYPE (optype))
   

libgo patch committed: Update to Go1.18beta2 release

2022-02-11 Thread Ian Lance Taylor via Gcc-patches
I've committed a change to update libgo to the Go1.18beta2 release.
Bootstrapped and tested on x86_64-pc-linux-gnu.  As usual with these
release updates, the change is too large for this e-mail.  Please see
the git history or https://go.dev/cl/384695 for the exact changes.

Ian

gotools/:

* Makefile.am (go_cmd_cgo_files): Add ast_go118.go
(check-go-tool): Copy golang.org/x/tools directories.
* Makefile.in: Regenerate.
1829e768a958f9886085d3f7a03677b2f45ea422
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 52f4b423f02..4e6bac7b7d5 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-b0dcd2d1e5e73952408b9f2d4d86ae12d102b20c
+47380f733ca932384e59492d2f04374edd8ec95e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gotools/Makefile.am b/gotools/Makefile.am
index 9e81024ea78..46481cb5173 100644
--- a/gotools/Makefile.am
+++ b/gotools/Makefile.am
@@ -62,6 +62,7 @@ go_cmd_gofmt_files = \
 
 go_cmd_cgo_files = \
$(cmdsrcdir)/cgo/ast.go \
+   $(cmdsrcdir)/cgo/ast_go118.go \
$(cmdsrcdir)/cgo/doc.go \
$(cmdsrcdir)/cgo/gcc.go \
$(cmdsrcdir)/cgo/godefs.go \
@@ -224,6 +225,7 @@ check-go-tool: go$(EXEEXT) $(noinst_PROGRAMS) check-head 
check-gccgo check-gcc
cp -r $(libgosrcdir)/golang.org/x/mod 
check-go-dir/src/cmd/vendor/golang.org/x/
cp -r $(libgosrcdir)/golang.org/x/crypto 
check-go-dir/src/cmd/vendor/golang.org/x/
cp -r $(libgosrcdir)/golang.org/x/xerrors 
check-go-dir/src/cmd/vendor/golang.org/x/
+   cp -r $(libgosrcdir)/golang.org/x/tools 
check-go-dir/src/cmd/vendor/golang.org/x/
cp $(libgodir)/objabi.go check-go-dir/src/cmd/internal/objabi/
@abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \
abs_checkdir=`cd check-go-dir && $(PWD_COMMAND)`; \
diff --git a/libgo/MERGE b/libgo/MERGE
index 4473f479d5f..662af9af882 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-21a4e67ad58e3c4a7c5254f60cda5be5c3c450ff
+41f485b9a7d8fd647c415be1d11b612063dff21c
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 5c377a30df9..be889f2a984 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -220,6 +220,7 @@ toolexeclibgodatabasesql_DATA = \
 toolexeclibgodebugdir = $(toolexeclibgodir)/debug
 
 toolexeclibgodebug_DATA = \
+   debug/buildinfo.gox \
debug/dwarf.gox \
debug/elf.gox \
debug/gosym.gox \
@@ -325,6 +326,7 @@ toolexeclibgonetdir = $(toolexeclibgodir)/net
 toolexeclibgonet_DATA = \
net/http.gox \
net/mail.gox \
+   net/netip.gox \
net/rpc.gox \
net/smtp.gox \
net/textproto.gox \
@@ -429,6 +431,7 @@ noinst_DATA = \
internal/testenv.gox \
internal/trace.gox \
net/internal/socktest.gox \
+   os/exec/internal/fdtest.gox \
os/signal/internal/pty.gox \
reflect/internal/example1.gox \
reflect/internal/example2.gox
@@ -483,53 +486,68 @@ version.go: s-version; @true
 s-version: Makefile
rm -f version.go.tmp
echo "package sys" > version.go.tmp
-   echo 'const GOARCH = "'$(GOARCH)'"' >> version.go.tmp
-   echo 'const GOOS = "'$(GOOS)'"' >> version.go.tmp
echo 'const GccgoToolDir = "$(libexecsubdir)"' >> version.go.tmp
echo 'const StackGuardMultiplierDefault = 1' >> version.go.tmp
-   echo >> version.go.tmp
-   echo "const (" >> version.go.tmp
-   echo "  UNKNOWN ArchFamilyType = iota" >> version.go.tmp
+   $(SHELL) $(srcdir)/mvifdiff.sh version.go.tmp version.go
+   $(STAMP) $@
+
+zgoarch.go: s-zgoarch; @true
+s-zgoarch: Makefile goarch.sh
+   rm -f zgoarch.go.tmp
+   echo "package goarch" > zgoarch.go.tmp
+   echo >> zgoarch.go.tmp
+   echo 'const GOARCH = "'$(GOARCH)'"' >> zgoarch.go.tmp
+   echo >> zgoarch.go.tmp
+   echo 'const (' >> zgoarch.go.tmp
+   echo "  _ArchFamily = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) family`" 
>> zgoarch.go.tmp
+   echo "  _BigEndian = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) 
bigendian`" >> zgoarch.go.tmp
+   echo "  _DefaultPhysPageSize = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) 
defaultphyspagesize`" >> zgoarch.go.tmp
+   echo "  _Int64Align = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) 
int64align`" >> zgoarch.go.tmp
+   echo "  _MinFrameSize = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) 
minframesize`" >> zgoarch.go.tmp
+   echo "  _PCQuantum = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) 
pcquantum`" >> zgoarch.go.tmp
+   echo "  _StackAlign = `$(SHELL) $(srcdir)/goarch.sh $(GOARCH) 
stackalign`" >> zgoarch.go.tmp
+   echo ")" >> zgoarch.go.tmp
+   echo >> zgoarch.go.tmp
+   echo "const (" >> zgoarch.go.tmp
+   echo "  UNKNOWN ArchFamilyType = iota" >> zgoarch.go.tmp
for a in $(ALLGOARCHFAMILY); do \
-   

[committed] i18n: fix exgettext handling of C++ sources

2022-02-11 Thread Joseph Myers
The move of source files to .cc names broke most message extraction by
exgettext because it processed .c files with --language=GCC-source but
didn't process .cc files that way.  Fix to process files identified as
C++ that way as well.

Tested with "make gcc.pot".  Applied to mainline.

* exgettext: Also process C++ sources with --language=GCC-source.

diff --git a/gcc/po/exgettext b/gcc/po/exgettext
index a69cdacb9bf..95cb0e75554 100644
--- a/gcc/po/exgettext
+++ b/gcc/po/exgettext
@@ -69,6 +69,7 @@ posrcxx=$pwd/$T/po-cxx-sources
 pottmp1=$pwd/$T/tmp1.pot
 pottmp2=$pwd/$T/tmp2.pot
 pottmp3=$pwd/$T/tmp3.pot
+pottmp4=$pwd/$T/tmp4.pot
 pottmp=$pwd/$T/tmp.pot
 
 # Locate files to scan.  We scan the following directories:
@@ -312,8 +313,13 @@ $xgettext --default-domain=$package --directory=$srcdir \
  --copyright-holder="Free Software Foundation, Inc." \
  --msgid-bugs-address="$BUGURL" \
  --language=GCC-source -o $pottmp3
+$xgettext --default-domain=$package --directory=$srcdir \
+ --add-comments --keyword= `cat $kopt2` --files-from=$posrcxx \
+ --copyright-holder="Free Software Foundation, Inc." \
+ --msgid-bugs-address="$BUGURL" \
+ --language=GCC-source -o $pottmp4
 $xgettext --default-domain=$package \
- --add-comments $pottmp1 $pottmp2 $pottmp3 \
+ --add-comments $pottmp1 $pottmp2 $pottmp3 $pottmp4 \
  --copyright-holder="Free Software Foundation, Inc." \
  --msgid-bugs-address="$BUGURL" \
  --language=PO -o $pottmp

-- 
Joseph S. Myers
jos...@codesourcery.com


[committed] preprocessor: Extract messages from cpp_*_at calls for translation

2022-02-11 Thread Joseph Myers
The logic in libcpp/Makefile.in listing diagnostic functions in a call
to xgettext was missing cpp_warning_at, cpp_pedwarning_at and
cpp_error_at, so resulting in some messages not being extracted for
translation; add those functions to those for which messages are
extracted.

Tested with "make cpplib.pot".  Applied to mainline.

* Makefile.in (po/$(PACKAGE).pot): Also handle cpp_warning_at,
cpp_pedwarning_at and cpp_error_at.

diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in
index 9e4c3fe5c16..08d48def0bc 100644
--- a/libcpp/Makefile.in
+++ b/libcpp/Makefile.in
@@ -252,10 +252,13 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
  --keyword=cpp_warning:3 \
  --keyword=cpp_pedwarning:3 \
  --keyword=cpp_warning_syshdr:3 \
+ --keyword=cpp_warning_at:4 \
+ --keyword=cpp_pedwarning_at:4 \
  --keyword=cpp_error_with_line:5 \
  --keyword=cpp_warning_with_line:5 \
  --keyword=cpp_pedwarning_with_line:5 \
  --keyword=cpp_warning_with_line_syshdr:5 \
+ --keyword=cpp_error_at:4 \
  --keyword=cpp_errno:3 \
  --keyword=SYNTAX_ERROR --keyword=SYNTAX_ERROR2 \
  --copyright-holder="Free Software Foundation, Inc." \

-- 
Joseph S. Myers
jos...@codesourcery.com


[pushed] LRA, rs6000, Darwin: Amend lo_sum use for forced constants [PR104117].

2022-02-11 Thread Iain Sandoe via Gcc-patches
Two issues resulted in this PR, which manifests when we force a constant into
memory in LRA (in PIC code on Darwin).  The presence of such forced constants
is quite dependent on other RTL optimisations, and it is easy for the issue to
become latent for a specific case.

First, in the Darwin-specific rs6000 backend code, we were not being careful
enough in rejecting invalid symbolic addresses.  Specifically, when generating
PIC code, we require a SYMBOL_REF to be wrapped in an UNSPEC_MACHOPIC_OFFSET.

Second, LRA was attempting to load a register using an invalid lo_sum address.

The LRA changes are approved in the PR by Vladimir, and the RS6000 changes are
Darwin-specific (although, of course, any observations are welcome).

Tested on several lo_sum targets and x86_64 all languages except as noted:
powerpc64-linux (m32/m64) -D
powerpc64le-linux  -D
powerpc64-aix -Ada -Go -D
aarch64-linux -Ada -D
x86_64-linux all langs -D
powerpc-darwin9 (master and 11.2) -D -Go.

pushed to master, thanks,
Iain

Signed-off-by: Iain Sandoe 
Co-authored-by: Vladimir Makarov 

PR target/104117

gcc/ChangeLog:

* config/rs6000/rs6000.cc (darwin_rs6000_legitimate_lo_sum_const_p):
Check for UNSPEC_MACHOPIC_OFFSET wrappers on symbolic addresses when
emitting PIC code.
(legitimate_lo_sum_address_p): Likewise.
* lra-constraints.cc (process_address_1): Do not attempt to emit a reg
load from an invalid lo_sum address.
---
 gcc/config/rs6000/rs6000.cc | 38 +++--
 gcc/lra-constraints.cc  | 17 ++---
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index eaba9a2d698..bc3ef0721a4 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -8317,8 +8317,14 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, 
machine_mode mode)
   if (GET_CODE (x) == CONST)
 x = XEXP (x, 0);
 
+  /* If we are building PIC code, then any symbol must be wrapped in an
+ UNSPEC_MACHOPIC_OFFSET so that it will get the picbase subtracted.  */
+  bool machopic_offs_p = false;
   if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_MACHOPIC_OFFSET)
-x =  XVECEXP (x, 0, 0);
+{
+  x =  XVECEXP (x, 0, 0);
+  machopic_offs_p = true;
+}
 
   rtx sym = NULL_RTX;
   unsigned HOST_WIDE_INT offset = 0;
@@ -8349,6 +8355,9 @@ darwin_rs6000_legitimate_lo_sum_const_p (rtx x, 
machine_mode mode)
   if (sym)
 {
   tree decl = SYMBOL_REF_DECL (sym);
+  /* As noted above, PIC code cannot use a bare SYMBOL_REF.  */
+  if (TARGET_MACHO && flag_pic && !machopic_offs_p)
+   return false;
 #if TARGET_MACHO
   if (MACHO_SYMBOL_INDIRECTION_P (sym))
   /* The decl in an indirection symbol is the original one, which might
@@ -8936,7 +8945,7 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, 
int strict)
 return false;
   x = XEXP (x, 1);
 
-  if (TARGET_ELF || TARGET_MACHO)
+  if (TARGET_ELF)
 {
   bool large_toc_ok;
 
@@ -8962,7 +8971,32 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, 
int strict)
 
   return CONSTANT_P (x) || large_toc_ok;
 }
+  else if (TARGET_MACHO)
+{
+  if (GET_MODE_NUNITS (mode) != 1)
+   return false;
+  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
+ && !(/* see above  */
+  TARGET_HARD_FLOAT && (mode == DFmode || mode == DDmode)))
+   return false;
+#if TARGET_MACHO
+  if (MACHO_DYNAMIC_NO_PIC_P || !flag_pic)
+   return CONSTANT_P (x);
+#endif
+  /* Macho-O PIC code from here.  */
+  if (GET_CODE (x) == CONST)
+   x = XEXP (x, 0);
+
+  /* SYMBOL_REFs need to be wrapped in an UNSPEC_MACHOPIC_OFFSET.  */
+  if (SYMBOL_REF_P (x))
+   return false;
 
+  /* So this is OK if the wrapped object is const.  */
+  if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_MACHOPIC_OFFSET)
+   return CONSTANT_P (XVECEXP (x, 0, 0));
+  return CONSTANT_P (x);
+}
   return false;
 }
 
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index fdff9e0720a..c700c3f4578 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -3625,21 +3625,8 @@ process_address_1 (int nop, bool check_only_p,
  *ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
  if (!valid_address_p (op, &ad, cn))
{
- /* Try to put lo_sum into register.  */
- insn = emit_insn (gen_rtx_SET
-   (new_reg,
-gen_rtx_LO_SUM (Pmode, new_reg, 
addr)));
- code = recog_memoized (insn);
- if (code >= 0)
-   {
- *ad.inner = new_reg;
- if (!valid_address_p (op, &ad, cn))
-   {
- *ad.inner = addr;
-  

Merge from trunk to gccgo branch

2022-02-11 Thread Ian Lance Taylor via Gcc-patches
I merged trunk revision 8dc2499aa62f768c6395c9754b8cabc1ce25c494 to
the gccgo branch.

Ian


[PATCH v7 00/12] Add LoongArch support.

2022-02-11 Thread xuchenghua
From: Chenghua Xu 

Hi, all:

This is the v7 version of LoongArch Port. Please review.

We know it is stage4, I think it is ok for a new prot.
The kernel side upstream waiting for a approval by gcc side,
if it is blocked by stage4, a approval for GCC13 will be appreciation.


The LoongArch architecture (LoongArch) is an Instruction Set
Architecture (ISA) that has a Reduced Instruction Set Computer (RISC)
style.
The documents are on
https://loongson.github.io/LoongArch-Documentation/README-EN.html

The ELF ABI Documents are on:
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html

The binutils has been merged into trunk:
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=560b3fe208255ae909b4b1c88ba9c28b09043307

Note: We split -mabi= into -mabi=lp64d/f/s, the new options not support by 
upstream binutils yet,
this GCC port requires the following patch applied to binutils to build.
https://github.com/loongson/binutils-gdb/commit/aacb0bf860f02aa5a7dcb76dd0e392bf871c7586
(will be submitted to upstream after gcc side comfirmed)

We have compiled more than 300 CLFS packages with this compiler.
The CLFS are currently used on Cfarm machines gcc400 and gcc401.

Changelog:

v1 -> v2
1. Split patch set.
2. Change some code style.
3. Add -mabi=lp64d/f/s options.
4. Change GLIBC_DYNAMIC_LINKER_LP64 name.

v2 -> v3
1. Change some code style.
2. Bug fix.

v3 -> v4
1. Change some code style.
2. Bug fix.
3. Delete some builtin macros.

v4 -> v5
1. delete wrong insn zero_extendsidi2_internal.
2. Adjust some build options.
3. Change some .c files to .cc.

v5 -> v6
1. Fix compilation issues. The generated files *.opt and *.h
   are generated to $(objdir).

v6 -> v7
1. Bug fix.
2. Change some code style.

chenglulu (12):
  LoongArch Port: Regenerate configure
  LoongArch Port: gcc build
  LoongArch Port: Regenerate gcc/configure.
  LoongArch Port: Machine description files.
  LoongArch Port: Machine description C files and .h files.
  LoongArch Port: Builtin functions.
  LoongArch Port: Builtin macros.
  LoongArch Port: libgcc
  LoongArch Port: Regenerate libgcc/configure.
  LoongArch Port: libgomp
  LoongArch Port: gcc/testsuite
  LoongArch Port: Add doc.

 config/picflag.m4 |3 +
 configure |   10 +-
 configure.ac  |   10 +-
 contrib/config-list.mk|5 +-
 contrib/gcc_update|2 +
 .../config/loongarch/loongarch-common.cc  |   73 +
 gcc/config.gcc|  410 +-
 gcc/config/host-linux.cc  |2 +
 gcc/config/loongarch/constraints.md   |  212 +
 gcc/config/loongarch/generic.md   |  132 +
 gcc/config/loongarch/genopts/genstr.sh|   91 +
 .../loongarch/genopts/loongarch-strings   |   58 +
 gcc/config/loongarch/genopts/loongarch.opt.in |  189 +
 gcc/config/loongarch/gnu-user.h   |   84 +
 gcc/config/loongarch/la464.md |  132 +
 gcc/config/loongarch/larchintrin.h|  413 ++
 gcc/config/loongarch/linux.h  |   50 +
 gcc/config/loongarch/loongarch-builtins.cc|  511 ++
 gcc/config/loongarch/loongarch-c.cc   |  109 +
 gcc/config/loongarch/loongarch-cpu.cc |  206 +
 gcc/config/loongarch/loongarch-cpu.h  |   30 +
 gcc/config/loongarch/loongarch-def.c  |  164 +
 gcc/config/loongarch/loongarch-def.h  |  151 +
 gcc/config/loongarch/loongarch-driver.cc  |  187 +
 gcc/config/loongarch/loongarch-driver.h   |   69 +
 gcc/config/loongarch/loongarch-ftypes.def |  106 +
 gcc/config/loongarch/loongarch-modes.def  |   29 +
 gcc/config/loongarch/loongarch-opts.cc|  580 ++
 gcc/config/loongarch/loongarch-opts.h |   86 +
 gcc/config/loongarch/loongarch-protos.h   |  241 +
 gcc/config/loongarch/loongarch-str.h  |   57 +
 gcc/config/loongarch/loongarch-tune.h |   72 +
 gcc/config/loongarch/loongarch.cc | 6318 +
 gcc/config/loongarch/loongarch.h  | 1271 
 gcc/config/loongarch/loongarch.md | 3702 ++
 gcc/config/loongarch/loongarch.opt|  189 +
 gcc/config/loongarch/predicates.md|  531 ++
 gcc/config/loongarch/sync.md  |  574 ++
 gcc/config/loongarch/t-linux  |   53 +
 gcc/config/loongarch/t-loongarch  |   68 +
 gcc/configure |   66 +-
 gcc/configure.ac  |   33 +-
 gcc/doc/install.texi  |   47 +-
 gcc/doc/invoke.texi   |  201 +
 gcc/doc/md.texi   |   55 +
 gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C|2 +-
 gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C   |2 +-
 gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C   |2 +-
 gcc/testsuite/gcc.dg/20020312-2.c |2 +
 gcc/t

[PATCH v7 01/12] LoongArch Port: Regenerate configure

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

* config/picflag.m4: Default add build option '-fpic' for LoongArch.
* configure: Add LoongArch tuples.
* configure.ac: Like wise.
---
 config/picflag.m4 |  3 +++
 configure | 10 +-
 configure.ac  | 10 +-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/config/picflag.m4 b/config/picflag.m4
index 8b106f9af88..0aefcf619bf 100644
--- a/config/picflag.m4
+++ b/config/picflag.m4
@@ -44,6 +44,9 @@ case "${$2}" in
# sets the default TLS model and affects inlining.
$1=-fPIC
;;
+loongarch*-*-*)
+   $1=-fpic
+   ;;
 mips-sgi-irix6*)
# PIC is the default.
;;
diff --git a/configure b/configure
index 9c2d7df1bb2..87548f0da96 100755
--- a/configure
+++ b/configure
@@ -3060,7 +3060,7 @@ case "${ENABLE_GOLD}" in
   # Check for target supported by gold.
   case "${target}" in
 i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-* \
-| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-*)
+| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-* | loongarch*-*-*)
  configdirs="$configdirs gold"
  if test x${ENABLE_GOLD} = xdefault; then
default_ld=gold
@@ -3646,6 +3646,9 @@ case "${target}" in
   i[3456789]86-*-*)
 libgloss_dir=i386
 ;;
+  loongarch*-*-*)
+libgloss_dir=loongarch
+;;
   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
 libgloss_dir=m68hc11
 ;;
@@ -4030,6 +4033,11 @@ case "${target}" in
   wasm32-*-*)
 noconfigdirs="$noconfigdirs ld"
 ;;
+  loongarch*-*-linux*)
+;;
+  loongarch*-*-*)
+noconfigdirs="$noconfigdirs gprof"
+;;
 esac
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
diff --git a/configure.ac b/configure.ac
index 68cc5cc31fe..55362afeeae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -353,7 +353,7 @@ case "${ENABLE_GOLD}" in
   # Check for target supported by gold.
   case "${target}" in
 i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-* \
-| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-*)
+| aarch64*-*-* | tilegx*-*-* | mips*-*-* | s390*-*-* | loongarch*-*-*)
  configdirs="$configdirs gold"
  if test x${ENABLE_GOLD} = xdefault; then
default_ld=gold
@@ -899,6 +899,9 @@ case "${target}" in
   i[[3456789]]86-*-*)
 libgloss_dir=i386
 ;;
+  loongarch*-*-*)
+libgloss_dir=loongarch
+;;
   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
 libgloss_dir=m68hc11
 ;;
@@ -1283,6 +1286,11 @@ case "${target}" in
   wasm32-*-*)
 noconfigdirs="$noconfigdirs ld"
 ;;
+  loongarch*-*-linux*)
+;;
+  loongarch*-*-*)
+noconfigdirs="$noconfigdirs gprof"
+;;
 esac
 
 # If we aren't building newlib, then don't build libgloss, since libgloss
-- 
2.31.1



[PATCH v7 03/12] LoongArch Port: Regenerate gcc/configure.

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

gcc/
* configure: Regenerate.
---
 gcc/configure | 66 ++-
 1 file changed, 60 insertions(+), 6 deletions(-)

diff --git a/gcc/configure b/gcc/configure
index 258b17a226e..fc967b70b2c 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -5442,6 +5442,9 @@ case "${target}" in
# sets the default TLS model and affects inlining.
PICFLAG_FOR_TARGET=-fPIC
;;
+loongarch*-*-*)
+   PICFLAG_FOR_TARGET=-fpic
+   ;;
 mips-sgi-irix6*)
# PIC is the default.
;;
@@ -7963,6 +7966,9 @@ else
 mips*-*-*)
   enable_fixed_point=yes
   ;;
+loongarch*-*-*)
+  enable_fixed_point=yes
+  ;;
 *)
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fixed-point is not 
supported for this target, ignored" >&5
 $as_echo "$as_me: WARNING: fixed-point is not supported for this target, 
ignored" >&2;}
@@ -19659,7 +19665,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 19662 "configure"
+#line 19668 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19765,7 +19771,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 19768 "configure"
+#line 19774 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -25548,6 +25554,17 @@ foo:   data8   25
movlr24 = @tprel(foo#)'
tls_as_opt=--fatal-warnings
;;
+  loongarch*-*-*)
+conftest_s='
+   .section .tdata,"awT",@progbits
+x: .word 2
+   .text
+   la.tls.gd $a0,x
+   bl __tls_get_addr'
+   tls_first_major=0
+   tls_first_minor=0
+   tls_as_opt='--fatal-warnings'
+   ;;
   microblaze*-*-*)
 conftest_s='
.section .tdata,"awT",@progbits
@@ -28770,6 +28787,43 @@ $as_echo "#define HAVE_AS_MARCH_ZIFENCEI 1" 
>>confdefs.h
 fi
 
 ;;
+  loongarch*-*-*)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for 
.dtprelword support" >&5
+$as_echo_n "checking assembler for .dtprelword support... " >&6; }
+if ${gcc_cv_as_loongarch_dtprelword+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_loongarch_dtprelword=no
+  if test x$gcc_cv_as != x; then
+$as_echo '' > conftest.s
+if { ac_try='$gcc_cv_as $gcc_cv_as_flags 2,18,0 -o conftest.o conftest.s 
>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then
+   .section .tdata,"awT",@progbits
+x:
+   .word 2
+   .text
+   .dtprelword x+0x8000
+else
+  echo "configure: failed program was" >&5
+  cat conftest.s >&5
+fi
+rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 
$gcc_cv_as_loongarch_dtprelword" >&5
+$as_echo "$gcc_cv_as_loongarch_dtprelword" >&6; }
+
+if test $gcc_cv_as_loongarch_dtprelword != yes; then
+
+$as_echo "#define HAVE_AS_DTPRELWORD 1" >>confdefs.h
+
+fi
+;;
 s390*-*-*)
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for 
.gnu_attribute support" >&5
 $as_echo_n "checking assembler for .gnu_attribute support... " >&6; }
@@ -28933,11 +28987,11 @@ fi
 ;;
 esac
 
-# Mips and HP-UX need the GNU assembler.
+# Mips, LoongArch and HP-UX need the GNU assembler.
 # Linux on IA64 might be able to use the Intel assembler.
 
 case "$target" in
-  mips*-*-* | *-*-hpux* )
+  mips*-*-* | loongarch*-*-* | *-*-hpux* )
 if test x$gas_flag = xyes \
|| test x"$host" != x"$build" \
|| test ! -x "$gcc_cv_as" \
@@ -29374,8 +29428,8 @@ esac
 # ??? Once 2.11 is released, probably need to add first known working
 # version to the per-target configury.
 case "$cpu_type" in
-  aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | m32c | m68k \
-  | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \
+  aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | loongarch | 
m32c \
+  | m68k | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | 
sparc \
   | tilegx | tilepro | visium | xstormy16 | xtensa)
 insn="nop"
 ;;
-- 
2.31.1



[PATCH v7 07/12] LoongArch Port: Builtin macros.

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

gcc/

*config/loongarch/loongarch-c.cc
---
 gcc/config/loongarch/loongarch-c.cc | 109 
 1 file changed, 109 insertions(+)
 create mode 100644 gcc/config/loongarch/loongarch-c.cc

diff --git a/gcc/config/loongarch/loongarch-c.cc 
b/gcc/config/loongarch/loongarch-c.cc
new file mode 100644
index 000..e914bf306d5
--- /dev/null
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -0,0 +1,109 @@
+/* LoongArch-specific code for C family languages.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "c-family/c-common.h"
+#include "cpplib.h"
+
+#define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+
+/* Define preprocessor macros for the -march and -mtune options.
+   PREFIX is either _LOONGARCH_ARCH or _LOONGARCH_TUNE, INFO is
+   the selected processor.  If INFO's canonical name is "foo",
+   define PREFIX to be "foo", and define an additional macro
+   PREFIX_FOO.  */
+#define LARCH_CPP_SET_PROCESSOR(PREFIX, CPU_TYPE)  \
+  do   \
+{  \
+  char *macro, *p; \
+  int cpu_type = (CPU_TYPE);   \
+   \
+  macro = concat ((PREFIX), "_",   \
+ loongarch_cpu_strings[cpu_type], NULL);   \
+  for (p = macro; *p != 0; p++)\
+   *p = TOUPPER (*p);  \
+   \
+  builtin_define (macro);  \
+  builtin_define_with_value ((PREFIX), \
+loongarch_cpu_strings[cpu_type], 1);   \
+  free (macro);\
+}  \
+  while (0)
+
+void
+loongarch_cpu_cpp_builtins (cpp_reader *pfile)
+{
+  builtin_assert ("machine=loongarch");
+  builtin_assert ("cpu=loongarch");
+  builtin_define ("__loongarch__");
+
+  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", __ACTUAL_ARCH);
+  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", __ACTUAL_TUNE);
+
+  /* Base architecture / ABI.  */
+  if (TARGET_64BIT)
+{
+  builtin_define ("__loongarch_grlen=64");
+  builtin_define ("__loongarch64");
+}
+
+  if (TARGET_ABI_LP64)
+{
+  builtin_define ("_ABILP64=3");
+  builtin_define ("_LOONGARCH_SIM=_ABILP64");
+  builtin_define ("__loongarch_lp64");
+}
+
+  /* These defines reflect the ABI in use, not whether the
+ FPU is directly accessible.  */
+  if (TARGET_DOUBLE_FLOAT_ABI)
+builtin_define ("__loongarch_double_float=1");
+  else if (TARGET_SINGLE_FLOAT_ABI)
+builtin_define ("__loongarch_single_float=1");
+
+  if (TARGET_DOUBLE_FLOAT_ABI || TARGET_SINGLE_FLOAT_ABI)
+builtin_define ("__loongarch_hard_float=1");
+  else
+builtin_define ("__loongarch_soft_float=1");
+
+
+  /* ISA Extensions.  */
+  if (TARGET_DOUBLE_FLOAT)
+builtin_define ("__loongarch_frlen=64");
+  else if (TARGET_SINGLE_FLOAT)
+builtin_define ("__loongarch_frlen=32");
+  else
+builtin_define ("__loongarch_frlen=0");
+
+  /* Native Data Sizes.  */
+  builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE);
+  builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE);
+  builtin_define_with_int_value ("_LOONGARCH_SZPTR", POINTER_SIZE);
+  builtin_define_with_int_value ("_LOONGARCH_FPSET", 32 / MAX_FPRS_PER_FMT);
+  builtin_define_with_int_value ("_LOONGARCH_SPFPSET", 32);
+
+}
-- 
2.31.1



[PATCH v7 06/12] LoongArch Port: Builtin functions.

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

gcc/

* config/loongarch/larchintrin.h: New file.
* config/loongarch/loongarch-builtins.cc: New file.
---
 gcc/config/loongarch/larchintrin.h | 413 +
 gcc/config/loongarch/loongarch-builtins.cc | 511 +
 2 files changed, 924 insertions(+)
 create mode 100644 gcc/config/loongarch/larchintrin.h
 create mode 100644 gcc/config/loongarch/loongarch-builtins.cc

diff --git a/gcc/config/loongarch/larchintrin.h 
b/gcc/config/loongarch/larchintrin.h
new file mode 100644
index 000..d8e2a743ae5
--- /dev/null
+++ b/gcc/config/loongarch/larchintrin.h
@@ -0,0 +1,413 @@
+/* Intrinsics for LoongArch BASE operations.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 3, or (at your
+option) any later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+.  */
+
+#ifndef _GCC_LOONGARCH_BASE_INTRIN_H
+#define _GCC_LOONGARCH_BASE_INTRIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct drdtime
+{
+  unsigned long dvalue;
+  unsigned long dtimeid;
+} __drdtime_t;
+
+typedef struct rdtime
+{
+  unsigned int value;
+  unsigned int timeid;
+} __rdtime_t;
+
+#ifdef __loongarch64
+extern __inline __drdtime_t
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__builtin_loongarch_rdtime_d (void)
+{
+  __drdtime_t drdtime;
+  __asm__ volatile (
+"rdtime.d\t%[val],%[tid]\n\t"
+: [val]"=&r"(drdtime.dvalue),[tid]"=&r"(drdtime.dtimeid)
+:);
+  return drdtime;
+}
+#define __rdtime_d __builtin_loongarch_rdtime_d
+#endif
+
+extern __inline __rdtime_t
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__builtin_loongarch_rdtimeh_w (void)
+{
+  __rdtime_t rdtime;
+  __asm__ volatile (
+"rdtimeh.w\t%[val],%[tid]\n\t"
+: [val]"=&r"(rdtime.value),[tid]"=&r"(rdtime.timeid)
+:);
+  return rdtime;
+}
+#define __rdtimel_w __builtin_loongarch_rdtimel_w
+
+extern __inline __rdtime_t
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__builtin_loongarch_rdtimel_w (void)
+{
+  __rdtime_t rdtime;
+  __asm__ volatile (
+"rdtimel.w\t%[val],%[tid]\n\t"
+: [val]"=&r"(rdtime.value),[tid]"=&r"(rdtime.timeid)
+:);
+  return rdtime;
+}
+#define __rdtimeh_w __builtin_loongarch_rdtimeh_w
+
+/* Assembly instruction format:rj, fcsr.  */
+/* Data types in instruction templates:  USI, UQI.  */
+#define __movfcsr2gr(/*ui5*/ _1) __builtin_loongarch_movfcsr2gr ((_1));
+
+/* Assembly instruction format:0, fcsr, rj.  */
+/* Data types in instruction templates:  VOID, UQI, USI.  */
+#define __movgr2fcsr(/*ui5*/ _1, _2) \
+  __builtin_loongarch_movgr2fcsr ((unsigned short) _1, (unsigned int) _2);
+
+#if defined __loongarch64
+/* Assembly instruction format:ui5, rj, si12.  */
+/* Data types in instruction templates:  VOID, USI, UDI, SI.  */
+#define __dcacop(/*ui5*/ _1, /*unsigned long int*/ _2, /*si12*/ _3) \
+  ((void) __builtin_loongarch_dcacop ((_1), (unsigned long int) (_2), (_3)))
+#else
+#error "Don't support this ABI."
+#endif
+
+/* Assembly instruction format:rd, rj.  */
+/* Data types in instruction templates:  USI, USI.  */
+extern __inline unsigned int
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__cpucfg (unsigned int _1)
+{
+  return (unsigned int) __builtin_loongarch_cpucfg ((unsigned int) _1);
+}
+
+#ifdef __loongarch64
+/* Assembly instruction format:rd, rj.  */
+/* Data types in instruction templates:  DI, DI.  */
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__asrtle_d (long int _1, long int _2)
+{
+  __builtin_loongarch_asrtle_d ((long int) _1, (long int) _2);
+}
+
+/* Assembly instruction format:rd, rj.  */
+/* Data types in instruction templates:  DI, DI.  */
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__asrtgt_d (long int _1, long int _2)
+{
+  __builtin_loongarch_asrtgt_d ((long int) _1, (long int) _2);
+}
+#endif
+
+#if defined __loongarch64
+/* Assembly instruction format:rd, rj, ui5.  */
+/* 

[PATCH v7 02/12] LoongArch Port: gcc build

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

gcc/

* common/config/loongarch/loongarch-common.cc: New file.
* config/loongarch/genopts/genstr.sh: New file.
* config/loongarch/genopts/loongarch-strings: New file.
* config/loongarch/genopts/loongarch.opt.in: New file.
* config/loongarch/loongarch-str.h: New file.
* config/loongarch/gnu-user.h: New file.
* config/loongarch/linux.h: New file.
* config/loongarch/loongarch-cpu.cc: New file.
* config/loongarch/loongarch-cpu.h: New file.
* config/loongarch/loongarch-def.c: New file.
* config/loongarch/loongarch-def.h: New file.
* config/loongarch/loongarch-driver.cc: New file.
* config/loongarch/loongarch-driver.h: New file.
* config/loongarch/loongarch-opts.cc: New file.
* config/loongarch/loongarch-opts.h: New file.
* config/loongarch/loongarch.opt: New file.
* config/loongarch/t-linux: New file.
* config/loongarch/t-loongarch: New file.
* gcc_update (files_and_dependencies): Add
config/loongarch/loongarch.opt and config/loongarch/loongarch-str.h.
* config.gcc: Add LoongArch support.
* configure.ac: Add LoongArch support.
---
 contrib/gcc_update|   2 +
 .../config/loongarch/loongarch-common.cc  |  73 +++
 gcc/config.gcc| 410 -
 gcc/config/loongarch/genopts/genstr.sh|  91 +++
 .../loongarch/genopts/loongarch-strings   |  58 ++
 gcc/config/loongarch/genopts/loongarch.opt.in | 189 ++
 gcc/config/loongarch/gnu-user.h   |  84 +++
 gcc/config/loongarch/linux.h  |  50 ++
 gcc/config/loongarch/loongarch-cpu.cc | 206 +++
 gcc/config/loongarch/loongarch-cpu.h  |  30 +
 gcc/config/loongarch/loongarch-def.c  | 164 +
 gcc/config/loongarch/loongarch-def.h  | 151 +
 gcc/config/loongarch/loongarch-driver.cc  | 187 ++
 gcc/config/loongarch/loongarch-driver.h   |  69 +++
 gcc/config/loongarch/loongarch-opts.cc| 580 ++
 gcc/config/loongarch/loongarch-opts.h |  86 +++
 gcc/config/loongarch/loongarch-str.h  |  57 ++
 gcc/config/loongarch/loongarch.opt| 189 ++
 gcc/config/loongarch/t-linux  |  53 ++
 gcc/config/loongarch/t-loongarch  |  68 ++
 gcc/configure.ac  |  33 +-
 21 files changed, 2825 insertions(+), 5 deletions(-)
 create mode 100644 gcc/common/config/loongarch/loongarch-common.cc
 create mode 100755 gcc/config/loongarch/genopts/genstr.sh
 create mode 100644 gcc/config/loongarch/genopts/loongarch-strings
 create mode 100644 gcc/config/loongarch/genopts/loongarch.opt.in
 create mode 100644 gcc/config/loongarch/gnu-user.h
 create mode 100644 gcc/config/loongarch/linux.h
 create mode 100644 gcc/config/loongarch/loongarch-cpu.cc
 create mode 100644 gcc/config/loongarch/loongarch-cpu.h
 create mode 100644 gcc/config/loongarch/loongarch-def.c
 create mode 100644 gcc/config/loongarch/loongarch-def.h
 create mode 100644 gcc/config/loongarch/loongarch-driver.cc
 create mode 100644 gcc/config/loongarch/loongarch-driver.h
 create mode 100644 gcc/config/loongarch/loongarch-opts.cc
 create mode 100644 gcc/config/loongarch/loongarch-opts.h
 create mode 100644 gcc/config/loongarch/loongarch-str.h
 create mode 100644 gcc/config/loongarch/loongarch.opt
 create mode 100644 gcc/config/loongarch/t-linux
 create mode 100644 gcc/config/loongarch/t-loongarch

diff --git a/contrib/gcc_update b/contrib/gcc_update
index 1cf15f9b3c2..641ce164775 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -86,6 +86,8 @@ gcc/config/arm/arm-tables.opt: gcc/config/arm/arm-cpus.in 
gcc/config/arm/parsecp
 gcc/config/c6x/c6x-tables.opt: gcc/config/c6x/c6x-isas.def 
gcc/config/c6x/genopt.sh
 gcc/config/c6x/c6x-sched.md: gcc/config/c6x/c6x-sched.md.in 
gcc/config/c6x/gensched.sh
 gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in 
gcc/config/c6x/genmult.sh
+gcc/config/loongarch/loongarch-str.h: gcc/config/loongarch/genopts/genstr.sh 
gcc/config/loongarch/genopts/loongarch-string
+gcc/config/loongarch/loongarch.opt: gcc/config/loongarch/genopts/genstr.sh 
gcc/config/loongarch/genopts/loongarch.opt.in
 gcc/config/m68k/m68k-tables.opt: gcc/config/m68k/m68k-devices.def 
gcc/config/m68k/m68k-isas.def gcc/config/m68k/m68k-microarchs.def 
gcc/config/m68k/genopt.sh
 gcc/config/mips/mips-tables.opt: gcc/config/mips/mips-cpus.def 
gcc/config/mips/genopt.sh
 gcc/config/rs6000/rs6000-tables.opt: gcc/config/rs6000/rs6000-cpus.def 
gcc/config/rs6000/genopt.sh
diff --git a/gcc/common/config/loongarch/loongarch-common.cc 
b/gcc/common/config/loongarch/loongarch-common.cc
new file mode 100644
index 000..5bdfd2a30e1
--- /dev/null
+++ b/gcc/common/config/loongarch/loongarch-common.cc
@@ -0,0 +1,73 @@
+/* Common hooks for LoongArch.
+

[PATCH v7 10/12] LoongArch Port: libgomp

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

libgomp/

* configure.tgt: Add LoongArch triplet.
---
 libgomp/configure.tgt | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index d4f1e741b5a..2cd7272fcd8 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -56,6 +56,10 @@ if test x$enable_linux_futex = xyes; then
config_path="linux/ia64 linux posix"
;;
 
+loongarch*-*-linux*)
+   config_path="linux posix"
+   ;;
+
 mips*-*-linux*)
config_path="linux/mips linux posix"
;;
-- 
2.31.1



[PATCH v7 08/12] LoongArch Port: libgcc

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

libgcc/

* config/loongarch/crtfastmath.c: New file.
* config/loongarch/crti.S: Like wise.
* config/loongarch/crtn.S: Like wise.
* config/loongarch/linux-unwind.h: Like wise.
* config/loongarch/sfp-machine.h: Like wise.
* config/loongarch/t-crtstuff: Like wise.
* config/loongarch/t-loongarch: Like wise.
* config/loongarch/t-loongarch64: Like wise.
* config/loongarch/t-softfp-tf: Like wise.
* config.host: Add LoongArch tuples.
* configure.ac: Add LoongArch support.
---
 libgcc/config.host |  28 -
 libgcc/config/loongarch/crtfastmath.c  |  52 +
 libgcc/config/loongarch/crti.S |  43 +++
 libgcc/config/loongarch/crtn.S |  39 +++
 libgcc/config/loongarch/linux-unwind.h |  80 +
 libgcc/config/loongarch/sfp-machine.h  | 152 +
 libgcc/config/loongarch/t-crtstuff |   5 +
 libgcc/config/loongarch/t-loongarch|   7 ++
 libgcc/config/loongarch/t-loongarch64  |   1 +
 libgcc/config/loongarch/t-softfp-tf|   3 +
 libgcc/configure.ac|   2 +-
 11 files changed, 410 insertions(+), 2 deletions(-)
 create mode 100644 libgcc/config/loongarch/crtfastmath.c
 create mode 100644 libgcc/config/loongarch/crti.S
 create mode 100644 libgcc/config/loongarch/crtn.S
 create mode 100644 libgcc/config/loongarch/linux-unwind.h
 create mode 100644 libgcc/config/loongarch/sfp-machine.h
 create mode 100644 libgcc/config/loongarch/t-crtstuff
 create mode 100644 libgcc/config/loongarch/t-loongarch
 create mode 100644 libgcc/config/loongarch/t-loongarch64
 create mode 100644 libgcc/config/loongarch/t-softfp-tf

diff --git a/libgcc/config.host b/libgcc/config.host
index 094fd3ad254..8c56fcae5d2 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -138,6 +138,22 @@ hppa*-*-*)
 lm32*-*-*)
cpu_type=lm32
;;
+loongarch*-*-*)
+   cpu_type=loongarch
+   tmake_file="loongarch/t-loongarch"
+   if test "${libgcc_cv_loongarch_hard_float}" = yes; then
+   tmake_file="${tmake_file} t-hardfp-sfdf t-hardfp"
+   else
+   tmake_file="${tmake_file} t-softfp-sfdf"
+   fi
+   if test "${ac_cv_sizeof_long_double}" = 16; then
+   tmake_file="${tmake_file} loongarch/t-softfp-tf"
+   fi
+   if test "${host_address}" = 64; then
+   tmake_file="${tmake_file} loongarch/t-loongarch64"
+   fi
+   tmake_file="${tmake_file} t-softfp"
+   ;;
 m32r*-*-*)
 cpu_type=m32r
 ;;
@@ -925,7 +941,17 @@ lm32-*-rtems*)
 lm32-*-uclinux*)
 extra_parts="$extra_parts crtbegin.o crtendS.o crtbeginT.o"
 tmake_file="lm32/t-lm32 lm32/t-uclinux t-libgcc-pic t-softfp-sfdf 
t-softfp"
-   ;;  
+   ;;
+loongarch*-*-linux*)
+   extra_parts="$extra_parts crtfastmath.o"
+   tmake_file="${tmake_file} t-crtfm loongarch/t-crtstuff"
+   case ${host} in
+ *)
+   tmake_file="${tmake_file} t-slibgcc-libgcc"
+   ;;
+   esac
+   md_unwind_header=loongarch/linux-unwind.h
+   ;;
 m32r-*-elf*)
tmake_file="$tmake_file m32r/t-m32r t-fdpbit"
extra_parts="$extra_parts crtinit.o crtfini.o"
diff --git a/libgcc/config/loongarch/crtfastmath.c 
b/libgcc/config/loongarch/crtfastmath.c
new file mode 100644
index 000..52b0d6da087
--- /dev/null
+++ b/libgcc/config/loongarch/crtfastmath.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2021-2022 Free Software Foundation, Inc.
+   Contributed by Loongson Ltd.
+   Based on MIPS target for GNU compiler.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License
+and a copy of the GCC Runtime Library Exception along with this
+program; see the files COPYING3 and COPYING.RUNTIME respectively.
+If not, see .  */
+
+#ifdef __loongarch_hard_float
+
+/* Rounding control.  */
+#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED.  */
+#define _FPU_RC_ZERO0x100
+#define _FPU_RC_UP  0x200
+#define _FPU_RC_DOWN0x300
+
+/* Enable interrupts for IEEE exceptions.  */
+#define _FPU_IEEE 0x001F
+
+/* Macros for accessing the hardware control word.  */
+#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr

[PATCH v7 11/12] LoongArch Port: gcc/testsuite

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

gcc/testsuite/

* g++.dg/cpp0x/constexpr-rom.C: Add build options for LoongArch.
* g++.old-deja/g++.abi/ptrmem.C: Add LoongArch support.
* g++.old-deja/g++.pt/ptrmem6.C: xfail for LoongArch.
* gcc.dg/20020312-2.c: Add LoongArch support.
* gcc.dg/loop-8.c: Skip on LoongArch.
* gcc.dg/torture/stackalign/builtin-apply-2.c: Likewise.
* gcc.dg/tree-ssa/ssa-fre-3.c: Likewise.
* go.test/go-test.exp: Define the LoongArch target.
* lib/target-supports.exp: Like wise.
* gcc.target/loongarch/loongarch.exp: New file.
* gcc.target/loongarch/tst-asm-const.c: Like wise.
---
 gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C|  2 +-
 gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C   |  2 +-
 gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C   |  2 +-
 gcc/testsuite/gcc.dg/20020312-2.c |  2 +
 gcc/testsuite/gcc.dg/loop-8.c |  2 +-
 .../torture/stackalign/builtin-apply-2.c  |  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c |  2 +-
 .../gcc.target/loongarch/loongarch.exp| 40 +++
 .../gcc.target/loongarch/tst-asm-const.c  | 16 
 gcc/testsuite/go.test/go-test.exp |  3 ++
 gcc/testsuite/lib/target-supports.exp | 14 +++
 11 files changed, 81 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/loongarch.exp
 create mode 100644 gcc/testsuite/gcc.target/loongarch/tst-asm-const.c

diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C
index 2e0ef685f36..424979a604b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-rom.C
@@ -1,6 +1,6 @@
 // PR c++/49673: check that test_data goes into .rodata
 // { dg-do compile { target c++11 } }
-// { dg-additional-options -G0 { target { { alpha*-*-* frv*-*-* ia64-*-* 
lm32*-*-* m32r*-*-* microblaze*-*-* mips*-*-* nios2-*-* powerpc*-*-* 
rs6000*-*-* } && { ! { *-*-darwin* *-*-aix* alpha*-*-*vms* } } } } }
+// { dg-additional-options -G0 { target { { alpha*-*-* frv*-*-* ia64-*-* 
lm32*-*-* m32r*-*-* microblaze*-*-* mips*-*-* loongarch*-*-* nios2-*-* 
powerpc*-*-* rs6000*-*-* } && { ! { *-*-darwin* *-*-aix* alpha*-*-*vms* } } } } 
}
 // { dg-final { scan-assembler "\\.rdata" { target mips*-*-* } } }
 // { dg-final { scan-assembler "rodata" { target { { *-*-linux-gnu *-*-gnu* 
*-*-elf } && { ! { mips*-*-* riscv*-*-* } } } } } }
 
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C 
b/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C
index bda7960d8a2..f69000e9081 100644
--- a/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C
+++ b/gcc/testsuite/g++.old-deja/g++.abi/ptrmem.C
@@ -7,7 +7,7 @@
function.  However, some platforms use all bits to encode a
function pointer.  Such platforms use the lowest bit of the delta,
that is shifted left by one bit.  */
-#if defined __MN10300__ || defined __SH5__ || defined __arm__ || defined 
__thumb__ || defined __mips__ || defined __aarch64__ || defined __PRU__
+#if defined __MN10300__ || defined __SH5__ || defined __arm__ || defined 
__thumb__ || defined __mips__ || defined __aarch64__ || defined __PRU__ || 
defined __loongarch__
 #define ADJUST_PTRFN(func, virt) ((void (*)())(func))
 #define ADJUST_DELTA(delta, virt) (((delta) << 1) + !!(virt))
 #else
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C 
b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C
index 9f4bbe43f89..8f8f7017ab7 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C
@@ -25,7 +25,7 @@ int main() {
   h<&B::j>(); // { dg-error "" } 
   g<(void (A::*)()) &A::f>(); // { dg-error "" "" { xfail c++11 } }
   h<(int A::*) &A::i>(); // { dg-error "" "" { xfail c++11 } }
-  g<(void (A::*)()) &B::f>(); // { dg-error "" "" { xfail { c++11 && { 
aarch64*-*-* arm*-*-* mips*-*-* } } } }
+  g<(void (A::*)()) &B::f>(); // { dg-error "" "" { xfail { c++11 && { 
aarch64*-*-* arm*-*-* mips*-*-* loongarch*-*-* } } } }
   h<(int A::*) &B::j>(); // { dg-error "" } 
   g<(void (A::*)()) 0>(); // { dg-error "" "" { target { ! c++11 } } }
   h<(int A::*) 0>(); // { dg-error "" "" { target { ! c++11 } } }
diff --git a/gcc/testsuite/gcc.dg/20020312-2.c 
b/gcc/testsuite/gcc.dg/20020312-2.c
index 52c33d09b90..92bc150df0f 100644
--- a/gcc/testsuite/gcc.dg/20020312-2.c
+++ b/gcc/testsuite/gcc.dg/20020312-2.c
@@ -37,6 +37,8 @@ extern void abort (void);
 /* PIC register is r1, but is used even without -fpic.  */
 #elif defined(__lm32__)
 /* No pic register.  */
+#elif defined(__loongarch__)
+/* No pic register.  */
 #elif defined(__M32R__)
 /* No pic register.  */
 #elif defined(__m68k__)
diff --git a/gcc/testsuite/gcc.dg/loop-8.c b/gcc/testsuite/gcc.dg/loop-8.c
index a685fc25056..8e5f2087831 100644
--- a/gcc/testsuite/gcc.dg/loop-8.c
+++ b/gcc/testsuite/gcc.dg/loop-8.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } *

[PATCH v7 09/12] LoongArch Port: Regenerate libgcc/configure.

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

* libgcc/configure: Regenerate.
---
 libgcc/configure | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libgcc/configure b/libgcc/configure
index 4919a56f518..ce04c4f529f 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -2412,6 +2412,9 @@ case "${host}" in
# sets the default TLS model and affects inlining.
PICFLAG=-fPIC
;;
+loongarch*-*-*)
+   PICFLAG=-fpic
+   ;;
 mips-sgi-irix6*)
# PIC is the default.
;;
@@ -5066,7 +5069,7 @@ $as_echo "$libgcc_cv_cfi" >&6; }
 # word size rather than the address size.
 cat > conftest.c <

[PATCH v7 12/12] LoongArch Port: Add doc.

2022-02-11 Thread xuchenghua
From: chenglulu 

2022-02-12  Chenghua Xu  
Lulu Cheng  

* contrib/config-list.mk: Add LoongArch triplet.
* gcc/doc/install.texi: Add LoongArch options section.
* gcc/doc/invoke.texi: Add LoongArch options section.
* gcc/doc/md.texi: Add LoongArch options section.
---
 contrib/config-list.mk |   5 +-
 gcc/doc/install.texi   |  47 +-
 gcc/doc/invoke.texi| 201 +
 gcc/doc/md.texi|  55 +++
 4 files changed, 302 insertions(+), 6 deletions(-)

diff --git a/contrib/config-list.mk b/contrib/config-list.mk
index 3e1d1321861..ba6f12e4693 100644
--- a/contrib/config-list.mk
+++ b/contrib/config-list.mk
@@ -57,7 +57,10 @@ LIST = aarch64-elf aarch64-linux-gnu aarch64-rtems \
   i686-wrs-vxworksae \
   i686-cygwinOPT-enable-threads=yes i686-mingw32crt ia64-elf \
   ia64-freebsd6 ia64-linux ia64-hpux ia64-hp-vms iq2000-elf lm32-elf \
-  lm32-rtems lm32-uclinux m32c-rtems m32c-elf m32r-elf m32rle-elf \
+  lm32-rtems lm32-uclinux \
+  loongarch64-linux-gnu loongarch64-linux-gnuf64 \
+  loongarch64-linux-gnuf32 loongarch64-linux-gnusf \
+  m32c-rtems m32c-elf m32r-elf m32rle-elf \
   m68k-elf m68k-netbsdelf \
   m68k-uclinux m68k-linux m68k-rtems \
   mcore-elf microblaze-linux microblaze-elf \
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 7258f9def6c..5fb55b1d064 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -747,9 +747,9 @@ Here are the possible CPU types:
 @quotation
 aarch64, aarch64_be, alpha, alpha64, amdgcn, arc, arceb, arm, armeb, avr, bfin,
 bpf, cr16, cris, csky, epiphany, fido, fr30, frv, ft32, h8300, hppa, hppa2.0,
-hppa64, i486, i686, ia64, iq2000, lm32, m32c, m32r, m32rle, m68k, mcore,
-microblaze, microblazeel, mips, mips64, mips64el, mips64octeon, mips64orion,
-mips64vr, mipsel, mipsisa32, mipsisa32r2, mipsisa64, mipsisa64r2,
+hppa64, i486, i686, ia64, iq2000, lm32, loongarch64, m32c, m32r, m32rle, m68k,
+mcore, microblaze, microblazeel, mips, mips64, mips64el, mips64octeon,
+mips64orion, mips64vr, mipsel, mipsisa32, mipsisa32r2, mipsisa64, mipsisa64r2,
 mipsisa64r2el, mipsisa64sb1, mipsisa64sr71k, mipstx39, mmix, mn10300, moxie,
 msp430, nds32be, nds32le, nios2, nvptx, or1k, pdp11, powerpc, powerpc64,
 powerpc64le, powerpcle, pru, riscv32, riscv32be, riscv64, riscv64be, rl78, rx,
@@ -1166,8 +1166,9 @@ sysv, aix.
 @itemx --without-multilib-list
 Specify what multilibs to build.  @var{list} is a comma separated list of
 values, possibly consisting of a single value.  Currently only implemented
-for aarch64*-*-*, arm*-*-*, riscv*-*-*, sh*-*-* and x86-64-*-linux*.  The
-accepted values and meaning for each target is given below.
+for aarch64*-*-*, arm*-*-*, loongarch64-*-*, riscv*-*-*, sh*-*-* and
+x86-64-*-linux*.  The accepted values and meaning for each target is given
+below.
 
 @table @code
 @item aarch64*-*-*
@@ -1254,6 +1255,14 @@ profile.  The union of these options is considered when 
specifying both
 @code{-mfloat-abi=hard}
 @end multitable
 
+@item loongarch*-*-*
+@var{list} is a comma-separated list of the following ABI identifiers:
+@code{lp64d[/base]} @code{lp64f[/base]} @code{lp64d[/base]}, where the
+@code{/base} suffix may be omitted, to enable their respective run-time
+libraries.  If @var{list} is empty, @code{default}
+or @option{--with-multilib-list} is not specified, then the default ABI
+as specified by @option{--with-abi} or implied by @option{--target} is 
selected.
+
 @item riscv*-*-*
 @var{list} is a single ABI name.  The target architecture must be either
 @code{rv32gc} or @code{rv64gc}.  This will build a single multilib for the
@@ -4439,6 +4448,34 @@ This configuration is intended for embedded systems.
 Lattice Mico32 processor.
 This configuration is intended for embedded systems running uClinux.
 
+@html
+
+@end html
+@anchor{loongarch}
+@heading LoongArch
+LoongArch processor.
+The following LoongArch targets are available:
+@table @code
+@item loongarch64-linux-gnu*
+LoongArch processor running GNU/Linux.  This target triplet may be coupled
+with a small set of possible suffixes to identify their default ABI type:
+@table @code
+@item f64
+Uses @code{lp64d/base} ABI by default.
+@item f32
+Uses @code{lp64f/base} ABI by default.
+@item sf
+Uses @code{lp64s/base} ABI by default.
+@end table
+
+@item loongarch64-linux-gnu
+Same as @code{loongarch64-linux-gnuf64}, but may be used with
+@option{--with-abi=*} to configure the default ABI type.
+@end table
+
+More information about LoongArch can be found at
+@uref{https://github.com/loongson/LoongArch-Documentation}.
+
 @html
 
 @end html
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b49ba22df89..a60a63c4e96 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -995,6 +995,16 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-mbarrel-shift-enabled  -mdivide-enabled  -mmultiply-enabled @gol
 -msign-extend-enabled  -muser-enabled}
 
+@emph{LoongArch Options}
+@g

Re: [PATCH v2] MIPS: IPL is 8bit in Cause register if TARGET_MCU

2022-02-11 Thread Jeff Law via Gcc-patches




On 2/8/2022 8:18 PM, YunQiang Su wrote:

If MIPS MCU extension is enable, the IPL section in Cause register
has been expand to 8bit instead of 6bit.

gcc/ChangeLog:

* config/mips/mips.cc (mips_expand_prologue):
  IPL is 8bit for MCU ASE.

OK
jeff



Re: [PATCH] [PATCH,v4,1/1,AARCH64][PR102768] aarch64: Add compiler support for Shadow Call Stack

2022-02-11 Thread Dan Li via Gcc-patches




On 2/11/22 07:35, Richard Sandiford wrote:

Dan Li  writes:

On 2/11/22 01:53, Richard Sandiford wrote:

Dan Li  writes:

On 2/10/22 01:55, Richard Sandiford wrote:



And I think maybe we could handle this through three patches:
1.Keep current patch (a V5) unchanged for scs.
2.Add shrink-warpping for X30:
logically this might be a separate topic, and I think more testing
might be needed here (Well, I'm a little worried about if there might
be other effects, since I just read this part of the code roughly
yesterday).
3.Add scs push/pop to shrink-wrapping (and maybe we can do the same for
the PAC code in pro/epilogue, since it's also the operation of the X30).


Yeah, that's fair.

(Like I said earlier, I wasn't asking for the shrink-wrapping change.
It was just a note in passing.  But as you point out, the individual
shrink-wrapping support would be even more work than I'd imagined.)



Got it!

Thanks,
Dan


Re: [PATCH] x86: Update PR 35513 tests

2022-02-11 Thread Hongtao Liu via Gcc-patches
On Thu, Feb 10, 2022 at 9:58 PM H.J. Lu via Gcc-patches
 wrote:
>
> 1. Require linker with GNU_PROPERTY_1_NEEDED support for PR 35513
> run-time tests.
> 2. Compile pr35513-8.c to scan assembly code.
>
> PR testsuite/104481
> * g++.target/i386/pr35513-1.C: Require property_1_needed target.
> * g++.target/i386/pr35513-2.C: Likewise.
> * gcc.target/i386/pr35513-8.c: Change to compile.
> * lib/target-supports.exp (check_compile): Support assembly code.
> (check_effective_target_property_1_needed): New proc.
This is for testcase fixup, and i think it should be ok.
> ---
>  gcc/testsuite/g++.target/i386/pr35513-1.C |  2 +-
>  gcc/testsuite/g++.target/i386/pr35513-2.C |  2 +-
>  gcc/testsuite/gcc.target/i386/pr35513-8.c |  2 +-
>  gcc/testsuite/lib/target-supports.exp | 37 +++
>  4 files changed, 40 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/testsuite/g++.target/i386/pr35513-1.C 
> b/gcc/testsuite/g++.target/i386/pr35513-1.C
> index 6f8db37fb7c..daa615662c5 100644
> --- a/gcc/testsuite/g++.target/i386/pr35513-1.C
> +++ b/gcc/testsuite/g++.target/i386/pr35513-1.C
> @@ -1,4 +1,4 @@
> -// { dg-do run }
> +// { dg-do run { target property_1_needed } }
>  // { dg-options "-O2 -mno-direct-extern-access" }
>
>  #include 
> diff --git a/gcc/testsuite/g++.target/i386/pr35513-2.C 
> b/gcc/testsuite/g++.target/i386/pr35513-2.C
> index 9143ff3f0a5..ecccdaeb666 100644
> --- a/gcc/testsuite/g++.target/i386/pr35513-2.C
> +++ b/gcc/testsuite/g++.target/i386/pr35513-2.C
> @@ -1,4 +1,4 @@
> -// { dg-do run  }
> +// { dg-do run { target property_1_needed } }
>  // { dg-options "-O2 -mno-direct-extern-access" }
>
>  class Foo
> diff --git a/gcc/testsuite/gcc.target/i386/pr35513-8.c 
> b/gcc/testsuite/gcc.target/i386/pr35513-8.c
> index 7ba67de2156..d51f7efb353 100644
> --- a/gcc/testsuite/gcc.target/i386/pr35513-8.c
> +++ b/gcc/testsuite/gcc.target/i386/pr35513-8.c
> @@ -1,4 +1,4 @@
> -/* { dg-do assemble { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
>  /* { dg-require-effective-target maybe_x32 } */
>  /* { dg-options "-mx32 -O2 -fno-pic -fexceptions 
> -fasynchronous-unwind-tables -mno-direct-extern-access" } */
>
> diff --git a/gcc/testsuite/lib/target-supports.exp 
> b/gcc/testsuite/lib/target-supports.exp
> index 4463cc8d7ed..0d8a7df5026 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -30,6 +30,7 @@
>  #
>  # Assume by default that CONTENTS is C code.
>  # Otherwise, code should contain:
> +# "/* Assembly" for assembly code,
>  # "// C++" for c++,
>  # "// D" for D,
>  # "! Fortran" for Fortran code,
> @@ -57,6 +58,7 @@ proc check_compile {basename type contents args} {
> set options ""
>  }
>  switch -glob -- $contents {
> +   "*/* Assembly*" { set src ${basename}[pid].S }
> "*! Fortran*" { set src ${basename}[pid].f90 }
> "*// C++*" { set src ${basename}[pid].cc }
> "*// D*" { set src ${basename}[pid].d }
> @@ -11758,3 +11760,38 @@ proc check_effective_target_pytest3 { } {
>  return 0;
>  }
>  }
> +
> +proc check_effective_target_property_1_needed { } {
> +  return [check_no_compiler_messages_nocache property_1_needed executable {
> +/* Assembly code */
> +#ifdef __LP64__
> +# define __PROPERTY_ALIGN 3
> +#else
> +# define __PROPERTY_ALIGN 2
> +#endif
> +
> +   .section ".note.gnu.property", "a"
> +   .p2align __PROPERTY_ALIGN
> +   .long 1f - 0f   /* name length.  */
> +   .long 4f - 1f   /* data length.  */
> +   /* NT_GNU_PROPERTY_TYPE_0.   */
> +   .long 5 /* note type.  */
> +0:
> +   .asciz "GNU"/* vendor name.  */
> +1:
> +   .p2align __PROPERTY_ALIGN
> +   /* GNU_PROPERTY_1_NEEDED.  */
> +   .long 0xb0008000/* pr_type.  */
> +   .long 3f - 2f   /* pr_datasz.  */
> +2:
> +   /* GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.  */
> +   .long 1
> +3:
> +   .p2align __PROPERTY_ALIGN
> +4:
> +   .text
> +   .globl main
> +main:
> +   .byte 0
> +  } ""]
> +}
> --
> 2.34.1
>


-- 
BR,
Hongtao


Re: [PATCH] c: Add diagnostic when operator= is used as truth cond [PR25689]

2022-02-11 Thread Zhao Wei Liew via Gcc-patches
On Fri, 11 Feb 2022 at 20:47, Jason Merrill  wrote:
> >
> > On the other hand, for empty classes, it seems that a COMPOUND_EXPR
> > is built in build_over_call under the is_really_empty_class guard (line 
> > 9791).
> > I don't understand the tree structure that I should identify though.
> > Could you give me any further explanations on that?
>
> True, that's not very recognizable.  I suppose we could use a
> TREE_LANG_FLAG to mark that COMPOUND_EXPR, or we could leave empty
> classes alone; neither assignment nor comparison of empty classes should
> happen much in practice.

I agree. I'll leave them alone.

> >
> > Got it. May I know why it's better to use *_nofold here?
>
> To avoid trying to do constexpr evaluation of the function operand when
> it's non-constant; in the interesting cases it won't be needed.
>
> However, have you tested virtual operator=?
>

Yup, everything seems to work as expected for structs using virtual operator=.
I've updated the test suite to reflect the tests.

One thing to note: I've commented out 2 test statements that shouldn't
work. One of them
is caused by trivial assignments in empty classes being COMPOUND_EXPRs as we
discussed above. The other is an existing issue caused by trivial
assignments in non-empty
classes being MODIFY_EXPRs.

> > On an unrelated note, I adjusted the if condition to use INDIRECT_REF_P 
> > (cond)
> > instead of TREE_OPERAND_LENGTH (cond) >= 1.
> > I hope that's better for semantics.
>
> Yes; REFERENCE_REF_P might be even better.
>

Alright, I've changed it to REFERENCE_REF_P and it seems to work fine as well.



-Everything below is the actual patch v3-



When compiling the following code with g++ -Wparentheses, GCC does not
warn on the if statement. For example, there is no warning for this code:

struct A {
A& operator=(int);
operator bool();
};

void f(A a) {
if (a = 0); // no warning
}

This is because a = 0 is a call to operator=, which GCC does not handle.

This patch fixes this issue by handling calls to operator= when deciding
to warn.

Bootstrapped and tested on x86_64-pc-linux-gnu.

v2: https://gcc.gnu.org/pipermail/gcc-patches/2022-February/590236.html
Changes since v2:
1. Add more test cases in Wparentheses-31.C.
2. Refactor added logic to a function (is_assignment_overload_ref_p).
3. Use REFERENCE_REF_P instead of INDIRECT_REF_P.

v1: https://gcc.gnu.org/pipermail/gcc-patches/2022-February/590158.html
Changes since v1:
1. Use CALL_EXPR_OPERATOR_SYNTAX to avoid warnings for explicit
   operator=() calls.
2. Use INDIRECT_REF_P to filter implicit operator=() calls.
3. Use cp_get_callee_fndecl_nofold.
4. Add spaces before (.

PR c/25689

gcc/cp/ChangeLog:

* semantics.cc (maybe_convert_cond): Handle the implicit
  operator=() case for -Wparentheses.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wparentheses-31.C: New test.
---
 gcc/cp/semantics.cc | 21 +++-
 gcc/testsuite/g++.dg/warn/Wparentheses-31.C | 55 +
 2 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wparentheses-31.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 0cb17a6a8ab..30ffb23a032 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -815,6 +815,25 @@ finish_goto_stmt (tree destination)
   return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
 }

+/* Returns true if EXPR is a reference to an implicit
+   call to operator=(). */
+static bool
+is_assignment_overload_ref_p (tree expr)
+{
+  if (expr == NULL_TREE || !REFERENCE_REF_P (expr))
+return false;
+
+  tree fn = TREE_OPERAND (expr, 0);
+  if (TREE_CODE (fn) != CALL_EXPR || !CALL_EXPR_OPERATOR_SYNTAX (fn))
+return false;
+
+  tree fndecl = cp_get_callee_fndecl_nofold (fn);
+  return fndecl != NULL_TREE
+&& DECL_OVERLOADED_OPERATOR_P (fndecl)
+&& DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR)
+&& DECL_ASSIGNMENT_OPERATOR_P (fndecl);
+}
+
 /* COND is the condition-expression for an if, while, etc.,
statement.  Convert it to a boolean value, if appropriate.
In addition, verify sequence points if -Wsequence-point is enabled.  */
@@ -836,7 +855,7 @@ maybe_convert_cond (tree cond)
   /* Do the conversion.  */
   cond = convert_from_reference (cond);

-  if (TREE_CODE (cond) == MODIFY_EXPR
+  if ((TREE_CODE (cond) == MODIFY_EXPR || is_assignment_overload_ref_p (cond))
   && warn_parentheses
   && !warning_suppressed_p (cond, OPT_Wparentheses)
   && warning_at (cp_expr_loc_or_input_loc (cond),
diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-31.C
b/gcc/testsuite/g++.dg/warn/Wparentheses-31.C
new file mode 100644
index 000..7a5789fb7a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wparentheses-31.C
@@ -0,0 +1,55 @@
+/* Test that -Wparentheses warns for struct/class assignments,
+   except for explicit calls to operator= (). */
+/* PR c/25689 */
+/* { dg-options "-Wparentheses" }  */
+
+str