Re: [COMMITTED] ada: Remove the body of System.Storage_Elements

2023-05-29 Thread Eric Botcazou via Gcc-patches
> Is this an issue with the patch? Or does it need a newer Ada compiler
> to for building it?

Neither, it's very likely an issue with your build procedure: you need to use 
a matching host Ada compiler to build a cross Ada compiler, that's documented 
in https://gcc.gnu.org/install/prerequisites.html#GNAT-prerequisite

"In order to build a cross compiler, it is strongly recommended to install the 
new compiler as native first, and then use it to build the cross compiler. 
Other native compiler versions may work but this is not guaranteed and will 
typically fail with hard to understand compilation errors during the build."

-- 
Eric Botcazou




Re: [PATCH] tree: Fix up save_expr [PR52339]

2023-05-30 Thread Eric Botcazou via Gcc-patches
> We want to be able to treat such things as invariant somehow even if we
> can't do that for references to user data that might be changed by
> intervening code.
> 
> That is, indicate that we know that the _REF actually refers to a const
> variable or is otherwise known to be unchanging.
> 
> Perhaps that should be a new flag that tree_invariant_p can check
> instead of TREE_READONLY.

Richard earlier suggested a langhook; given that Ada will be the main (sole?) 
user of it, this would probably be better.

-- 
Eric Botcazou





Re: [PATCH v2] Store_bit_field_1: Use SUBREG instead of REG if possible

2023-07-19 Thread Eric Botcazou via Gcc-patches
> I don't see that.  That's definitely not what GCC expects here,
> the left-most word of the doubleword should be unchanged.
> 
> Your testcase should be a dg-do-run and probably more like
> 
> NOMIPS16 int __attribute__((noipa)) test (const unsigned char *buf)
> {
>   int val;
>   ((unsigned char*)&val)[0] = *buf++;
>   ((unsigned char*)&val)[1] = *buf++;
>   ((unsigned char*)&val)[2] = *buf++;
>   ((unsigned char*)&val)[3] = *buf++;
>   return val;
> }
> int main()
> {
>   int val = 0x01020304;
>   val = test (&val);
>   if (val != 0x01020304)
> abort ();
> }
> 
> not sure if I got endianess correct.  Now, the question is what
> WORD_REGISTER_OPERATIONS implies for a bitfield insert and what
> the MIPS ABI says for returning SImode.

WORD_REGISTER_OPERATIONS must *not* be taken account for bit-fields, see e;g. 
word_register_operation_p:

/* Return true if X is an operation that always operates on the full
   registers for WORD_REGISTER_OPERATIONS architectures.  */

inline bool
word_register_operation_p (const_rtx x)
{
  switch (GET_CODE (x))
{
case CONST_INT:
case ROTATE:
case ROTATERT:
case SIGN_EXTRACT:
case ZERO_EXTRACT:
  return false;

default:
  return true;
}
}

-- 
Eric Botcazou




[PATCH] Use default lower bound for vector types in debug info

2022-07-04 Thread Eric Botcazou via Gcc-patches
Hi,

vector types are represented as array types with DW_AT_GNU_vector attribute in 
the debug info and a range [0 .. TYPE_VECTOR_SUBPARTS - 1].  That's obviously 
skewed toward the C family of languages, therefore the attached patch changes 
the lower bound to the default for the language of the CU, if any.

Tested on x86-64/Linux, OK for the mainline?


gcc/
* dwarf2out.cc (gen_array_type_die): Use the default lower bound of
the language for vector types.

-- 
Eric Botcazoudiff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index b468a4b9c0f..149aeaf1a55 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -22539,11 +22539,14 @@ gen_array_type_die (tree type, dw_die_ref context_die)
 
   if (TREE_CODE (type) == VECTOR_TYPE)
 {
-  /* For VECTOR_TYPEs we use an array die with appropriate bounds.  */
+  /* For VECTOR_TYPEs we use an array DIE with appropriate bounds.  */
+  int lb = lower_bound_default ();
+  if (lb == -1)
+	lb = 0;
   dw_die_ref subrange_die = new_die (DW_TAG_subrange_type, array_die, NULL);
-  add_bound_info (subrange_die, DW_AT_lower_bound, size_zero_node, NULL);
+  add_bound_info (subrange_die, DW_AT_lower_bound, size_int (lb), NULL);
   add_bound_info (subrange_die, DW_AT_upper_bound,
-		  size_int (TYPE_VECTOR_SUBPARTS (type) - 1), NULL);
+		  size_int (lb + TYPE_VECTOR_SUBPARTS (type) - 1), NULL);
 }
   else
 add_subscript_info (array_die, type, collapse_nested_arrays);


Re: [PATCH] Use default lower bound for vector types in debug info

2022-07-04 Thread Eric Botcazou via Gcc-patches
> For late generated vector types this might result in inconsistencies with
> early (user) generated types when using LTO.

Is that a problem?  That's no different with regular array types.

> Is there context available somehow so we can do like the is_ overloads
> on a decl and use a default according to that?

Not sure, the only safe thing to do would be to return -1 as the default lower 
bound if flag_generate_lto.

-- 
Eric Botcazou




[PATCH] Fix ICE on view conversion between struct and integer

2022-07-14 Thread Eric Botcazou via Gcc-patches
Hi,

you can build a view conversion between pretty much anything in Ada including
between types with different sizes, although the compiler warns in this case
and gigi pads the smaller type to end up with the same size.

The attached testcase triggers an ICE at -O or above for one of them:

FAIL: gnat.dg/opt98.adb (test for excess errors)
Excess errors:
during GIMPLE pass: esra
+===GNAT BUG DETECTED==+
| 13.0.0 20220713 (experimental) [master 6f5cf9470aa] (x86_64-suse-linux) GCC 
error:|
| in gimplify_modify_expr, at gimplify.cc:6254 |
| Error detected around /home/eric/cvs/gcc/gcc/testsuite/gnat.dg/opt98.adb:10:7|
| Compiling /home/eric/cvs/gcc/gcc/testsuite/gnat.dg/opt98.adb |

  if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
{
  /* We should have got an SSA name from the start.  */
  gcc_assert (TREE_CODE (*to_p) == SSA_NAME
  || ! gimple_in_ssa_p (cfun));
}

This happens from prepare_gimple_addressable for the variable to be marked with
DECL_NOT_GIMPLE_REG_P when its initialization is gimplified, so it's apparently
just a matter of setting the flag earlier.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2022-07-14  Eric Botcazou  

* gimplify.cc (lookup_tmp_var): Add NOT_GIMPLE_REG boolean parameter
and set DECL_NOT_GIMPLE_REG_P on the variable according to it.
(internal_get_tmp_var): Add NOT_GIMPLE_REG boolean parameter and pass
it in the call to lookup_tmp_var.
(get_formal_tmp_var): Pass false in the call to lookup_tmp_var.
(get_initialized_tmp_var): Likewise.
(prepare_gimple_addressable): Call internal_get_tmp_var instead of
get_initialized_tmp_var with NOT_GIMPLE_REG set to true.


2022-07-14  Eric Botcazou  

* gnat.dg/opt98.ads, gnat.dg/opt98.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 04990ad91a6..2ac7ca0855e 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -573,20 +573,26 @@ create_tmp_from_val (tree val)
 }
 
 /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
-   an existing expression temporary.  */
+   an existing expression temporary.  If NOT_GIMPLE_REG, mark it as such.  */
 
 static tree
-lookup_tmp_var (tree val, bool is_formal)
+lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg)
 {
   tree ret;
 
+  /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P.  */
+  gcc_assert (!is_formal || !not_gimple_reg);
+
   /* If not optimizing, never really reuse a temporary.  local-alloc
  won't allocate any variable that is used in more than one basic
  block, which means it will go into memory, causing much extra
  work in reload and final and poorer code generation, outweighing
  the extra memory allocation here.  */
   if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
-ret = create_tmp_from_val (val);
+{
+  ret = create_tmp_from_val (val);
+  DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg;
+}
   else
 {
   elt_t elt, *elt_p;
@@ -617,7 +623,7 @@ lookup_tmp_var (tree val, bool is_formal)
 
 static tree
 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
-  bool is_formal, bool allow_ssa)
+		  bool is_formal, bool allow_ssa, bool not_gimple_reg)
 {
   tree t, mod;
 
@@ -639,7 +645,7 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
 	}
 }
   else
-t = lookup_tmp_var (val, is_formal);
+t = lookup_tmp_var (val, is_formal, not_gimple_reg);
 
   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
 
@@ -667,7 +673,7 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
 tree
 get_formal_tmp_var (tree val, gimple_seq *pre_p)
 {
-  return internal_get_tmp_var (val, pre_p, NULL, true, true);
+  return internal_get_tmp_var (val, pre_p, NULL, true, true, false);
 }
 
 /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
@@ -678,7 +684,7 @@ get_initialized_tmp_var (tree val, gimple_seq *pre_p,
 			 gimple_seq *post_p /* = NULL */,
 			 bool allow_ssa /* = true */)
 {
-  return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
+  return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false);
 }
 
 /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
@@ -4574,13 +4580,10 @@ prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
 {
   while (handled_component_p (*expr_p))
 expr_p = &TREE_OPERAND (*expr_p, 0);
+
+  /* Do not allow an SSA name as the temporary.  */
   if (is_gimple_reg (*expr_p))
-{
-  /* Do not allow an SSA name as the temporary.  */
-  tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
-  DECL_NOT_GIMPLE_REG_P (var) = 1;
-  *expr_p = var;
-}
+*expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
 }

Re: [PATCH 2/2] Avoid registering __builtin_setjmp_receiver label twice [PR101347]

2022-07-20 Thread Eric Botcazou via Gcc-patches
> Eric is probably most familiar with this, but can you make sure to bootstrap
> and test this on a SJLJ EH target?  I'm not sure --enable-sjlj-exceptions
> is well tested anywhere but on targets not supporting DWARF EH and the
> configury is a bit odd suggesting the option is mostly ignored ...

This is a specific circuitry for __builtln_setjmp so it is *not* exercised by 
the SJLJ exception scheme.  It used to be exercised by the GNAT bootstrap, but 
that's no longer the case either.

I think that the fix is sensible, assuming that it passes the C testsuite.

-- 
Eric Botcazou




Re: [PATCH] configure: Implement --enable-host-bind-now

2023-06-27 Thread Eric Botcazou via Gcc-patches
> Arg, once again, I'm sorry.  I don't know how this happened.  It would
> be trivial to fix it but since
> 
> commit 4a48a38fa99f067b8f3a3d1a5dc7a1e602db351f
> Author: Eric Botcazou 
> Date:   Wed Jun 21 18:19:36 2023 +0200
> 
> ada: Fix build of GNAT tools
> 
> the build with Ada included fails with --enable-host-pie.  So that needs
> to be fixed first.
> 
> Eric, I'm not asking you to fix that, but I'm curious, what did the
> commit above fix?  The patch looks correct; I'm just puzzled why I
> hadn't seen any build failures.

The GNAT tools were failing to build for a compiler configured with --disable-
host-pie --enable-default-pie.

-- 
Eric Botcazou




[PATCH] Fix couple of endianness issues in fold_ctor_reference

2023-06-30 Thread Eric Botcazou via Gcc-patches
Hi,

fold_ctor_reference attempts to use a recursive local processing in order to 
call native_encode_expr on the leaf nodes of the constructor, before falling 
back to calling native_encode_initializer if this fails.  There are a couple 
of issues related to endianness present in it:
  1) it does not specifically handle integral bit-fields; now these are left 
justified on big-endian platforms so cannot be treated like ordinary fields.
  2) it does not check that the constructor uses the native storage order.

Proposed fix attached, tested on x86-64/Linux and SPARC/Solaris, OK for the 
mainline and some branches?


2023-06-30  Eric Botcazou  

* gimple-fold.cc (fold_array_ctor_reference): Fix head comment.
(fold_nonarray_ctor_reference): Likewise.  Specifically deal
with integral bit-fields.
(fold_ctor_reference): Check that the constructor uses the
native storage order.


2023-06-30  Eric Botcazou  

* gcc.c-torture/execute/20230630-1.c: New test.
* gcc.c-torture/execute/20230630-2.c: Likewise.

-- 
Eric Botcazoudiff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 3d46b76edeb..e80a72dfa22 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -7849,12 +7849,11 @@ get_base_constructor (tree base, poly_int64_pod *bit_offset,
 }
 }
 
-/* CTOR is CONSTRUCTOR of an array type.  Fold a reference of SIZE bits
-   to the memory at bit OFFSET. When non-null, TYPE is the expected
-   type of the reference; otherwise the type of the referenced element
-   is used instead. When SIZE is zero, attempt to fold a reference to
-   the entire element which OFFSET refers to.  Increment *SUBOFF by
-   the bit offset of the accessed element.  */
+/* CTOR is a CONSTRUCTOR of an array or vector type.  Fold a reference of SIZE
+   bits to the memory at bit OFFSET.  If non-null, TYPE is the expected type of
+   the reference; otherwise the type of the referenced element is used instead.
+   When SIZE is zero, attempt to fold a reference to the entire element OFFSET
+   refers to.  Increment *SUBOFF by the bit offset of the accessed element.  */
 
 static tree
 fold_array_ctor_reference (tree type, tree ctor,
@@ -8019,13 +8018,11 @@ fold_array_ctor_reference (tree type, tree ctor,
   return type ? build_zero_cst (type) : NULL_TREE;
 }
 
-/* CTOR is CONSTRUCTOR of an aggregate or vector.  Fold a reference
-   of SIZE bits to the memory at bit OFFSET.   When non-null, TYPE
-   is the expected type of the reference; otherwise the type of
-   the referenced member is used instead.  When SIZE is zero,
-   attempt to fold a reference to the entire member which OFFSET
-   refers to; in this case.  Increment *SUBOFF by the bit offset
-   of the accessed member.  */
+/* CTOR is a CONSTRUCTOR of a record or union type.  Fold a reference of SIZE
+   bits to the memory at bit OFFSET.  If non-null, TYPE is the expected type of
+   the reference; otherwise the type of the referenced member is used instead.
+   When SIZE is zero, attempt to fold a reference to the entire member OFFSET
+   refers to.  Increment *SUBOFF by the bit offset of the accessed member.  */
 
 static tree
 fold_nonarray_ctor_reference (tree type, tree ctor,
@@ -8037,8 +8034,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
   unsigned HOST_WIDE_INT cnt;
   tree cfield, cval;
 
-  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield,
-			cval)
+  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
 {
   tree byte_offset = DECL_FIELD_OFFSET (cfield);
   tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
@@ -8110,6 +8106,19 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
 	return NULL_TREE;
 
 	  offset_int inner_offset = offset_int (offset) - bitoffset;
+
+	  /* Integral bit-fields are left-justified on big-endian targets, so
+	 we must arrange for native_encode_int to look at the MSB.  */
+  if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
+	{
+	  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+		return NULL_TREE;
+	  const unsigned int encoding_size
+		= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (cfield)));
+	  if (BYTES_BIG_ENDIAN)
+		inner_offset += encoding_size - wi::to_offset (field_size);
+	}
+
 	  return fold_ctor_reference (type, cval,
   inner_offset.to_uhwi (), size,
   from_decl, suboff);
@@ -8122,7 +8131,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
   return build_zero_cst (type);
 }
 
-/* CTOR is value initializing memory.  Fold a reference of TYPE and
+/* CTOR is a value initializing memory.  Fold a reference of TYPE and
bit size POLY_SIZE to the memory at bit POLY_OFFSET.  When POLY_SIZE
is zero, attempt to fold a reference to the entire subobject
which OFFSET refers to.  This is used when folding accesses to
@@ -8163,7 +8172,8 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
 	}
   return ret;
 

Re: [COMMITTED] ada: Fix crash on vector initialization

2023-07-07 Thread Eric Botcazou via Gcc-patches
> Such assignments to container aggregates are later transformed into
> procedure calls to the procedures named in the Aggregate aspect
> definition, for which the delayed expansion is not required/expected.
> 
> gcc/ada/
> 
>   * exp_aggr.adb (Convert_To_Assignments): Do not mark node for
>   delayed expansion if parent type has the Aggregate aspect.
>   * sem_util.adb (Is_Container_Aggregate): Move...
>   * sem_util.ads (Is_Container_Aggregate): ... here and make it
>   public.

This is not a regression but the problem is quite visible in Ada 2022 so I 
backported the fix onto the 13 branch.

-- 
Eric Botcazou




Re: [COMMITTED] ada: Fix internal error on aggregate within container aggregate

2023-07-07 Thread Eric Botcazou via Gcc-patches
> This just applies the same fix to Expand_Array_Aggregate as the one that was
> recently applied to Convert_To_Assignments.
> 
> gcc/ada/
> 
>   * exp_aggr.adb (Convert_To_Assignments): Tweak comment.
>   (Expand_Array_Aggregate): Do not delay the expansion if the parent
>   node is a container aggregate.

This is not a regression but the problem is quite visible in Ada 2022 so I 
backported the fix onto the 13 branch.

-- 
Eric Botcazou




Re: [COMMITTED] ada: Fix expanding container aggregates

2023-07-07 Thread Eric Botcazou via Gcc-patches
> Ensure that that container aggregate expressions are expanded as
> such and not as records even if the type of the expression is a
> record.
> 
> gcc/ada/
> 
>   * exp_aggr.adb (Expand_N_Aggregate): Ensure that container
>   aggregate expressions do not get expanded as records but instead
>   as container aggregates.

This is not a regression but the problem is quite visible in Ada 2022 so I 
backported the fix onto the 13 branch.

-- 
Eric Botcazou





Re: [COMMITTED] ada: Follow-up fix for compilation issue with recent MinGW-w64 versions

2023-07-11 Thread Eric Botcazou via Gcc-patches
> It turns out that adaint.c includes other Windows header files than just
> windows.h, so defining WIN32_LEAN_AND_MEAN is not sufficient for it.
> 
> gcc/ada/
> 
>   * adaint.c [_WIN32]: Undefine 'abort' macro.

I backported it onto the 13 branch.

-- 
Eric Botcazou




[PATCH] Fix small regression in Ada

2023-02-14 Thread Eric Botcazou via Gcc-patches
It is present on the mainline and 12 branch and comes from Andrew P. and me 
forgetting about the VOID_TYPE_P case of SAVE_EXPRs.

Tested on x86-64/Linux, applied on mainline and 12 branch as obvious.


2023-02-14  Eric Botcazou  

gcc/
* gimplify.cc (gimplify_save_expr): Add missing guard.

gcc/ada/
* gcc-interface/trans.cc (gnat_gimplify_expr): Add missing guard.


2023-02-14  Eric Botcazou  

* gnat.dg/shift2.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index 28e3867d142..5fc1a26fede 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -9049,7 +9049,9 @@ gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
 
   /* Propagate TREE_NO_WARNING from expression to temporary by using the
 	 SAVE_EXPR itself as an intermediate step.  See gimplify_save_expr.  */
-  if (SAVE_EXPR_RESOLVED_P (expr))
+  if (type == void_type_node)
+	;
+  else if (SAVE_EXPR_RESOLVED_P (expr))
 	TREE_NO_WARNING (op) = TREE_NO_WARNING (expr);
   else
 	TREE_NO_WARNING (expr) = TREE_NO_WARNING (op);
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 1b362dd83e3..96845154a92 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -6441,7 +6441,7 @@ gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
   val = TREE_OPERAND (*expr_p, 0);
 
-  if (TREE_TYPE (val) == error_mark_node)
+  if (val && TREE_TYPE (val) == error_mark_node)
 return GS_ERROR;
 
   /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
-- { dg-do compile }

with Interfaces; use Interfaces;

function Shift2 (V : Unsigned_32) return Unsigned_32 is
begin
  return Shift_Left (V, (case V is when 0 => 1, when others => 0));
end;


[PATCH] Fix PR target/90458

2023-02-15 Thread Eric Botcazou via Gcc-patches
Hi,

this is the incompatibility of -fstack-clash-protection with Windows SEH.  Now 
the Windows ports always enable TARGET_STACK_PROBE, which means that the stack 
is always probed (out of line) so -fstack-clash-protection does nothing more.

Tested on x86-64/Windows and Linux, OK for all active branches?


2023-02-15  Eric Botcazou  

* config/i386/i386.cc (ix86_compute_frame_layout): Disable the
effects of -fstack-clash-protection for TARGET_STACK_PROBE.
(ix86_expand_prologue): Likewise.

-- 
Eric Botcazoudiff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 3cacf738c4a..22f444be23c 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -6876,7 +6876,9 @@ ix86_compute_frame_layout (void)
 	 stack clash protections are enabled and the allocated frame is
 	 larger than the probe interval, then use pushes to save
 	 callee saved registers.  */
-  || (flag_stack_clash_protection && to_allocate > get_probe_interval ()))
+  || (flag_stack_clash_protection
+	  && !ix86_target_stack_probe ()
+	  && to_allocate > get_probe_interval ()))
 frame->save_regs_using_mov = false;
 
   if (ix86_using_red_zone ()
@@ -8761,8 +8763,11 @@ ix86_expand_prologue (void)
   sse_registers_saved = true;
 }
 
-  /* If stack clash protection is requested, then probe the stack.  */
-  if (allocate >= 0 && flag_stack_clash_protection)
+  /* If stack clash protection is requested, then probe the stack, unless it
+ is already probed on the target.  */
+  if (allocate >= 0
+  && flag_stack_clash_protection
+  && !ix86_target_stack_probe ())
 {
   ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
   allocate = 0;


Re: [PATCH] Fix PR target/90458

2023-02-16 Thread Eric Botcazou via Gcc-patches
> This fixes dg.exp/stack-check-2.c, -7, 8, and -16.c, which is great!

Try the attached patch.

-- 
Eric Botcazoudiff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 227e3004077..d4f036a3f1e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -11655,6 +11655,11 @@ proc check_effective_target_autoincdec { } {
 # 
 proc check_effective_target_supports_stack_clash_protection { } {
 
+# Stack probing is done unconditionally out-of-line on Windows
+if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
+	return 0
+}
+
 if { [istarget x86_64-*-*] || [istarget i?86-*-*] 
 	  || [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
 	  || [istarget aarch64*-**] || [istarget s390*-*-*]


Re: [PATCH] Fix PR target/90458

2023-02-17 Thread Eric Botcazou via Gcc-patches
> Is there a way to say that the test results should be inverted on a
> particular platform (instead of purely unsupported)?

Yes, you can do pretty much what you want with the testsuite harness.

-- 
Eric Botcazou




Re: [PATCH] tree: Fix up save_expr [PR52339]

2023-05-13 Thread Eric Botcazou via Gcc-patches
> I think we really need Eric (as one who e.g. introduced the
> DECL_INVARIANT_P apparently for this kind of stuff) to have a look at that
> on the Ada side.

I have been investigating this for a few days and it's no small change for Ada 
and probably for other languages with dynamic types.  SAVE_EXPRs are delicate 
to handle because 1) they are TREE_SIDE_EFFECTS (it's explained in save_expr) 
so out of TREE_READONLY && !TREE_SIDE_EFFECTS trees, you now get side effects 
which then propagate to all parent nodes 2) their placement is problematic in 
conditional expressions, for example if you replace

  cond > 0 ? A : A + 1

with

  cond > 0 ? SAVE_EXPR (A) : SAVE_EXPR (A) + 1

then gimplification will, say, create the temporary and initialize it in the 
first arm so, if at runtime you take the second arm, you'll read the temporary 
uninitialized.  That's caught for scalar values by the SSA form (if your patch 
is applied to a GCC 12 tree, you'll get ICEs in the ACATS testsuite because of 
this through finalize_type_size -> variable_size -> save_expr, it is probably 
mitigated/addressed in GCC 14 by 68e0063397ba820e71adc220b2da0581dce29ffa).
That's also why making gnat_invariant_expr return (some of) them does not look 
really safe.

In addition to this, in Ada we have bounds of unconstrained arrays which are 
both read-only and stored indirectly, i.e. you have an INDIRECT_REF in the 
tree (it is marked TREE_THIS_NOTRAP because the bounds are always present), 
and which obviously play a crucial role in loops running over the arrays.
This issue is responsible for the regressions in the gnat.dg testsuite.

I think that we can reasonably deal with the second issue in the Ada front-end 
because we know the semantics of the bounds of unconstrained arrays, and I'm 
testing a patch to that effect, but the first issue might be annoying too.

-- 
Eric Botcazou




Re: [PATCH 01/14] ada: use _P() defines from tree.h

2023-05-15 Thread Eric Botcazou via Gcc-patches
>   && DECL_RETURN_VALUE_P (inner))
> diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
> index 0c4f8b90c8e..460ef6f1f01 100644
> --- a/gcc/ada/gcc-interface/utils.cc
> +++ b/gcc/ada/gcc-interface/utils.cc
> @@ -1966,7 +1966,7 @@ finish_record_type (tree record_type, tree field_list,
> int rep_level, bool debug_info_p)
>  {
>const enum tree_code orig_code = TREE_CODE (record_type);
> -  const bool had_size = TYPE_SIZE (record_type) != NULL_TREE;
> +  const bool had_size = COMPLETE_TYPE_P (record_type);
>const bool had_align = TYPE_ALIGN (record_type) > 0;
>/* For all-repped records with a size specified, lay the QUAL_UNION_TYPE
>   out just like a UNION_TYPE, since the size will be fixed.  */

This one is not an improvement but more of a coincidence; the rest is OK.

-- 
Eric Botcazou




[PATCH] Fix internal error on small array with negative lower bound

2023-05-18 Thread Eric Botcazou via Gcc-patches
Hi,

Ada supports arrays with negative indices, although the internal index type is
sizetype like in other languages, which is unsigned.  This means that negative
values are represented by very large numbers, which works with a bit of care.
The attached test exposes a small loophole in output_constructor_bitfield.

Tested on x86-64/Linux, OK for the mainline?


2023-05-18  Eric Botcazou 

* varasm.cc (output_constructor_bitfield): Call tree_to_uhwi instead
of tree_to_shwi on array indices.  Minor tweaks.


2023-05-18  Eric Botcazou 

* gnat.dg/specs/array6.ads: New test.

-- 
Eric Botcazoudiff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 2256194d934..478cbfe6736 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -5585,19 +5585,18 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
 
   /* Relative index of this element if this is an array component.  */
   HOST_WIDE_INT relative_index
-= (!local->field
-   ? (local->index
-	  ? (tree_to_shwi (local->index)
-	 - tree_to_shwi (local->min_index))
-	  : local->last_relative_index + 1)
-   : 0);
+= (local->field
+   ? 0
+   : (local->index
+	  ? tree_to_uhwi (local->index) - tree_to_uhwi (local->min_index)
+	  : local->last_relative_index + 1));
 
   /* Bit position of this element from the start of the containing
  constructor.  */
   HOST_WIDE_INT constructor_relative_ebitpos
-  = (local->field
-	 ? int_bit_position (local->field)
-	 : ebitsize * relative_index);
+= (local->field
+   ? int_bit_position (local->field)
+   : ebitsize * relative_index);
 
   /* Bit position of this element from the start of a possibly ongoing
  outer byte buffer.  */
-- { dg-do compile }

package Array6 is 

  type Range_Type is range -10 ..  10;
  type Array_Type is array (Range_Type range <> ) of Short_Short_Integer;

  type Record_Type is record 
A : Array_Type(-2..4);
  end record ;

  Rec : Record_Type := (A => (others => -1));

end Array6;


Re: [PATCH] Fix internal error on small array with negative lower bound

2023-05-18 Thread Eric Botcazou via Gcc-patches
> Would it be better to use
> 
>   wi::to_uhwi (wi::to_wide (local->index) - wi::to_wide (local->min_index))
> 
> to honor the actual sign of the indices?  I think nothing forbids frontends
> to use a signed TYPE_DOMAIN here?  But the difference should be always
> representable in an unsigned value of course.

We use tree_to_uhwi everywhere else though, see categorize_ctor_elements_1:

  if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
mult = (tree_to_uhwi (hi_index)
- tree_to_uhwi (lo_index) + 1);

or store_constructor

this_node_count = (tree_to_uhwi (hi_index)
   - tree_to_uhwi (lo_index) + 1);

so the proposed form looks better for the sake of consistency.

-- 
Eric Botcazou




[PATCH] Fix handling of non-integral bit-fields in native_encode_initializer

2023-05-22 Thread Eric Botcazou via Gcc-patches
Hi,

the encoder for CONSTRUCTORs assumes that all bit-fields (DECL_BIT_FIELD) have
integral types, but that's not the case in Ada where they may have pretty much
any type, resulting in a wrong encoding for them.

The attached fix filters out non-integral bit-fields, except if they start and
end on a byte boundary because they are correctly handled in this case.

Bootstrapped/regtested on x86-64/Linux, OK for mainline and 13 branch?


2023-05-22  Eric Botcazou  

* fold-const.cc (native_encode_initializer) : Apply the
specific treatment for bit-fields only if they have an integral type
and filter out non-integral bit-fields that do not start and end on
a byte boundary.


2023-05-22  Eric Botcazou  

* gnat.dg/opt101.adb: New test.
* gnat.dg/opt101_pkg.ads: New helper.

-- 
Eric Botcazoudiff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 25466e97220..57521501fff 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -8360,20 +8360,26 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
 	  if (fieldsize == 0)
 		continue;
 
+	  /* Prepare to deal with integral bit-fields and filter out other
+		 bit-fields that do not start and end on a byte boundary.  */
 	  if (DECL_BIT_FIELD (field))
 		{
 		  if (!tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (field)))
 		return 0;
-		  fieldsize = TYPE_PRECISION (TREE_TYPE (field));
 		  bpos = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
-		  if (bpos % BITS_PER_UNIT)
-		bpos %= BITS_PER_UNIT;
-		  else
-		bpos = 0;
-		  fieldsize += bpos;
-		  epos = fieldsize % BITS_PER_UNIT;
-		  fieldsize += BITS_PER_UNIT - 1;
-		  fieldsize /= BITS_PER_UNIT;
+		  if (INTEGRAL_TYPE_P (TREE_TYPE (field)))
+		{
+		  bpos %= BITS_PER_UNIT;
+		  fieldsize = TYPE_PRECISION (TREE_TYPE (field)) + bpos;
+		  epos = fieldsize % BITS_PER_UNIT;
+		  fieldsize += BITS_PER_UNIT - 1;
+		  fieldsize /= BITS_PER_UNIT;
+		}
+		  else if (bpos % BITS_PER_UNIT
+			   || DECL_SIZE (field) == NULL_TREE
+			   || !tree_fits_shwi_p (DECL_SIZE (field))
+			   || tree_to_shwi (DECL_SIZE (field)) % BITS_PER_UNIT)
+		return 0;
 		}
 
 	  if (off != -1 && pos + fieldsize <= off)
@@ -8382,7 +8388,8 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
 	  if (val == NULL_TREE)
 		continue;
 
-	  if (DECL_BIT_FIELD (field))
+	  if (DECL_BIT_FIELD (field)
+		  && INTEGRAL_TYPE_P (TREE_TYPE (field)))
 		{
 		  /* FIXME: Handle PDP endian.  */
 		  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
-- { dg-do run }
-- { dg-options "-O" }

pragma Optimize_Alignment (Space);

with Opt101_Pkg; use Opt101_Pkg;

procedure Opt101 is

  C1 : Cont1;
  C2 : Cont2;

begin
  C1 := ((1234, 1, 2), 1, 2);
  if C1.R.I1 /= 1 or C1.I2 /= 2 then
raise Program_Error;
  end if;

  C2 := (1, (1234, 1, 2), 2);
  if C2.R.I1 /= 1 or C2.I2 /= 2 then
raise Program_Error;
  end if;
end;
package Opt101_Pkg is

  type Int is mod 16;

  type Rec is record
S : Short_Integer;
I1, I2 : Int;
  end record;
  pragma Pack (Rec);
  for Rec'Alignment use 4;

  type Cont1 is record
R : Rec;
I1, I2 : Int;
  end record;
  pragma Pack (Cont1);

  type Cont2 is record
I1 : Int;
R  : Rec;
I2 : Int;
  end record;
  pragma Pack (Cont2);
  pragma No_Component_Reordering (Cont2);

end Opt101_Pkg;


Re: [PATCH] Fix handling of non-integral bit-fields in native_encode_initializer

2023-05-23 Thread Eric Botcazou via Gcc-patches
> OK.

Thanks!

> Can we handle non-integer bitfields by recursing with a temporary buffer to
> encode it byte-aligned and then apply shifting and masking to get it in
> place? Or is that not worth it?

Certainly doable, something along these lines is implemented in varasm.c to 
output these non-integral bit-fields (output_constructor et al) so we could 
even try to share some code.  However, in practice, these cases turn out to be 
rare because the tree_output_constant_def path in gimplify_init_constructor is 
well guarded.

-- 
Eric Botcazou




[PATCH] Fix artificial overflow during GENERIC folding

2023-05-24 Thread Eric Botcazou via Gcc-patches
Hi,

on the attached testcase, the Ada compiler gives a bogus warning:
storage_offset1.ads:16:52: warning: Constraint_Error will be raised at run 
time [enabled by default]

This directly comes from the GENERIC folding setting a bogus TREE_OVERFLOW on 
an INTEGER_CST during the (T)P - (T)(P + A) -> -(T) A transformation:

  /* (T)P - (T)(P + A) -> -(T) A */
  (simplify
   (minus (convert? @0)
(convert (plus:c @@0 @1)))
   (if (INTEGRAL_TYPE_P (type)
&& TYPE_OVERFLOW_UNDEFINED (type)
&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
(with { tree utype = unsigned_type_for (type); }
 (convert (negate (convert:utype @1
(if (element_precision (type) <= element_precision (TREE_TYPE (@1))
 /* For integer types, if A has a smaller type
than T the result depends on the possible
overflow in P + A.
E.g. T=size_t, A=(unsigned)429497295, P>0.
However, if an overflow in P + A would cause
undefined behavior, we can assume that there
is no overflow.  */
 || (INTEGRAL_TYPE_P (TREE_TYPE (@1))
 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1
 (negate (convert @1)
  (simplify
   (minus (convert @0)
(convert (pointer_plus @@0 @1)))
   (if (INTEGRAL_TYPE_P (type)
&& TYPE_OVERFLOW_UNDEFINED (type)
&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
(with { tree utype = unsigned_type_for (type); }
 (convert (negate (convert:utype @1
(if (element_precision (type) <= element_precision (TREE_TYPE (@1))
 /* For pointer types, if the conversion of A to the
final type requires a sign- or zero-extension,
then we have to punt - it is not defined which
one is correct.  */
 || (POINTER_TYPE_P (TREE_TYPE (@0))
 && TREE_CODE (@1) == INTEGER_CST
 && tree_int_cst_sign_bit (@1) == 0))
 (negate (convert @1)

Ironically enough, this occurs because of the intermediate conversion to an 
unsigned type which is supposed to hide overflows, but is counter-productive 
for constants because TREE_OVERFLOW is always set for them, so it ends up 
setting a bogus TREE_OVERFLOW when converting back to the original type.

The fix simply redirects INTEGER_CSTs to the other, direct path without the 
intermediate conversion to the unsigned type.

Tested on x86-64/Linux, OK for the mainline?


2023-05-24  Eric Botcazou 

* match.pd ((T)P - (T)(P + A) -> -(T) A): Avoid artificial overflow
on constants.


2023-05-24  Eric Botcazou 

* gnat.dg/specs/storage_offset1.ads: New test.

-- 
Eric Botcazoudiff --git a/gcc/match.pd b/gcc/match.pd
index 1fe0559acfb..b9d04dd423b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3194,6 +3194,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (convert (plus:c @@0 @1)))
(if (INTEGRAL_TYPE_P (type)
 	&& TYPE_OVERFLOW_UNDEFINED (type)
+	&& TREE_CODE (@1) != INTEGER_CST
 	&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
 (with { tree utype = unsigned_type_for (type); }
  (convert (negate (convert:utype @1
@@ -3213,6 +3214,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (convert (pointer_plus @@0 @1)))
(if (INTEGRAL_TYPE_P (type)
 	&& TYPE_OVERFLOW_UNDEFINED (type)
+	&& TREE_CODE (@1) != INTEGER_CST
 	&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
 (with { tree utype = unsigned_type_for (type); }
  (convert (negate (convert:utype @1
-- { dg-do compile }

with System.Storage_Elements; use System.Storage_Elements;
with System;

package Storage_Offset1 is

  type Rec is record
I1, I2 : Integer;
  end record;

  type Ptr is access all Rec;

  R : Ptr := new Rec;

  Offset : constant Storage_Offset := R.I1'Address - R.I2'Address;

end Storage_Offset1;


Re: [PATCH] Fix artificial overflow during GENERIC folding

2023-05-24 Thread Eric Botcazou via Gcc-patches
> I don't like littering the patterns with this and it's likely far from the
> only cases we have?

Maybe, but that's the only problematic case we have in Ada.  It occurs only on 
mainline because we have streamlined address calculations there, from out-of-
line to inline expansion, i.e. from run time to compile time.

> Since we did move some of the patterns from fold-const.cc to match.pd and
> the frontends might be interested in TREE_OVERFLOW (otherwise we'd just
> scrap that!) I'm not sure removing the flag is good (and I never was really
> convinced the setting for the implementation defined behavior on conversion
> to unsigned is good).

Yes, the Ada front-end relies on the TREE_OVERFLOW flag to detect overflows at 
compile time, so it cannot be removed, but it must be set correctly, which is 
not the case here: (T)p - (T) (p + 4) where T is signed should just yield -4.

> Am I correct that the user writing such a conversion in Ada _should_
> get a constraint violation?  So it's just the middle-end introducing it
> to avoid undefined signed overflow that's on error?

Yes, it's a Constraint_Error in Ada to convert a value of an unsigned type to 
a signed type if it does not fit in the signed type.

> I'll also note that fold_convert_const_int_from_int shouldn't set
> TREE_OVERFLOW on unsigned destination types?  So it's the
> outer conversion back to signed that generates the TREE_OVERFLOW?

Yes, 4 is converted to unsigned, then negated, yielding a huge number, and the 
final conversion back to signed yields -4 with TREE_OVERFLOW set.

> Would it help to use a (view_convert ...) here?  For non-constants that
> should be folded back to a sign changing (convert ...) but the constant
> folding should hopefully happen earlier?  But it's again implementation
> defined behavior we have here, so not sure we need TREE_OVERFLOW at all.

I'm not sure we need to jump through too many hoops here: the intermediate 
conversion trick is a kludge because we lack a proper method to selectively 
disable undefined overflow at run time, but that's not the case at compile 
time where we have a finer-grained control (and even different rules) so I 
don't really see a problem with handling the two cases differently.

-- 
Eric Botcazou




Re: [PATCH] Fix artificial overflow during GENERIC folding

2023-05-24 Thread Eric Botcazou via Gcc-patches
> But nobody is going to understand why the INTEGER_CST case goes the
> other way.

I can add a fat comment to that effect of course. :-)

> As you say we don't have a good way to say we're doing
> this to avoid undefined behavior, but then a view-convert back would
> be a good way to indicate that?  I can't come up with a better name
> for a custom operator we could also use,
> 
>   (convert_without_overflow (negate (convert:utype @1
> 
> maybe?  As said, if view_convert works I prefer that.  Does it?

Well, VIEW_CONVERT_EXPR adds its own set of problems in GENERIC and it will 
precisely survive when it is not needed, so I'm not sure that's any better.

-- 
Eric Botcazou




Re: [PATCH]middle-end fix floating out of constants in conditionals

2022-09-26 Thread Eric Botcazou via Gcc-patches
> I think the better fix would be to only consider TREE_CONSTANT (arg)
> if it wasn't constant initially.  Because clearly "simplify" intends
> to be "constant" here.  In fact I wonder why we test !TREE_CONSTANT (arg)
> at all, we don't simplify 'arg' ...
> 
> Eric added this test (previosuly we'd just always done the folding),
> but I think not enough?

Before my change we had always done the folding *only* for TREE_CONSTANT (arg)
and my change allowed it for some cases of !TREE_CONSTANT (arg), but I did not
want to touch the !TREE_CONSTANT (arg) case at all:

* fold-const.c (fold_binary_op_with_conditional_arg): Do not restrict
the folding to constants.  Remove redundant final conversion.

Tamar's issue appears to be for TREE_CONSTANT (arg) so orthogonal to mine.

-- 
Eric Botcazou




Re: [PATCH]middle-end fix floating out of constants in conditionals

2022-09-26 Thread Eric Botcazou via Gcc-patches
> Before my change we had always done the folding *only* for TREE_CONSTANT
> (arg) and my change allowed it for some cases of !TREE_CONSTANT (arg), but
> I did not want to touch the !TREE_CONSTANT (arg) case at all:

...to touch the TREE_CONSTANT (arg) case at all...

-- 
Eric Botcazou





[PATCH] Fix wrong code generated by unroll-and-jam pass

2022-10-05 Thread Eric Botcazou via Gcc-patches
Hi,

as shown by the attached testcase, there is a loophole in the unroll-and-jam
pass that can quickly result in wrong code generation.  The code reads:

if (!compute_data_dependences_for_loop (outer, true, &loop_nest,
&datarefs, &dependences))
{
  if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Cannot analyze data dependencies\n");
  free_data_refs (datarefs);
  free_dependence_relations (dependences);
  continue;
}

but compute_data_dependences_for_loop may return true even if the analysis is
reported as failing by compute_affine_dependence for some dependence pair:

(compute_affine_dependence
  ref_a: data[_14], stmt_a: data[_14] = i_59;
  ref_b: data[_14], stmt_b: data[_14] = i_59;
Data ref a:
#(Data Ref: 
#  bb: 12 
#  stmt: data[_14] = i_59;
#  ref: data[_14];
#  base_object: data;
#  Access function 0: scev_not_known;
#)
Data ref b:
#(Data Ref: 
#  bb: 12 
#  stmt: data[_14] = i_59;
#  ref: data[_14];
#  base_object: data;
#  Access function 0: scev_not_known;
#)
affine dependence test not usable: access function not affine or constant.
) -> dependence analysis failed

Note that this is a self-dependence pair and the code for them reads:

  /* Nothing interesting for the self dependencies.  */
  if (dra == drb)
continue;

This means that the pass may reorder "complex" accesses to the same memory
location in successive iterations, which is OK for reads but not for writes.

Proposed fix attached, tested on x86-64/Linux, OK for all active branches?


2022-10-05  Eric Botcazou  

* gimple-loop-jam.cc (tree_loop_unroll_and_jam): Bail out for a self
dependency that is a write-after-write if the access function is not
affine or constant.


2022-10-05  Eric Botcazou  

* gcc.c-torture/execute/20221005-1.c: New test.

-- 
Eric Botcazoudiff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc
index a8a57d3d384..4f7a6e5bbae 100644
--- a/gcc/gimple-loop-jam.cc
+++ b/gcc/gimple-loop-jam.cc
@@ -545,11 +545,25 @@ tree_loop_unroll_and_jam (void)
 	  /* If the refs are independend there's nothing to do.  */
 	  if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
 	continue;
+
 	  dra = DDR_A (ddr);
 	  drb = DDR_B (ddr);
-	  /* Nothing interesting for the self dependencies.  */
+
+	  /* Nothing interesting for the self dependencies, except for WAW if
+	 the access function is not affine or constant because we may end
+	 up reordering writes to the same location.  */
 	  if (dra == drb)
-	continue;
+	{
+	  if (DR_IS_WRITE (dra)
+		  && !DR_ACCESS_FNS (dra).is_empty ()
+		  && DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
+		{
+		  unroll_factor = 0;
+		  break;
+		}
+	  else
+		continue;
+	}
 
 	  /* Now check the distance vector, for determining a sensible
 	 outer unroll factor, and for validity of merging the inner
#include 

int
main (int argc, char** argv)
{
  const int len = argc == 2 ? atoi(argv[1]) : 4;

  int count;
  int data[64];
  int M1[len][len];
  int M2[len][len];

  for (int i = 0; i < len; i++)
for (int j = 0 ; j < len ; j++)
  M1[i][j] = M2[i][j] = i*len + j;

  M2[1][0] = M2[0][1];

  /* This writes successively 0 and 1 into data[M2[0][1]].  */
  for (int i = 0; i < len - 1; i++)
for (int j = 0 ; j < len ; j++)
  if (M1[i+1][j] > M1[i][j]) 
data[M2[i][j]] = i;

  if (data [M2[0][1]] != 1)
abort ();

  return 0;
}


Re: [PATCH] Fix wrong code generated by unroll-and-jam pass

2022-10-06 Thread Eric Botcazou via Gcc-patches
> I'm wondering if testing DR_IS_WRITE (dra) is enough here and whether
> the logic also applies to RAW and WAR.  So should it be either
> (DR_IS_WRITE (dra) || DR_IS_WRITE (drb)) or DR_IS_WRITE (dra) &&
> DR_IS_WRITE (drb) instead?

It's a self-dependence, i.e. dra == drb in the block.  Or do you mean for 
other dependence pairs in general?  For them, I think that the code does the 
proper filtering in adjust_unroll_factor, but I may be wrong of course.

-- 
Eric Botcazou




[PATCH] Reduce DF computation at -O0

2022-10-06 Thread Eric Botcazou via Gcc-patches
Hi,

even at -O0 there may be a fair amount of DF computation performed when
compiling large units and part of it appears to be useless.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2022-10-06  Eric Botcazou  

* function.cc (thread_prologue_and_epilogue_insns): Update only entry
and exit blocks when not optimizing.  Remove dead statement.

-- 
Eric Botcazoudiff --git a/gcc/function.cc b/gcc/function.cc
index 5498a712c4a..6474a663b30 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -6249,10 +6249,15 @@ thread_prologue_and_epilogue_insns (void)
 	}
 }
 
-  /* Threading the prologue and epilogue changes the artificial refs
- in the entry and exit blocks.  */
-  epilogue_completed = 1;
-  df_update_entry_exit_and_calls ();
+  /* Threading the prologue and epilogue changes the artificial refs in the
+ entry and exit blocks, and may invalidate DF info for tail calls.  */
+  if (optimize)
+df_update_entry_exit_and_calls ();
+  else
+{
+  df_update_entry_block_defs ();
+  df_update_exit_block_uses ();
+}
 }
 
 /* Reposition the prologue-end and epilogue-begin notes after


[Ada] Enable support for atomic primitives on SPARC/Linux

2022-10-11 Thread Eric Botcazou via Gcc-patches
The SPARC/Linux port is very similar to the SPARC/Solaris port nowadays so it 
makes sense to copy the setting of the support for atomic primitives.

This fixes the single regression in the gnat.dg testsuite:
FAIL: gnat.dg/prot7.adb (test for excess errors)

Tested on SPARC64/Linux, applied on the mainline.


2022-10-11  Eric Botcazou  

* libgnat/system-linux-sparc.ads (Support_Atomic_Primitives): New
constant set to True.

-- 
Eric Botcazoudiff --git a/gcc/ada/libgnat/system-linux-sparc.ads b/gcc/ada/libgnat/system-linux-sparc.ads
index cc502da3e5b..6d4ee380b2d 100644
--- a/gcc/ada/libgnat/system-linux-sparc.ads
+++ b/gcc/ada/libgnat/system-linux-sparc.ads
@@ -133,6 +133,7 @@ private
Stack_Check_Probes: constant Boolean := True;
Stack_Check_Limits: constant Boolean := False;
Support_Aggregates: constant Boolean := True;
+   Support_Atomic_Primitives : constant Boolean := True;
Support_Composite_Assign  : constant Boolean := True;
Support_Composite_Compare : constant Boolean := True;
Support_Long_Shifts   : constant Boolean := True;


[PATCH] Fix emit_group_store regression on big-endian

2022-10-11 Thread Eric Botcazou via Gcc-patches
Hi,

the recent optimization implemented for complex modes in:
  https://gcc.gnu.org/pipermail/gcc-patches/2022-May/595865.html
contains an oversight for big-endian platforms in the "interesting corner 
case" mentioned in the message: it uses a lowpart SUBREG when the integer 
modes have different sizes, but this does not match the semantics of the 
PARALLELs which have a bundled byte offset; this offset is always zero in the 
code path and the lowpart is not at offset zero on big-endian platforms.

Calling validate_subreg with this zero offset would fix the regression by 
disabling the optimization on big-endian platforms, so instead the attached 
fix adds the appropriate right shift for them.

This fixes the following regressions in the C testsuite on SPARC64/Linux:
FAIL: gcc.c-torture/execute/20041124-1.c   -O0  execution test
FAIL: gcc.c-torture/execute/20041124-1.c   -O1  execution test
FAIL: gcc.c-torture/execute/20041124-1.c   -O2  execution test
FAIL: gcc.c-torture/execute/20041124-1.c   -O2 -flto -fno-use-linker-plugin -
flto-partition=none  execution test
FAIL: gcc.c-torture/execute/20041124-1.c   -O2 -flto -fuse-linker-plugin -fno-
fat-lto-objects  execution test
FAIL: gcc.c-torture/execute/20041124-1.c   -O3 -g  execution test
FAIL: gcc.c-torture/execute/20041124-1.c   -Os  execution test
FAIL: gcc.dg/compat/struct-by-value-11 c_compat_x_tst.o-c_compat_y_tst.o 
execute 
FAIL: gcc.dg/compat/struct-by-value-12 c_compat_x_tst.o-c_compat_y_tst.o 
execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t027 c_compat_x_tst.o-c_compat_y_tst.o 
execute 

Tested on SPARC64/Linux, OK for the mainline?


2022-10-11  Eric Botcazou  

* expr.cc (emit_group_stote): Fix handling of modes of different
sizes for big-endian targets in latest change and add commentary.

-- 
Eric Botcazoudiff --git a/gcc/expr.cc b/gcc/expr.cc
index ba627f176a7..b897b6dc385 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -2813,50 +2813,69 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
   else
 	adj_bytelen = bytelen;
 
+  /* Deal with destination CONCATs by either storing into one of the parts
+	 or doing a copy after storing into a register or stack temporary.  */
   if (GET_CODE (dst) == CONCAT)
 	{
 	  if (known_le (bytepos + adj_bytelen,
 			GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)
 	dest = XEXP (dst, 0);
+
 	  else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)
 	{
 	  bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
 	  dest = XEXP (dst, 1);
 	}
+
 	  else
 	{
 	  machine_mode dest_mode = GET_MODE (dest);
 	  machine_mode tmp_mode = GET_MODE (tmps[i]);
-	  scalar_int_mode imode;
+	  scalar_int_mode dest_imode;
 
 	  gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
 
-	  if (finish == 1
+	  /* If the source is a single scalar integer register, and the
+		 destination has a complex mode for which a same-sized integer
+		 mode exists, then we can take the left-justified part of the
+		 source in the complex mode.  */
+	  if (finish == start + 1
 		  && REG_P (tmps[i])
-		  && COMPLEX_MODE_P (dest_mode)
 		  && SCALAR_INT_MODE_P (tmp_mode)
-		  && int_mode_for_mode (dest_mode).exists (&imode))
+		  && COMPLEX_MODE_P (dest_mode)
+		  && int_mode_for_mode (dest_mode).exists (&dest_imode))
 		{
-		  if (tmp_mode != imode)
+		  const scalar_int_mode tmp_imode
+		= as_a  (tmp_mode);
+
+		  if (GET_MODE_BITSIZE (dest_imode)
+		  < GET_MODE_BITSIZE (tmp_imode))
 		{
-		  rtx tmp = gen_reg_rtx (imode);
-		  emit_move_insn (tmp, gen_lowpart (imode, tmps[i]));
-		  dst = gen_lowpart (dest_mode, tmp);
+		  dest = gen_reg_rtx (dest_imode);
+		  if (BYTES_BIG_ENDIAN)
+			tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
+		GET_MODE_BITSIZE (tmp_imode)
+		- GET_MODE_BITSIZE (dest_imode),
+		NULL_RTX, 1);
+		  emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
+		  dst = gen_lowpart (dest_mode, dest);
 		}
 		  else
 		dst = gen_lowpart (dest_mode, tmps[i]);
 		}
+
+	  /* Otherwise spill the source onto the stack using the more
+		 aligned of the two modes.  */
 	  else if (GET_MODE_ALIGNMENT (dest_mode)
-		  >= GET_MODE_ALIGNMENT (tmp_mode))
+		   >= GET_MODE_ALIGNMENT (tmp_mode))
 		{
 		  dest = assign_stack_temp (dest_mode,
 	GET_MODE_SIZE (dest_mode));
-		  emit_move_insn (adjust_address (dest,
-		  tmp_mode,
-		  bytepos),
+		  emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
   tmps[i]);
 		  dst = dest;
 		}
+
 	  else
 		{
 		  dest = assign_stack_temp (tmp_mode,
@@ -2864,6 +2883,7 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
 		  emit_move_insn (dest, tmps[i]);
 		  dst = adjust_address (dest, dest_mode, bytepos);
 		}
+
 	  break;
 	}
 	}


Re: [RFC] Teach vectorizer to deal with bitfield reads

2022-10-12 Thread Eric Botcazou via Gcc-patches
> Let me know if you believe this is a good approach? I've ran regression
> tests and this hasn't broken anything so far...

Small regression in Ada though, probably a missing guard somewhere:

=== gnat tests ===


Running target unix
FAIL: gnat.dg/loop_optimization23.adb 3 blank line(s) in output
FAIL: gnat.dg/loop_optimization23.adb (test for excess errors)
UNRESOLVED: gnat.dg/loop_optimization23.adb compilation failed to produce 
execut
able
FAIL: gnat.dg/loop_optimization23_pkg.adb 3 blank line(s) in output
FAIL: gnat.dg/loop_optimization23_pkg.adb (test for excess errors)

In order to reproduce, configure the compiler with Ada enabled, build it, and 
copy $[srcdir)/gcc/testsuite/gnat.dg/loop_optimization23_pkg.ad[sb] into the 
build directory, then just issue:

gcc/gnat1 -quiet loop_optimization23_pkg.adb -O2 -Igcc/ada/rts

eric@fomalhaut:~/build/gcc/native> gcc/gnat1 -quiet 
loop_optimization23_pkg.adb -O2 -Igcc/ada/rts
during GIMPLE pass: vect
+===GNAT BUG DETECTED==+
| 13.0.0 20221012 (experimental) [master ca7f7c3f140] (x86_64-suse-linux) GCC 
error:|
| in exact_div, at poly-int.h:2232 |
| Error detected around loop_optimization23_pkg.adb:5:3|
| Compiling loop_optimization23_pkg.adb

-- 
Eric Botcazou




Re: [PATCH] x86: Disable SSE on unwind-c.c and unwind-dw2.c

2022-03-06 Thread Eric Botcazou via Gcc-patches
>   PR target/104781
>   * config.host (tmake_file): Add i386/32/t-eh-return-no-sse for
>   32-bit x86 Cygwin and Solaris.
>   * config/i386/32/t-eh-return-no-sse: New file.

What about MinGW here?

-- 
Eric Botcazou




Re: [PATCH v3] x86: Disable SSE on unwind-c.c and unwind-dw2.c

2022-03-08 Thread Eric Botcazou via Gcc-patches
> Disabling sse/sse2 might be a problem especially on mingw where we need to
> restore SSE registers in the EH return, no?

Not in 32-bit mode I think, all XMM registers are call used.

-- 
Eric Botcazou




Re: [PATCH] ifcvt: Punt if not onlyjump_p for find_if_case_{1, 2} [PR104814]

2022-03-13 Thread Eric Botcazou via Gcc-patches
> Bootstrapped/regtested on {x86_64,i686,powerpc64le,aarch64,s390x}-linux,
> ok for trunk?
> 
> 2022-03-13  Jakub Jelinek  
> 
>   PR rtl-optimization/104814
>   * ifcvt.cc (find_if_case_1, find_if_case_2): Punt if test_bb
>   doesn't end with onlyjump_p.
> 
>   * gcc.c-torture/execute/pr104814.c: New test.
> 
> --- gcc/ifcvt.cc.jj   2022-02-09 12:55:50.750773751 +0100
> +++ gcc/ifcvt.cc  2022-03-11 17:30:44.248855063 +0100
> @@ -5259,6 +5259,10 @@ find_if_case_1 (basic_block test_bb, edg
> && CROSSING_JUMP_P (BB_END (else_bb
>  return FALSE;
> 
> +  /* Verify test_bb ends in a conditional jump with no other side-effects. 
> */ +  if (!BB_END (test_bb) || !onlyjump_p (BB_END (test_bb)))
> +return FALSE;
> +
>/* THEN has one successor.  */
>if (!single_succ_p (then_bb))
>  return FALSE;
> @@ -5380,6 +5384,10 @@ find_if_case_2 (basic_block test_bb, edg
> && CROSSING_JUMP_P (BB_END (else_bb
>  return FALSE;
> 
> +  /* Verify test_bb ends in a conditional jump with no other side-effects. 
> */ +  if (!BB_END (test_bb) || !onlyjump_p (BB_END (test_bb)))
> +return FALSE;
> +
>/* ELSE has one successor.  */
>if (!single_succ_p (else_bb))
>  return FALSE;

Are the !BB_END tests really necessary?  cond_exec_process_if_block has the 
same test on onlyjump_p without it.  Likewise for noce_find_if_block.

-- 
Eric Botcazou




Re: [PATCH] ifcvt, v2: Punt if not onlyjump_p for find_if_case_{1, 2} [PR104814]

2022-03-14 Thread Eric Botcazou via Gcc-patches
> Here is an updated patch for it.  Ok for trunk?
> 
> 2022-03-14  Jakub Jelinek  
> 
>   PR rtl-optimization/104814
> * ifcvt.cc (find_if_case_1, find_if_case_2): Punt if test_bb doesn't
>   end with onlyjump_p.  Assume BB_END (test_bb) is always non-NULL.
> 
>   * gcc.c-torture/execute/pr104814.c: New test.

OK, thanks.

-- 
Eric Botcazou




[Ada] Fix PR ada/104767

2022-03-24 Thread Eric Botcazou via Gcc-patches
This is a regression present on mainline, 11 and 10 branches.  When the serial 
port is closed, we need to ensure that the port handle is properly reset for 
it to be detected as closed.

Tested on x86-64/Linux, applied on mainline, 11 and 10 branches.


2022-03-24  Pascal Obry  

PR ada/104767
* libgnat/g-sercom__mingw.adb (Close): Reset port handle to -1.
* libgnat/g-sercom__linux.adb (Close): Likewise.

-- 
Eric Botcazoudiff --git a/gcc/ada/libgnat/g-sercom__linux.adb b/gcc/ada/libgnat/g-sercom__linux.adb
index a2a64b1c17f..73bbb69300e 100644
--- a/gcc/ada/libgnat/g-sercom__linux.adb
+++ b/gcc/ada/libgnat/g-sercom__linux.adb
@@ -382,6 +382,7 @@ package body GNAT.Serial_Communications is
begin
   if Port.H /= -1 then
  Res := close (int (Port.H));
+ Port.H := -1;
   end if;
end Close;
 
diff --git a/gcc/ada/libgnat/g-sercom__mingw.adb b/gcc/ada/libgnat/g-sercom__mingw.adb
index aea78aead8c..d3301bd045b 100644
--- a/gcc/ada/libgnat/g-sercom__mingw.adb
+++ b/gcc/ada/libgnat/g-sercom__mingw.adb
@@ -70,6 +70,7 @@ package body GNAT.Serial_Communications is
begin
   if Port.H /= -1 then
  Success := CloseHandle (HANDLE (Port.H));
+ Port.H := -1;
 
  if Success = Win32.FALSE then
 Raise_Error ("error closing the port");


[c-family] Fix issue for pointers to anonymous types with -fdump-ada-spec

2022-03-25 Thread Eric Botcazou via Gcc-patches
This used to work long ago but broke at some point, so I'm applying the fix
only on the mainline, all the more so that it deals the "section" attribute.

Tested on x86-64/Linux, applied on the mainline.


2022-03-25  Eric Botcazou  

c-family/
* c-ada-spec.cc (dump_ada_import): Deal with the "section" attribute.
(dump_ada_node) : Do not modify and pass the name, but
the referenced type instead.  Deal with the anonymous original type
of a typedef'ed type.  In the actual access case, follow the chain of
external subtypes.
: Tidy up control flow.

-- 
Eric Botcazoudiff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index aeb429136b6..f291e150934 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -1526,6 +1526,15 @@ dump_ada_import (pretty_printer *buffer, tree t, int spc)
 
   newline_and_indent (buffer, spc + 5);
 
+  tree sec = lookup_attribute ("section", DECL_ATTRIBUTES (t));
+  if (sec)
+{
+  pp_string (buffer, "Linker_Section => \"");
+  pp_string (buffer, TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec;
+  pp_string (buffer, "\", ");
+  newline_and_indent (buffer, spc + 5);
+}
+
   pp_string (buffer, "External_Name => \"");
 
   if (is_stdcall)
@@ -2179,10 +2188,11 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 	}
   else
 	{
-	  const unsigned int quals = TYPE_QUALS (TREE_TYPE (node));
+	  tree ref_type = TREE_TYPE (node);
+	  const unsigned int quals = TYPE_QUALS (ref_type);
 	  bool is_access = false;
 
-	  if (VOID_TYPE_P (TREE_TYPE (node)))
+	  if (VOID_TYPE_P (ref_type))
 	{
 	  if (!name_only)
 		pp_string (buffer, "new ");
@@ -2197,9 +2207,8 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 	  else
 	{
 	  if (TREE_CODE (node) == POINTER_TYPE
-		  && TREE_CODE (TREE_TYPE (node)) == INTEGER_TYPE
-		  && id_equal (DECL_NAME (TYPE_NAME (TREE_TYPE (node))),
-			   "char"))
+		  && TREE_CODE (ref_type) == INTEGER_TYPE
+		  && id_equal (DECL_NAME (TYPE_NAME (ref_type)), "char"))
 		{
 		  if (!name_only)
 		pp_string (buffer, "new ");
@@ -2214,28 +2223,11 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 		}
 	  else
 		{
-		  tree type_name = TYPE_NAME (TREE_TYPE (node));
-
-		  /* Generate "access " instead of "access "
-		 if the subtype comes from another file, because subtype
-		 declarations do not contribute to the limited view of a
-		 package and thus subtypes cannot be referenced through
-		 a limited_with clause.  */
-		  if (type_name
-		  && TREE_CODE (type_name) == TYPE_DECL
-		  && DECL_ORIGINAL_TYPE (type_name)
-		  && TYPE_NAME (DECL_ORIGINAL_TYPE (type_name)))
-		{
-		  const expanded_location xloc
-			= expand_location (decl_sloc (type_name, false));
-		  if (xloc.line
-			  && xloc.file
-			  && xloc.file != current_source_file)
-			type_name = DECL_ORIGINAL_TYPE (type_name);
-		}
+		  tree stub = TYPE_STUB_DECL (ref_type);
+		  tree type_name = TYPE_NAME (ref_type);
 
 		  /* For now, handle access-to-access as System.Address.  */
-		  if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
+		  if (TREE_CODE (ref_type) == POINTER_TYPE)
 		{
 		  if (package_prefix)
 			{
@@ -2251,7 +2243,7 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 
 		  if (!package_prefix)
 		pp_string (buffer, "access");
-		  else if (AGGREGATE_TYPE_P (TREE_TYPE (node)))
+		  else if (AGGREGATE_TYPE_P (ref_type))
 		{
 		  if (!type || TREE_CODE (type) != FUNCTION_DECL)
 			{
@@ -2281,12 +2273,41 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 			pp_string (buffer, "all ");
 		}
 
-		  if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node)) && type_name)
-		dump_ada_node (buffer, type_name, TREE_TYPE (node), spc,
-   is_access, true);
-		  else
-		dump_ada_node (buffer, TREE_TYPE (node), TREE_TYPE (node),
-   spc, false, true);
+		  /* If this is the anonymous original type of a typedef'ed
+		 type, then use the name of the latter.  */
+		  if (!type_name
+		  && stub
+		  && DECL_CHAIN (stub)
+		  && TREE_CODE (DECL_CHAIN (stub)) == TYPE_DECL
+		  && DECL_ORIGINAL_TYPE (DECL_CHAIN (stub)) == ref_type)
+		ref_type = TREE_TYPE (DECL_CHAIN (stub));
+
+		  /* Generate "access " instead of "access "
+		 if the subtype comes from another file, because subtype
+		 declarations do not contribute to the limited view of a
+		 package and thus subtypes cannot be referenced through
+		 a limited_with clause.  */
+		  else if (is_access)
+		while (type_name
+			   && TREE_CODE (type_name) == TYPE_DECL
+			   && DECL_ORIGINAL_TYPE (type_name)
+			   && TYPE_NAME (DECL_ORIGINAL_TYPE (type_name)))
+		  {
+			const expanded_location xloc
+			  = expand_location (decl_sloc (type_name, false));
+			if (xloc.line
+			&& xloc.file
+	

Re: [wwwdocs] Add Ada's changelog entry

2022-04-04 Thread Eric Botcazou via Gcc-patches
> this is my first patch to GCC, if there is anything off, please, say
> so. I have used the default HTML formatting that comes with Emacs. I
> have created the patch using the `git format-patch` utility.

Thanks for your contribution.  Small nit:

+  Support for 128bit integers has beed added.

The support was already present in GCC 11, the criterion being the use of the 
'Max_Integer_Size attribute in system.ads.

-- 
Eric Botcazou




Re: [PATCH] Disable float128 tests on VxWorks, PR target/104253.

2022-04-07 Thread Eric Botcazou via Gcc-patches
> I have run the tests on my usual Linux systems (little endian power10,
> little endian power9, big endian power8), but I don't have access to a
> VxWorks system.  Eric does this fix the failure for you?

Yes, if you add '*' at the end of the selector, i.e. [istarget *-*-vxworks*].

> If it does fix the failure, can I apply the patch to the master branch and
> backport it to GCC 11 and GCC 10?  Sorry about the breakage.

That would be perfect, thanks in advance.

-- 
Eric Botcazou




Re: [PATCH] simplify-rtx: Don't assume shift count has the same mode as the shift [PR105247]

2022-04-14 Thread Eric Botcazou via Gcc-patches
> 2022-04-13  Jakub Jelinek  
> 
>   PR target/105247
>   * simplify-rtx.cc (simplify_const_binary_operation): For shifts
>   or rotates by VOIDmode constant integer shift count use word_mode
>   for the operand if int_mode is narrower than word.
> 
>   * gcc.c-torture/compile/pr105247.c: New test.

OK, thanks.

-- 
Eric Botcazou




Re: [PATCH] rtlanal: Fix up replace_rtx [PR105333]

2022-04-22 Thread Eric Botcazou via Gcc-patches
> 2022-04-22  Jakub Jelinek  
> 
>   PR rtl-optimization/105333
>   * rtlanal.cc (replace_rtx): Use simplify_subreg or
>   simplify_unary_operation if CONST_SCALAR_INT_P rather than just
>   CONST_INT_P.
> 
>   * gcc.dg/pr105333.c: New test.

OK, thanks.

-- 
Eric Botcazou




Re: Difference between 32-bit SPARCv9 and SPARCv8+?

2022-01-23 Thread Eric Botcazou via Gcc-patches
> While playing around with the compiler options trying to find a solution, I
> made an interesting discovery which is that GCC support 64-bit compare and
> swap on SPARCv8plus but not on 32-bit SPARCv9:
> 
> glaubitz@gcc202:~$ echo | gcc -mv8plus -E -dM -|grep -i SWAP
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
> glaubitz@gcc202:~$ echo | gcc -mcpu=v9 -m32 -E -dM -|grep -i SWAP
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
> #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
> glaubitz@gcc202:~$
> 
> Is this intentional? If yes, what is the exact difference between V8+ and
> 32-bit V9?

V8+ requires the full 64-bit registers to be preserved by the kernel, whereas 
32-bit V9 does not.

-- 
Eric Botcazou




Re: Difference between 32-bit SPARCv9 and SPARCv8+?

2022-01-23 Thread Eric Botcazou via Gcc-patches
> Does anyone know the reasoning behind this?

Solaris preserves the full 64-bit registers in 32-bit mode.

-- 
Eric Botcazou




[Ada] Fix PR ada/104258

2022-01-28 Thread Eric Botcazou via Gcc-patches
This is a regression present on mainline and 11 branch: the new transformation 
applied during expansion by Narrow_Large_Operation would incorrectly perform 
name resolution for the operator again.

Tested on x86_64-suse-linux, applied on mainline and 11 branch.


2022-01-28  Eric Botcazou  

PR ada/104258
* exp_ch4.adb (Narrow_Large_Operation): Also copy the entity, if
any, when rewriting the operator node.


2022-01-28  Eric Botcazou  

* gnat.dg/generic_comp.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index c31f5bb36ba..2506c67e936 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -14314,9 +14314,13 @@ package body Exp_Ch4 is
  return;
   end if;
 
-  --  Finally, rewrite the operation in the narrower type
+  --  Finally, rewrite the operation in the narrower type, but make sure
+  --  not to perform name resolution for the operator again.
 
   Nop := New_Op_Node (Kind, Sloc (N));
+  if Nkind (N) in N_Has_Entity then
+ Set_Entity (Nop, Entity (N));
+  end if;
 
   if Binary then
  Set_Left_Opnd (Nop, Convert_To (Ntyp, L));
-- { dg-do run }

procedure Generic_Comp is

   generic
  type Element_Type is private;
  type Index_Type is (<>);
  type Array_Type is array (Index_Type range <>) of Element_Type;
  with function ">" (Left, Right : Element_Type) return Boolean is <>;
   procedure Gen (Data: in out Array_Type);

   procedure Gen (Data: in out Array_Type) is
   begin
  if not (Data'Length > 1)
or else not (Integer'(Data'Length) > 1)
or else not Standard.">" (Data'Length, 1)
or else not Standard.">" (Integer'(Data'Length), 1)
  then
 raise Program_Error;
  end if;
   end;

   type My_Array is array (Positive range <>) of Integer;

   function Less_Than (L, R : Integer) return Boolean is
   begin
  return L < R;
   end;

   procedure Chk_Down is new Gen (Element_Type => Integer,
  Index_Type   => Positive,
  Array_Type   => My_Array,
  ">"  => Less_Than);

   Data : My_Array (1 .. 2);

begin
   Chk_Down (Data);
end;


Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-01-31 Thread Eric Botcazou via Gcc-patches
> Unfortunately this breaks quite a lot of things.

Right, for example in Ada where we now happily turn a division by zero, which 
should raise an exception with -gnatp, into nonsense.  Do we really need this 
rather useless optimization in GCC?  Blindly mimicing LLVM is not a reason...

I have installed the attached testcase, which now fails because of the change.

* gnat.dg/div_zero.adb: New test.

-- 
Eric Botcazou-- { dg-do run }

-- This test requires architecture- and OS-specific support code for unwinding
-- through signal frames (typically located in *-unwind.h) to pass.  Feel free
-- to disable it if this code hasn't been implemented yet.

procedure Div_Zero is

  pragma Suppress (All_Checks);

  function Zero return Integer is
  begin
return 0;
  end;

  D : Integer := Zero;

begin
  D := 1 / D;
  raise Program_Error;
exception
  when Constraint_Error => null;
end;


[SPARC] Use V8+ default in 32-bit mode on SPARC64/Linux

2022-01-31 Thread Eric Botcazou via Gcc-patches
This is what has been done for ages on SPARC/Solaris and makes it possible to 
use 64-bit atomic instructions even in 32-bit mode.

Tested on SPARC64/Linux, applied on the mainline.


2022-01-31  Eric Botcazou 

PR target/104189
* config/sparc/linux64.h (TARGET_DEFAULT): Add MASK_V8PLUS.

-- 
Eric Botcazoudiff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index 46823b62a3f..d08a2ef96fe 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -35,8 +35,8 @@ along with GCC; see the file COPYING3.  If not see
 #if defined(TARGET_64BIT_DEFAULT) && TARGET_CPU_DEFAULT >= TARGET_CPU_v9
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
-  (MASK_V9 + MASK_PTR64 + MASK_64BIT + MASK_STACK_BIAS + \
-   MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
+  (MASK_V9 + MASK_64BIT + MASK_PTR64 + MASK_STACK_BIAS + \
+   MASK_V8PLUS + MASK_APP_REGS + MASK_FPU + MASK_LONG_DOUBLE_128)
 #endif
 
 /* This must be v9a not just v9 because by default we enable


Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-02-02 Thread Eric Botcazou via Gcc-patches
> Since I didn't see anyone responding to this problem, I filed PR
> 104356 to record the regression.
> And yes this should be handled correctly.

Thanks.  Note that we have an example of this in libgcc/libgcc2.c too.

-- 
Eric Botcazou




Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-02-03 Thread Eric Botcazou via Gcc-patches
> Well, yes, we have to fix it.  I will share my thoughts when coming
> along the bugreport.

IMO we should simply scrap it, as it does not serve any useful purpose, breaks 
a very ancient and useful idiom and also introduces an artificial discrepancy 
between 1/X and 2/X for example.

-- 
Eric Botcazou




Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-02-03 Thread Eric Botcazou via Gcc-patches
> The optimization can be useful, it doesn't have to be for user written
> y = 1 / x; but can appear through inlining or some other optimizations, e.g.
> jump threading and suddenly we have constant 1 in some bb, if it a never
> executed at runtime block, it will be likely shorter because of the
> optimization, if it is not, then it will be cheaper.

The hundreds of people having worked on GCC for the past 30 years must have 
been stupid then, how come have they missed such a great optimization? ;-)

-- 
Eric Botcazou




Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-02-03 Thread Eric Botcazou via Gcc-patches
> Yes, I think the intent is clear.  The question is whether we should
> re-instantiate the clear intent of preserving a literal / 0 as well
> (for C, without -fnon-call-exceptions).

Note that the code is precisely compiled with -fnon-call-exceptions:

ifeq ($(LIB2_DIVMOD_EXCEPTION_FLAGS),)
# Provide default flags for compiling divmod functions, if they haven't been
# set already by a target-specific Makefile fragment.
LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions -fnon-call-exceptions
endif

# Build LIB2_DIVMOD_FUNCS.
lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
$(lib2-divmod-o): %$(objext): $(srcdir)/libgcc2.c
$(gcc_compile) -DL$* -c $< \
  $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
libgcc-objects += $(lib2-divmod-o)

ifeq ($(enable_shared),yes)
lib2-divmod-s-o = $(patsubst %,%_s$(objext),$(LIB2_DIVMOD_FUNCS))
$(lib2-divmod-s-o): %_s$(objext): $(srcdir)/libgcc2.c
$(gcc_s_compile) -DL$* -c $< \
  $(LIB2_DIVMOD_EXCEPTION_FLAGS)
libgcc-s-objects += $(lib2-divmod-s-o)
endif

so it seems like we were about to reinvent the wheel here. ;-)

-- 
Eric Botcazou




Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-02-04 Thread Eric Botcazou via Gcc-patches
> Well, yes, we have to fix it.

Here's the fix we agreed upon in the audit trail, OK for the mainline?

PR tree-optimization/104356
* match.pd (X / bool_range_Y is X): Add guard.
(X / X is one): Likewise.
(X / abs (X) is X < 0 ? -1 : 1): Likewise.
(X / -X is -1): Likewise.
(1 / X -> X == 1): Likewise.

-- 
Eric Botcazou
diff --git a/gcc/match.pd b/gcc/match.pd
index b942cb2930a..4b695db7a25 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -401,27 +401,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  /* X / bool_range_Y is X.  */ 
  (simplify
   (div @0 SSA_NAME@1)
-  (if (INTEGRAL_TYPE_P (type) && ssa_name_has_boolean_range (@1))
+  (if (INTEGRAL_TYPE_P (type)
+   && ssa_name_has_boolean_range (@1)
+   && !flag_non_call_exceptions)
@0))
  /* X / X is one.  */
  (simplify
   (div @0 @0)
   /* But not for 0 / 0 so that we can get the proper warnings and errors.
  And not for _Fract types where we can't build 1.  */
-  (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type)))
+  (if (!integer_zerop (@0)
+   && (!flag_non_call_exceptions || tree_expr_nonzero_p (@0))
+   && !ALL_FRACT_MODE_P (TYPE_MODE (type)))
{ build_one_cst (type); }))
  /* X / abs (X) is X < 0 ? -1 : 1.  */
  (simplify
(div:C @0 (abs @0))
(if (INTEGRAL_TYPE_P (type)
-	&& TYPE_OVERFLOW_UNDEFINED (type))
+	&& TYPE_OVERFLOW_UNDEFINED (type)
+	&& !integer_zerop (@0)
+	&& (!flag_non_call_exceptions || tree_expr_nonzero_p (@0)))
 (cond (lt @0 { build_zero_cst (type); })
   { build_minus_one_cst (type); } { build_one_cst (type); })))
  /* X / -X is -1.  */
  (simplify
(div:C @0 (negate @0))
(if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
-	&& TYPE_OVERFLOW_UNDEFINED (type))
+	&& TYPE_OVERFLOW_UNDEFINED (type)
+	&& !integer_zerop (@0)
+	&& (!flag_non_call_exceptions || tree_expr_nonzero_p (@0)))
 { build_minus_one_cst (type); })))
 
 /* For unsigned integral types, FLOOR_DIV_EXPR is the same as
@@ -444,6 +452,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (trunc_div integer_onep@0 @1)
  (if (INTEGRAL_TYPE_P (type)
   && !integer_zerop (@1)
+  && (!flag_non_call_exceptions || tree_expr_nonzero_p (@1))
   && TYPE_PRECISION (type) > 1)
   (if (TYPE_UNSIGNED (type))
(convert (eq:boolean_type_node @1 { build_one_cst (type); }))


Re: [PATCH] match.pd: Fix up 1 / X for unsigned X optimization [PR104280]

2022-02-04 Thread Eric Botcazou via Gcc-patches
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -401,27 +401,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > 
> >   /* X / bool_range_Y is X.  */
> >   (simplify
> >   
> >(div @0 SSA_NAME@1)
> > 
> > -  (if (INTEGRAL_TYPE_P (type) && ssa_name_has_boolean_range (@1))
> > +  (if (INTEGRAL_TYPE_P (type)
> > +   && ssa_name_has_boolean_range (@1)
> > +   && !flag_non_call_exceptions)
> 
> ssa_name_has_boolean_range call is certainly more expensive than
> !flag_non_call_exceptions check, can you swap those two?

But !flag_non_call_exceptions is (almost) always true for the C family of 
languages, so you're going to penalize them by doing this.

> And similarly, TYPE_PRECISION (type) > 1 check is very cheap, can
> it be done before the && !integer_zerop (@1) line?

Yes, it clearly belongs there.

-- 
Eric Botcazou





[patch] Fix PR debug/104366

2022-02-04 Thread Eric Botcazou via Gcc-patches
Hi,

this completes my fix for PR debug/101947 by emptying the base_types vector 
before (re)populating it.

Tested on x86_64-suse-linux, OK for the mainline?


2022-02-04  Eric Botcazou  

PR debug/104366
* dwarf2out.cc (dwarf2out_finish): Empty base_types.
(dwarf2out_early_finish): Likewise.

-- 
Eric Botcazoudiff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index e60575b1398..d1e8654e4d7 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -32155,6 +32155,7 @@ dwarf2out_finish (const char *filename)
 FOR_EACH_CHILD (die, c, gcc_assert (! c->die_mark));
   }
 #endif
+  base_types.truncate (0);
   for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
 resolve_addr (ctnode->root_die);
   resolve_addr (comp_unit_die ());
@@ -32999,6 +33000,7 @@ dwarf2out_early_finish (const char *filename)
  location related output removed and some LTO specific changes.
  Some refactoring might make both smaller and easier to match up.  */
 
+  base_types.truncate (0);
   for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
 mark_base_types (ctnode->root_die);
   mark_base_types (comp_unit_die ());


Re: [PATCH 1/4][RFC] middle-end/90348 - add explicit birth

2022-02-05 Thread Eric Botcazou via Gcc-patches
> In the past stack sharing has been quite important for the linux
> kernel.  So perhaps one of the tests we should do if we wanted to go
> forward in this cycle would be to test kernel builds to see if any start
> tripping over the stack space diagnostics they've put in place over the
> years.

Stack slot sharing is important generally speaking, not just for the kernel.
As demonstrated by the recent controversy about the 1/X optimization, last- 
minute broad changes made during stage #4 are generally not a good idea, and 
I'm not sure what the incentive for fixing PR middle-end/90348 now is (it's 
labeled a 9/10/11/12 regression).  At a minimum, I think that a switch to 
revert to the pre-12 behavior would be in order if the patch goes in now.

-- 
Eric Botcazou




Re: [PATCH 1/4][RFC] middle-end/90348 - add explicit birth

2022-02-08 Thread Eric Botcazou via Gcc-patches
> I don't think an option to go to pre-12 behavior is useful.  I'll
> postpone the series to stage1.

FWIW fine with me.

-- 
Eric Botcazou




Re: libgo patch committed: Update to Go1.18beta2 release

2022-02-15 Thread Eric Botcazou via Gcc-patches
> I've committed a change to update libgo to the Go1.18beta2 release.

This apparently broke the build on SPARC/Solaris 11.3:

/homes/botcazou/gcc-head/src/libgo/go/runtime/mem_gccgo.go:32:26: error: 
reference to undefined name 'open'
   32 | mmapFD = open(&devZero[0], 0 /* O_RDONLY */, 0)
  |  ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/mem_gccgo.go:35:25: error: 
reference to undefined name 'exit'
   35 | exit(2)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/mem_gccgo.go:56:25: error: 
reference to undefined name 'exit'
   56 | exit(2)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/mem_gccgo.go:60:25: error: 
reference to undefined name 'exit'
   60 | exit(2)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/os_gccgo.go:53:15: error: 
reference to undefined name 'open'
   53 | fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
  |   ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/os_gccgo.go:54:14: error: 
reference to undefined name 'read'
   54 | n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
  |  ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/os_gccgo.go:55:9: error: 
reference to undefined name 'closefd'
   55 | closefd(fd)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/panic.go:1077:9: error: 
reference to undefined name 'exit'
 1077 | exit(2)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/panic.go:1115:17: error: 
reference to undefined name 'exit'
 1115 | exit(2)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/panic.go:1172:17: error: 
reference to undefined name 'exit'
 1172 | exit(4)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/panic.go:1176:17: error: 
reference to undefined name 'exit'
 1176 | exit(5)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:312:9: error: reference 
to undefined name 'exit'
  312 | exit(0)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:872:17: error: reference 
to undefined name 'usleep'
  872 | usleep(1000)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:875:9: error: reference 
to undefined name 'usleep'
  875 | usleep(1000)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:877:9: error: reference 
to undefined name 'usleep'
  877 | usleep(1000)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:1493:9: error: reference 
to undefined name 'exitThread'
 1493 | exitThread(&m.freeWait)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:1715:17: error: 
reference to undefined name 'exit'
 1715 | exit(1)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:1926:25: error: 
reference to undefined name 'usleep_no_g'
 1926 | usleep_no_g(1)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:2431:17: error: 
reference to undefined name 'setThreadCPUProfiler'
 2431 | setThreadCPUProfiler(hz)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:4364:9: error: reference 
to undefined name 'setThreadCPUProfiler'
 4364 | setThreadCPUProfiler(0)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:4370:17: error: 
reference to undefined name 'setProcessCPUProfiler'
 4370 | setProcessCPUProfiler(hz)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:4380:17: error: 
reference to undefined name 'setThreadCPUProfiler'
 4380 | setThreadCPUProfiler(hz)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:4846:17: error: 
reference to undefined name 'usleep'
 4846 | usleep(delay)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/proc.go:5671:57: error: 
reference to undefined name 'usleep'
 5671 | usleep(3)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/runtime.go:35:17: error: 
reference to undefined name 'usleep'
   35 | usleep(100 * 1000)
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/runtime.go:66:9: error: 
reference to undefined name 'exit'
   66 | exit(int32(code))
  | ^
/homes/botcazou/gcc-head/src/libgo/go/runtime/signal_unix.go:662:25: error: 
reference to undefined name 'usleep'
  662 | usleep(5 * 1000 * 1000)
  | ^
/homes/botcazou/gcc-head/src/li

Re: libgo patch committed: Update to Go1.18beta2 release

2022-02-17 Thread Eric Botcazou via Gcc-patches
> I've committed this patch to fix these problems.  Bootstrapped and ran
> Go testsuite on x86_64-pc-linux-gnu and x86_64-solaris.

Fine by me, thanks for the quick turnaround!

-- 
Eric Botcazou




Re: [PATCH] i386: Skip decimal float vector modes in type_natural_mode [PR79754]

2022-02-17 Thread Eric Botcazou via Gcc-patches
> gcc/testsuite/ChangeLog:
> 
> PR target/79754
> * gcc.target/i386/pr79754.c: New test.
> 
> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
> 
> Pushed to master.

And 11 branch apparently, but it should be:

/* { dg-do compile { target dfp } } */

instead of just:

/* { dg-do compile } *

-- 
Eric Botcazou




Re: [PATCH] PR middle-end/80270: ICE in extract_bit_field_1

2022-02-28 Thread Eric Botcazou via Gcc-patches
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check with no new failures.  Ok for mainline?
> 
> 
> 2022-02-27  Roger Sayle  
> 
> gcc/ChangeLog
>   PR middle-end/80270
>   * expmed.cc (extract_integral_bit_field): If OP0 is a hard
>   register, copy it to a pseudo before calling simplify_gen_subreg.

Looks good to me, but why not using copy_to_reg here?

-- 
Eric Botcazou




Fix PR target/103274

2021-11-30 Thread Eric Botcazou via Gcc-patches
This fixes a thinko in my fix for the -freorder-blocks-and-partition glitch 
with SEH on 64-bit Windows:
  https://gcc.gnu.org/pipermail/gcc-patches/2021-February/565208.html

Even if no exceptions are active, e.g. in C, we always need to consider calls.

Tested on x86-64/Windows, applied on mainline, 11 and 10 branches as obvious.


2021-11-30  Eric Botcazou 

PR target/103274
* config/i386/i386.c (ix86_output_call_insn): Beef up comment about
nops emitted with SEH.
* config/i386/winnt.c (i386_pe_seh_unwind_emit): When switching to
the cold section, emit a nop before the directive if the previous
active instruction is a call.

-- 
Eric Botcazoudiff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 2657e7817ae..0e6bf3e0fef 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16438,8 +16438,10 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
 	break;
 
 	  /* If we get to the epilogue note, prevent a catch region from
-	 being adjacent to the standard epilogue sequence.  If non-
-	 call-exceptions, we'll have done this during epilogue emission. */
+	 being adjacent to the standard epilogue sequence.  Note that,
+	 if non-call exceptions are enabled, we already did it during
+	 epilogue expansion, or else, if the insn can throw internally,
+	 we already did it during the reorg pass.  */
 	  if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
 	  && !flag_non_call_exceptions
 	  && !can_throw_internal (insn))
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 7c0ea4f731c..0aaf46f050a 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1243,9 +1243,9 @@ i386_pe_seh_unwind_emit (FILE *out_file, rtx_insn *insn)
   seh = cfun->machine->seh;
   if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
 {
-  /* See ix86_seh_fixup_eh_fallthru for the rationale.  */
+  /* See ix86_output_call_insn/seh_fixup_eh_fallthru for the rationale.  */
   rtx_insn *prev = prev_active_insn (insn);
-  if (prev && !insn_nothrow_p (prev))
+  if (prev && (CALL_P (prev) || !insn_nothrow_p (prev)))
 	fputs ("\tnop\n", out_file);
   fputs ("\t.seh_endproc\n", out_file);
   seh->in_cold_section = true;


Re: [PATCH] fix spelling of -linker-output-auto-nolto-rel

2021-12-03 Thread Eric Botcazou via Gcc-patches
> The transposition nolto -> notlo is confusing and it makes the long
> name even harder to read than it already is - I kept reading it as
> "not lo" until I realized it was a simply typo.

Thanks for catching this!

-- 
Eric Botcazou




Re: [PATCH] machmode: Introduce GET_MODE_NEXT_MODE with previous GET_MODE_WIDER_MODE meaning, add new GET_MODE_WIDER_MODE

2022-10-12 Thread Eric Botcazou via Gcc-patches
> Though I admit I didn't go carefully through all 24 GET_MODE_WIDER_MODE
> uses, 54 FOR_EACH_MODE_IN_CLASS uses, 3 FOR_EACH_MODE uses, 24
> FOR_EACH_MODE_FROM, 6 FOR_EACH_MODE_UNTIL and 15 FOR_EACH_WIDER_MODE uses.
> It is more important to go through the GET_MODE_WIDER_MODE and
> FOR_EACH_WIDER_MODE uses because the patch changes behavior for those,
> the rest keep their previous meaning and so can be changed incrementally
> if the other meaning is desirable to them (I've of course changed the 3
> spots I had to change in the previous BFmode patch and whatever triggered
> during the bootstraps).
> 
> Thoughts on this?

Can't we declare that one is wider than the other, for example BFmode since it 
has got a larger range?  Though I guess this would mean special-casing them in 
genmodes.cc as they are presumably strictly identical except for the format.

-- 
Eric Botcazou




[PATCH] Fix bogus -Wstringop-overflow warning

2022-10-13 Thread Eric Botcazou via Gcc-patches
Hi,

if you compile the attached testcase with -O2 -fno-inline -Wall, you get:

In function 'process_array3':
cc1: warning: 'process_array4' accessing 4 bytes in a region of size 3 [-
Wstringop-overflow=]
cc1: note: referencing argument 1 of type 'char[4]'
t.c:6:6: note: in a call to function 'process_array4'
6 | void process_array4 (char a[4], int n)
  |  ^~
cc1: warning: 'process_array4' accessing 4 bytes in a region of size 3 [-
Wstringop-overflow=]
cc1: note: referencing argument 1 of type 'char[4]'
t.c:6:6: note: in a call to function 'process_array4'

That's because the ICF IPA pass has identified the two functions and turned 
process_array3 into a wrapper of process_array4.  This looks sensible to me 
given that the only difference between them is an "access" attribute on their 
type describing the access size of the parameter and the "access" attribute 
does not affect type identity (struct attribute_spec.affects_type_identity).

Hence the proposed fix, tested on x86-64/Linux, OK for the mainline?


2022-10-13  Eric Botcazou  

* gimple-ssa-warn-access.cc (pass_waccess::check_call): Return
early for calls made from thunks.


2022-10-13  Eric Botcazou  

* gcc.dg/Wstringop-overflow-89.c: New test.

-- 
Eric Botcazoudiff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 04aa849a4b1..59a70530600 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -4291,14 +4291,18 @@ pass_waccess::check_pointer_uses (gimple *stmt, tree ptr,
 void
 pass_waccess::check_call (gcall *stmt)
 {
-  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
-check_builtin (stmt);
+  /* Skip special calls generated by the compiler.  */
+  if (gimple_call_from_thunk_p (stmt))
+return;
 
   /* .ASAN_MARK doesn't access any vars, only modifies shadow memory.  */
   if (gimple_call_internal_p (stmt)
   && gimple_call_internal_fn (stmt) == IFN_ASAN_MARK)
 return;
 
+  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+check_builtin (stmt);
+
   if (!m_early_checks_p)
 if (tree callee = gimple_call_fndecl (stmt))
   {
/* { dg-do compile } */
/* { dg-options "-O2 -fno-inline -Wall" } */

extern void process (char);

void process_array4 (char a[4], int n)
{
  for (int i = 0; i < n; i++)
process (a[i]);
}

void process_array3 (char a[3], int n)
{
  for (int i = 0; i < n; i++)
process (a[i]);
}


Re: [PATCH] Fix bogus -Wstringop-overflow warning

2022-10-13 Thread Eric Botcazou via Gcc-patches
> Not a fan as it could potentially hide a real issue, but I don't really
> have a better solution.

Thanks.

> I pondered suggesting "access" affect type identity, but the cases where
> that's really important are probably better handled by the "fn spec"
> attribute, leaving "access" strictly impacting diagnostics.

I can expand a bit here, because I tried to change the "access" attribute that 
way and this badly breaks the C compiler, for example:

int foo (int n, char m[1][n]);

int foo (int n, char m[1][n]) {}

no longer compiles with an error about different function types.

-- 
Eric Botcazou




[SPARC] Fix PR target/107248

2022-10-14 Thread Eric Botcazou via Gcc-patches
This is the infamous PR rtl-optimization/38644 rearing its ugly head for leaf 
functions on SPARC more than a decade later...  Richard E.'s generic solution 
has never been implemented so let's do as other RISC back-ends did.

Tested on SPARC64/Linux, applied on all active branches.


2022-10-14  Eric Botcazou  

PR target/107248
* config/sparc/sparc.cc (sparc_expand_prologue): Emit a frame
blockage for leaf functions.
(sparc_flat_expand_prologue): Emit frame instead of full blockage.
(sparc_expand_epilogue): Emit a frame blockage for leaf functions.
(sparc_flat_expand_epilogue): Emit frame instead of full blockage.

-- 
Eric Botcazoudiff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index c72c38e1999..10c0f52d3d9 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -6051,6 +6051,9 @@ sparc_expand_prologue (void)
 	}
 
   RTX_FRAME_RELATED_P (insn) = 1;
+
+  /* Ensure no memory access is done before the frame is established.  */
+  emit_insn (gen_frame_blockage ());
 }
   else
 {
@@ -6065,13 +6068,7 @@ sparc_expand_prologue (void)
 	  /* %sp is not the CFA register anymore.  */
 	  emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
 
-	  /* Make sure no %fp-based store is issued until after the frame is
-	 established.  The offset between the frame pointer and the stack
-	 pointer is calculated relative to the value of the stack pointer
-	 at the end of the function prologue, and moving instructions that
-	 access the stack via the frame pointer between the instructions
-	 that decrement the stack pointer could result in accessing the
-	 register window save area, which is volatile.  */
+	  /* Likewise.  */
 	  emit_insn (gen_frame_blockage ());
 	}
   else
@@ -6167,8 +6164,8 @@ sparc_flat_expand_prologue (void)
 	}
   RTX_FRAME_RELATED_P (insn) = 1;
 
-  /* Ensure nothing is scheduled until after the frame is established.  */
-  emit_insn (gen_blockage ());
+  /* Ensure no memory access is done before the frame is established.  */
+  emit_insn (gen_frame_blockage ());
 
   if (frame_pointer_needed)
 	{
@@ -6255,6 +6252,9 @@ sparc_expand_epilogue (bool for_eh)
 ; /* do nothing.  */
   else if (sparc_leaf_function_p)
 {
+  /* Ensure no memory access is done after the frame is destroyed.  */
+  emit_insn (gen_frame_blockage ());
+
   if (size <= 4096)
 	emit_insn (gen_stack_pointer_inc (GEN_INT (size)));
   else if (size <= 8192)
@@ -6305,15 +6305,15 @@ sparc_flat_expand_epilogue (bool for_eh)
 ; /* do nothing.  */
   else if (frame_pointer_needed)
 {
-  /* Make sure the frame is destroyed after everything else is done.  */
-  emit_insn (gen_blockage ());
+  /* Ensure no memory access is done after the frame is destroyed.  */
+  emit_insn (gen_frame_blockage ());
 
   emit_move_insn (stack_pointer_rtx, gen_rtx_REG (Pmode, 1));
 }
   else
 {
   /* Likewise.  */
-  emit_insn (gen_blockage ());
+  emit_insn (gen_frame_blockage ());
 
   if (size <= 4096)
 	emit_insn (gen_stack_pointer_inc (GEN_INT (size)));


Re: Adding a new thread model to GCC

2022-10-21 Thread Eric Botcazou via Gcc-patches
> How does this compare with Eric B's proposal at
> https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html ?

My proposal was to reimplement (and extend) the native thread model (win32) 
instead of adding a new one, the advantage being that you don't need an extra 
threading layer between GCC and Windows.

-- 
Eric Botcazou




Re: Adding a new thread model to GCC

2022-10-24 Thread Eric Botcazou via Gcc-patches
> could you please refresh/recheck your patch for the current gcc master
> and solve the objections noted in the thread? is it possible?

I can do the former, but not the latter as my development setup (mostly 
testing) on Windows has nearly vanished in the meantime.  But this rewritten 
implementation is the one used by the C/C++/Ada compilers from AdaCore.

-- 
Eric Botcazou




[PATCH] Relax assertion in profile.cc

2022-10-24 Thread Eric Botcazou via Gcc-patches
Hi,

this assertion in branch_prob:

  if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
{
  location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
  gcc_checking_assert (!RESERVED_LOCATION_P (loc));

had been correct until:

2021-08-11  Bernd Edlinger  

PR debug/101598
* gcc-interface/trans.c (Subprogram_Body_to_gnu): Set the
DECL_SOURCE_LOCATION of DECL_IGNORED_P gnu_subprog_decl to
UNKNOWN_LOCATION.

was installed.

Tested on x86-64/Linux, OK for mainline and 12 branch?


2022-10-24  Eric Botcazou  

* profile.cc (branch_prob): Be prepared for ignored functions with
DECL_SOURCE_LOCATION set to UNKNOWN_LOCATION.


2022-10-24  Eric Botcazou  

* gnat.dg/specs/coverage1.ads: New test.

-- 
Eric Botcazoudiff --git a/gcc/profile.cc b/gcc/profile.cc
index 96121d60711..1527a04124f 100644
--- a/gcc/profile.cc
+++ b/gcc/profile.cc
@@ -1457,11 +1457,13 @@ branch_prob (bool thunk)
 	  if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
 	{
 	  location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
-	  gcc_checking_assert (!RESERVED_LOCATION_P (loc));
-	  seen_locations.add (loc);
-	  expanded_location curr_location = expand_location (loc);
-	  output_location (&streamed_locations, curr_location.file,
-			   MAX (1, curr_location.line), &offset, bb);
+	  if (!RESERVED_LOCATION_P (loc))
+		{
+		  seen_locations.add (loc);
+		  expanded_location curr_location = expand_location (loc);
+		  output_location (&streamed_locations, curr_location.file,
+   MAX (1, curr_location.line), &offset, bb);
+		}
 	}
 
 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-- { dg-do compile }
-- { dg-options "-ftest-coverage" }

package Coverage1 is

  type Rec is record
I : Integer := 0;
  end record;

end Coverage1;


Re: vect: Make vect_check_gather_scatter reject offsets that aren't multiples of BITS_PER_UNIT [PR107346]

2022-10-24 Thread Eric Botcazou via Gcc-patches
> Eric - the docs of DECL_BIT_FIELD are vague enough "must be accessed
> specially" but ISTR it might eventually only apply to the fields
> (bit) size and not it's position.  OTOH the Ada frontend might not
> be too careful in setting this flag for bit-packed structs?

It sets the flag when the alignment or size of the field does not match that 
of its type, which indeed means that it needs to be accessed specially.

-- 
Eric Botcazou




[PATCH] ARM: Make ARMv8-M attribute cmse_nonsecure_call work in Ada

2022-10-24 Thread Eric Botcazou via Gcc-patches
Hi,

until most other machine attributes, this one does not work in Ada because,
while it applies to pointer-to-function types, it is explicitly marked as
requiring declarations in the implementation.

Now, in Ada, machine attributes are specified like this:

  type Non_Secure is access procedure;
  pragma Machine_Attribute (Non_Secure, "cmse_nonsecure_call");

i.e. not attached to the declaration of Non_Secure (testcase attached).

So the attached patch extends the support to Ada by also accepting
pointer-to-function types in the handler.

Tested on arm-eabi, OK for the mainline?


2022-10-24  Eric Botcazou  

* config/arm/arm.cc (arm_attribute_table) : Change
decl_required field to false.
(arm_handle_cmse_nonsecure_call): Deal with a TYPE node.


-- 
Eric Botcazoudiff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index ee8f1babf8a..fc96ed9cce4 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -375,7 +375,7 @@ static const struct attribute_spec arm_attribute_table[] =
   /* ARMv8-M Security Extensions support.  */
   { "cmse_nonsecure_entry", 0, 0, true, false, false, false,
 arm_handle_cmse_nonsecure_entry, NULL },
-  { "cmse_nonsecure_call", 0, 0, true, false, false, true,
+  { "cmse_nonsecure_call", 0, 0, false, false, false, true,
 arm_handle_cmse_nonsecure_call, NULL },
   { "Advanced SIMD type", 1, 1, false, true, false, true, NULL, NULL },
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
@@ -7605,8 +7605,8 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name,
  int /* flags */,
  bool *no_add_attrs)
 {
-  tree decl = NULL_TREE, fntype = NULL_TREE;
-  tree type;
+  tree decl = NULL_TREE;
+  tree fntype, type;
 
   if (!use_cmse)
 {
@@ -7616,16 +7616,20 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name,
   return NULL_TREE;
 }
 
-  if (TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == TYPE_DECL)
+  if (DECL_P (*node))
 {
-  decl = *node;
-  fntype = TREE_TYPE (decl);
+  fntype = TREE_TYPE (*node);
+
+  if (TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == TYPE_DECL)
+	decl = *node;
 }
+  else
+fntype = *node;
 
-  while (fntype != NULL_TREE && TREE_CODE (fntype) == POINTER_TYPE)
+  while (fntype && TREE_CODE (fntype) == POINTER_TYPE)
 fntype = TREE_TYPE (fntype);
 
-  if (!decl || TREE_CODE (fntype) != FUNCTION_TYPE)
+  if ((DECL_P (*node) && !decl) || TREE_CODE (fntype) != FUNCTION_TYPE)
 {
 	warning (OPT_Wattributes, "%qE attribute only applies to base type of a "
 		 "function pointer", name);
@@ -7640,10 +7644,17 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name,
 
   /* Prevent trees being shared among function types with and without
  cmse_nonsecure_call attribute.  */
-  type = TREE_TYPE (decl);
+  if (decl)
+{
+  type = build_distinct_type_copy (TREE_TYPE (decl));
+  TREE_TYPE (decl) = type;
+}
+  else
+{
+  type = build_distinct_type_copy (*node);
+  *node = type;
+}
 
-  type = build_distinct_type_copy (type);
-  TREE_TYPE (decl) = type;
   fntype = type;
 
   while (TREE_CODE (fntype) != FUNCTION_TYPE)
package P is

  type Non_Secure is access procedure;
  pragma Machine_Attribute (Non_Secure, "cmse_nonsecure_call");

  procedure Call (Proc : Non_Secure);

  procedure Foo;
  pragma Machine_Attribute (Foo, "cmse_nonsecure_call");

end P;
package body P is

  procedure Call (Proc : Non_Secure) is
  begin
Proc.all;
  end;

  procedure Foo is null;

end P;


[PATCH] Aarch64: Do not define DONT_USE_BUILTIN_SETJMP

2022-10-24 Thread Eric Botcazou via Gcc-patches
Hi,

we have been using an Ada compiler for the Aarch64 architecture configured 
with SJLJ exceptions as for the other architectures for some time, and have 
not run into any problems so far so the setting looks obsolete now.

OK for the mainline?


2022-10-24  Eric Botcazou  

* config/aarch64/aarch64.h (DONT_USE_BUILTIN_SETJMP): Delete.

-- 
Eric Botcazou
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 05da9af0367..e60f9bce023 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -571,10 +571,6 @@ enum class aarch64_feature : unsigned char {
 #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, R4_REGNUM)
 #define EH_RETURN_HANDLER_RTX  aarch64_eh_return_handler_rtx ()
 
-/* Don't use __builtin_setjmp until we've defined it.  */
-#undef DONT_USE_BUILTIN_SETJMP
-#define DONT_USE_BUILTIN_SETJMP 1
-
 #undef TARGET_COMPUTE_FRAME_LAYOUT
 #define TARGET_COMPUTE_FRAME_LAYOUT aarch64_layout_frame
 


Re: [PATCH] x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns

2022-10-28 Thread Eric Botcazou via Gcc-patches
> (set (reg:SI 93)
>  (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0]
> 
> as
> 
> (set (reg:SI 93)
>  (neg:SI (ltu:SI (const_int 1) (const_int 0 [0]
> 
> which leads to incorrect results since LTU on MODE_CC register isn't the
> same as "unsigned less than" in x86 backend.

That's not specific to the x86 back-end, i.e. it's a generic caveat.

>   PR target/107172
>   * config/i386/i386.md (UNSPEC_CC_NE): New.
>   Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns.

FWIW the SPARC back-end uses a COMPARE instead of an UNSPEC here.

-- 
Eric Botcazou




[PATCH] Restore RTL alias analysis for hard frame pointer

2022-10-28 Thread Eric Botcazou via Gcc-patches
Hi,

the following change:

2021-07-28  Bin Cheng  

* alias.c (init_alias_analysis): Don't skip prologue/epilogue.

broke the alias analysis for the hard frame pointer (when it is used as a 
frame pointer, i.e. when the frame pointer is not eliminated) described in the 
large comment at the top of the file, because static_reg_base_value is set for 
it and, consequently, new_reg_base_value too.  So when the instruction saving 
the stack pointer into the hard frame pointer in the prologue is processed, it 
is viewed as a second set of the hard frame pointer and to a different value 
by record_set, which then resets new_reg_base_value to 0 and the game is over.

This e.g. hampers the performance of the var-tracking RTL pass for parameters 
passed on the stack like on x86, leading to regressions when debugging, but 
code generation is very likely affected too.

Bootstrapped/regtested on x86-64/Linux, OK for mainline and 12 branch?


2022-10-28  Eric Botcazou  

* alias.cc (init_alias_analysis): Do not record sets to the hard
frame pointer if the frame pointer has not been eliminated.

-- 
Eric Botcazoudiff --git a/gcc/alias.cc b/gcc/alias.cc
index d54feb15268..c62837dd854 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -3369,6 +3369,10 @@ memory_modified_in_insn_p (const_rtx mem, const_rtx insn)
 void
 init_alias_analysis (void)
 {
+  const bool frame_pointer_eliminated
+= reload_completed
+  && !frame_pointer_needed
+  && targetm.can_eliminate (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
   unsigned int maxreg = max_reg_num ();
   int changed, pass;
   int i;
@@ -3446,12 +3450,8 @@ init_alias_analysis (void)
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
 	if (static_reg_base_value[i]
 	/* Don't treat the hard frame pointer as special if we
-	   eliminated the frame pointer to the stack pointer instead.  */
-	&& !(i == HARD_FRAME_POINTER_REGNUM
-		 && reload_completed
-		 && !frame_pointer_needed
-		 && targetm.can_eliminate (FRAME_POINTER_REGNUM,
-	   STACK_POINTER_REGNUM)))
+	   eliminated the frame pointer to the stack pointer.  */
+	&& !(i == HARD_FRAME_POINTER_REGNUM && frame_pointer_eliminated))
 	  {
 	new_reg_base_value[i] = static_reg_base_value[i];
 	bitmap_set_bit (reg_seen, i);
@@ -3467,10 +3467,15 @@ init_alias_analysis (void)
 		{
 		  rtx note, set;
 
+		  /* Treat the hard frame pointer as special unless we
+		 eliminated the frame pointer to the stack pointer.  */
+		  if (!frame_pointer_eliminated
+		  && modified_in_p (hard_frame_pointer_rtx, insn))
+		continue;
+
 		  /* If this insn has a noalias note, process it,  Otherwise,
 		 scan for sets.  A simple set will have no side effects
 		 which could change the base value of any other register.  */
-
 		  if (GET_CODE (PATTERN (insn)) == SET
 		  && REG_NOTES (insn) != 0
 		  && find_reg_note (insn, REG_NOALIAS, NULL_RTX))


Re: RFC - VRP1 default mode

2022-10-28 Thread Eric Botcazou via Gcc-patches
> I get a clean testsuite run configured and bootstrapped with
> 
> --enable-languages=c,c++,go,fortran,ada,obj-c++,jit --enable-host-shared
> 
> Is there a PR or specific tests in either fortran or ada for those
> improvements? ie, something specific I should check for? Part of rangers
> point is to be able to do symbolic relationships without storing the
> symbolic in the range, just picking it up from the IL as needed.

The motivating Ada example for symbolic ranges was gnat.dg/opt40.adb.

-- 
Eric Botcazou




Re: [PATCH] x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns

2022-10-28 Thread Eric Botcazou via Gcc-patches
> COMPARE may also set CC register to a constant when both operands are
> known constants.

No, a COMPARE is never evaluated alone, only the CC user may be evaluated.

-- 
Eric Botcazou




Re: [PATCH] x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns

2022-10-28 Thread Eric Botcazou via Gcc-patches
> You mean in CCV?  That works yes, but only because (or if) the setter
> and getter of the CC reg both use CCV (so never use any other flag at
> the same time; CCV has an empty intersection with all other CC modes).

We're talking about CCC here AFAIK, i.e. the carry, not CCV.

-- 
Eric Botcazou




Re: [PATCH] Restore RTL alias analysis for hard frame pointer

2022-10-29 Thread Eric Botcazou via Gcc-patches
> OK for trunk and 12 after a while of burn-in.

Thanks!

> Oh, do you have a testcase suitable for the testsuite?

I only have an Ada testcase for GDB, let me try to find something more usable.

-- 
Eric Botcazou




Repair --disable-sjlj-exceptions

2022-10-29 Thread Eric Botcazou via Gcc-patches
It was broken by:

2022-08-31  Martin Liska  

* config.build: Remove deprecated ports.
* config.gcc: Likewise.
* config.host: Likewise.
* configure.ac: Likewise.
* configure: Regenerate.
* config/pa/pa-hpux10.h: Removed.
* config/pa/pa-hpux10.opt: Removed.
* config/pa/t-dce-thr: Removed.

Tested by building i686-w64-mingw32 with --disable-sjlj-exceptions, applied on 
the mainline as obvious.


2022-10-29  Eric Botcazou  

* configure.ac (sjlj-exceptions): Restore dropped line.
* configure: Regenerate.

-- 
Eric Botcazoudiff --git a/gcc/configure.ac b/gcc/configure.ac
index eb92a37cd46..4ecccffc324 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1805,6 +1805,7 @@ AC_SUBST(objext)
 AC_ARG_ENABLE(sjlj-exceptions,
 [AS_HELP_STRING([--enable-sjlj-exceptions],
 [arrange to use setjmp/longjmp exception handling])],
+[force_sjlj_exceptions=yes],
 [case $target in
   lm32*-*-*)
  force_sjlj_exceptions=yes


Re: Adding a new thread model to GCC

2022-10-31 Thread Eric Botcazou via Gcc-patches
> could you please refresh/recheck your patch for the current gcc master
> and solve the objections noted in the thread? is it possible?

I have attached a revised version of the original patch at:
  https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html

This reimplements the GNU threads library on native Windows (except for the
Objective-C specific subset) using direct Win32 API calls, in lieu of the
implementation based on semaphores.  This base implementations requires
Windows XP/Server 2003, which was the default minimal setting of MinGW-W64
until end of 2020.  This also adds the support required for the C++11 threads,
using again direct Win32 API calls; this additional layer requires Windows
Vista/Server 2008 and is enabled only if _WIN32_WINNT >= 0x0600.

This also changes libstdc++ to pass -D_WIN32_WINNT=0x0600 but only when the
switch --enable-libstdcxx-threads is passed, which means that C++11 threads
are still disabled by default *unless* MinGW-W64 itself is configured for
Windows Vista/Server 2008 or later by default (this has been the case in
the development version since end of 2020, for earlier versions you can
configure it --with-default-win32-winnt=0x0600 to get the same effect).

I only manually tested it on i686-w64-mingw32 and x86_64-w64-mingw32 but
AdaCore has used it in their C/C++/Ada compilers for 3 years now and the
30_threads chapter of the libstdc++ testsuite was clean at the time.


2022-10-31  Eric Botcazou  

libgcc/
* config.host (i[34567]86-*-mingw*): Add thread fragment after EH one
as well as new i386/t-slibgcc-mingw fragment.
(x86_64-*-mingw*): Likewise.
* config/i386/gthr-win32.h: If _WIN32_WINNT is at least 0x0600, define
both __GTHREAD_HAS_COND and __GTHREADS_CXX0X to 1.
Error out if _GTHREAD_USE_MUTEX_TIMEDLOCK is 1.
Include stdlib.h instead of errno.h and do not include _mingw.h.
(CONST_CAST2): Add specific definition for C++.
(ATTRIBUTE_UNUSED): New macro.
(__UNUSED_PARAM): Delete.
Define WIN32_LEAN_AND_MEAN before including windows.h.
(__gthread_objc_data_tls): Use TLS_OUT_OF_INDEXES instead of (DWORD)-1.
(__gthread_objc_init_thread_system): Likewise.
(__gthread_objc_thread_get_data): Minor tweak.
(__gthread_objc_condition_allocate): Use ATTRIBUTE_UNUSED.
(__gthread_objc_condition_deallocate): Likewise.
(__gthread_objc_condition_wait): Likewise.
(__gthread_objc_condition_broadcast): Likewise.
(__gthread_objc_condition_signal): Likewise.
Include sys/time.h.
(__gthr_win32_DWORD): New typedef.
(__gthr_win32_HANDLE): Likewise.
(__gthr_win32_CRITICAL_SECTION): Likewise.
(__gthr_win32_CONDITION_VARIABLE): Likewise.
(__gthread_t): Adjust.
(__gthread_key_t): Likewise.
(__gthread_mutex_t): Likewise.
(__gthread_recursive_mutex_t): Likewise.
(__gthread_cond_t): New typedef.
(__gthread_time_t): Likewise.
(__GTHREAD_MUTEX_INIT_DEFAULT): Delete.
(__GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT): Likewise.
(__GTHREAD_COND_INIT_FUNCTION): Define.
(__GTHREAD_TIME_INIT): Likewise.
(__gthr_i486_lock_cmp_xchg): Delete.
(__gthr_win32_create): Declare.
(__gthr_win32_join): Likewise.
(__gthr_win32_self): Likewise.
(__gthr_win32_detach): Likewise.
(__gthr_win32_equal): Likewise.
(__gthr_win32_yield): Likewise.
(__gthr_win32_mutex_destroy): Likewise.
(__gthr_win32_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1.
(__gthr_win32_cond_broadcast): Likewise.
(__gthr_win32_cond_signal): Likewise.
(__gthr_win32_cond_wait): Likewise.
(__gthr_win32_cond_timedwait): Likewise.
(__gthr_win32_recursive_mutex_init_function): Delete.
(__gthr_win32_recursive_mutex_lock): Likewise.
(__gthr_win32_recursive_mutex_unlock): Likewise.
(__gthr_win32_recursive_mutex_destroy): Likewise.
(__gthread_create): New inline function.
(__gthread_join): Likewise.
(__gthread_self): Likewise.
(__gthread_detach): Likewise.
(__gthread_equal): Likewise.
(__gthread_yield): Likewise.
(__gthread_cond_init_function): Likewise if __GTHREADS_HAS_COND is 1.
(__gthread_cond_broadcast): Likewise.
(__gthread_cond_signal): Likewise.
(__gthread_cond_wait): Likewise.
(__gthread_cond_timedwait): Likewise.
(__GTHREAD_WIN32_INLINE): New macro.
(__GTHREAD_WIN32_COND_INLINE): Likewise.
(__GTHREAD_WIN32_ACTIVE_P): Likewise.
Define WIN32_LEAN_AND_MEAN before including windows.h.
(__gthread_once): Minor tweaks.
(__gthread_key_create): Use ATTRIBUTE_UNUSED and TLS_OUT_OF_INDEXES.
(__gthread_key_delete): Minor tweak.
(__gthread_getspecific): Likewise.
(__gthread_setspecific): Likewise

Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref

2022-10-31 Thread Eric Botcazou via Gcc-patches
> The test was only failing for me with -m32 (and not -m64), so I didn't
> notice until now. That probably means we should make the test fail more
> reliably if the padding isn't being cleared.

The tests fail randomly for me on SPARC64/Linux:

FAIL: 29_atomics/atomic/compare_exchange_padding.cc execution test
FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test

/home/ebotcazou/src/libstdc++-v3/testsuite/29_atomics/atomic_ref/
compare_exchange_padding.cc:34: int main(): Assertion 'compare_struct(ts, es)' 
failed.
FAIL: 29_atomics/atomic_ref/compare_exchange_padding.cc execution test

  std::atomic as{ s };
  auto ts = as.load();
  VERIFY( !compare_struct(s, ts) ); // padding cleared on construction
  as.exchange(s);
  auto es = as.load();
  VERIFY( compare_struct(ts, es) ); // padding cleared on exchange

How is it supposed to pass exactly?  AFAICS you have no control on the padding 
bits of ts or es and, indeed, at -O2 the loads are scalarized:

  __buf$c_81 = MEM[(struct S *)&__buf].c;
  __buf$s_59 = MEM[(struct S *)&__buf].s;
  __buf ={v} {CLOBBER(eol)};
  ts.c = __buf$c_81;
  ts.s = __buf$s_59;
[...]
  __buf$c_100 = MEM[(struct S *)&__buf].c;
  __buf$s_35 = MEM[(struct S *)&__buf].s;
  __buf ={v} {CLOBBER(eol)};
  es.c = __buf$c_100;
  es.s = __buf$s_35;
  _66 = MEM  [(char * {ref-all})&ts];
  _101 = MEM  [(char * {ref-all})&es];
  if (_66 != _101)
goto ; [0.04%]
  else
goto ; [99.96%]

so the result of the 4-byte comparison is random.

-- 
Eric Botcazou




Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref

2022-10-31 Thread Eric Botcazou via Gcc-patches
> I suppose we could use memcmp on the as variable itself, to inspect
> the actual stored padding rather than the returned copy of it.

Yes, that's probably the only safe stance when optimization is enabled.

-- 
Eric Botcazou




Re: Adding a new thread model to GCC

2022-11-01 Thread Eric Botcazou via Gcc-patches
> I have faced with "#error Timed lock primitives are not supported on
> Windows targets" and I'm not sure I understood the reason correctly.
> 
> as far as I understand, the definition for
> `_GTHREAD_USE_MUTEX_TIMEDLOCK` comes from libstdc++/configure as a
> result of some test.
> 
> why did I faced with this error? what should I do to avoid this?

Run autoheader + autoconf in the libstdc++-v3 source repository.

-- 
Eric Botcazou




Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref

2022-11-01 Thread Eric Botcazou via Gcc-patches
> Do those loads still get scalarized at -O0?

Presumably not at the GIMPLE level, but possibly at the RTL level.

-- 
Eric Botcazou




Re: [PATCH] x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns

2022-11-01 Thread Eric Botcazou via Gcc-patches
> Yes.  But it is all the same: neither signed overflow nor unsigned
> overflow (of an addition, say) can be described as the result of an
> RTL comparison.

I disagree, see for example the implementation of the addvdi4_sp3 pattern (for 
which we indeed use an UNSPEC) and of the uaddvdi4_sp32 pattern (for which we 
describe the overflow with a COMPARE) in the SPARC back-end.  And that's even 
simpler for an unsigned subtraction, where we do not need a special CC mode.

Sure there is a technical difficulty for unsigned negation because of the 
canonicalization rules, hence the trick used in the SPARC back-end, but 
unsigned overflow is much easier to deal with than signed overflow.

-- 
Eric Botcazou




Re: Adding a new thread model to GCC

2022-11-02 Thread Eric Botcazou via Gcc-patches
> I was able to successfully build gcc-trunk using the provided patch.
> moreover, I was able to successfully build all of the packages used in
> the toolchain!
> (gmp, mpfr, mpc, isl, libgnurx, bzip2, termcap, libffi, expat, ncurses,
> readline, gdbm, tcl, tk, openssl, xz-utils, sqlite, python3, binutils,
> gdb, make)

Great!  Did you check that C++ threads are enabled in your build?  If they 
are, you must be able to run the attached C++ test; if they are not (because 
the MinGW64 build is configured for older versions of Windows), you need to 
configure the compiler with the option --enable-libstdcxx-threads.

-- 
Eric Botcazou#include 
#include 
#include 
#include 
#include 

#define NUM_THREADS 4

std::condition_variable cond;
std::mutex mx;
int started = 0;

void
do_thread ()
{
  std::unique_lock lock(mx);
  std::cout << "Start thread " << started << std::endl;
  if(++started >= NUM_THREADS)
cond.notify_all();
  else
cond.wait(lock);
}

int
main ()
{
  std::vector vec;
  for (int i = 0; i < NUM_THREADS; ++i)
vec.emplace_back(&do_thread);
  for (int i = 0; i < NUM_THREADS; ++i)
vec[i].join();
  vec.clear();
  return 0;
}


[PATCH] Fix bogus -Wstringop-overflow warning in Ada

2022-08-16 Thread Eric Botcazou via Gcc-patches
Hi,

the following bogus warning:

In function 'lto26',
inlined from 'main' at /home/eric/gnat/bugs/V721-018/b~lto26.adb:237:7:
lto26.adb:11:13: warning: writing 1 byte into a region of size 0 [-Wstringop-
overflow=]
   11 | Set (R, (7, 0, 84, Stream_Element (I), 0, 0, 0), 1);
  | ^
lto26.adb: In function 'main':
lto26.adb:11:50: note: at offset -9223372036854775808 into destination object 
'A.0' of size 7
   11 | Set (R, (7, 0, 84, Stream_Element (I), 0, 0, 0), 1);
  |  ^

comes from a discrepancy between get_offset_range, which uses a signed type, 
and handle_array_ref, which uses an unsigned one, to do offset computations.

Tested on x86-64/Linux, OK for the mainline?


2022-08-16  Eric Botcazou  

* pointer-query.cc (handle_array_ref): Fix handling of low bound.


2022-08-16  Eric Botcazou  

* gnat.dg/lto26.adb: New test.
* gnat.dg/lto26_pkg1.ads, gnat.dg/lto26_pkg1.adb: New helper.
* gnat.dg/lto26_pkg2.ads, gnat.dg/lto26_pkg2.adb: Likewise.

-- 
Eric Botcazoudiff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index ae561731216..0f0100233c1 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -1796,14 +1796,19 @@ handle_array_ref (tree aref, gimple *stmt, bool addr, int ostype,
   orng[0] = -orng[1] - 1;
 }
 
-  /* Convert the array index range determined above to a byte
- offset.  */
+  /* Convert the array index range determined above to a byte offset.  */
   tree lowbnd = array_ref_low_bound (aref);
-  if (!integer_zerop (lowbnd) && tree_fits_uhwi_p (lowbnd))
-{
-  /* Adjust the index by the low bound of the array domain
-	 (normally zero but 1 in Fortran).  */
-  unsigned HOST_WIDE_INT lb = tree_to_uhwi (lowbnd);
+  if (TREE_CODE (lowbnd) == INTEGER_CST && !integer_zerop (lowbnd))
+{
+  /* Adjust the index by the low bound of the array domain (0 in C/C++,
+	 1 in Fortran and anything in Ada) by applying the same processing
+	 as in get_offset_range.  */
+  const wide_int wlb = wi::to_wide (lowbnd);
+  signop sgn = SIGNED;
+  if (TYPE_UNSIGNED (TREE_TYPE (lowbnd))
+	  && wlb.get_precision () < TYPE_PRECISION (sizetype))
+	sgn = UNSIGNED;
+  const offset_int lb = offset_int::from (wlb, sgn);
   orng[0] -= lb;
   orng[1] -= lb;
 }
with Lto26_Pkg2; use Lto26_Pkg2;

package body Lto26_Pkg1 is

  procedure Set (R : Rec; A : Stream_Element_Array; C :Unsigned_8) is
procedure My_Build is new Build;
  begin
 My_Build (A, C);
  end;

end Lto26_Pkg1;
with Ada.Finalization;
with Ada.Streams;  use Ada.Streams;
with Interfaces; use Interfaces;

package Lto26_Pkg1 is

  type Rec is new Ada.Finalization.Limited_Controlled with null record;

  procedure Set (R : Rec; A : Stream_Element_Array; C :Unsigned_8);

end Lto26_Pkg1;
with Ada.Streams; use Ada.Streams;
with Interfaces; use Interfaces;

package Lto26_Pkg2 is

  generic
  procedure Build (A : Stream_Element_Array; C : Unsigned_8);

end Lto26_Pkg2;
package body Lto26_Pkg2 is

  procedure Build (A : Stream_Element_Array; C : Unsigned_8) is
Start  : Stream_Element_Offset := A'First;
Next   : Stream_Element_Offset;
Length : Unsigned_8;
  begin
for I in 1 .. C loop
  Length := Unsigned_8 (A (A'First));
  Next   := Start + Stream_Element_Offset (Length);
  Start  := Next;
end loop;
  end;

end Lto26_Pkg2;
-- { dg-do run }
-- { dg-options "-O2 -flto" { target lto } }

with Ada.Streams; use Ada.Streams;
with Lto26_Pkg1; use Lto26_Pkg1;

procedure Lto26 is
  R : Rec;
begin
  for I in 1 .. 10 loop
Set (R, (7, 0, 84, Stream_Element (I), 0, 0, 0), 1);
  end loop;
end;


Re: [PATCH] Fix bogus -Wstringop-overflow warning in Ada

2022-08-17 Thread Eric Botcazou via Gcc-patches
> Hmm, can we instead do
> 
>   if (!integer_zerop (lowbnd) && tree_fits_shwi_p (lowbnd))
>{
>   const offset_int lb = offset_int::from (lowbnd, SIGNED);
> ...
> 
> ?

Apparently not:

In file included from /home/eric/cvs/gcc/gcc/coretypes.h:460,
 from /home/eric/cvs/gcc/gcc/pointer-query.cc:23:
/home/eric/cvs/gcc/gcc/wide-int.h: In instantiation of 
'wide_int_ref_storage::wide_int_ref_storage(const T&) [with T = 
tree_node*; bool SE = false; bool HDP = true]':
/home/eric/cvs/gcc/gcc/wide-int.h:782:15:   required from 
'generic_wide_int::generic_wide_int(const T&) [with T = tree_node*; storage 
= wide_int_ref_storage]'
/home/eric/cvs/gcc/gcc/pointer-query.cc:1803:46:   required from here
/home/eric/cvs/gcc/gcc/wide-int.h:1024:48: error: incomplete type 
'wi::int_traits' used in nested name specifier
 1024 |   : storage_ref (wi::int_traits ::decompose (scratch,
  |  ~~^
 1025 | wi::get_precision (x), 
x))
  | 
~

And:
 
  const offset_int lb = wi::to_offset (lowbnd);

compiles but does *not* fix the problem since it does a zero-extension.

[Either extension is fine, as long as it's the same in get_offset_range].

> In particular interpreting the unsigned lowbnd as SIGNED when
> not wlb.get_precision () < TYPE_PRECISION (sizetype), offset_int
> should handle all positive and negative byte offsets since it can
> also represent them measured in bits.  Unfortunately the
> wide_int classes do not provide the maximum precision they can
> handle.  That said, the check, if any, should guard the whole
> orng adjustment, no?  (in fact I wonder why we just ignore lowbnd
> if it doesn't fit or is variable...)

Yes, tree_fits_uhwi_p (or tree_fits_shwi_p) is bogus here, but the test 
against INTEGER_CST is used everywhere else and should be good enough.

-- 
Eric Botcazou




Re: [PATCH] Fix bogus -Wstringop-overflow warning in Ada

2022-08-18 Thread Eric Botcazou via Gcc-patches
> Meh.  OK, eventually would need "indirection" through a wide-int then.
> Like
> 
>   offset_int::from (wi::to_wide (lowbnd), TYPE_SIGN (TREE_TYPE (lowbnd)))

That would be OK if get_offset_range did the same, but it does not since it 
forces a sign-extension whatever the sign of a large type:

  signop sgn = SIGNED;
  /* Only convert signed integers or unsigned sizetype to a signed
 offset and avoid converting large positive values in narrower
 types to negative offsets.  */
  if (TYPE_UNSIGNED (type)
  && wr[0].get_precision () < TYPE_PRECISION (sizetype))
sgn = UNSIGNED;

> I think it should extend according to sing of lowbnd?  Or does Ada
> use an unsigned lowbnd to represent a signed value here?  At least
> that's what I had issues with with your patch.

It uses sizetype like everyone else and the signedness was forced on it 
because of the POINTER_PLUS_EXPR thing, i.e. it was signed before.

-- 
Eric Botcazou




Re: [PATCH] Fix bogus -Wstringop-overflow warning in Ada

2022-08-18 Thread Eric Botcazou via Gcc-patches
> Hmm :/  But that means we _should_ force a sign extension but only
> from ptrofftype_p ()?  That is, your test above should maybe read
> 
>signop sgn = TYPE_SIGN (type);
>if (ptrofftype_p (type))
>  sgn = SIGNED;
> 
> assuming 'type' is the type of lowbnd

Yes, that's essentially equivalent to what get_offset_range does, but I'm not 
sure why having two slightly different ways of doing it would be better than a 
single one here,   Maybe replace the call to get_precision in both places with 
TYPE_PRECSION (type) then?

-- 
Eric Botcazou





[SPARC] Fix PR target/105292

2022-05-10 Thread Eric Botcazou via Gcc-patches
This is a regression present since the 10.x series, but the underlying issue 
has been there since the TARGET_VEC_PERM_CONST hook was implemented, in the 
form of an ICE when expanding a constant VEC_PERM_EXPR in V4QI, while the 
back-end only supports V8QI constant VEC_PERM_EXPRs.

Tested on SPARC/Solaris, applied to all active branches.


2022-05-10  Eric Botcazou  

PR target/105292
* config/sparc/sparc.cc (sparc_vectorize_vec_perm_const): Return
true only for 8-byte vector modes.


2022-05-10  Eric Botcazou  

* gcc.target/sparc/20220510-1.c: New test.

-- 
Eric Botcazoudiff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index 467a9f171d2..aca925befe1 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -13041,9 +13041,9 @@ sparc_vectorize_vec_perm_const (machine_mode vmode, rtx target, rtx op0,
   if (!TARGET_VIS2)
 return false;
 
-  /* All permutes are supported.  */
+  /* All 8-byte permutes are supported.  */
   if (!target)
-return true;
+return GET_MODE_SIZE (vmode) == 8;
 
   /* Force target-independent code to convert constant permutations on other
  modes down to V8QI.  Rely on this to avoid the complexity of the byte
/* PR target/105292 */
/* Reported by Koakuma  */

/* { dg-do compile } */
/* { dg-options "-O3 -mvis2" } */

extern void get_vbytes_v2 (unsigned);

typedef struct {
  unsigned ctt_info;
  unsigned ctt_size;
} ctf_type_t;

typedef struct {
  unsigned short cts_offset;
  unsigned short cts_bits;
} ctf_slice_t;

void flip_types_len (ctf_type_t *t, int bsx1, int bsx2)
{
  const int kind = t->ctt_info;

  get_vbytes_v2 (t->ctt_size);

  if (kind == 4)
{
  ctf_slice_t *s = (ctf_slice_t *)t;
  s->cts_offset = __builtin_bswap16(bsx1);
  s->cts_bits   = __builtin_bswap16(bsx2);
}
}


[PATCH] Fix wrong SRA with VIEW_CONVERT_EXPR and reverse SSO

2022-05-13 Thread Eric Botcazou via Gcc-patches
Hi,

most cases of VIEW_CONVERT_EXPRs involving reverse scalar storage order are
disqualified for SRA because they are storage_order_barrier_p, but you can
still have a VIEW_CONVERT_EXPR to a regular composite type being applied to
a component of a record type with reverse scalar storage order, although this
is pretty rare even in Ada (the only idiomatic way I know of is to use 'Valid
on a floating-point component).

In this case, the bypass for !useless_type_conversion_p in sra_modify_assign,
albeit already heavily guarded, triggers and may generate wrong code, e.g. on
the attached testcase, so the patch makes sure that it does only when the SSO
is the same on both side.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2022-05-13  Eric Botcazou  

* tree-sra.c (sra_modify_assign): Check that the scalar storage order
is the same on the LHS and RHS before rewriting one with the model of
the other.


2022-05-13  Eric Botcazou  

* gnat.dg/sso17.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index a86f8c01346..081c51b58a4 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -4270,32 +4270,31 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
   sra_stats.exprs++;
 }
 
-  if (modify_this_stmt)
-{
-  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
+  if (modify_this_stmt
+  && !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
+{
+  /* If we can avoid creating a VIEW_CONVERT_EXPR, then do so.
+	 ??? This should move to fold_stmt which we simply should
+	 call after building a VIEW_CONVERT_EXPR here.  */
+  if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
+	  && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (lhs)) == racc->reverse
+	  && !contains_bitfld_component_ref_p (lhs))
 	{
-	  /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
-	 ???  This should move to fold_stmt which we simply should
-	 call after building a VIEW_CONVERT_EXPR here.  */
-	  if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
-	  && !contains_bitfld_component_ref_p (lhs))
-	{
-	  lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
-	  gimple_assign_set_lhs (stmt, lhs);
-	}
-	  else if (lacc
-		   && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
-		   && !contains_vce_or_bfcref_p (rhs))
-	rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
+	  lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
+	  gimple_assign_set_lhs (stmt, lhs);
+	}
+  else if (lacc
+	   && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
+	   && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (rhs)) == lacc->reverse
+	   && !contains_vce_or_bfcref_p (rhs))
+	rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
 
-	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
-	{
-	  rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
- rhs);
-	  if (is_gimple_reg_type (TREE_TYPE (lhs))
-		  && TREE_CODE (lhs) != SSA_NAME)
-		force_gimple_rhs = true;
-	}
+  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
+	{
+	  rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
+	  if (is_gimple_reg_type (TREE_TYPE (lhs))
+	  && TREE_CODE (lhs) != SSA_NAME)
+	force_gimple_rhs = true;
 	}
 }
 
--  { dg-do run }
--  { dg-options "-gnatws -O" }

with System;

procedure SSO17 is

  type My_Float is new Float range 0.0 .. 359.99;

  type Rec is record
Az : My_Float;
El : My_Float;
  end record;
  for Rec'Bit_Order use System.High_Order_First;
  for Rec'Scalar_Storage_Order use System.High_Order_First;

  R : Rec;

  procedure Is_True (B : Boolean);
  pragma No_Inline (Is_True);

  procedure Is_True (B : Boolean) is
  begin
if not B then
  raise Program_Error;
end if;
  end;

begin
  R := (Az => 1.1, El => 2.2);
  Is_True (R.Az'Valid);
  R := (Az => 3.3, El => 4.4);
  Is_True (R.Az'Valid);
end;


[PATCH] Do not use DW_OP_not for TRUTH_NOT_EXPR in conditional expressions

2022-05-13 Thread Eric Botcazou via Gcc-patches
Hi,

DW_OP_not is a bitwise, not a logical NOT, so it computes the wrong result in 
a DWARF conditional expression.

Tested (GCC + GDB° on x86-64/Linux, OK for the mainline?


2022-05-13  Eric Botcazou  

* dwarf2out.c (loc_list_from_tree_1) : Swap the operands
if the condition is a TRUTH_NOT_EXPR.

-- 
Eric Botcazoudiff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 5681b01749a..affa2b5e52e 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -19497,6 +19497,15 @@ loc_list_from_tree_1 (tree loc, int want_address,
 	  list_ret
 	= loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
 0, context);
+	/* DW_OP_not is a bitwise, not a logical NOT, so avoid it.  */
+	else if (TREE_CODE (TREE_OPERAND (loc, 0)) == TRUTH_NOT_EXPR)
+	  {
+	lhs = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0, context);
+	rhs = loc_list_from_tree_1 (TREE_OPERAND (loc, 1), 0, context);
+	list_ret
+	  = loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
+  0, context);
+	  }
 	else
 	  list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
 	if (list_ret == 0 || lhs == 0 || rhs == 0)


Re: [PATCH] Do not use DW_OP_not for TRUTH_NOT_EXPR in conditional expressions

2022-05-13 Thread Eric Botcazou via Gcc-patches
> But this doesn't fix
> 
> case TRUTH_NOT_EXPR:
> case BIT_NOT_EXPR:
>   op = DW_OP_not;
>   goto do_unop;

Nope (I couldn't trigger it after my change).

> I also wonder where we get the TRUTH_NOT_EXPR to expand from?  I suspect
> some non-gimplified global tree?

Yes, it's in the TYPE_SIZE of a global type:

package P is

  type Rec (Defined : Boolean) is record
case Defined is
   when false => null;
   when others => I : Integer;
end case;
  end record;

  A : access Rec;

end P;

-- 
Eric Botcazou





Re: [PATCH] Fix wrong SRA with VIEW_CONVERT_EXPR and reverse SSO

2022-05-13 Thread Eric Botcazou via Gcc-patches
> OK.  Possibly also qualifies for the branch(es) as wrong-code fix.

Thanks.  It's not a regression, but I can indeed put in on recent branches.

-- 
Eric Botcazou




Re: [PATCH] Do not use DW_OP_not for TRUTH_NOT_EXPR in conditional expressions

2022-05-16 Thread Eric Botcazou via Gcc-patches
> But this doesn't fix
> 
> case TRUTH_NOT_EXPR:
> case BIT_NOT_EXPR:
>   op = DW_OP_not;
>   goto do_unop;

Revised patch attached, using Jakub's suggestion.  The original (buggy) DWARF 
procedure for the Ada testcase I previously posted is:

.uleb128 0x8# (DIE (0x5b) DW_TAG_dwarf_procedure)
.uleb128 0xc# DW_AT_location
.byte   0x12# DW_OP_dup
.byte   0x20# DW_OP_not
.byte   0x28# DW_OP_bra
.value  0x4
.byte   0x34# DW_OP_lit4
.byte   0x2f# DW_OP_skip
.value  0x1
.byte   0x30# DW_OP_lit0
.byte   0x16# DW_OP_swap
.byte   0x13# DW_OP_drop

With Jakub's fix:

.uleb128 0x8# (DIE (0x5b) DW_TAG_dwarf_procedure)
.uleb128 0xd# DW_AT_location
.byte   0x12# DW_OP_dup
.byte   0x30# DW_OP_lit0
.byte   0x29# DW_OP_eq
.byte   0x28# DW_OP_bra
.value  0x4
.byte   0x34# DW_OP_lit4
.byte   0x2f# DW_OP_skip
.value  0x1
.byte   0x30# DW_OP_lit0
.byte   0x16# DW_OP_swap
.byte   0x13# DW_OP_drop

With mine:

.uleb128 0x8# (DIE (0x5b) DW_TAG_dwarf_procedure)
.uleb128 0xb# DW_AT_location
.byte   0x12# DW_OP_dup
.byte   0x28# DW_OP_bra
.value  0x4
.byte   0x30# DW_OP_lit0
.byte   0x2f# DW_OP_skip
.value  0x1
.byte   0x34# DW_OP_lit4
.byte   0x16# DW_OP_swap
.byte   0x13# DW_OP_drop


* dwarf2out.c (loc_list_from_tree_1) : Do a logical
instead of a bitwise negation.
: Swap the operands if the condition is TRUTH_NOT_EXPR.

-- 
Eric Botcazou
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 5681b01749a..c333c595026 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -19449,6 +19449,14 @@ loc_list_from_tree_1 (tree loc, int want_address,
   break;
 
 case TRUTH_NOT_EXPR:
+  list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
+  if (list_ret == 0)
+	return 0;
+
+  add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_lit0, 0, 0));
+  add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_eq, 0, 0));
+  break;
+
 case BIT_NOT_EXPR:
   op = DW_OP_not;
   goto do_unop;
@@ -19497,6 +19505,15 @@ loc_list_from_tree_1 (tree loc, int want_address,
 	  list_ret
 	= loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
 0, context);
+	/* Likewise, swap the operands for a logically negated condition.  */
+	else if (TREE_CODE (TREE_OPERAND (loc, 0)) == TRUTH_NOT_EXPR)
+	  {
+	lhs = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0, context);
+	rhs = loc_list_from_tree_1 (TREE_OPERAND (loc, 1), 0, context);
+	list_ret
+	  = loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
+  0, context);
+	  }
 	else
 	  list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
 	if (list_ret == 0 || lhs == 0 || rhs == 0)


Re: [PATCH] Do not use DW_OP_not for TRUTH_NOT_EXPR in conditional expressions

2022-05-16 Thread Eric Botcazou via Gcc-patches
> It won't work for types larger than size of address, it would need to use
> dwarf_OP (DW_OP_const_type) instead of DW_OP_lit0 in that case.
> But maybe TRUTH_NOT_EXPR will be never seen for such types and after all,
> even the loc_list_from_tree_1 INTEGER_CST case doesn't handle that
> (the RTL case does).
> So I think at least for now it is ok.

Thanks.  Any objection to me installing it on the 12 branch as well?

-- 
Eric Botcazou




[c-family] Reduce usage of limited_with clauses with -fdump-ada-spec

2022-05-18 Thread Eric Botcazou via Gcc-patches
The problem is that subtypes are not part of the limited view of a package so
we need to use types in conjunction with limited_with clauses, which is not
always desirable since this yields less portable Ada bindings.  The patch
also contains a small enhancement for complex floating-point types.

Tested on x86-64/Linux, applied on mainline and 12 branch.


2022-05-18  Eric Botcazou  

* c-ada-spec.cc (dump_ada_node) : Deal with usual
floating-point complex types.
: Do not use limited_with clause if the designated
type is a scalar type.

-- 
Eric Botcazoudiff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index f291e150934..faf71742522 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -2105,6 +2105,21 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 	  append_withs ("Interfaces.C.Extensions", false);
 	  pp_string (buffer, "Extensions.CFloat_128");
 	}
+  else if (TREE_TYPE (node) == float_type_node)
+	{
+	  append_withs ("Ada.Numerics.Complex_Types", false);
+	  pp_string (buffer, "Ada.Numerics.Complex_Types.Complex");
+	}
+  else if (TREE_TYPE (node) == double_type_node)
+	{
+	  append_withs ("Ada.Numerics.Long_Complex_Types", false);
+	  pp_string (buffer, "Ada.Numerics.Long_Complex_Types.Complex");
+	}
+  else if (TREE_TYPE (node) == long_double_type_node)
+	{
+	  append_withs ("Ada.Numerics.Long_Long_Complex_Types", false);
+	  pp_string (buffer, "Ada.Numerics.Long_Long_Complex_Types.Complex");
+	}
   else
 	pp_string (buffer, "");
   break;
@@ -2190,7 +2205,7 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 	{
 	  tree ref_type = TREE_TYPE (node);
 	  const unsigned int quals = TYPE_QUALS (ref_type);
-	  bool is_access = false;
+	  bool is_access;
 
 	  if (VOID_TYPE_P (ref_type))
 	{
@@ -2242,7 +2257,10 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 		}
 
 		  if (!package_prefix)
-		pp_string (buffer, "access");
+		{
+		  is_access = false;
+		  pp_string (buffer, "access");
+		}
 		  else if (AGGREGATE_TYPE_P (ref_type))
 		{
 		  if (!type || TREE_CODE (type) != FUNCTION_DECL)
@@ -2256,17 +2274,21 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 			pp_string (buffer, "all ");
 			}
 		  else if (quals & TYPE_QUAL_CONST)
-			pp_string (buffer, "in ");
+			{
+			  is_access = false;
+			  pp_string (buffer, "in ");
+			}
 		  else
 			{
 			  is_access = true;
 			  pp_string (buffer, "access ");
-			  /* ??? should be configurable: access or in out.  */
 			}
 		}
 		  else
 		{
-		  is_access = true;
+		  /* We want to use regular with clauses for scalar types,
+			 as they are not involved in circular declarations.  */
+		  is_access = false;
 		  pp_string (buffer, "access ");
 
 		  if (!name_only)


  1   2   >