Re: [patch] Fix ICE during RTL expansion at -O1

2013-04-14 Thread Eric Botcazou
 This is a quadratic algorithm and as such not ok.  We already have
 aliasing_component_refs_p in tree-ssa-alias.c which is supposed to be
 the non-quadratic replacement.  It's not used via decl_refs_may_alias_p,
 so that may be the thing to fix.

aliasing_component_refs_p isn't powerful enough, it eliminates the quadratic 
aspect by assuming that all offsets are constants, so it misses cases like 
(*p)[i].f1 vs a[j].f2.  Moreover it assumes TBAA and we don't need it here.

I can rewrite nonoverlapping_component_refs_of_decl_p to make it non-quadratic 
and catch the same cases I think, patch attached (without the vect testsuite 
adjustments, but they are still needed).

 nonoverlapping_component_refs_of_decl_p on RTL should go - in fact
 we do call the tree oracle from all its callers so we only ever do redundant
 work (after your proposed patch even more so).

Not clear if the tree oracle can catch the above case with *p and a, but, yes, 
nonoverlapping_component_refs_p should go in the long term.


* alias.c (nonoverlapping_component_refs_p): Protect again LTO quirk.
* tree-ssa-alias.c (nonoverlapping_component_refs_of_decl_p): New.
(decl_refs_may_alias_p): Add REF1 and REF2 parameters.
Use nonoverlapping_component_refs_of_decl_p to disambiguate component
references.
(refs_may_alias_p_1): Adjust call to decl_refs_may_alias_p.
* tree-streamer.c (record_common_node): Adjust reference in comment.


-- 
Eric BotcazouIndex: alias.c
===
--- alias.c	(revision 197926)
+++ alias.c	(working copy)
@@ -2232,8 +2232,11 @@ nonoverlapping_component_refs_p (const_r
 
 found:
   /* If we're left with accessing different fields of a structure, then no
-	 possible overlap, unless they are both bitfields.  */
-  if (TREE_CODE (typex) == RECORD_TYPE  fieldx != fieldy)
+	 possible overlap, unless they are both bitfields.
+	 ??? Pointer inequality is too fragile in the LTO compiler.  */
+  if (TREE_CODE (typex) == RECORD_TYPE
+	   fieldx != fieldy
+	   DECL_NAME (fieldx) != DECL_NAME (fieldy))
 	return !(DECL_BIT_FIELD (fieldx)  DECL_BIT_FIELD (fieldy));
 
   /* The comparison on the current field failed.  If we're accessing
Index: tree-ssa-alias.c
===
--- tree-ssa-alias.c	(revision 197926)
+++ tree-ssa-alias.c	(working copy)
@@ -719,14 +719,110 @@ aliasing_component_refs_p (tree ref1,
   return false;
 }
 
+/* Return true if we can determine that component references REF1 and REF2,
+   that are within a common DECL, cannot overlap.  */
+
+static bool
+nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
+{
+  vectree, va_stack component_refs1;
+  vectree, va_stack component_refs2;
+
+  vec_stack_alloc (tree, component_refs1, 16);
+  vec_stack_alloc (tree, component_refs2, 16);
+
+  /* Create the stack of handled components for REF1.  */
+  while (handled_component_p (ref1))
+{
+  component_refs1.safe_push (ref1);
+  ref1 = TREE_OPERAND (ref1, 0);
+}
+  if (TREE_CODE (ref1) == MEM_REF)
+{
+  if (!integer_zerop (TREE_OPERAND (ref1, 1)))
+	goto may_overlap;
+  ref1 = TREE_OPERAND (TREE_OPERAND (ref1, 0), 0);
+}
+
+  /* Create the stack of handled components for REF2.  */
+  while (handled_component_p (ref2))
+{
+  component_refs2.safe_push (ref2);
+  ref2 = TREE_OPERAND (ref2, 0);
+}
+  if (TREE_CODE (ref2) == MEM_REF)
+{
+  if (!integer_zerop (TREE_OPERAND (ref2, 1)))
+	goto may_overlap;
+  ref2 = TREE_OPERAND (TREE_OPERAND (ref2, 0), 0);
+}
+
+  /* We must have the same base DECL.  */
+  gcc_assert (ref1 == ref2);
+
+  /* Pop the stacks in parallel and examine the COMPONENT_REFs of the same
+ rank.  This is sufficient because you cannot reference several fields
+ at a time (unlike for arrays with slices), unless you're in a union,
+ in which case the return value will be false in any case.  */
+  while (true)
+{
+  do
+	{
+	  if (component_refs1.is_empty ())
+	goto may_overlap;
+	  ref1 = component_refs1.pop ();
+	}
+  while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0;
+
+  do
+	{
+	  if (component_refs2.is_empty ())
+	 goto may_overlap;
+	  ref2 = component_refs2.pop ();
+	}
+  while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0;
+
+  /* Beware of BIT_FIELD_REF.  */
+  if (TREE_CODE (ref1) != COMPONENT_REF
+	  || TREE_CODE (ref2) != COMPONENT_REF)
+	goto may_overlap;
+
+  tree field1 = TREE_OPERAND (ref1, 1);
+  tree field2 = TREE_OPERAND (ref2, 1);
+
+  /* ??? We cannot simply use the type of operand #0 of the refs here
+	 as the Fortran compiler smuggles type punning into COMPONENT_REFs
+	 for common blocks instead of using unions like everyone else.  */
+  tree type1 = TYPE_MAIN_VARIANT (DECL_CONTEXT (field1));
+  tree type2 = TYPE_MAIN_VARIANT 

[patch] Fix PR middle-end/56474

2013-04-14 Thread Eric Botcazou
Hi,

this is a regression present on the mainline and 4.8 branch and introduced by 
the latest series of sizetype changes.  Associated adjustments were made in 
the various front-ends for it, most notably Ada which was the most affected, 
but this issue slipped through the cracks in the form of a bogus overflow 
detection for 0-based arrays with variable upper bound included in a record 
with discriminant.

The proposed fix is to disable overflow detection in sizetype for one special 
case (0 - 1) in size_binop_loc.  An equivalent kludge was added to layout_type 
to disable overflow detection for the size expression of [0, -1] arrays.

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


2013-04-14  Eric Botcazou  ebotca...@adacore.com

PR middle-end/56474
* fold-const.c (size_binop_loc): Disable overflow detection for 0 - 1.


2013-04-14  Eric Botcazou  ebotca...@adacore.com

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


-- 
Eric BotcazouIndex: fold-const.c
===
--- fold-const.c	(revision 197926)
+++ fold-const.c	(working copy)
@@ -1422,9 +1422,13 @@ size_binop_loc (location_t loc, enum tre
   gcc_assert (int_binop_types_match_p (code, TREE_TYPE (arg0),
TREE_TYPE (arg1)));
 
-  /* Handle the special case of two integer constants faster.  */
+  /* Handle general case of two integer constants.  For sizetype constant
+ calculations, we always want to know about overflow, even in the
+ unsigned case.  */
   if (TREE_CODE (arg0) == INTEGER_CST  TREE_CODE (arg1) == INTEGER_CST)
 {
+  int overflowable = -1;
+
   /* And some specific cases even faster than that.  */
   if (code == PLUS_EXPR)
 	{
@@ -1437,6 +1441,11 @@ size_binop_loc (location_t loc, enum tre
 	{
 	  if (integer_zerop (arg1)  !TREE_OVERFLOW (arg1))
 	return arg0;
+
+	  /* ??? We make an exception for 0 - 1 because it's an idiom
+	 used in length calculations for zero-based arrays.  */
+	  if (integer_zerop (arg0)  integer_onep (arg1))
+	overflowable = 1;
 	}
   else if (code == MULT_EXPR)
 	{
@@ -1444,10 +1453,7 @@ size_binop_loc (location_t loc, enum tre
 	return arg1;
 	}
 
-  /* Handle general case of two integer constants.  For sizetype
- constant calculations we always want to know about overflow,
-	 even in the unsigned case.  */
-  return int_const_binop_1 (code, arg0, arg1, -1);
+  return int_const_binop_1 (code, arg0, arg1, overflowable);
 }
 
   return fold_build2_loc (loc, code, type, arg0, arg1);-- PR middle-end/56474
-- Reported by Pavel Zhukov pa...@zhukoff.net

-- { dg-do compile }

with Ada.Streams;

package Array3 is

   use type Ada.Streams.Stream_Element_Offset;

   type Vector (Size : Ada.Streams.Stream_Element_Offset) is record
  Value : Ada.Streams.Stream_Element_Array (0 .. Size);
   end record;

   Empty_Vector : Vector (-1);

end Array3;

[SPARC] Fix PR target/56890

2013-04-14 Thread Eric Botcazou
To my great surprise, this PR shows that the SPARC back-end allows QImode and 
HImode values to live in FP registers, but can neither load nor move them.
This can result in an unrecognizable move insn between FP registers or an 
illegal fdtox instruction in 64-bit mode as shown by the submitted testcases.

The attached patch changes that and yields no regressions both in 32-bit and 
64-bit modes.  Any objections to applying it to all active branches?


2013-04-14  Eric Botcazou  ebotca...@adacore.com

PR target/56890
* config/sparc/sparc.c (enum sparc_mode_class): Add H_MODE value.
(S_MODES): Set H_MODE bit.
(SF_MODES): Set only S_MODE and SF_MODE bits.
(DF_MODES): Set SF_MODES and only D_MODE and DF_MODE bits.
(sparc_init_modes) MODE_INT: Set H_MODE bit for sub-word modes.
MODE_VECTOR_INT: Do not set SF_MODE for sub-word modes.
MODE_FLOAT: Likewise.


2013-04-14  Eric Botcazou  ebotca...@adacore.com

* gcc.dg/pr56890-1.c: New test.
* gcc.dg/pr56890-2.c: Likewise.


-- 
Eric BotcazouIndex: config/sparc/sparc.c
===
--- config/sparc/sparc.c	(revision 197926)
+++ config/sparc/sparc.c	(working copy)
@@ -4467,13 +4467,14 @@ mem_min_alignment (rtx mem, int desired)
mapped into one sparc_mode_class mode.  */
 
 enum sparc_mode_class {
-  S_MODE, D_MODE, T_MODE, O_MODE,
+  H_MODE, S_MODE, D_MODE, T_MODE, O_MODE,
   SF_MODE, DF_MODE, TF_MODE, OF_MODE,
   CC_MODE, CCFP_MODE
 };
 
 /* Modes for single-word and smaller quantities.  */
-#define S_MODES ((1  (int) S_MODE) | (1  (int) SF_MODE))
+#define S_MODES \
+  ((1  (int) H_MODE) | (1  (int) S_MODE) | (1  (int) SF_MODE))
 
 /* Modes for double-word and smaller quantities.  */
 #define D_MODES (S_MODES | (1  (int) D_MODE) | (1  DF_MODE))
@@ -4484,13 +4485,11 @@ enum sparc_mode_class {
 /* Modes for 8-word and smaller quantities.  */
 #define O_MODES (T_MODES | (1  (int) O_MODE) | (1  (int) OF_MODE))
 
-/* Modes for single-float quantities.  We must allow any single word or
-   smaller quantity.  This is because the fix/float conversion instructions
-   take integer inputs/outputs from the float registers.  */
-#define SF_MODES (S_MODES)
+/* Modes for single-float quantities.  */
+#define SF_MODES ((1  (int) S_MODE) | (1  (int) SF_MODE))
 
 /* Modes for double-float and smaller quantities.  */
-#define DF_MODES (D_MODES)
+#define DF_MODES (SF_MODES | (1  (int) D_MODE) | (1  DF_MODE))
 
 /* Modes for quad-float and smaller quantities.  */
 #define TF_MODES (DF_MODES | (1  (int) TF_MODE))
@@ -4586,7 +4585,9 @@ sparc_init_modes (void)
 	case MODE_INT:
 	case MODE_PARTIAL_INT:
 	case MODE_COMPLEX_INT:
-	  if (GET_MODE_SIZE (i) = 4)
+	  if (GET_MODE_SIZE (i)  4)
+	sparc_mode_class[i] = 1  (int) H_MODE;
+	  else if (GET_MODE_SIZE (i) == 4)
 	sparc_mode_class[i] = 1  (int) S_MODE;
 	  else if (GET_MODE_SIZE (i) == 8)
 	sparc_mode_class[i] = 1  (int) D_MODE;
@@ -4598,14 +4599,16 @@ sparc_init_modes (void)
 	sparc_mode_class[i] = 0;
 	  break;
 	case MODE_VECTOR_INT:
-	  if (GET_MODE_SIZE (i) = 4)
-	sparc_mode_class[i] = 1  (int)SF_MODE;
+	  if (GET_MODE_SIZE (i) == 4)
+	sparc_mode_class[i] = 1  (int) SF_MODE;
 	  else if (GET_MODE_SIZE (i) == 8)
-	sparc_mode_class[i] = 1  (int)DF_MODE;
+	sparc_mode_class[i] = 1  (int) DF_MODE;
+	  else
+	sparc_mode_class[i] = 0;
 	  break;
 	case MODE_FLOAT:
 	case MODE_COMPLEX_FLOAT:
-	  if (GET_MODE_SIZE (i) = 4)
+	  if (GET_MODE_SIZE (i) == 4)
 	sparc_mode_class[i] = 1  (int) SF_MODE;
 	  else if (GET_MODE_SIZE (i) == 8)
 	sparc_mode_class[i] = 1  (int) DF_MODE;
/* PR target/56890 */
/* Reported by Rainer Jung rainer.j...@kippdata.de */

/* { dg-do assemble } */
/* { dg-options -O2 } */

unsigned int buggy(unsigned int min, unsigned int max)
{
if (max  16384) {
unsigned short num16 = 0;
num16 = min + (long) ((double) (max - min + 1.0) * (num16 / (65535 + 1.0)));
return num16;
}
return 0;
}
/* PR target/56890 */
/* Reported by Rainer Jung rainer.j...@kippdata.de */

/* { dg-do assemble } */
/* { dg-options -O } */

unsigned int buggy(unsigned int min, unsigned int max)
{
unsigned int number;
if (max  16384) {
unsigned short num16;
num16 = min + (long) ((double) (max - min + 1.0) * (num16 / (65535 + 1.0)));
return num16;
}
else {
(number) = min + (long) ((double) (max - min + 1.0) * (number / (4294967295U + 1.0)));
}
return number;
}


Re: Fill more delay slots in conditional returns

2013-04-14 Thread Eric Botcazou
 I don't recall ever working on this aspect of reorg.  The obvious worry
 is that with reorg moving stuff around those notes may not be valid
 anymore in the general case.

Yes, in the general case I agree that's too dangerous.  In this particular 
case, i.e. backward scan only, this might be plausible, although one has 
probably to worry about what happens if the insn is removed from the delay 
slot and put back into the RTL stream.

 Just a note, there's a formatting error in this code.  The real_insn =
 statement is indented too far.  Feel free to fix that :-)

Patch attached (I've also reindented a block of code in reorg.c), tested on 
the SPARC and applied on the mainline.

 Seems reasonable.  This might just be an oversight by the original
 author.  Effectively we're going to start marking the referenced
 resources with your patch.  We still defer killing as far as I can tell.

OK.

 If you want to run with it, I won't object.  My worry would be we might
 not see the fallout for a long time as the number of things that have to
 fall into place for an observable failure here are very high.

Indeed, I spotted these two cases when I was playing with the allocation of 
registers for the private target.  They showed up only under very specific 
circumstances; with the default setting, neither makes a difference for the 
various testcases I'm looking at.  So, in the end, I probably won't pursue.

Thanks for your feedback.


* reorg.c (fill_simple_delay_slots): Reindent block of code.
* resource.c (mark_target_live_regs): Reformat conditional block.


-- 
Eric BotcazouIndex: reorg.c
===
--- reorg.c	(revision 197926)
+++ reorg.c	(working copy)
@@ -2144,69 +2144,66 @@ fill_simple_delay_slots (int non_jumps_p
 	  if (CALL_P (insn))
 	maybe_never = 1;
 
-	for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1);
-		 trial = next_trial)
-	  {
-		next_trial = next_nonnote_insn (trial);
-
-		/* This must be an INSN or CALL_INSN.  */
-		pat = PATTERN (trial);
-
-		/* Stand-alone USE and CLOBBER are just for flow.  */
-		if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
-		  continue;
-
-		/* If this already has filled delay slots, get the insn needing
-		   the delay slots.  */
-		if (GET_CODE (pat) == SEQUENCE)
-		  trial_delay = XVECEXP (pat, 0, 0);
-		else
-		  trial_delay = trial;
-
-		/* Stop our search when seeing a jump.  */
-		if (JUMP_P (trial_delay))
-		  break;
-
-		/* See if we have a resource problem before we try to
-		   split.  */
-		if (GET_CODE (pat) != SEQUENCE
-		 ! insn_references_resource_p (trial, set, true)
-		 ! insn_sets_resource_p (trial, set, true)
-		 ! insn_sets_resource_p (trial, needed, true)
+	  for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1);
+	   trial = next_trial)
+	{
+	  next_trial = next_nonnote_insn (trial);
+
+	  /* This must be an INSN or CALL_INSN.  */
+	  pat = PATTERN (trial);
+
+	  /* Stand-alone USE and CLOBBER are just for flow.  */
+	  if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
+		continue;
+
+	  /* If this already has filled delay slots, get the insn needing
+		 the delay slots.  */
+	  if (GET_CODE (pat) == SEQUENCE)
+		trial_delay = XVECEXP (pat, 0, 0);
+	  else
+		trial_delay = trial;
+
+	  /* Stop our search when seeing a jump.  */
+	  if (JUMP_P (trial_delay))
+		break;
+
+	  /* See if we have a resource problem before we try to split.  */
+	  if (GET_CODE (pat) != SEQUENCE
+		   ! insn_references_resource_p (trial, set, true)
+		   ! insn_sets_resource_p (trial, set, true)
+		   ! insn_sets_resource_p (trial, needed, true)
 #ifdef HAVE_cc0
-		 ! (reg_mentioned_p (cc0_rtx, pat)  ! sets_cc0_p (pat))
+		   ! (reg_mentioned_p (cc0_rtx, pat)  ! sets_cc0_p (pat))
 #endif
-		 ! (maybe_never  may_trap_or_fault_p (pat))
-		 (trial = try_split (pat, trial, 0))
-		 eligible_for_delay (insn, slots_filled, trial, flags)
-		 ! can_throw_internal(trial))
-		  {
-		next_trial = next_nonnote_insn (trial);
-		delay_list = add_to_delay_list (trial, delay_list);
-
+		   ! (maybe_never  may_trap_or_fault_p (pat))
+		   (trial = try_split (pat, trial, 0))
+		   eligible_for_delay (insn, slots_filled, trial, flags)
+		   ! can_throw_internal(trial))
+		{
+		  next_trial = next_nonnote_insn (trial);
+		  delay_list = add_to_delay_list (trial, delay_list);
 #ifdef HAVE_cc0
-		if (reg_mentioned_p (cc0_rtx, pat))
-		  link_cc0_insns (trial);
+		  if (reg_mentioned_p (cc0_rtx, pat))
+		link_cc0_insns (trial);
 #endif
+		  delete_related_insns (trial);
+		  if (slots_to_fill == ++slots_filled)
+		break;
+		  continue;
+		}
+
+	  mark_set_resources (trial, set, 0, MARK_SRC_DEST_CALL);
+	  mark_referenced_resources (trial, needed, true);
 
-		delete_related_insns (trial);
-		if (slots_to_fill == ++slots_filled)
-		  break;
-		 

[patch, fortran] Really fix PR 56782

2013-04-14 Thread Thomas Koenig

Hello world,

the attached patch completely fixes the regression,
PR 56782.

Regression-tested.  OK for trunk and 4.8?

Thomas

2013-04-14  Thomas Koenig  tkoe...@gcc.gnu.org

PR fortran/56782
* frontend-passes.c (copy_walk_reduction_arg):  Do not
call the expression walker with callback_reduction.
(insert_iterator_function):  New function.
(callback_reduction):  If an iterator is present, call
insert_iterator_function and reset the iterator on the
original array iterator.

2013-04-08  Thomas Koenig  tkoe...@gcc.gnu.org

PR fortran/56782
* gfortran.dg/array_constructor_45.f90:  New test.
* gfortran.dg/array_constructor_46.f90:  New test.
* gfortran.dg/array_constructor_40.f90:  Adjust number of
while loops.
Index: fortran/frontend-passes.c
===
--- fortran/frontend-passes.c	(Revision 197610)
+++ fortran/frontend-passes.c	(Arbeitskopie)
@@ -221,8 +221,47 @@ copy_walk_reduction_arg (gfc_expr *e, gfc_expr *fn
   fcn-symtree-n.sym-attr.access = ACCESS_PRIVATE;
 }
 
-  (void) gfc_expr_walker (fcn, callback_reduction, NULL);
+  return fcn;
+}
 
+/* Auxiliary function to create function with an an array expression with
+   iterator argument.  */
+
+static gfc_expr *
+insert_iterator_function (gfc_expr *e, gfc_expr *fn, gfc_iterator *iterator)
+{
+  gfc_expr *fcn, *new_expr;
+  gfc_isym_id id;
+  gfc_constructor_base newbase;
+  gfc_constructor *new_c;
+
+  newbase = NULL;
+  new_expr = gfc_get_expr ();
+  new_expr-expr_type = EXPR_ARRAY;
+  new_expr-ts = e-ts;
+  new_expr-where = e-where;
+  new_expr-rank = 1;
+  new_c = gfc_constructor_append_expr (newbase, gfc_copy_expr(e), (e-where));
+  new_c-iterator = iterator;
+  new_expr-value.constructor = newbase;
+
+  id = fn-value.function.isym-id;
+
+  if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
+fcn = gfc_build_intrinsic_call (current_ns,
+fn-value.function.isym-id,
+fn-value.function.isym-name,
+fn-where, 3, new_expr,
+NULL, NULL);
+  else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
+fcn = gfc_build_intrinsic_call (current_ns,
+fn-value.function.isym-id,
+fn-value.function.isym-name,
+fn-where, 2, new_expr,
+NULL);
+  else
+gfc_internal_error (Illegal id in insert_iterator_function);
+
   return fcn;
 }
 
@@ -300,15 +339,19 @@ callback_reduction (gfc_expr **e, int *walk_subtre
 
   c = gfc_constructor_first (arg-value.constructor);
 
-  /* Don't do any simplififcation if we have
- - no element in the constructor or
- - only have a single element in the array which contains an
- iterator.  */
+  /* Don't do any simplififcation if we have no element
+ in the constructor.  */
 
-  if (c == NULL || (c-iterator != NULL  gfc_constructor_next (c) == NULL))
+  if (c == NULL)
 return 0;
 
-  res = copy_walk_reduction_arg (c-expr, fn);
+  if (c-iterator)
+{
+  res = insert_iterator_function (c-expr, fn, c-iterator);
+  c-iterator = NULL;
+}
+  else
+res = copy_walk_reduction_arg (c-expr, fn);
 
   c = gfc_constructor_next (c);
   while (c)
@@ -320,7 +363,15 @@ callback_reduction (gfc_expr **e, int *walk_subtre
   new_expr-where = fn-where;
   new_expr-value.op.op = op;
   new_expr-value.op.op1 = res;
-  new_expr-value.op.op2 = copy_walk_reduction_arg (c-expr, fn);
+
+  if (c-iterator)
+	{
+	  new_expr-value.op.op2 = insert_iterator_function (c-expr, fn, c-iterator);
+	  c-iterator = NULL;
+	}
+  else
+	new_expr-value.op.op2 = copy_walk_reduction_arg (c-expr, fn);
+
   res = new_expr;
   c = gfc_constructor_next (c);
 }
Index: testsuite/gfortran.dg/array_constructor_40.f90
===
--- testsuite/gfortran.dg/array_constructor_40.f90	(Revision 197233)
+++ testsuite/gfortran.dg/array_constructor_40.f90	(Arbeitskopie)
@@ -48,5 +48,5 @@ program main
   call baz(a,b,res);
   if (abs(res - 8.1)  1e-5) call abort
 end program main
-! { dg-final { scan-tree-dump-times while 3 original } }
+! { dg-final { scan-tree-dump-times while 5 original } }
 ! { dg-final { cleanup-tree-dump original } }
! { dg-do run }
! PR PR 56872 - wrong front-end optimization with a
! single array constructor and another value.
program main
  real:: s
  integer :: m
  integer :: k
  real :: res

  m = 2
  s = 1000.

  res = SUM([3.0,(s**(REAL(k-1)/REAL(m-1)),k=1,m),17.])
  if (abs(res - 1021.)1e-4) call abort
end
! { dg-do run }
! { dg-options -ffrontend-optimize -fdump-tree-original }
! Test that nested array constructors are optimized.
program main
  implicit none
  integer, parameter :: dp=selected_real_kind(15)
  real(kind=dp), dimension(2,2) :: a
  real(kind=dp) thirteen

  data a /2._dp,3._dp,5._dp,7._dp/
  thirteen = 13._dp
  if (abs (product([[11._dp, thirteen], a]) - 30030._dp)  1e-8) call abort
end program 

Re: [PATCH] Enable java for aarch64

2013-04-14 Thread Andrew Haley
On 04/13/2013 07:21 PM, Andreas Schwab wrote:
 # of unexpected failures  29

Looks basically OK.  What were the failures, though?

Andrew.



Re: [PATCH] Enable java for aarch64

2013-04-14 Thread Matthias Klose
Am 13.04.2013 20:21, schrieb Andreas Schwab:
 This enables building java for aarch64.

Afaics, the aarch64 changes for boehm-gc are not yet checked in. Aren't these
needed as a prerequisite?



Re: Can -mno-big-switch be removed from the PA port?

2013-04-14 Thread Steven Bosscher
On Tue, Apr 9, 2013 at 3:46 AM, John David Anglin wrote:
  Seems to cause a reload problem:
 Problem may be in not removing the continuation character \ from various
 macro definitions.

Right, ASM_OUTPUT_ADDR_VEC_ELT and ASM_OUTPUT_ADDR_DIFF_ELT had a
trailing '\' that I should have removed. And I did remove it from the
tree that I used to do a cross-build, but forgot to update the patch.
Oops.

Correct patch attached.

Ciao!
Steveb
* config.gcc (hppa*-*-*): Remove MASK_BIG_SWITCH from CPU default.
* config/pa/pa.opt: Make mbig-switch a no-op.
* config/pa/pa.h (TARGET_DEFAULT): Remove MASK_BIG_SWITCH.
(CASE_VECTOR_MODE): Always return SImode.
(ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Remove code
for the !TARGET_BIG_SWITCH case.
* config/pa/pa-linux.h: Likewise.
* config/pa/pa-openbsd.h: Likewise.
* config/pa/pa-hpux.h: Define TARGET_DEFAULT to 0.
* config/pa/pa.md (short_jump): Remove define_insn.
(casesi): Remove code for the !TARGET_BIG_SWITCH case.
(casesi0): Remove define_insn.
* config/pa/pa.c  (pa_reorg): Remove code for !TARGET_BIG_SWITCH.
* doc/invoke.texi (HPPA Options): Delete documentation for mbig-switch
and mno-big-switch

Index: config.gcc
===
--- config.gcc  (revision 197941)
+++ config.gcc  (working copy)
@@ -3694,7 +3694,6 @@ case ${target} in
;;
 
hppa*-*-*)
-   target_cpu_default2=MASK_BIG_SWITCH
if test x$gas = xyes
then

target_cpu_default2=${target_cpu_default2}|MASK_GAS|MASK_JUMP_IN_DELAY
Index: config/pa/pa.opt
===
--- config/pa/pa.opt(revision 197941)
+++ config/pa/pa.opt(working copy)
@@ -38,8 +38,8 @@ Target RejectNegative
 Generate PA2.0 code (requires binutils 2.10 or later)
 
 mbig-switch
-Target Report Mask(BIG_SWITCH)
-Generate code for huge switch statements
+Target Ignore
+Does nothing.  Preserved for backward compatibility.
 
 mdisable-fpregs
 Target Report Mask(DISABLE_FPREGS)
Index: config/pa/pa.h
===
--- config/pa/pa.h  (revision 197941)
+++ config/pa/pa.h  (working copy)
@@ -114,7 +114,7 @@ extern unsigned long total_code_bytes;
 #define TARGET_HPUX_UNWIND_LIBRARY 0
 
 #ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_GAS | MASK_JUMP_IN_DELAY | MASK_BIG_SWITCH)
+#define TARGET_DEFAULT (MASK_GAS | MASK_JUMP_IN_DELAY)
 #endif
 
 #ifndef TARGET_CPU_DEFAULT
@@ -983,12 +983,11 @@ do {  
 \
 
 #define FUNCTION_NAME_P(NAME)  (*(NAME) == '@')
 
-/* Specify the machine mode that this machine uses for the index in the
-   tablejump instruction.  For small tables, an element consists of a
-   ia-relative branch and its delay slot.  When -mbig-switch is specified,
-   we use a 32-bit absolute address for non-pic code, and a 32-bit offset
-   for both 32 and 64-bit pic code.  */
-#define CASE_VECTOR_MODE (TARGET_BIG_SWITCH ? SImode : DImode)
+/* Specify the machine mode that this machine uses for the index in the
+   tablejump instruction.  
+   We use a 32-bit absolute address for non-pic code, and a 32-bit offset
+   for both 32 and 64-bit pic code.  */
+#define CASE_VECTOR_MODE SImode
 
 /* Jump tables must be 32-bit aligned, no matter the size of the element.  */
 #define ADDR_VEC_ALIGN(ADDR_VEC) 2
@@ -1165,8 +1164,8 @@ do {  
 \
   pa_output_ascii ((FILE), (P), (SIZE))
 
 /* Jump tables are always placed in the text section.  Technically, it
-   is possible to put them in the readonly data section when -mbig-switch
-   is specified.  This has the benefit of getting the table out of .text
+   is possible to put them in the readonly data section.
+   This has the benefit of getting the table out of .text
and reducing branch lengths as a result.  The downside is that an
additional insn (addil) is needed to access the table when generating
PIC code.  The address difference table also has to use 32-bit
@@ -1182,20 +1181,14 @@ do {
 \
 /* This is how to output an element of a case-vector that is absolute.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
-  if (TARGET_BIG_SWITCH)   \
-fprintf (FILE, \t.word L$%04d\n, VALUE); \
-  else \
-fprintf (FILE, \tb L$%04d\n\tnop\n, VALUE)
+  fprintf (FILE, \t.word L$%04d\n, VALUE);
 
 /* This is how to output an element of a case-vector that is relative. 
Since we always place jump tables in the text section, the difference
is absolute and 

Re: Fix std::pair std::is_copy_assignable behavior

2013-04-14 Thread François Dumont

On 04/14/2013 03:33 AM, Gabriel Dos Reis wrote:

Does DR 1402 resolution generalization need a Standard committee validation
first ?

I cannot see why we would want otherwise :-)

-- Gaby

I rather wonder if gcc only accept modifications that has been validated 
by the Standard committee first or if we can first apply the 
modification to challenge it as much as possible while discussing about 
it at the same time.


Of course I ask because the compiler modification has a relatively 
limited (bad) impact like libstdc++ testsuite have shown.


[Patch, fortran] PR56816: double free on unfinished SELECT TYPE statement

2013-04-14 Thread Mikael Morin
Hello,

this fixes a case where an unfinished SELECT TYPE statement was leading
to an ICE because at the time the statement was rejected, the compiler
tried to free some symbols that had already freed with the SELECT TYPE
namespace.

The fix moves the namespace allocation and cleanup out of
gfc_match_namespace.  A syntax error is added to avoid the default
unclassifiable statement error.

Bootstrapped (with asan) and regression tested on x86_64-linux.
OK for trunk/4.8?

Mikael


2013-04-14  Mikael Morin  mik...@gcc.gnu.org

PR fortran/56816
* match.c (gfc_match_select_type): Add syntax error. Move namespace
allocation and cleanup...
* parse.c (decode_statement): ... here.

2013-04-14  Mikael Morin  mik...@gcc.gnu.org

PR fortran/56816
* gfortran.dg/select_type_33.f03: New test.


diff --git a/match.c b/match.c
index a1529da..b5e9609 100644
--- a/match.c
+++ b/match.c
@@ -5337,7 +5337,6 @@ gfc_match_select_type (void)
   char name[GFC_MAX_SYMBOL_LEN];
   bool class_array;
   gfc_symbol *sym;
-  gfc_namespace *parent_ns;
 
   m = gfc_match_label ();
   if (m == MATCH_ERROR)
@@ -5347,8 +5346,6 @@ gfc_match_select_type (void)
   if (m != MATCH_YES)
 return m;
 
-  gfc_current_ns = gfc_build_block_ns (gfc_current_ns);
-
   m = gfc_match ( %n = %e, name, expr2);
   if (m == MATCH_YES)
 {
@@ -5379,7 +5376,10 @@ gfc_match_select_type (void)
 
   m = gfc_match ( )%t);
   if (m != MATCH_YES)
-goto cleanup;
+{
+  gfc_error (parse error in SELECT TYPE statement at %C);
+  goto cleanup;
+}
 
   /* This ghastly expression seems to be needed to distinguish a CLASS
  array, which can have a reference, from other expressions that
@@ -5417,9 +5417,6 @@ gfc_match_select_type (void)
   return MATCH_YES;
 
 cleanup:
-  parent_ns = gfc_current_ns-parent;
-  gfc_free_namespace (gfc_current_ns);
-  gfc_current_ns = parent_ns;
   return m;
 }
 
diff --git a/parse.c b/parse.c
index 6dde0c6..74a5b4b 100644
--- a/parse.c
+++ b/parse.c
@@ -262,6 +262,7 @@ end_of_block:
 static gfc_statement
 decode_statement (void)
 {
+  gfc_namespace *ns;
   gfc_statement st;
   locus old_locus;
   match m;
@@ -363,7 +364,12 @@ decode_statement (void)
   match (NULL, gfc_match_associate, ST_ASSOCIATE);
   match (NULL, gfc_match_critical, ST_CRITICAL);
   match (NULL, gfc_match_select, ST_SELECT_CASE);
+
+  gfc_current_ns = gfc_build_block_ns (gfc_current_ns);
   match (NULL, gfc_match_select_type, ST_SELECT_TYPE);
+  ns = gfc_current_ns;
+  gfc_current_ns = gfc_current_ns-parent;
+  gfc_free_namespace (ns);
 
   /* General statement matching: Instead of testing every possible
  statement, we eliminate most possibilities by peeking at the


! { dg-do compile }
!
! PR fortran/56816
! The unfinished SELECT TYPE statement below was leading to an ICE because
! at the time the statement was rejected, the compiler tried to free
! some symbols that had already been freed with the SELECT TYPE
! namespace.
!
! Original testcase from Dominique Pelletier dominique.pellet...@polymtl.ca
!
module any_list_module
implicit none

private
public :: anylist, anyitem

type anylist
end type

type anyitem
class(*), allocatable :: value
end type
end module any_list_module


module my_item_list_module

use any_list_module
implicit none

type, extends (anyitem) :: myitem
end type myitem

contains

subroutine myprint (this)
class (myitem) ::   this

select type ( v = this % value ! { dg-error parse error in SELECT 
TYPE }
end select  ! { dg-error Expecting END SUBROUTINE 
}
end subroutine myprint

end module my_item_list_module


Re: [Patch, fortran] PR56816: double free on unfinished SELECT TYPE statement

2013-04-14 Thread Thomas Koenig

Hi Mikael,


Bootstrapped (with asan) and regression tested on x86_64-linux.
OK for trunk/4.8?


OK for both.

Thanks for the patch!

Thomas



[patch] fix verify_rtl_sharing handling of SEQUENCEs

2013-04-14 Thread Steven Bosscher
Hello,

My new delay branch scheduler uses TODO_verify_rtl_sharing but it
turns out that verify_rtl_sharing doesn't handle SEQUENCEs correctly:
Clearing the used-flags is done correctly, but verifying insns in the
SEQUENCE fails. The problem is that every insn in the SEQUENCE is
marked used via PATTERN(SEQUENCE) and also via PREV_INSN/NEXT_INSN of
the insns in the SEQUENCE.

Fixed with the attached patch. Bootstrapepdtested on
sparc64-unknown-linux-gnu, and cross-builttested on mips-elf, both
with TODO_verify_rtl_sharing added to the passes in reorg.c.
Will commit as obvious.

Ciao!
Steven
* emit-rtl.c (reset_insn_used_flags): New function.
(verify_insn_sharing): New function.
(verify_rtl_sharing): Fix marking and verification of insns.

Index: emit-rtl.c
===
--- emit-rtl.c  (revision 197944)
+++ emit-rtl.c  (working copy)
@@ -2596,47 +2596,64 @@ verify_rtx_sharing (rtx orig, rtx insn)
   return;
 }
 
+/* Reset used-flags for INSN.  */
+
+static void
+reset_insn_used_flags (rtx insn)
+{
+  gcc_assert (INSN_P (insn));
+  reset_used_flags (PATTERN (insn));
+  reset_used_flags (REG_NOTES (insn));
+  if (CALL_P (insn))
+reset_used_flags (CALL_INSN_FUNCTION_USAGE (insn));
+}
+
+/* Verify sharing in INSN.  */
+
+static void
+verify_insn_sharing (rtx insn)
+{
+  gcc_assert (INSN_P (insn));
+  reset_used_flags (PATTERN (insn));
+  reset_used_flags (REG_NOTES (insn));
+  if (CALL_P (insn))
+reset_used_flags (CALL_INSN_FUNCTION_USAGE (insn));
+}
+
 /* Go through all the RTL insn bodies and check that there is no unexpected
sharing in between the subexpressions.  */
 
 DEBUG_FUNCTION void
 verify_rtl_sharing (void)
 {
-  rtx p;
+  rtx p, pat;
+  int i;
 
   timevar_push (TV_VERIFY_RTL_SHARING);
 
   for (p = get_insns (); p; p = NEXT_INSN (p))
 if (INSN_P (p))
   {
-   reset_used_flags (PATTERN (p));
-   reset_used_flags (REG_NOTES (p));
-   if (CALL_P (p))
- reset_used_flags (CALL_INSN_FUNCTION_USAGE (p));
-   if (GET_CODE (PATTERN (p)) == SEQUENCE)
+rtx pat = PATTERN (p);
+if (GET_CODE (pat) != SEQUENCE)
+ reset_insn_used_flags (p);
+   else
  {
-   int i;
-   rtx q, sequence = PATTERN (p);
-
-   for (i = 0; i  XVECLEN (sequence, 0); i++)
- {
-   q = XVECEXP (sequence, 0, i);
-   gcc_assert (INSN_P (q));
-   reset_used_flags (PATTERN (q));
-   reset_used_flags (REG_NOTES (q));
-   if (CALL_P (q))
- reset_used_flags (CALL_INSN_FUNCTION_USAGE (q));
- }
+   gcc_assert (REG_NOTES (p) == NULL);
+   for (i = 0; i  XVECLEN (pat, 0); i++)
+ reset_insn_used_flags (XVECEXP (pat, 0, i));
  }
   }
 
   for (p = get_insns (); p; p = NEXT_INSN (p))
 if (INSN_P (p))
   {
-   verify_rtx_sharing (PATTERN (p), p);
-   verify_rtx_sharing (REG_NOTES (p), p);
-   if (CALL_P (p))
- verify_rtx_sharing (CALL_INSN_FUNCTION_USAGE (p), p);
+rtx pat = PATTERN (p);
+if (GET_CODE (pat) != SEQUENCE)
+ verify_insn_sharing (p);
+   else
+ for (i = 0; i  XVECLEN (pat, 0); i++)
+   verify_insn_sharing (XVECEXP (pat, 0, i));
   }
 
   timevar_pop (TV_VERIFY_RTL_SHARING);


Re: [patch, fortran] Really fix PR 56782

2013-04-14 Thread Mikael Morin
Hello,

Le 14/04/2013 11:57, Thomas Koenig a écrit :
 Hello world,
 
 the attached patch completely fixes the regression,
 PR 56782.

typo: it's PR 56872 everywhere.

 Regression-tested.  OK for trunk and 4.8?
 
 Thomas
 
 2013-04-14  Thomas Koenig  tkoe...@gcc.gnu.org
 
 PR fortran/56782
 * frontend-passes.c (copy_walk_reduction_arg):  Do not
 call the expression walker with callback_reduction.
 (insert_iterator_function):  New function.
 (callback_reduction):  If an iterator is present, call
 insert_iterator_function and reset the iterator on the
 original array iterator.
 
 2013-04-08  Thomas Koenig  tkoe...@gcc.gnu.org
 
 PR fortran/56782
 * gfortran.dg/array_constructor_45.f90:  New test.
 * gfortran.dg/array_constructor_46.f90:  New test.
 * gfortran.dg/array_constructor_40.f90:  Adjust number of
 while loops.

 Index: fortran/frontend-passes.c
 ===
 --- fortran/frontend-passes.c (Revision 197610)
 +++ fortran/frontend-passes.c (Arbeitskopie)
 @@ -221,8 +221,47 @@ copy_walk_reduction_arg (gfc_expr *e, gfc_expr *fn
fcn-symtree-n.sym-attr.access = ACCESS_PRIVATE;
  }
  
 -  (void) gfc_expr_walker (fcn, callback_reduction, NULL);

why remove this?

 +  return fcn;
 +}
  
 +/* Auxiliary function to create function with an an array expression with
 +   iterator argument.  */
 +
 +static gfc_expr *
 +insert_iterator_function (gfc_expr *e, gfc_expr *fn, gfc_iterator *iterator)
 +{

[...]

 +
 +  if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
 +fcn = gfc_build_intrinsic_call (current_ns,
 + fn-value.function.isym-id,
 + fn-value.function.isym-name,
 + fn-where, 3, new_expr,
 + NULL, NULL);
 +  else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
 +fcn = gfc_build_intrinsic_call (current_ns,
 + fn-value.function.isym-id,
 + fn-value.function.isym-name,
 + fn-where, 2, new_expr,
 + NULL);
 +  else
 +gfc_internal_error (Illegal id in insert_iterator_function);

This duplicated code could probably be merged with
copy_walk_reduction_arg.  I think callback_reduction's iterator handling
should happen there as well.
Like this:

copy_walk_reduction_arg (...)
{
  fcn = gfc_copy_expr (c-expr);
  gfc_expr_walker (fcn, callback_reduction, NULL);
  if (c-iterator)
{
  /* wrap in array constructor  */
}

  if (!scalar)
{
  /* wrap in intrinsic call */
}

  return ...;
}


Mikael


[patch][mips] split mips_reorg in pre- and post-dbr_schedule parts

2013-04-14 Thread Steven Bosscher
Hello,

This patch splits mips_reorg.c in a pre-dbr_schedule part and a new,
machine specific post-dbr_schedule pass. With this patch,
cleanup_barriers and dbr_schedule can be static functions again.

Cross-builttested mips-sim. OK for trunk?

Ciao!
Steven

* config/mips/mips.c: Include tree-pass.h.
(mips_reorg): Split in pre- and post-dbr_schedule parts.
(mips_machine_reorg2): Move mips_reorg post-dbr_schedule parts here.
(pass_mips_machine_reorg2): New machine specific pass.
(insert_pass_mips_machine_reorg2): New pass plugin definition.
(mips_option_override): Register the new pass.
* rtl.h (cleanup_barriers): Remove prototype.
(dbr_schedule): Likewise.
* jump.c (cleanup_barriers): Make static.
* reorg.c (dbr_schedule): Likewise.

Index: config/mips/mips.c
===
--- config/mips/mips.c  (revision 197944)
+++ config/mips/mips.c  (working copy)
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include diagnostic.h
 #include target-globals.h
 #include opts.h
+#include tree-pass.h
 
 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF.  */
 #define UNSPEC_ADDRESS_P(X)\
@@ -16356,12 +16357,14 @@ mips_reorg (void)
   mips_df_reorg ();
   free_bb_for_insn ();
 }
+}
 
-  if (optimize  0  flag_delayed_branch)
-{
-  cleanup_barriers ();
-  dbr_schedule (get_insns ());
-}
+/* We use a machine specific pass to do a second machine dependent reorg
+   pass after delay branch scheduling.  */
+
+static unsigned int
+mips_machine_reorg2 (void)
+{
   mips_reorg_process_insns ();
   if (!TARGET_MIPS16
TARGET_EXPLICIT_RELOCS
@@ -16374,6 +16377,34 @@ mips_reorg (void)
 mips_reorg_process_insns ();
   mips16_split_long_branches ();
 }
+
+struct rtl_opt_pass pass_mips_machine_reorg2 =
+{
+ {
+  RTL_PASS,
+  mach2, /* name */
+  OPTGROUP_NONE,   /* optinfo_flags */
+  NULL,/* gate */
+  mips_machine_reorg2, /* execute */
+  NULL,/* sub */
+  NULL,/* next */
+  0,   /* static_pass_number */
+  TV_MACH_DEP, /* tv_id */
+  0,   /* properties_required */
+  0,   /* properties_provided */
+  0,   /* properties_destroyed */
+  0,   /* todo_flags_start */
+  TODO_verify_rtl_sharing, /* todo_flags_finish */
+ }
+};
+
+struct register_pass_info insert_pass_mips_machine_reorg2 =
+{
+  pass_mips_machine_reorg2.pass,  /* pass */
+  dbr,   /* reference_pass_name */
+  1,   /* ref_pass_instance_number */
+  PASS_POS_INSERT_AFTER/* po_op */
+};
 
 /* Implement TARGET_ASM_OUTPUT_MI_THUNK.  Generate rtl rather than asm text
in order to avoid duplicating too much logic from elsewhere.  */
@@ -17149,6 +17180,11 @@ mips_option_override (void)
  Do all CPP-sensitive stuff in uncompressed mode; we'll switch modes
  later if required.  */
   mips_set_compression_mode (0);
+
+  /* We register a second machine specific reorg pass after delay slot
+ filling.  Registering the pass must be done at start up.  It's
+ convenient to do it here.  */
+  register_pass (insert_pass_mips_machine_reorg2);
 }
 
 /* Swap the register information for registers I and I + 1, which
Index: rtl.h
===
--- rtl.h   (revision 197944)
+++ rtl.h   (working copy)
@@ -1924,7 +1924,6 @@ extern enum rtx_code swap_condition (enum rtx_code
 extern enum rtx_code unsigned_condition (enum rtx_code);
 extern enum rtx_code signed_condition (enum rtx_code);
 extern void mark_jump_label (rtx, rtx, int);
-extern unsigned int cleanup_barriers (void);
 
 /* In jump.c */
 extern rtx delete_related_insns (rtx);
@@ -2668,9 +2667,6 @@ extern void reg_scan (rtx, unsigned int);
 extern void fix_register (const char *, int, int);
 extern bool invalid_mode_change_p (unsigned int, enum reg_class);
 
-/* In reorg.c */
-extern void dbr_schedule (rtx);
-
 /* In reload1.c */
 extern int function_invariant_p (const_rtx);
 
Index: jump.c
===
--- jump.c  (revision 197944)
+++ jump.c  (working copy)
@@ -118,7 +118,7 @@ rebuild_jump_labels_chain (rtx chain)
This simple pass moves barriers and removes duplicates so that the
old code is happy.
  */
-unsigned int
+static unsigned int
 cleanup_barriers (void)
 {
   rtx insn, next, prev;
Index: reorg.c
===
--- reorg.c 

Re: [patch, fortran] Really fix PR 56782

2013-04-14 Thread Thomas Koenig

Hi Mikael,



-  (void) gfc_expr_walker (fcn, callback_reduction, NULL);


why remove this?


Because it is not needed, as the test case _46 shows.  No need
to run this twice, it doesn't get better :-)

It is a leftover from when the callback function returned 1.

  gfc_internal_error (Illegal id in insert_iterator_function);


This duplicated code could probably be merged with
copy_walk_reduction_arg.


I thought about it. The reason why I didn't do it was
because the expr to be wrapped inside the call is different.
Another reason was that I didn't get it right when I tried
this approach.
So, I'd rather leave it as is.

I think callback_reduction's iterator handling

should happen there as well.


Like I said, it is done automatically by the expression
walker.

Thomas


*ping* - Re: [Patch, Fortran] PR39505 - add support for !GCC$ attributes NO_ARG_CHECK

2013-04-14 Thread Tobias Burnus

Early *ping*.

For a usage, see for instance Open MPI, which since 1.7.0 uses it. From 
their trunk version:

http://svn.open-mpi.org/svn/ompi/trunk/config/ompi_fortran_check_ignore_tkr.m4
http://svn.open-mpi.org/svn/ompi/trunk/ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-interfaces.h.in

Tobias


Tobias Burnus wrote:

Minor patch update due to Janus' gfc_explicit_interface_required patch.

Build and regtested on x86-64-gnu-linux.
OK for the trunk?

Tobias


Tobias Burnus wrote:

Minor patch update:
- Changed FAILURE to false due to Janne's patch
- Removed a left-over #if 0 debug code

On Tobias Burnus wrote:
Many compilers have some pragma or directive to disable the type, 
kind and rank (TKR) checks. That feature matches C's void* pointer 
and can be used in conjunction with passing some byte data to a 
procedure, which only needs to know either the pointer address or 
pointer address and size.


I think the most useful application are MPI implementation. 
Currently, the do not offer explicit interfaces for their procedures 
which take a void *buffer argument. For MPI 3.0, many compiler 
have started to use compiler directives which disable TKR checks - 
and where gfortran is left out.


The Fortran standard does not provide such a feature - and it likely 
won't have one in the next standard, either. The Technical 
Specification ISO/ICE TS 29113:2012 provides TYPE(*), which disables 
the TK part of TKR. That's fine if one has either scalars or arrays 
(including array elements) - then one can use type(*) :: buf and 
type(*),dimension(*) :: buf. But that doesn't allow for scalars 
*and* arrays [1]. The next Fortran standard might allow for scalars 
passed to type(*),dimension(*) in Bind(C) procedures - but seemingly 
not for non-Bind(C) procedures nor is a draft in sight [2].


(There is a possibility to pass both scalars and arrays to a dummy 
argument, namely: type(*), dimension(..) but that uses not 
directly the address but passes an array descriptor.)


Other compilers have:

  !DEC$ ATTRIBUTES NO_ARG_CHECK :: buf
  !$PRAGMA IGNORE_TKR buf
  !DIR$ IGNORE_TKR buf
  !IBM* IGNORE_TKR buf

With the attached patch, gfortran does likewise. I essentially use 
the same mechanism as TYPE(*) with the code - after resolving the 
symbol, I even set ts.type = BT_ASSUMED. Contrary to some other 
compilers, which only allow the attribute for interfaces, this patch 
also allows it for Fortran procedures. But due to the TYPE(*) 
constraints, one can only use it with C_LOC or pass it on to another 
NO_ARG_CHECK dummy.


By the way, the recommended data type with this feature is TYPE(*). 
In order to increase compatibility with other codes, it also accepts 
intrinsic numeric types (and logical) of any kind.


Build and regtested on x86-64-gnu-linux.
OK for the trunk?

Tobias

[1] Generic interfaces are not really a solution as one needs one 
per rank, i.e. scalar+15 ranks = 16 specific functions; with two 
such arguments, up to 16*16 = 256 combinations. As other compilers 
support directives and as, e.g., MPI has many interfaces, MPI 
vendors won't go that route. However, I assume that they will start 
using gfortran's dimension(..) at some point, in line with MPI 3. 
Either the 4.8+ one with gfortran's current descriptor or the one 
from Fortran-Dev.


[2] Even if a first draft were available, one had to wait until at 
least the first J3/WG5 vote to be _reasonable_ sure that the 
proposal is in and won't be modified.








Re: [SPARC] Fix PR target/56890

2013-04-14 Thread David Miller
From: Eric Botcazou ebotca...@adacore.com
Date: Sun, 14 Apr 2013 10:39:59 +0200

 To my great surprise, this PR shows that the SPARC back-end allows QImode and 
 HImode values to live in FP registers, but can neither load nor move them.
 This can result in an unrecognizable move insn between FP registers or an 
 illegal fdtox instruction in 64-bit mode as shown by the submitted testcases.
 
 The attached patch changes that and yields no regressions both in 32-bit and 
 64-bit modes.  Any objections to applying it to all active branches?

No objections.

We can actually support this by adding patterns for the partial store
instructions, which can store 8-bit and 16-bit quantities from FP
registers.


RE: [Patch] [MIPS] Fix Many warnings in MIPS port (Was: [PATCH] [MIPS] microMIPS gcc support)

2013-04-14 Thread Moore, Catherine


 -Original Message-
 From: David Daney [mailto:ddaney.c...@gmail.com]
 Sent: Friday, April 12, 2013 7:29 PM
 To: Moore, Catherine
 Cc: Rozycki, Maciej; gcc-patches@gcc.gnu.org; Richard Sandiford
 Subject: Re: [Patch] [MIPS] Fix Many warnings in MIPS port (Was: [PATCH]
 [MIPS] microMIPS gcc support)
 
 On 04/12/2013 03:07 PM, Moore, Catherine wrote:
  Hi David,
  Please try the attached patch.  Is this OK to checkin?
 
 I don't think it is correct... 

And you would be right.  I attached the wrong patch.  Try this one instead:

Index: configure
===
--- configure   (revision 197950)
+++ configure   (working copy)
@@ -17830,7 +17830,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat  conftest.$ac_ext _LT_EOF
-#line 17831 configure
+#line 17833 configure
 #include confdefs.h

 #if HAVE_DLFCN_H
@@ -17936,7 +17936,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat  conftest.$ac_ext _LT_EOF
-#line 17937 configure
+#line 17939 configure
 #include confdefs.h

 #if HAVE_DLFCN_H
@@ -25766,7 +25766,7 @@
   gcc_cv_as_micromips_support=no
   if test x$gcc_cv_as != x; then
 $as_echo '.set micromips'  conftest.s
-if { ac_try='$gcc_cv_as $gcc_cv_as_flags  -o conftest.o conftest.s 5'
+if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o 
conftest.s 5'
   { { eval echo \\$as_me\:${as_lineno-$LINENO}: \$ac_try\; } 5
   (eval $ac_try) 25
   ac_status=$?
Index: configure.ac
===
--- configure.ac(revision 197950)
+++ configure.ac(working copy)
@@ -4058,7 +4058,7 @@
  [Define if your assembler supports .gnu_attribute.])])

 gcc_GAS_CHECK_FEATURE([.micromips support],
-  gcc_cv_as_micromips_support,,,
+  gcc_cv_as_micromips_support,,[--fatal-warnings],
   [.set micromips],,
   [AC_DEFINE(HAVE_GAS_MICROMIPS, 1,
   [Define if your assembler supports the .set micromips directive])])


Sorry for the confusion. 
Catherine

 
  2013-04-12  Catherine Moorec...@codesourcery.com
 
   * configure.ac (.micromips support): Add --fatal-warnings option.
   * configure: Regenerate.
 
 
 [...]
 
  Index: configure.ac
 
 ==
 =
  --- configure.ac(revision 197936)
  +++ configure.ac(working copy)
  @@ -4051,6 +4051,12 @@ LCF0:
  [AC_DEFINE(HAVE_AS_NO_SHARED, 1,
   [Define if the assembler understands -mno-shared.])])
 
  +gcc_GAS_CHECK_FEATURE([.micromips support],
  +  gcc_cv_as_micromips_support,,[--fatal-warnings],
  +  [.set micromips],,
  +  [AC_DEFINE(HAVE_GAS_MICROMIPS, 1,
  +  [Define if your assembler supports the .set micromips
  + directive])])
  +
 
 There is already an existing check.  Just modify that one instead of adding a
 duplicate.  Something like the attached (untested)
 
gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
  gcc_cv_as_mips_gnu_attribute, [2,18,0],,
  [.gnu_attribute 4,1],,
 
 
 I didn't have time to test this yet.  I may try Monday.
 
 David Daney


[Java,docs] Some style and link changes to gcj.texi

2013-04-14 Thread Gerald Pfeifer
This updates one link (sources.redhat.com now redirects to
sourceware.org), remove one generic one that used to point to
sun.com.  And, while at it, I noticed that gcc should read GCC.

Applied to mainline; I'll probably backport to the 4.8 branch
later.

Gerald

2013-04-15  Gerald Pfeifer  ger...@pfeifer.com

* gcj.texi (Configure-time Options): Refer to GCC, not gcc.
(Resources): Adjust reference to Mauve.
Remove link to java.sun.com.
Refer to GCC, not gcc.

Index: gcj.texi
===
--- gcj.texi(revision 197950)
+++ gcj.texi(working copy)
@@ -609,7 +609,7 @@
 processor.
 
 @item -fuse-atomic-builtins
-On some systems, gcc can generate code for built-in atomic operations.
+On some systems, GCC can generate code for built-in atomic operations.
 Use this option to force gcj to use these builtins when compiling Java
 code.  Where this capability is present it should be automatically
 detected, so you won't usually need to use this option.
@@ -2712,18 +2712,17 @@
 heavily on documentation from Sun Microsystems.  In particular we have
 used The Java Language Specification (both first and second editions),
 the Java Class Libraries (volumes one and two), and the Java Virtual
-Machine Specification.  In addition we've used the online documentation
-at @uref{http://java.sun.com/}.
+Machine Specification.  In addition we've used Sun's online documentation.
 
 The current @command{gcj} home page is
 @uref{http://gcc.gnu.org/java/}.
 
-For more information on gcc, see @uref{http://gcc.gnu.org/}.
+For more information on GCC, see @uref{http://gcc.gnu.org/}.
 
 Some @code{libgcj} testing is done using the Mauve test suite.  This is
 a free software Java class library test suite which is being written
 because the JCK is not free.  See
-@uref{http://sources.redhat.com/mauve/} for more information.
+@uref{http://www.sourceware.org/mauve/} for more information.
 
 
 @node Index


Re: [PATCH] color diagnostics markers

2013-04-14 Thread Marc Glisse

On Wed, 10 Apr 2013, Gabriel Dos Reis wrote:


On Wed, Apr 10, 2013 at 1:42 PM, Manuel López-Ibáñez
lopeziba...@gmail.com wrote:

On 9 April 2013 15:21, Jakub Jelinek ja...@redhat.com wrote:

white).  The default is still -fdiagnostics-color=never, can be changed
later on.


Apart from my comments elsewhere
(http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00614.html), the patch
looks fine to me. But perhaps we should change the default to auto, at
least during Stage 1, to find out whether some bug was introduced. If
agreed, I could do this in a follow-up patch that also disables colors
for the testsuite.

Cheers,

Manuel.


I am still of the opinion that the default should be discussed differently,
and I strongly suggest that it defaults to never.  I do not believe we do
need to do otherwise now.

As I stated before, our pursuit of enabling everything new thing by default
may have made C++ diagnostics more terrifying.


Hello,

I would like to suggest that the default be auto when the environment 
variable GCC_COLORS is defined. It can stay never otherwise (I would 
prefer auto as well, colors don't make the diagnostics any longer, only 
more readable, and an empty GCC_COLORS is an easy way to disable them, but 
I see you have a strong opinion on this so I won't insist).


Defining a variable in my environment counts as a clear intention. And 
without it, if I want to always use colors, I need to either type the 
option every time, or create wrappers for every version of every front-end 
that I use.


For grep, I can have colors by default with GREP_OPTIONS=--color=auto. Any 
alternative mean to enable colors by default would be ok with me.


By the way, I was unlucky enough to try colors by compiling a non-existing 
file, but this message doesn't get any colors:


g++: error: zz.cc: No such file or directory
g++: fatal error: no input files

(not that it needs them, it is short enough)

--
Marc Glisse


Re: [patch] PR middle-end/43631

2013-04-14 Thread Steven Bosscher
On Fri, Apr 12, 2013 at 6:46 PM, Steven Bosscher wrote:
 Can we reorganize insn-notes.def so that the 3 classes are clearly separated
 (and optionally define a NOTE_INSN_CLASS macro so that we don't need to
 enumerate the notes each time)?

 That's probably a good idea, yes.

This didn't really help make things look prettier. The notes are
enumerated in many other places, for various purposes. I didn't like
special-casing this one INSN_NOTE oddity when there are so many others
already. So I created a note_outside_basic_block_p instead, I hope you
agree with this approach.

While there, I noticed that we could use a make_note_raw.


 Reading your patch, it apppears that NOTE_INSN_SWITCH_TEXT_SECTIONS is the
 only member of the 1st class and that almost all notes are in the 2nd class
 except for the 2 LOCATION and the 2 EH_REGION recently added notes.

 I think DELETED_LABEL and DELETED_DEBUG_LABEL also can only live
 outside basic blocks (i.e. like SWITCH_TEXT_SECTIONS), but I'm not
 sure.

It turns out that DELETED_LABEL cannot be emitted, it can only be
created by patching out a label. Likewise for DELETED_DEBUG_LABEL, so
I've included that one also in the gcc_assert for this.

  - Remove the

 This and the next should be the only functions called to insert an insn
 once delay slots have been filled since only they know how to update a
 SEQUENCE.

 from the head comment of functions that are now private to emit-rtl.c.

 OK.

Done.

Updated patch attached, similarly tested. OK for trunk?

Ciao!
Steven
PR middle-end/43631
* emit-rtl.c (make_note_raw): New function.
(link_insn_into_chain): New static inline function.
(add_insn): Use it.
(add_insn_before, add_insn_after): Factor insn chain linking code...
(add_insn_before_nobb, add_insn_after_nobb): ...here, new functions
using link_insn_into_chain.
(note_outside_basic_block_p): New helper function for emit_note_after
and emit_note_before.
(emit_note_after): Use nobb variant of add_insn_after if the note
should not be contained in a basic block.
(emit_note_before): Use nobb variant of add_insn_before if the note
should not be contained in a basic block.
(emit_note_copy): Use make_note_raw.
(emit_note): Likewise.
* bb-reorder.c (insert_section_boundary_note): Remove hack to set
BLOCK_FOR_INSN to NULL manually for NOTE_INSN_SWITCH_TEXT_SECTIONS.
* jump.c (cleanup_barriers): Use reorder_insns_nobb to avoid making
the moved barrier the tail of the basic block it follows.
* var-tracking.c (pass_variable_tracking): Add TODO_verify_flow.

Index: emit-rtl.c
===
--- emit-rtl.c  (revision 197942)
+++ emit-rtl.c  (working copy)
@@ -3751,62 +3751,135 @@ make_call_insn_raw (rtx pattern)
 
   return insn;
 }
+
+/* Like `make_insn_raw' but make a NOTE instead of an insn.  */
+
+static rtx
+make_note_raw (enum insn_note subtype)
+{
+  /* Some notes are never created this way at all.  These notes are
+ only created by patching out insns.  */
+  gcc_assert (subtype != NOTE_INSN_DELETED_LABEL
+  subtype != NOTE_INSN_DELETED_DEBUG_LABEL);
+
+  rtx note = rtx_alloc (NOTE);
+  INSN_UID (note) = cur_insn_uid++;
+  NOTE_KIND (note) = subtype;
+  BLOCK_FOR_INSN (note) = NULL;
+  memset (NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
+  return note;
+}
 
+/* Add INSN to the end of the doubly-linked list, between PREV and NEXT.
+   INSN may be any object that can appear in the chain: INSN_P and NOTE_P 
objects,
+   but also BARRIERs and JUMP_TABLE_DATAs.  PREV and NEXT may be NULL.  */
+
+static inline void
+link_insn_into_chain (rtx insn, rtx prev, rtx next)
+{
+  PREV_INSN (insn) = prev;
+  NEXT_INSN (insn) = next;
+  if (prev != NULL)
+{
+  NEXT_INSN (prev) = insn;
+  if (NONJUMP_INSN_P (prev)  GET_CODE (PATTERN (prev)) == SEQUENCE)
+   {
+ rtx sequence = PATTERN (prev);
+ NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
+   }
+}
+  if (next != NULL)
+{
+  PREV_INSN (next) = insn;
+  if (NONJUMP_INSN_P (next)  GET_CODE (PATTERN (next)) == SEQUENCE)
+   PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
+}
+}
+
 /* Add INSN to the end of the doubly-linked list.
INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */
 
 void
 add_insn (rtx insn)
 {
-  PREV_INSN (insn) = get_last_insn();
-  NEXT_INSN (insn) = 0;
-
-  if (NULL != get_last_insn())
-NEXT_INSN (get_last_insn ()) = insn;
-
+  rtx prev = get_last_insn ();
+  link_insn_into_chain (insn, prev, NULL);
   if (NULL == get_insns ())
 set_first_insn (insn);
-
   set_last_insn (insn);
 }
 
-/* Add INSN into the doubly-linked list after insn AFTER.  This and
-   the next should be the only functions called to insert an insn once
-   delay slots have been filled since only 

RE: [PATCH, AArch64] Add/Sub and set flags instructions in extend and shift_extend mode

2013-04-14 Thread Hurugalawadi, Naveen
 If you're going to do it in one file you'll need to use
 scan-assembler-times.

Hi,

Thanks for the suggestion.

Please find attached the modified patch as per your suggestions.
Please review the same and let me know if there should be any 
further modifications in it.

Thanks,
Naveen
--- gcc/config/aarch64/aarch64.md	2013-04-15 09:41:29.711014628 +0530
+++ gcc/config/aarch64/aarch64.md	2013-04-15 09:44:00.327014894 +0530
@@ -1291,6 +1291,78 @@
(set_attr mode SI)]
 )
 
+(define_insn *adds_optabALLX:mode_GPI:mode
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:GPI
+	  (ANY_EXTEND:GPI (match_operand:ALLX 1 register_operand r))
+	  (match_operand:GPI 2 register_operand r))
+	(const_int 0)))
+   (set (match_operand:GPI 0 register_operand =r)
+	(plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
+  
+  adds\\t%GPI:w0, %GPI:w2, %GPI:w1, suxtALLX:size
+  [(set_attr v8type alus_ext)
+   (set_attr mode GPI:MODE)]
+)
+
+(define_insn *subs_optabALLX:mode_GPI:mode
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:GPI (match_operand:GPI 1 register_operand r)
+		(ANY_EXTEND:GPI
+		 (match_operand:ALLX 2 register_operand r)))
+	(const_int 0)))
+   (set (match_operand:GPI 0 register_operand =r)
+	(minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2]
+  
+  subs\\t%GPI:w0, %GPI:w1, %GPI:w2, suxtALLX:size
+  [(set_attr v8type alus_ext)
+   (set_attr mode GPI:MODE)]
+)
+
+(define_insn *adds_optabmode_multp2
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (plus:GPI (ANY_EXTRACT:GPI
+		(mult:GPI (match_operand:GPI 1 register_operand r)
+			  (match_operand 2 aarch64_pwr_imm3 Up3))
+		(match_operand 3 const_int_operand n)
+		(const_int 0))
+		   (match_operand:GPI 4 register_operand r))
+	(const_int 0)))
+   (set (match_operand:GPI 0 register_operand =r)
+	(plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
+   (match_dup 3)
+   (const_int 0))
+		  (match_dup 4)))]
+  aarch64_is_extend_from_extract (MODEmode, operands[2], operands[3])
+  adds\\t%w0, %w4, %w1, suxt%e3 %p2
+  [(set_attr v8type alus_ext)
+   (set_attr mode MODE)]
+)
+
+(define_insn *subs_optabmode_multp2
+  [(set (reg:CC_NZ CC_REGNUM)
+	(compare:CC_NZ
+	 (minus:GPI (match_operand:GPI 4 register_operand r)
+		(ANY_EXTRACT:GPI
+		 (mult:GPI (match_operand:GPI 1 register_operand r)
+			   (match_operand 2 aarch64_pwr_imm3 Up3))
+		 (match_operand 3 const_int_operand n)
+		 (const_int 0)))
+	(const_int 0)))
+   (set (match_operand:GPI 0 register_operand =r)
+	(minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
+  (mult:GPI (match_dup 1) (match_dup 2))
+  (match_dup 3)
+  (const_int 0]
+  aarch64_is_extend_from_extract (MODEmode, operands[2], operands[3])
+  subs\\t%w0, %w4, %w1, suxt%e3 %p2
+  [(set_attr v8type alus_ext)
+   (set_attr mode MODE)]
+)
+
 (define_insn *addmode3nr_compare0
   [(set (reg:CC_NZ CC_REGNUM)
 	(compare:CC_NZ
--- gcc/testsuite/gcc.target/aarch64/adds3.c	1970-01-01 05:30:00.0 +0530
+++ gcc/testsuite/gcc.target/aarch64/adds3.c	2013-04-15 09:48:57.555015416 +0530
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+/* { dg-options -O2 --save-temps } */
+
+extern void abort (void);
+typedef long long s64;
+
+int
+adds_ext (s64 a, int b, int c)
+{
+ s64 d = a + b;
+
+  if (d == 0)
+return a + c;
+  else
+return b + d + c;
+}
+
+int
+adds_shift_ext (s64 a, int b, int c)
+{
+ s64 d = (a + ((s64)b  3));
+
+  if (d == 0)
+return a + c;
+  else
+return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = adds_ext (0x1302ll, 41, 15);
+  if (x != 318767203)
+abort ();
+
+  x = adds_ext (0x50505050ll, 29, 4);
+  if (x != 1347440782)
+abort ();
+
+  x = adds_ext (0x12121212121ll, 2, 14);
+  if (x != 555819315)
+abort ();
+
+  x = adds_shift_ext (0x123456789ll, 4, 12);
+  if (x != 591751097)
+abort ();
+
+  x = adds_shift_ext (0x02020202ll, 9, 8);
+  if (x != 33686107)
+abort ();
+
+  x = adds_shift_ext (0x987987987987ll, 23, 41);
+  if (x != -2020050305)
+abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times adds\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, sxtw 2 } } */
--- gcc/testsuite/gcc.target/aarch64/subs3.c	1970-01-01 05:30:00.0 +0530
+++ gcc/testsuite/gcc.target/aarch64/subs3.c	2013-04-15 09:46:13.931015127 +0530
@@ -0,0 +1,61 @@
+/* { dg-do run } */
+/* { dg-options -O2 --save-temps } */
+
+extern void abort (void);
+typedef long long s64;
+
+int
+subs_ext (s64 a, int b, int c)
+{
+ s64 d = a - b;
+
+  if (d == 0)
+return a + c;
+  else
+return b + d + c;
+}
+
+int
+subs_shift_ext (s64 a, int b, int c)
+{
+ s64 d = (a - ((s64)b  3));
+
+  if (d == 0)
+return a + c;
+  else
+return b + d + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = subs_ext (0x1302ll, 41, 15);
+  if (x != 318767121)
+abort ();
+
+  x = subs_ext (0x50505050ll, 29, 4);
+  if (x != 1347440724)
+abort ();
+
+  x = subs_ext (0x12121212121ll, 2, 14);
+  if (x != 555819311)
+abort ();

RE: [PATCH, AArch64] Compare instruction in shift_extend mode

2013-04-14 Thread Hurugalawadi, Naveen
Hi,

 Same issue as my previous reply applies here.

Thanks for the suggestion.

Please find attached the modified patch as per your suggestions.
Please review the same and let me know if there should be any 
further modifications in it.

Thanks,
Naveen

--- gcc/config/aarch64/aarch64.md	2013-04-15 09:41:29.711014628 +0530
+++ gcc/config/aarch64/aarch64.md	2013-04-15 09:51:08.027015641 +0530
@@ -2205,6 +2205,18 @@
(set_attr mode GPI:MODE)]
 )
 
+(define_insn *cmp_swp_optabALLX:mode_shft_GPI:mode
+  [(set (reg:CC_SWP CC_REGNUM)
+	(compare:CC_SWP (ashift:GPI
+			 (ANY_EXTEND:GPI
+			  (match_operand:ALLX 0 register_operand r))
+			 (match_operand:QI 1 aarch64_shift_imm_mode n))
+	(match_operand:GPI 2 register_operand r)))]
+  
+  cmp\\t%GPI:w2, %GPI:w0, suxtALLX:size %1
+  [(set_attr v8type alus_ext)
+   (set_attr mode GPI:MODE)]
+)
 
 ;; ---
 ;; Store-flag and conditional select insns
--- gcc/testsuite/gcc.target/aarch64/cmp.c	1970-01-01 05:30:00.0 +0530
+++ gcc/testsuite/gcc.target/aarch64/cmp.c	2013-04-15 09:54:29.471015995 +0530
@@ -0,0 +1,135 @@
+/* { dg-do run } */
+/* { dg-options -O2 --save-temps } */
+
+extern void abort (void);
+
+int
+cmp_si_test1 (int a, int b, int c)
+{
+  if (a  b)
+return a + c;
+  else
+return a + b + c;
+}
+
+int
+cmp_si_test2 (int a, int b, int c)
+{
+  if ((a  3)  b)
+return a + c;
+  else
+return a + b + c;
+}
+
+typedef long long s64;
+
+s64
+cmp_di_test1 (s64 a, s64 b, s64 c)
+{
+  if (a  b)
+return a + c;
+  else
+return a + b + c;
+}
+
+s64
+cmp_di_test2 (s64 a, s64 b, s64 c)
+{
+  if ((a  3)  b)
+return a + c;
+  else
+return a + b + c;
+}
+
+int
+cmp_di_test3 (int a, s64 b, s64 c)
+{
+  if (a  b)
+return a + c;
+  else
+return a + b + c;
+}
+
+int
+cmp_di_test4 (int a, s64 b, s64 c)
+{
+  if (((s64)a  3)  b)
+return a + c;
+  else
+return a + b + c;
+}
+
+int main ()
+{
+  int x;
+  s64 y;
+
+  x = cmp_si_test1 (2, 12, 5);
+  if (x != 19)
+abort ();
+
+  x = cmp_si_test1 (1, 2, 32);
+  if (x != 35)
+abort ();
+
+  x = cmp_si_test2 (7, 5, 15);
+  if (x != 27)
+abort ();
+
+  x = cmp_si_test2 (12, 1, 3);
+  if (x != 16)
+abort ();
+
+  y = cmp_di_test1 (0x20202020ll,
+		0x65161611ll,
+		0x42434243ll);
+  if (y != 0xc7797874ll)
+abort ();
+
+  y = cmp_di_test1 (0x1010101010101ll,
+		0x123456789abcdll,
+		0x5ll);
+  if (y != 0x7799bbde00223ll)
+abort ();
+
+  y = cmp_di_test2 (0x31313131ll,
+		0x35466561ll,
+		0x42434243ll);
+  if (y != 0xa8bad8d5ll)
+abort ();
+
+  y = cmp_di_test2 (0x101010101ll,
+		0x123456789ll,
+		0x5ll);
+  if (y != 0x7799bbddfll)
+abort ();
+
+  x = cmp_di_test3 (6252,
+0x64234978ll,
+0x12345123ll);
+  if (x != 1985458951)
+abort ();
+
+  x = cmp_di_test3 (7635,
+0x10101010ll,
+0x21212121ll);
+  if (x != 825315076)
+abort ();
+
+  x = cmp_di_test4 (202,
+0x984210421ll,
+0x18181818181ll);
+  if (x != 94537324)
+abort ();
+
+  x = cmp_di_test4 (167,
+0x987987987987ll,
+0x12312312ll);
+  if (x != -1714840256)
+abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times cmp\tw\[0-9\]+, w\[0-9\]+ 2 } } */
+/* { dg-final { scan-assembler-times cmp\tx\[0-9\]+, x\[0-9\]+ 4 } } */