public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Remove MISALIGNED_INDIRECT_REF
@ 2010-09-03 12:54 Richard Guenther
  2010-09-08  4:20 ` H.J. Lu
  2010-09-30  8:57 ` Ulrich Weigand
  0 siblings, 2 replies; 20+ messages in thread
From: Richard Guenther @ 2010-09-03 12:54 UTC (permalink / raw)
  To: gcc-patches


I need to stop with GIMPLE IL changes, so this is the 
MISALIGNED_INDIRECT_REF removal patch again, which completes the
transition to MEM_REF.

Compared to the previous versions I sent this picks up a patch
from Michael Matz in PR39954 to build aligned variants of a type.
This is needed as we can't really get rid of deriving alignment
information from types - at least I can't see an easy way without
pessimizing too much code.  So the vectorizer, when generating
a misaligned access now adjusts the alignment information in
the SSA_NAME_PTR_INFO struct and uses a type aligned the same
as the vector component type for the respective access.

Which means that this doesn't try to fix the issues with
aligned attributes not working on STRICT_ALIGNMENT targets.

Now all accesses produced by the vectorizer are handled by
induction variable optimization and prefetching.

Bootstrapped and tested on x86_64-unknown-linux-gnu, I'll leave
the patch for comments again until Monday and plan to commit it
at that point.

Thanks,
Richard.

2010-09-02  Richard Guenther  <rguenther@suse.de>

	* tree.def (MISALIGNED_INDIRECT_REF): Remove.
	* tree.h (INDIRECT_REF_P): Only check for INDIRECT_REF.
	(build_aligned_type): Declare.
	* tree.c (check_qualified_type): Also compare TYPE_ALIGN.
	(check_aligned_type): New function.
	(build_aligned_type): Likewise.
	* expr.c (expand_assignment): Handle misaligned stores via
	TARGET_MEM_REF and MEM_REF using movmisalign_optab.
	(expand_expr_real_1): Likewise.
	(safe_from_p): Remove MISALIGNED_INDIRECT_REF handling.
	* tree-vect-stmts.c (vectorizable_store): Do not build
	MISALIGNED_INDIRECT_REF but initialize alignment information.
	(vectorizable_load): Likewise.
	* builtins.c (get_object_alignment): Remove MISALIGNED_INDIRECT_REF
	handling.
	* cfgexpand.c (expand_debug_expr): Likewise.
	* dwarf2out.c (loc_list_from_tree): Likewise.
	* fold-const.c (maybe_lvalue_p): Likewise.
	(operand_equal_p): Likewise.
	(build_fold_addr_expr_with_type_loc): Likewise.
	* gimplify.c (gimplify_addr_expr): Likewise.
	(gimplify_expr): Likewise.
	* tree-cfg.c (verify_types_in_gimple_min_lval): Likewise.
	(verify_gimple_assign_single): Likewise.
	* tree-dump.c (dequeue_and_dump): Likewise.
	(tree_could_trap_p): Likewise.
	* tree-predcom.c (ref_at_iteration): Likewise.
	* tree-pretty-print.c (dump_generic_node): Likewise.
	(op_code_prio): Likewise.
	(op_symbol_code): Likewise.
	* tree-ssa-ccp.c (get_value_from_alignment): Likewise.
	* tree-ssa-loop-im.c (for_each_index): Likewise.
	(gen_lsm_tmp_name): Likewise.
	* tree-ssa-loop-ivopts.c (idx_find_step): Likewise.
	(find_interesting_uses_address): Likewise.
	* tree-ssa-loop-prefetch.c (idx_analyze_ref): Likewise.
	* tree-ssa-operands.c (get_expr_operands): Likewise.
	* tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
	* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
	(ao_ref_init_from_vn_reference): Likewise.
	* tree.c (staticp): Likewise.
	(build1_stat): Likewise.
	(reference_alias_ptr_type): Likewise.
	* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.

	* config/rs6000/rs6000.c (rs6000_check_sdmode): Remove
	MISALIGNED_INDIRECT_REF handling.

Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/cfgexpand.c	2010-09-03 12:27:27.000000000 +0200
*************** expand_debug_expr (tree exp)
*** 2450,2456 ****
  	return NULL;
        /* Fallthru.  */
      case INDIRECT_REF:
-     case MISALIGNED_INDIRECT_REF:
        op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
        if (!op0)
  	return NULL;
--- 2450,2455 ----
Index: trunk/gcc/dwarf2out.c
===================================================================
*** trunk.orig/gcc/dwarf2out.c	2010-09-03 12:10:26.000000000 +0200
--- trunk/gcc/dwarf2out.c	2010-09-03 12:27:27.000000000 +0200
*************** loc_list_from_tree (tree loc, int want_a
*** 15234,15240 ****
  	return 0;
        /* Fallthru.  */
      case INDIRECT_REF:
-     case MISALIGNED_INDIRECT_REF:
        list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
        have_address = 1;
        break;
--- 15234,15239 ----
Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/fold-const.c	2010-09-03 12:27:27.000000000 +0200
*************** maybe_lvalue_p (const_tree x)
*** 2044,2050 ****
    case COMPONENT_REF:
    case MEM_REF:
    case INDIRECT_REF:
-   case MISALIGNED_INDIRECT_REF:
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
    case BIT_FIELD_REF:
--- 2044,2049 ----
*************** operand_equal_p (const_tree arg0, const_
*** 2587,2593 ****
        switch (TREE_CODE (arg0))
  	{
  	case INDIRECT_REF:
- 	case MISALIGNED_INDIRECT_REF:
  	case REALPART_EXPR:
  	case IMAGPART_EXPR:
  	  return OP_SAME (0);
--- 2586,2591 ----
*************** build_fold_addr_expr_with_type_loc (loca
*** 7597,7604 ****
    if (TREE_CODE (t) == WITH_SIZE_EXPR)
      t = TREE_OPERAND (t, 0);
  
!   if (TREE_CODE (t) == INDIRECT_REF
!       || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
      {
        t = TREE_OPERAND (t, 0);
  
--- 7595,7601 ----
    if (TREE_CODE (t) == WITH_SIZE_EXPR)
      t = TREE_OPERAND (t, 0);
  
!   if (TREE_CODE (t) == INDIRECT_REF)
      {
        t = TREE_OPERAND (t, 0);
  
Index: trunk/gcc/gimplify.c
===================================================================
*** trunk.orig/gcc/gimplify.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/gimplify.c	2010-09-03 12:27:27.000000000 +0200
*************** gimplify_addr_expr (tree *expr_p, gimple
*** 4791,4797 ****
    switch (TREE_CODE (op0))
      {
      case INDIRECT_REF:
-     case MISALIGNED_INDIRECT_REF:
      do_indirect_ref:
        /* Check if we are dealing with an expression of the form '&*ptr'.
  	 While the front end folds away '&*ptr' into 'ptr', these
--- 4791,4796 ----
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 6784,6797 ****
  	  recalculate_side_effects (*expr_p);
  	  break;
  
- 	case MISALIGNED_INDIRECT_REF:
- 	  /* We can only reach this through re-gimplification from
- 	     tree optimizers.  */
- 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
- 			       is_gimple_reg, fb_rvalue);
- 	  recalculate_side_effects (*expr_p);
- 	  break;
- 
  	case INDIRECT_REF:
  	  {
  	    bool volatilep = TREE_THIS_VOLATILE (*expr_p);
--- 6783,6788 ----
Index: trunk/gcc/tree-cfg.c
===================================================================
*** trunk.orig/gcc/tree-cfg.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-cfg.c	2010-09-03 12:27:27.000000000 +0200
*************** verify_types_in_gimple_min_lval (tree ex
*** 2921,2928 ****
    if (is_gimple_id (expr))
      return false;
  
!   if (TREE_CODE (expr) != MISALIGNED_INDIRECT_REF
!       && TREE_CODE (expr) != TARGET_MEM_REF
        && TREE_CODE (expr) != MEM_REF)
      {
        error ("invalid expression for min lvalue");
--- 2921,2927 ----
    if (is_gimple_id (expr))
      return false;
  
!   if (TREE_CODE (expr) != TARGET_MEM_REF
        && TREE_CODE (expr) != MEM_REF)
      {
        error ("invalid expression for min lvalue");
*************** verify_gimple_assign_single (gimple stmt
*** 3792,3798 ****
  
      case COMPONENT_REF:
      case BIT_FIELD_REF:
-     case MISALIGNED_INDIRECT_REF:
      case ARRAY_REF:
      case ARRAY_RANGE_REF:
      case VIEW_CONVERT_EXPR:
--- 3791,3796 ----
Index: trunk/gcc/tree-dump.c
===================================================================
*** trunk.orig/gcc/tree-dump.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/tree-dump.c	2010-09-03 12:27:27.000000000 +0200
*************** dequeue_and_dump (dump_info_p di)
*** 572,578 ****
      case TRUTH_NOT_EXPR:
      case ADDR_EXPR:
      case INDIRECT_REF:
-     case MISALIGNED_INDIRECT_REF:
      case CLEANUP_POINT_EXPR:
      case SAVE_EXPR:
      case REALPART_EXPR:
--- 572,577 ----
Index: trunk/gcc/tree-eh.c
===================================================================
*** trunk.orig/gcc/tree-eh.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-eh.c	2010-09-03 12:27:27.000000000 +0200
*************** tree_could_trap_p (tree expr)
*** 2440,2446 ****
  	return false;
        /* Fallthru.  */
      case INDIRECT_REF:
-     case MISALIGNED_INDIRECT_REF:
        return !TREE_THIS_NOTRAP (expr);
  
      case ASM_EXPR:
--- 2440,2445 ----
Index: trunk/gcc/tree-predcom.c
===================================================================
*** trunk.orig/gcc/tree-predcom.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/tree-predcom.c	2010-09-03 12:27:27.000000000 +0200
*************** ref_at_iteration (struct loop *loop, tre
*** 1348,1358 ****
  	   && TREE_CODE (ref) != MEM_REF)
      return unshare_expr (ref);
  
!   if (INDIRECT_REF_P (ref)
!       || TREE_CODE (ref) == MEM_REF)
      {
-       /* Take care for MEM_REF and MISALIGNED_INDIRECT_REF at
-          the same time.  */
        ret = unshare_expr (ref);
        idx = TREE_OPERAND (ref, 0);
        idx_p = &TREE_OPERAND (ret, 0);
--- 1348,1355 ----
  	   && TREE_CODE (ref) != MEM_REF)
      return unshare_expr (ref);
  
!   if (TREE_CODE (ref) == MEM_REF)
      {
        ret = unshare_expr (ref);
        idx = TREE_OPERAND (ref, 0);
        idx_p = &TREE_OPERAND (ret, 0);
Index: trunk/gcc/tree-pretty-print.c
===================================================================
*** trunk.orig/gcc/tree-pretty-print.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-pretty-print.c	2010-09-03 12:27:27.000000000 +0200
*************** dump_generic_node (pretty_printer *buffe
*** 1592,1598 ****
      case ADDR_EXPR:
      case PREDECREMENT_EXPR:
      case PREINCREMENT_EXPR:
-     case MISALIGNED_INDIRECT_REF:
      case INDIRECT_REF:
        if (TREE_CODE (node) == ADDR_EXPR
  	  && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
--- 1592,1597 ----
*************** dump_generic_node (pretty_printer *buffe
*** 1609,1621 ****
  	}
        else
  	dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- 
-       if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF)
-         {
-           pp_string (buffer, "{misalignment: ");
-           dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-           pp_character (buffer, '}');
-         }
        break;
  
      case POSTDECREMENT_EXPR:
--- 1608,1613 ----
*************** op_code_prio (enum tree_code code)
*** 2554,2560 ****
      case PREINCREMENT_EXPR:
      case PREDECREMENT_EXPR:
      case NEGATE_EXPR:
-     case MISALIGNED_INDIRECT_REF:
      case INDIRECT_REF:
      case ADDR_EXPR:
      case FLOAT_EXPR:
--- 2546,2551 ----
*************** op_symbol_code (enum tree_code code)
*** 2724,2732 ****
      case INDIRECT_REF:
        return "*";
  
-     case MISALIGNED_INDIRECT_REF:
-       return "M*";
- 
      case TRUNC_DIV_EXPR:
      case RDIV_EXPR:
        return "/";
--- 2715,2720 ----
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c	2010-09-03 12:27:10.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c	2010-09-03 12:27:27.000000000 +0200
*************** get_value_from_alignment (tree expr)
*** 509,517 ****
    base = get_inner_reference (TREE_OPERAND (expr, 0),
  			      &bitsize, &bitpos, &offset,
  			      &mode, &align, &align, false);
!   if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
!     val = get_value_for_expr (TREE_OPERAND (base, 0), true);
!   else if (TREE_CODE (base) == MEM_REF)
      val = bit_value_binop (PLUS_EXPR, TREE_TYPE (expr),
  			   TREE_OPERAND (base, 0), TREE_OPERAND (base, 1));
    else if (base
--- 509,515 ----
    base = get_inner_reference (TREE_OPERAND (expr, 0),
  			      &bitsize, &bitpos, &offset,
  			      &mode, &align, &align, false);
!   if (TREE_CODE (base) == MEM_REF)
      val = bit_value_binop (PLUS_EXPR, TREE_TYPE (expr),
  			   TREE_OPERAND (base, 0), TREE_OPERAND (base, 1));
    else if (base
Index: trunk/gcc/tree-ssa-loop-im.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-im.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-im.c	2010-09-03 12:27:27.000000000 +0200
*************** for_each_index (tree *addr_p, bool (*cbc
*** 272,278 ****
  	case SSA_NAME:
  	  return cbck (*addr_p, addr_p, data);
  
- 	case MISALIGNED_INDIRECT_REF:
  	case MEM_REF:
  	  nxt = &TREE_OPERAND (*addr_p, 0);
  	  return cbck (*addr_p, nxt, data);
--- 272,277 ----
*************** gen_lsm_tmp_name (tree ref)
*** 1986,1992 ****
  
    switch (TREE_CODE (ref))
      {
-     case MISALIGNED_INDIRECT_REF:
      case MEM_REF:
        gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
        lsm_tmp_name_add ("_");
--- 1985,1990 ----
Index: trunk/gcc/tree-ssa-loop-ivopts.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-ivopts.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-ivopts.c	2010-09-03 12:27:27.000000000 +0200
*************** idx_find_step (tree base, tree *idx, voi
*** 1443,1451 ****
    tree step, iv_base, iv_step, lbound, off;
    struct loop *loop = dta->ivopts_data->current_loop;
  
-   if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
-     return false;
- 
    /* If base is a component ref, require that the offset of the reference
       be invariant.  */
    if (TREE_CODE (base) == COMPONENT_REF)
--- 1443,1448 ----
*************** find_interesting_uses_address (struct iv
*** 1765,1772 ****
  	goto fail;
        step = ifs_ivopts_data.step;
  
-       gcc_assert (TREE_CODE (base) != MISALIGNED_INDIRECT_REF);
- 
        /* Check that the base expression is addressable.  This needs
  	 to be done after substituting bases of IVs into it.  */
        if (may_be_nonaddressable_p (base))
--- 1762,1767 ----
Index: trunk/gcc/tree-ssa-loop-prefetch.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-prefetch.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/tree-ssa-loop-prefetch.c	2010-09-03 12:27:27.000000000 +0200
*************** idx_analyze_ref (tree base, tree *index,
*** 423,431 ****
    HOST_WIDE_INT idelta = 0, imult = 1;
    affine_iv iv;
  
-   if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
-     return false;
- 
    if (!simple_iv (ar_data->loop, loop_containing_stmt (ar_data->stmt),
  		  *index, &iv, true))
      return false;
--- 423,428 ----
Index: trunk/gcc/tree-ssa-operands.c
===================================================================
*** trunk.orig/gcc/tree-ssa-operands.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-ssa-operands.c	2010-09-03 12:27:27.000000000 +0200
*************** mark_address_taken (tree ref)
*** 711,718 ****
  }
  
  
! /* A subroutine of get_expr_operands to handle MEM_REF,
!    MISALIGNED_INDIRECT_REF.
  
     STMT is the statement being processed, EXPR is the MEM_REF
        that got us here.
--- 711,717 ----
  }
  
  
! /* A subroutine of get_expr_operands to handle MEM_REF.
  
     STMT is the statement being processed, EXPR is the MEM_REF
        that got us here.
*************** get_expr_operands (gimple stmt, tree *ex
*** 908,917 ****
        gcc_assert (gimple_debug_bind_p (stmt));
        return;
  
-     case MISALIGNED_INDIRECT_REF:
-       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
-       /* fall through */
- 
      case MEM_REF:
        get_indirect_ref_operands (stmt, expr, flags, true);
        return;
--- 907,912 ----
Index: trunk/gcc/tree-ssa-pre.c
===================================================================
*** trunk.orig/gcc/tree-ssa-pre.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-ssa-pre.c	2010-09-03 12:27:27.000000000 +0200
*************** create_component_ref_by_pieces_1 (basic_
*** 2822,2847 ****
  	return folded;
        }
        break;
-     case MISALIGNED_INDIRECT_REF:
-       {
- 	tree folded;
- 	tree genop1 = create_component_ref_by_pieces_1 (block, ref,
- 							operand,
- 							stmts, domstmt);
- 	if (!genop1)
- 	  return NULL_TREE;
- 	genop1 = fold_convert (build_pointer_type (currop->type),
- 			       genop1);
- 
- 	if (currop->opcode == MISALIGNED_INDIRECT_REF)
- 	  folded = fold_build2 (currop->opcode, currop->type,
- 				genop1, currop->op1);
- 	else
- 	  folded = fold_build1 (currop->opcode, currop->type,
- 				genop1);
- 	return folded;
-       }
-       break;
      case BIT_FIELD_REF:
        {
  	tree folded;
--- 2822,2827 ----
Index: trunk/gcc/tree-ssa-sccvn.c
===================================================================
*** trunk.orig/gcc/tree-ssa-sccvn.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree-ssa-sccvn.c	2010-09-03 12:27:27.000000000 +0200
*************** copy_reference_ops_from_ref (tree ref, V
*** 616,624 ****
  
        switch (temp.opcode)
  	{
- 	case MISALIGNED_INDIRECT_REF:
- 	  temp.op0 = TREE_OPERAND (ref, 1);
- 	  break;
  	case MEM_REF:
  	  /* The base address gets its own vn_reference_op_s structure.  */
  	  temp.op0 = TREE_OPERAND (ref, 1);
--- 616,621 ----
*************** ao_ref_init_from_vn_reference (ao_ref *r
*** 801,812 ****
  	  return false;
  
  	/* Record the base objects.  */
- 	case MISALIGNED_INDIRECT_REF:
- 	  *op0_p = build2 (MISALIGNED_INDIRECT_REF, op->type,
- 			   NULL_TREE, op->op0);
- 	  op0_p = &TREE_OPERAND (*op0_p, 0);
- 	  break;
- 
  	case MEM_REF:
  	  base_alias_set = get_deref_alias_set (op->op0);
  	  *op0_p = build2 (MEM_REF, op->type,
--- 798,803 ----
Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree.c	2010-09-03 13:14:37.000000000 +0200
*************** staticp (tree arg)
*** 2434,2440 ****
      case BIT_FIELD_REF:
        return NULL;
  
-     case MISALIGNED_INDIRECT_REF:
      case INDIRECT_REF:
        return TREE_CONSTANT (TREE_OPERAND (arg, 0)) ? arg : NULL;
  
--- 2434,2439 ----
*************** build1_stat (enum tree_code code, tree t
*** 3660,3666 ****
        TREE_READONLY (t) = 0;
        break;
  
-     case MISALIGNED_INDIRECT_REF:
      case INDIRECT_REF:
        /* Whether a dereference is readonly has nothing to do with whether
  	 its operand is readonly.  */
--- 3659,3664 ----
*************** reference_alias_ptr_type (const_tree t)
*** 3929,3936 ****
      return TREE_TYPE (TREE_OPERAND (base, 1));
    else if (TREE_CODE (base) == TARGET_MEM_REF)
      return TREE_TYPE (TMR_OFFSET (base)); 
-   else if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
-     return NULL_TREE;
    else
      return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base)));
  }
--- 3927,3932 ----
*************** check_qualified_type (const_tree cand, c
*** 5564,5569 ****
--- 5560,5582 ----
  	  && TYPE_NAME (cand) == TYPE_NAME (base)
  	  /* Apparently this is needed for Objective-C.  */
  	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
+ 	  /* Check alignment.  */
+ 	  && TYPE_ALIGN (cand) == TYPE_ALIGN (base)
+ 	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
+ 				   TYPE_ATTRIBUTES (base)));
+ }
+ 
+ /* Returns true iff CAND is equivalent to BASE with ALIGN.  */
+ 
+ static bool
+ check_aligned_type (const_tree cand, const_tree base, unsigned int align)
+ {
+   return (TYPE_QUALS (cand) == TYPE_QUALS (base)
+ 	  && TYPE_NAME (cand) == TYPE_NAME (base)
+ 	  /* Apparently this is needed for Objective-C.  */
+ 	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
+ 	  /* Check alignment.  */
+ 	  && TYPE_ALIGN (cand) == align
  	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
  				   TYPE_ATTRIBUTES (base)));
  }
*************** build_qualified_type (tree type, int typ
*** 5623,5628 ****
--- 5636,5662 ----
  
    return t;
  }
+ 
+ /* Create a variant of type T with alignment ALIGN.  */
+ 
+ tree
+ build_aligned_type (tree type, unsigned int align)
+ {
+   tree t;
+ 
+   if (TYPE_PACKED (type)
+       || TYPE_ALIGN (type) == align)
+     return type;
+ 
+   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+     if (check_aligned_type (t, type, align))
+       return t;
+ 
+   t = build_variant_type_copy (type);
+   TYPE_ALIGN (t) = align;
+ 
+   return t;
+ }
  
  /* Create a new distinct copy of TYPE.  The new type is made its own
     MAIN_VARIANT. If TYPE requires structural equality checks, the
Index: trunk/gcc/tree.def
===================================================================
*** trunk.orig/gcc/tree.def	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree.def	2010-09-03 12:27:27.000000000 +0200
*************** DEFTREECODE (ARRAY_REF, "array_ref", tcc
*** 414,433 ****
     of the range is taken from the type of the expression.  */
  DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", tcc_reference, 4)
  
- /* The ordering of the following codes is optimized for the checking
-    macros in tree.h.  Changing the order will degrade the speed of the
-    compiler.  INDIRECT_REF, MISALIGNED_INDIRECT_REF.  */
- 
  /* C unary `*' or Pascal `^'.  One operand, an expression for a pointer.  */
  DEFTREECODE (INDIRECT_REF, "indirect_ref", tcc_reference, 1)
  
- /* Same as INDIRECT_REF, but also specifies the alignment of the referenced
-    address:
-    Operand 0 is the referenced address (a pointer);
-    Operand 1 is an INTEGER_CST which represents the alignment of the address,
-    or 0 if the alignment is unknown.  */
- DEFTREECODE (MISALIGNED_INDIRECT_REF, "misaligned_indirect_ref", tcc_reference, 2)
- 
  /* Used to represent lookup in a virtual method table which is dependent on
     the runtime type of an object.  Operands are:
     OBJ_TYPE_REF_EXPR: An expression that evaluates the value to use.
--- 414,422 ----
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/tree.h	2010-09-03 13:00:51.000000000 +0200
*************** extern const enum tree_code_class tree_c
*** 117,124 ****
     ascending code order.  */
  
  #define INDIRECT_REF_P(CODE)\
!   (TREE_CODE (CODE) == INDIRECT_REF \
!    || TREE_CODE (CODE) == MISALIGNED_INDIRECT_REF)
  
  /* Nonzero if CODE represents a reference.  */
  
--- 117,123 ----
     ascending code order.  */
  
  #define INDIRECT_REF_P(CODE)\
!   (TREE_CODE (CODE) == INDIRECT_REF)
  
  /* Nonzero if CODE represents a reference.  */
  
*************** struct GTY(()) tree_common {
*** 602,608 ****
             all types
  
         TREE_THIS_NOTRAP in
!           (ALIGN/MISALIGNED_)INDIRECT_REF, ARRAY_REF, ARRAY_RANGE_REF
  
     deprecated_flag:
  
--- 601,607 ----
             all types
  
         TREE_THIS_NOTRAP in
!           INDIRECT_REF, ARRAY_REF, ARRAY_RANGE_REF
  
     deprecated_flag:
  
*************** extern void omp_clause_range_check_faile
*** 1250,1257 ****
  /* Nonzero means this node will not trap.  In an INDIRECT_REF, means
     accessing the memory pointed to won't generate a trap.  However,
     this only applies to an object when used appropriately: it doesn't
!    mean that writing a READONLY mem won't trap. Similarly for
!    MISALIGNED_INDIRECT_REF.
  
     In ARRAY_REF and ARRAY_RANGE_REF means that we know that the index
     (or slice of the array) always belongs to the range of the array.
--- 1249,1255 ----
  /* Nonzero means this node will not trap.  In an INDIRECT_REF, means
     accessing the memory pointed to won't generate a trap.  However,
     this only applies to an object when used appropriately: it doesn't
!    mean that writing a READONLY mem won't trap.
  
     In ARRAY_REF and ARRAY_RANGE_REF means that we know that the index
     (or slice of the array) always belongs to the range of the array.
*************** extern tree get_qualified_type (tree, in
*** 4306,4311 ****
--- 4304,4313 ----
  
  extern tree build_qualified_type (tree, int);
  
+ /* Create a variant of type T with alignment ALIGN.  */
+ 
+ extern tree build_aligned_type (tree, unsigned int);
+ 
  /* Like build_qualified_type, but only deals with the `const' and
     `volatile' qualifiers.  This interface is retained for backwards
     compatibility with the various front-ends; new code should use
Index: trunk/gcc/config/rs6000/rs6000.c
===================================================================
*** trunk.orig/gcc/config/rs6000/rs6000.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/config/rs6000/rs6000.c	2010-09-03 12:27:27.000000000 +0200
*************** rs6000_check_sdmode (tree *tp, int *walk
*** 14138,14144 ****
      case SSA_NAME:
      case REAL_CST:
      case MEM_REF:
-     case MISALIGNED_INDIRECT_REF:
      case VIEW_CONVERT_EXPR:
        if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
  	return *tp;
--- 14138,14143 ----
Index: trunk/gcc/emit-rtl.c
===================================================================
*** trunk.orig/gcc/emit-rtl.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/emit-rtl.c	2010-09-03 12:27:27.000000000 +0200
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1620,1634 ****
         type in all cases.  */
      align = MAX (align, TYPE_ALIGN (type));
  
-   else if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
-     {
-       if (integer_zerop (TREE_OPERAND (t, 1)))
- 	/* We don't know anything about the alignment.  */
- 	align = BITS_PER_UNIT;
-       else
- 	align = tree_low_cst (TREE_OPERAND (t, 1), 1);
-     }
- 
    /* If the size is known, we can set that.  */
    if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
      size = GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1));
--- 1620,1625 ----
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1782,1789 ****
  	    }
  
  	  /* If this is an indirect reference, record it.  */
! 	  else if (TREE_CODE (t) == MEM_REF 
! 		   || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
  	    {
  	      expr = t;
  	      offset = const0_rtx;
--- 1773,1779 ----
  	    }
  
  	  /* If this is an indirect reference, record it.  */
! 	  else if (TREE_CODE (t) == MEM_REF)
  	    {
  	      expr = t;
  	      offset = const0_rtx;
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1793,1800 ****
  
        /* If this is an indirect reference, record it.  */
        else if (TREE_CODE (t) == MEM_REF 
! 	       || TREE_CODE (t) == TARGET_MEM_REF
! 	       || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
  	{
  	  expr = t;
  	  offset = const0_rtx;
--- 1783,1789 ----
  
        /* If this is an indirect reference, record it.  */
        else if (TREE_CODE (t) == MEM_REF 
! 	       || TREE_CODE (t) == TARGET_MEM_REF)
  	{
  	  expr = t;
  	  offset = const0_rtx;
Index: trunk/gcc/expr.c
===================================================================
*** trunk.orig/gcc/expr.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/expr.c	2010-09-03 13:07:37.000000000 +0200
*************** expand_assignment (tree to, tree from, b
*** 4151,4156 ****
--- 4151,4158 ----
  {
    rtx to_rtx = 0;
    rtx result;
+   enum machine_mode mode;
+   int align, icode;
  
    /* Don't crash if the lhs of the assignment was erroneous.  */
    if (TREE_CODE (to) == ERROR_MARK)
*************** expand_assignment (tree to, tree from, b
*** 4163,4168 ****
--- 4165,4232 ----
    if (operand_equal_p (to, from, 0))
      return;
  
+   mode = TYPE_MODE (TREE_TYPE (to));
+   if ((TREE_CODE (to) == MEM_REF
+        || TREE_CODE (to) == TARGET_MEM_REF)
+       && mode != BLKmode
+       && ((align = MAX (TYPE_ALIGN (TREE_TYPE (to)),
+ 			get_object_alignment (to, BIGGEST_ALIGNMENT)))
+ 	  < (signed) GET_MODE_ALIGNMENT (mode))
+       && ((icode = optab_handler (movmisalign_optab, mode))
+ 	  != CODE_FOR_nothing))
+     {
+       enum machine_mode address_mode, op_mode1;
+       rtx insn, reg, op0, mem;
+ 
+       reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+       reg = force_not_mem (reg);
+ 
+       if (TREE_CODE (to) == MEM_REF)
+ 	{
+ 	  addr_space_t as
+ 	      = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 1))));
+ 	  tree base = TREE_OPERAND (to, 0);
+ 	  address_mode = targetm.addr_space.address_mode (as);
+ 	  op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ 	  op0 = convert_memory_address_addr_space (address_mode, op0, as);
+ 	  if (!integer_zerop (TREE_OPERAND (to, 1)))
+ 	    {
+ 	      rtx off
+ 		  = immed_double_int_const (mem_ref_offset (to), address_mode);
+ 	      op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
+ 	    }
+ 	  op0 = memory_address_addr_space (mode, op0, as);
+ 	  mem = gen_rtx_MEM (mode, op0);
+ 	  set_mem_attributes (mem, to, 0);
+ 	  set_mem_addr_space (mem, as);
+ 	}
+       else if (TREE_CODE (to) == TARGET_MEM_REF)
+ 	{
+ 	  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (to));
+ 	  struct mem_address addr;
+ 
+ 	  get_address_description (to, &addr);
+ 	  op0 = addr_for_mem_ref (&addr, as, true);
+ 	  op0 = memory_address_addr_space (mode, op0, as);
+ 	  mem = gen_rtx_MEM (mode, op0);
+ 	  set_mem_attributes (mem, to, 0);
+ 	  set_mem_addr_space (mem, as);
+ 	}
+       else
+ 	gcc_unreachable ();
+       if (TREE_THIS_VOLATILE (to))
+ 	MEM_VOLATILE_P (mem) = 1;
+ 
+       op_mode1 = insn_data[icode].operand[1].mode;
+       if (! (*insn_data[icode].operand[1].predicate) (reg, op_mode1)
+ 	  && op_mode1 != VOIDmode)
+ 	reg = copy_to_mode_reg (op_mode1, reg);
+ 
+       insn = GEN_FCN (icode) (mem, reg);
+       emit_insn (insn);
+       return;
+     }
+ 
    /* Assignment of a structure component needs special treatment
       if the structure component's rtx is not simply a MEM.
       Assignment of an array element at a constant index, and assignment of
*************** expand_assignment (tree to, tree from, b
*** 4297,4337 ****
        return;
      }
  
-    else if (TREE_CODE (to) == MISALIGNED_INDIRECT_REF)
-      {
-        addr_space_t as = ADDR_SPACE_GENERIC;
-        enum machine_mode mode, op_mode1;
-        enum insn_code icode;
-        rtx reg, addr, mem, insn;
- 
-        if (POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (to, 0))))
- 	 as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 0))));
- 
-        reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-        reg = force_not_mem (reg);
- 
-        mode = TYPE_MODE (TREE_TYPE (to));
-        addr = expand_expr (TREE_OPERAND (to, 0), NULL_RTX, VOIDmode,
-                          EXPAND_SUM);
-        addr = memory_address_addr_space (mode, addr, as);
-        mem = gen_rtx_MEM (mode, addr);
- 
-        set_mem_attributes (mem, to, 0);
-        set_mem_addr_space (mem, as);
- 
-        icode = optab_handler (movmisalign_optab, mode);
-        gcc_assert (icode != CODE_FOR_nothing);
- 
-        op_mode1 = insn_data[icode].operand[1].mode;
-        if (! (*insn_data[icode].operand[1].predicate) (reg, op_mode1)
-            && op_mode1 != VOIDmode)
-          reg = copy_to_mode_reg (op_mode1, reg);
- 
-       insn = GEN_FCN (icode) (mem, reg);
-        emit_insn (insn);
-        return;
-      }
- 
    /* If the rhs is a function call and its value is not an aggregate,
       call the function before we start to compute the lhs.
       This is needed for correct code for cases such as
--- 4361,4366 ----
*************** safe_from_p (const_rtx x, tree exp, int
*** 6659,6666 ****
  	    }
  	  break;
  
! 	case MISALIGNED_INDIRECT_REF:
! 	case INDIRECT_REF:
  	  if (MEM_P (x)
  	      && alias_sets_conflict_p (MEM_ALIAS_SET (x),
  					get_alias_set (exp)))
--- 6688,6694 ----
  	    }
  	  break;
  
! 	case MEM_REF:
  	  if (MEM_P (x)
  	      && alias_sets_conflict_p (MEM_ALIAS_SET (x),
  					get_alias_set (exp)))
*************** expand_expr_real_1 (tree exp, rtx target
*** 8598,8643 ****
  
        return expand_constructor (exp, target, modifier, false);
  
!     case MISALIGNED_INDIRECT_REF:
!     case INDIRECT_REF:
        {
! 	tree exp1 = treeop0;
! 	addr_space_t as = ADDR_SPACE_GENERIC;
! 
! 	if (modifier != EXPAND_WRITE)
! 	  {
! 	    tree t;
! 
! 	    t = fold_read_from_constant_string (exp);
! 	    if (t)
! 	      return expand_expr (t, target, tmode, modifier);
! 	  }
! 
! 	if (POINTER_TYPE_P (TREE_TYPE (exp1)))
! 	  as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp1)));
  
! 	op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
  	op0 = memory_address_addr_space (mode, op0, as);
- 
  	temp = gen_rtx_MEM (mode, op0);
- 
  	set_mem_attributes (temp, exp, 0);
  	set_mem_addr_space (temp, as);
! 
! 	/* Resolve the misalignment now, so that we don't have to remember
! 	   to resolve it later.  Of course, this only works for reads.  */
! 	if (code == MISALIGNED_INDIRECT_REF)
  	  {
- 	    int icode;
  	    rtx reg, insn;
  
- 	    gcc_assert (modifier == EXPAND_NORMAL
- 			|| modifier == EXPAND_STACK_PARM);
- 
- 	    /* The vectorizer should have already checked the mode.  */
- 	    icode = optab_handler (movmisalign_optab, mode);
- 	    gcc_assert (icode != CODE_FOR_nothing);
- 
  	    /* We've already validated the memory, and we're creating a
  	       new pseudo destination.  The predicates really can't fail.  */
  	    reg = gen_reg_rtx (mode);
--- 8626,8654 ----
  
        return expand_constructor (exp, target, modifier, false);
  
!     case TARGET_MEM_REF:
        {
! 	addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
! 	struct mem_address addr;
! 	int icode, align;
  
! 	get_address_description (exp, &addr);
! 	op0 = addr_for_mem_ref (&addr, as, true);
  	op0 = memory_address_addr_space (mode, op0, as);
  	temp = gen_rtx_MEM (mode, op0);
  	set_mem_attributes (temp, exp, 0);
  	set_mem_addr_space (temp, as);
! 	align = MAX (TYPE_ALIGN (TREE_TYPE (exp)),
! 		     get_object_alignment (exp, BIGGEST_ALIGNMENT));
! 	if (mode != BLKmode
! 	    && (unsigned) align < GET_MODE_ALIGNMENT (mode)
! 	    /* If the target does not have special handling for unaligned
! 	       loads of mode then it can use regular moves for them.  */
! 	    && ((icode = optab_handler (movmisalign_optab, mode))
! 		!= CODE_FOR_nothing))
  	  {
  	    rtx reg, insn;
  
  	    /* We've already validated the memory, and we're creating a
  	       new pseudo destination.  The predicates really can't fail.  */
  	    reg = gen_reg_rtx (mode);
*************** expand_expr_real_1 (tree exp, rtx target
*** 8648,8671 ****
  
  	    return reg;
  	  }
- 
  	return temp;
        }
  
-     case TARGET_MEM_REF:
-       {
- 	addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
- 	struct mem_address addr;
- 
- 	get_address_description (exp, &addr);
- 	op0 = addr_for_mem_ref (&addr, as, true);
- 	op0 = memory_address_addr_space (mode, op0, as);
- 	temp = gen_rtx_MEM (mode, op0);
- 	set_mem_attributes (temp, exp, 0);
- 	set_mem_addr_space (temp, as);
-       }
-       return temp;
- 
      case MEM_REF:
        {
  	addr_space_t as
--- 8659,8667 ----
*************** expand_expr_real_1 (tree exp, rtx target
*** 8673,8678 ****
--- 8669,8675 ----
  	enum machine_mode address_mode;
  	tree base = TREE_OPERAND (exp, 0);
  	gimple def_stmt;
+ 	int icode, align;
  	/* Handle expansion of non-aliased memory with non-BLKmode.  That
  	   might end up in a register.  */
  	if (TREE_CODE (base) == ADDR_EXPR)
*************** expand_expr_real_1 (tree exp, rtx target
*** 8717,8725 ****
  	address_mode = targetm.addr_space.address_mode (as);
  	base = TREE_OPERAND (exp, 0);
  	if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
! 	  base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
! 			 gimple_assign_rhs1 (def_stmt),
! 			 gimple_assign_rhs2 (def_stmt));
  	op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL);
  	op0 = convert_memory_address_addr_space (address_mode, op0, as);
  	if (!integer_zerop (TREE_OPERAND (exp, 1)))
--- 8714,8727 ----
  	address_mode = targetm.addr_space.address_mode (as);
  	base = TREE_OPERAND (exp, 0);
  	if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
! 	  {
! 	    tree mask = gimple_assign_rhs2 (def_stmt);
! 	    base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
! 			   gimple_assign_rhs1 (def_stmt), mask);
! 	    TREE_OPERAND (exp, 0) = base;
! 	  }
! 	align = MAX (TYPE_ALIGN (TREE_TYPE (exp)),
! 		     get_object_alignment (exp, BIGGEST_ALIGNMENT));
  	op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL);
  	op0 = convert_memory_address_addr_space (address_mode, op0, as);
  	if (!integer_zerop (TREE_OPERAND (exp, 1)))
*************** expand_expr_real_1 (tree exp, rtx target
*** 8734,8739 ****
--- 8736,8760 ----
  	set_mem_addr_space (temp, as);
  	if (TREE_THIS_VOLATILE (exp))
  	  MEM_VOLATILE_P (temp) = 1;
+ 	if (mode != BLKmode
+ 	    && (unsigned) align < GET_MODE_ALIGNMENT (mode)
+ 	    /* If the target does not have special handling for unaligned
+ 	       loads of mode then it can use regular moves for them.  */
+ 	    && ((icode = optab_handler (movmisalign_optab, mode))
+ 		!= CODE_FOR_nothing))
+ 	  {
+ 	    rtx reg, insn;
+ 
+ 	    /* We've already validated the memory, and we're creating a
+ 	       new pseudo destination.  The predicates really can't fail.  */
+ 	    reg = gen_reg_rtx (mode);
+ 
+ 	    /* Nor can the insn generator.  */
+ 	    insn = GEN_FCN (icode) (reg, temp);
+ 	    emit_insn (insn);
+ 
+ 	    return reg;
+ 	  }
  	return temp;
        }
  
Index: trunk/gcc/tree-vect-stmts.c
===================================================================
*** trunk.orig/gcc/tree-vect-stmts.c	2010-09-02 15:40:50.000000000 +0200
--- trunk/gcc/tree-vect-stmts.c	2010-09-03 13:05:49.000000000 +0200
*************** vectorizable_store (gimple stmt, gimple_
*** 3347,3352 ****
--- 3347,3354 ----
        next_stmt = first_stmt;
        for (i = 0; i < vec_num; i++)
  	{
+ 	  struct ptr_info_def *pi;
+ 
  	  if (i > 0)
  	    /* Bump the vector pointer.  */
  	    dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
*************** vectorizable_store (gimple stmt, gimple_
*** 3359,3376 ****
  	       vect_permute_store_chain().  */
  	    vec_oprnd = VEC_index (tree, result_chain, i);
  
            if (aligned_access_p (first_dr))
! 	    data_ref
! 	      = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
! 			build_int_cst (reference_alias_ptr_type
! 				         (DR_REF (first_dr)), 0));
!           else
!           {
!             int mis = DR_MISALIGNMENT (first_dr);
!             tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
!             tmis = size_binop (MULT_EXPR, tmis, size_int (BITS_PER_UNIT));
!             data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, dataref_ptr, tmis);
!            }
  
  	  /* Arguments are ready. Create the new vector stmt.  */
  	  new_stmt = gimple_build_assign (data_ref, vec_oprnd);
--- 3361,3388 ----
  	       vect_permute_store_chain().  */
  	    vec_oprnd = VEC_index (tree, result_chain, i);
  
+ 	  data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
+ 			     build_int_cst (reference_alias_ptr_type
+ 					    (DR_REF (first_dr)), 0));
+ 	  pi = get_ptr_info (dataref_ptr);
+ 	  pi->align = TYPE_ALIGN_UNIT (vectype);
            if (aligned_access_p (first_dr))
! 	    pi->misalign = 0;
!           else if (DR_MISALIGNMENT (first_dr) == -1)
! 	    {
! 	      TREE_TYPE (data_ref)
! 		= build_aligned_type (TREE_TYPE (data_ref),
! 				      TYPE_ALIGN (TREE_TYPE (vectype)));
! 	      pi->align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
! 	      pi->misalign = 0;
! 	    }
! 	  else
! 	    {
! 	      TREE_TYPE (data_ref)
! 		= build_aligned_type (TREE_TYPE (data_ref),
! 				      TYPE_ALIGN (TREE_TYPE (vectype)));
! 	      pi->misalign = DR_MISALIGNMENT (first_dr);
! 	    }
  
  	  /* Arguments are ready. Create the new vector stmt.  */
  	  new_stmt = gimple_build_assign (data_ref, vec_oprnd);
*************** vectorizable_load (gimple stmt, gimple_s
*** 3735,3754 ****
  	  switch (alignment_support_scheme)
  	    {
  	    case dr_aligned:
- 	      gcc_assert (aligned_access_p (first_dr));
- 	      data_ref
- 		= build2 (MEM_REF, vectype, dataref_ptr,
- 			  build_int_cst (reference_alias_ptr_type
- 					   (DR_REF (first_dr)), 0));
- 	      break;
  	    case dr_unaligned_supported:
  	      {
! 		int mis = DR_MISALIGNMENT (first_dr);
! 		tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
! 
! 		tmis = size_binop (MULT_EXPR, tmis, size_int(BITS_PER_UNIT));
! 		data_ref =
! 		  build2 (MISALIGNED_INDIRECT_REF, vectype, dataref_ptr, tmis);
  		break;
  	      }
  	    case dr_explicit_realign:
--- 3747,3781 ----
  	  switch (alignment_support_scheme)
  	    {
  	    case dr_aligned:
  	    case dr_unaligned_supported:
  	      {
! 		struct ptr_info_def *pi;
! 		data_ref
! 		  = build2 (MEM_REF, vectype, dataref_ptr,
! 			    build_int_cst (reference_alias_ptr_type
! 					   (DR_REF (first_dr)), 0));
! 		pi = get_ptr_info (dataref_ptr);
! 		pi->align = TYPE_ALIGN_UNIT (vectype);
! 		if (alignment_support_scheme == dr_aligned)
! 		  {
! 		    gcc_assert (aligned_access_p (first_dr));
! 		    pi->misalign = 0;
! 		  }
! 		else if (DR_MISALIGNMENT (first_dr) == -1)
! 		  {
! 		    TREE_TYPE (data_ref)
! 		      = build_aligned_type (TREE_TYPE (data_ref),
! 					    TYPE_ALIGN (TREE_TYPE (vectype)));
! 		    pi->align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
! 		    pi->misalign = 0;
! 		  }
! 		else
! 		  {
! 		    TREE_TYPE (data_ref)
! 		      = build_aligned_type (TREE_TYPE (data_ref),
! 					    TYPE_ALIGN (TREE_TYPE (vectype)));
! 		    pi->misalign = DR_MISALIGNMENT (first_dr);
! 		  }
  		break;
  	      }
  	    case dr_explicit_realign:
Index: trunk/gcc/builtins.c
===================================================================
*** trunk.orig/gcc/builtins.c	2010-09-03 11:51:23.000000000 +0200
--- trunk/gcc/builtins.c	2010-09-03 12:27:27.000000000 +0200
*************** get_object_alignment (tree exp, unsigned
*** 301,311 ****
      align = TYPE_ALIGN (TREE_TYPE (exp));
    else if (TREE_CODE (exp) == INDIRECT_REF)
      align = TYPE_ALIGN (TREE_TYPE (exp));
-   else if (TREE_CODE (exp) == MISALIGNED_INDIRECT_REF)
-     {
-       tree op1 = TREE_OPERAND (exp, 1);
-       align = integer_zerop (op1) ? BITS_PER_UNIT : TREE_INT_CST_LOW (op1);
-     }
    else if (TREE_CODE (exp) == MEM_REF)
      {
        tree addr = TREE_OPERAND (exp, 0);
--- 301,306 ----

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-03 12:54 [PATCH] Remove MISALIGNED_INDIRECT_REF Richard Guenther
@ 2010-09-08  4:20 ` H.J. Lu
  2010-10-31 19:14   ` H.J. Lu
  2010-09-30  8:57 ` Ulrich Weigand
  1 sibling, 1 reply; 20+ messages in thread
From: H.J. Lu @ 2010-09-08  4:20 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

On Fri, Sep 3, 2010 at 5:51 AM, Richard Guenther <rguenther@suse.de> wrote:
>
> I need to stop with GIMPLE IL changes, so this is the
> MISALIGNED_INDIRECT_REF removal patch again, which completes the
> transition to MEM_REF.
>
> Compared to the previous versions I sent this picks up a patch
> from Michael Matz in PR39954 to build aligned variants of a type.
> This is needed as we can't really get rid of deriving alignment
> information from types - at least I can't see an easy way without
> pessimizing too much code.  So the vectorizer, when generating
> a misaligned access now adjusts the alignment information in
> the SSA_NAME_PTR_INFO struct and uses a type aligned the same
> as the vector component type for the respective access.
>
> Which means that this doesn't try to fix the issues with
> aligned attributes not working on STRICT_ALIGNMENT targets.
>
> Now all accesses produced by the vectorizer are handled by
> induction variable optimization and prefetching.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, I'll leave
> the patch for comments again until Monday and plan to commit it
> at that point.
>
> Thanks,
> Richard.
>
> 2010-09-02  Richard Guenther  <rguenther@suse.de>
>
>        * tree.def (MISALIGNED_INDIRECT_REF): Remove.
>        * tree.h (INDIRECT_REF_P): Only check for INDIRECT_REF.
>        (build_aligned_type): Declare.
>        * tree.c (check_qualified_type): Also compare TYPE_ALIGN.
>        (check_aligned_type): New function.
>        (build_aligned_type): Likewise.
>        * expr.c (expand_assignment): Handle misaligned stores via
>        TARGET_MEM_REF and MEM_REF using movmisalign_optab.
>        (expand_expr_real_1): Likewise.
>        (safe_from_p): Remove MISALIGNED_INDIRECT_REF handling.
>        * tree-vect-stmts.c (vectorizable_store): Do not build
>        MISALIGNED_INDIRECT_REF but initialize alignment information.
>        (vectorizable_load): Likewise.
>        * builtins.c (get_object_alignment): Remove MISALIGNED_INDIRECT_REF
>        handling.
>        * cfgexpand.c (expand_debug_expr): Likewise.
>        * dwarf2out.c (loc_list_from_tree): Likewise.
>        * fold-const.c (maybe_lvalue_p): Likewise.
>        (operand_equal_p): Likewise.
>        (build_fold_addr_expr_with_type_loc): Likewise.
>        * gimplify.c (gimplify_addr_expr): Likewise.
>        (gimplify_expr): Likewise.
>        * tree-cfg.c (verify_types_in_gimple_min_lval): Likewise.
>        (verify_gimple_assign_single): Likewise.
>        * tree-dump.c (dequeue_and_dump): Likewise.
>        (tree_could_trap_p): Likewise.
>        * tree-predcom.c (ref_at_iteration): Likewise.
>        * tree-pretty-print.c (dump_generic_node): Likewise.
>        (op_code_prio): Likewise.
>        (op_symbol_code): Likewise.
>        * tree-ssa-ccp.c (get_value_from_alignment): Likewise.
>        * tree-ssa-loop-im.c (for_each_index): Likewise.
>        (gen_lsm_tmp_name): Likewise.
>        * tree-ssa-loop-ivopts.c (idx_find_step): Likewise.
>        (find_interesting_uses_address): Likewise.
>        * tree-ssa-loop-prefetch.c (idx_analyze_ref): Likewise.
>        * tree-ssa-operands.c (get_expr_operands): Likewise.
>        * tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
>        * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
>        (ao_ref_init_from_vn_reference): Likewise.
>        * tree.c (staticp): Likewise.
>        (build1_stat): Likewise.
>        (reference_alias_ptr_type): Likewise.
>        * emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
>
>        * config/rs6000/rs6000.c (rs6000_check_sdmode): Remove
>        MISALIGNED_INDIRECT_REF handling.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45589


-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-03 12:54 [PATCH] Remove MISALIGNED_INDIRECT_REF Richard Guenther
  2010-09-08  4:20 ` H.J. Lu
@ 2010-09-30  8:57 ` Ulrich Weigand
  2010-09-30 13:45   ` Richard Guenther
  2010-09-30 18:02   ` Eric Botcazou
  1 sibling, 2 replies; 20+ messages in thread
From: Ulrich Weigand @ 2010-09-30  8:57 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

Richard Guenther wrote:

> *************** expand_expr_real_1 (tree exp, rtx target
> *** 8734,8739 ****
> --- 8736,8760 ----
>   	set_mem_addr_space (temp, as);
>   	if (TREE_THIS_VOLATILE (exp))
>   	  MEM_VOLATILE_P (temp) = 1;
> + 	if (mode != BLKmode
> + 	    && (unsigned) align < GET_MODE_ALIGNMENT (mode)
> + 	    /* If the target does not have special handling for unaligned
> + 	       loads of mode then it can use regular moves for them.  */
> + 	    && ((icode = optab_handler (movmisalign_optab, mode))
> + 		!= CODE_FOR_nothing))
> + 	  {
> + 	    rtx reg, insn;
> + 
> + 	    /* We've already validated the memory, and we're creating a
> + 	       new pseudo destination.  The predicates really can't fail.  */
> + 	    reg = gen_reg_rtx (mode);
> + 
> + 	    /* Nor can the insn generator.  */
> + 	    insn = GEN_FCN (icode) (reg, temp);
> + 	    emit_insn (insn);
> + 
> + 	    return reg;
> + 	  }

In experimenting with a STRICT_ALIGNMENT target, I noticed that
the MEM rtx passed to the movmisalign expander sometimes has the
default mode alignment, even though this is not true (that's why
we need to use movmisalign in the first place).

This is caused by this sequence:

        temp = gen_rtx_MEM (mode, op0);
        set_mem_attributes (temp, exp, 0);

The naked MEM has no MEM_ATTRS structure.  According to the default
rules for STRICT_ALIGNMENT, this implies that MEM_ALIGN returns the
mode alignment:

/* For a MEM rtx, the alignment in bits.  We can use the alignment of the
   mode as a default when STRICT_ALIGNMENT, but not if not.  */
#define MEM_ALIGN(RTX)                                                  \
(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align                          \
 : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode                       \
    ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))

When set_mem_attributes is called, this means that this is now used as the
initial value of the local "align" variable:

void
set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
                                 HOST_WIDE_INT bitpos)
{
[...]
  unsigned int align = MEM_ALIGN (ref);

and later on in this function, "align" seems to be only increased, never
decremented, e.g. like here:

  else if (TREE_CODE (t) == MEM_REF)
    {
[snip]
        /* ??? This isn't fully correct, we can't set the alignment from the
           type in all cases.  */
        align = MAX (align, TYPE_ALIGN (type));

so that initial (wrong) value remains ...


This seems odd to me; in any case it results in an incorrect MEM_ALIGN value.

Should this be fixed in mainline (how?) even though I have no test there?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30  8:57 ` Ulrich Weigand
@ 2010-09-30 13:45   ` Richard Guenther
  2010-09-30 16:38     ` Michael Matz
  2010-09-30 18:02   ` Eric Botcazou
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Guenther @ 2010-09-30 13:45 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On Wed, 29 Sep 2010, Ulrich Weigand wrote:

> Richard Guenther wrote:
> 
> > *************** expand_expr_real_1 (tree exp, rtx target
> > *** 8734,8739 ****
> > --- 8736,8760 ----
> >   	set_mem_addr_space (temp, as);
> >   	if (TREE_THIS_VOLATILE (exp))
> >   	  MEM_VOLATILE_P (temp) = 1;
> > + 	if (mode != BLKmode
> > + 	    && (unsigned) align < GET_MODE_ALIGNMENT (mode)
> > + 	    /* If the target does not have special handling for unaligned
> > + 	       loads of mode then it can use regular moves for them.  */
> > + 	    && ((icode = optab_handler (movmisalign_optab, mode))
> > + 		!= CODE_FOR_nothing))
> > + 	  {
> > + 	    rtx reg, insn;
> > + 
> > + 	    /* We've already validated the memory, and we're creating a
> > + 	       new pseudo destination.  The predicates really can't fail.  */
> > + 	    reg = gen_reg_rtx (mode);
> > + 
> > + 	    /* Nor can the insn generator.  */
> > + 	    insn = GEN_FCN (icode) (reg, temp);
> > + 	    emit_insn (insn);
> > + 
> > + 	    return reg;
> > + 	  }
> 
> In experimenting with a STRICT_ALIGNMENT target, I noticed that
> the MEM rtx passed to the movmisalign expander sometimes has the
> default mode alignment, even though this is not true (that's why
> we need to use movmisalign in the first place).
> 
> This is caused by this sequence:
> 
>         temp = gen_rtx_MEM (mode, op0);
>         set_mem_attributes (temp, exp, 0);
> 
> The naked MEM has no MEM_ATTRS structure.  According to the default
> rules for STRICT_ALIGNMENT, this implies that MEM_ALIGN returns the
> mode alignment:
> 
> /* For a MEM rtx, the alignment in bits.  We can use the alignment of the
>    mode as a default when STRICT_ALIGNMENT, but not if not.  */
> #define MEM_ALIGN(RTX)                                                  \
> (MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align                          \
>  : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode                       \
>     ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
> 
> When set_mem_attributes is called, this means that this is now used as the
> initial value of the local "align" variable:
> 
> void
> set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
>                                  HOST_WIDE_INT bitpos)
> {
> [...]
>   unsigned int align = MEM_ALIGN (ref);
> 
> and later on in this function, "align" seems to be only increased, never
> decremented, e.g. like here:
> 
>   else if (TREE_CODE (t) == MEM_REF)
>     {
> [snip]
>         /* ??? This isn't fully correct, we can't set the alignment from the
>            type in all cases.  */
>         align = MAX (align, TYPE_ALIGN (type));
> 
> so that initial (wrong) value remains ...
> 
> 
> This seems odd to me; in any case it results in an incorrect MEM_ALIGN value.
> 
> Should this be fixed in mainline (how?) even though I have no test there?

Yes, I noticed the above, too, and it is that way since forever.

The problem is that MEM_ALIGN defaults to mode-alignment only on
strict-alignment targets.  Something that can't be right, or at least
it has very odd consequences.  This was changed way way way in the
past by Kenner (IIRC) who "simplified" the logic, removing some
extra explicit alignment handling.

The only sane (as in conservatively correct) variant would be

#define MEM_ALIGN(RTX) (MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align : 
BITS_PER_UNIT)

but I left it for strict-alignment target maintainers (or middle-end/rtl-
maintainers with some more "history") to sort out the existing issues.
Like for example

typedef int unaligned_int __attribute__((align(1)));

int __attribute__((noinline))
foo (unaligned_int *p)
{
  return *p;
}

int main()
{
  char c[5];
  return foo(&c[1]);
}

and watch it explode with all GCC versions on strict-align targets
(first of all because of the same problem as you noted, second of
course because the movmisaling handling is sth I added only for
4.6 and Jakub backported it to 4.5).

So, not "my" mess, really, but RMSs, Kenners and others' (if you
dare to try to go back in history ...).

My suggested fix (even if just applying that locally in
set_mem_attrs_minus_bitpos) would likely pessimize strict-align
targets, but you are free to give it some testing.

Richard.

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 13:45   ` Richard Guenther
@ 2010-09-30 16:38     ` Michael Matz
  2010-09-30 17:36       ` Ulrich Weigand
  0 siblings, 1 reply; 20+ messages in thread
From: Michael Matz @ 2010-09-30 16:38 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Ulrich Weigand, gcc-patches

Hi,

On Thu, 30 Sep 2010, Richard Guenther wrote:

> Yes, I noticed the above, too, and it is that way since forever.
> 
> The problem is that MEM_ALIGN defaults to mode-alignment only on
> strict-alignment targets.  Something that can't be right,

I think it is right.  The reasoning goes like so: On a strict-alignment 
target, when we see a MEM access, we know that it must obey the alignment 
requirements of the hardware, therefore MEMs that were generated correctly 
must have mode-compatible alignment.  Otherwise they shouldn't have been 
generated in the first place.  Which means the bug lies in generating 
those MEMs in the first place.

Another source of confusion always is if MEM_ALIGN is meant as an 
optimization hint or a correctness measure.  The latter implies that it 
must be correctly maintained in all transformations (and generated 
correctly from the beginning of course).  The implementation of 
MEM_ALIGN suggests that it's intended as correctness measure.

> or at least it has very odd consequences.

That for sure.


Ciao,
Micha.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 16:38     ` Michael Matz
@ 2010-09-30 17:36       ` Ulrich Weigand
  2010-09-30 18:01         ` Richard Guenther
  0 siblings, 1 reply; 20+ messages in thread
From: Ulrich Weigand @ 2010-09-30 17:36 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, gcc-patches

Michael Matz wrote:
> On Thu, 30 Sep 2010, Richard Guenther wrote:
> 
> > Yes, I noticed the above, too, and it is that way since forever.
> > 
> > The problem is that MEM_ALIGN defaults to mode-alignment only on
> > strict-alignment targets.  Something that can't be right,
> 
> I think it is right.  The reasoning goes like so: On a strict-alignment 
> target, when we see a MEM access, we know that it must obey the alignment 
> requirements of the hardware, therefore MEMs that were generated correctly 
> must have mode-compatible alignment.  Otherwise they shouldn't have been 
> generated in the first place.  Which means the bug lies in generating 
> those MEMs in the first place.

Well, in general this should be true for MEMs on a strict-alignment target.

However, the whole point of movmisalign is that it allows accesses to
memory that do *not* follow the rules that apply to general memory
accesses on the target.  Even on a strict-alignment target, it would
appear that it should be legal to use movmisalign on unaligned memory.

But if so, shouldn't the MEM RTX that is passed in to movmisalign then
still have *correct* MEM_ALIGN information that describes the actual
alignment of this particular misaligned access, even if it deviates
from the rules that would otherwise hold on the target?

> Another source of confusion always is if MEM_ALIGN is meant as an 
> optimization hint or a correctness measure.  The latter implies that it 
> must be correctly maintained in all transformations (and generated 
> correctly from the beginning of course).  The implementation of 
> MEM_ALIGN suggests that it's intended as correctness measure.

I agree that MEM_ALIGN should be required to be correct ...


Richard Guenther wrote:
> My suggested fix (even if just applying that locally in
> set_mem_attrs_minus_bitpos) would likely pessimize strict-align
> targets, but you are free to give it some testing.

I had been thinking of an even more local fix and just set
MEM_ALIGN explicitly when building the MEMs for the movmisalign
calls only ...


Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 17:36       ` Ulrich Weigand
@ 2010-09-30 18:01         ` Richard Guenther
  2010-09-30 18:03           ` Ulrich Weigand
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Guenther @ 2010-09-30 18:01 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Michael Matz, gcc-patches

On Thu, 30 Sep 2010, Ulrich Weigand wrote:

> Michael Matz wrote:
> > On Thu, 30 Sep 2010, Richard Guenther wrote:
> > 
> > > Yes, I noticed the above, too, and it is that way since forever.
> > > 
> > > The problem is that MEM_ALIGN defaults to mode-alignment only on
> > > strict-alignment targets.  Something that can't be right,
> > 
> > I think it is right.  The reasoning goes like so: On a strict-alignment 
> > target, when we see a MEM access, we know that it must obey the alignment 
> > requirements of the hardware, therefore MEMs that were generated correctly 
> > must have mode-compatible alignment.  Otherwise they shouldn't have been 
> > generated in the first place.  Which means the bug lies in generating 
> > those MEMs in the first place.
> 
> Well, in general this should be true for MEMs on a strict-alignment target.
> 
> However, the whole point of movmisalign is that it allows accesses to
> memory that do *not* follow the rules that apply to general memory
> accesses on the target.  Even on a strict-alignment target, it would
> appear that it should be legal to use movmisalign on unaligned memory.
> 
> But if so, shouldn't the MEM RTX that is passed in to movmisalign then
> still have *correct* MEM_ALIGN information that describes the actual
> alignment of this particular misaligned access, even if it deviates
> from the rules that would otherwise hold on the target?
> 
> > Another source of confusion always is if MEM_ALIGN is meant as an 
> > optimization hint or a correctness measure.  The latter implies that it 
> > must be correctly maintained in all transformations (and generated 
> > correctly from the beginning of course).  The implementation of 
> > MEM_ALIGN suggests that it's intended as correctness measure.
> 
> I agree that MEM_ALIGN should be required to be correct ...
> 
> 
> Richard Guenther wrote:
> > My suggested fix (even if just applying that locally in
> > set_mem_attrs_minus_bitpos) would likely pessimize strict-align
> > targets, but you are free to give it some testing.
> 
> I had been thinking of an even more local fix and just set
> MEM_ALIGN explicitly when building the MEMs for the movmisalign
> calls only ...

Sounds like a hack, not a fix.  If going that route I'd suggest
to explicitly pass alignment information to movmisalign (f.e. using
a helper in optabs.c if adding an additional operand looks too weird).

But at least making set_mem_attributes_minus_bitpos not re-use
existing MEM_ATTRs but always re-setting them (eventually
asserting that MEM_ATTR is NULL at its beginning, fixing up
callers) sounds like a more reasonable route.

Richard.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30  8:57 ` Ulrich Weigand
  2010-09-30 13:45   ` Richard Guenther
@ 2010-09-30 18:02   ` Eric Botcazou
  2010-09-30 18:02     ` Daniel Jacobowitz
  1 sibling, 1 reply; 20+ messages in thread
From: Eric Botcazou @ 2010-09-30 18:02 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches, Richard Guenther

> In experimenting with a STRICT_ALIGNMENT target, I noticed that
> the MEM rtx passed to the movmisalign expander sometimes has the
> default mode alignment, even though this is not true (that's why
> we need to use movmisalign in the first place).

But if you have movmisalign, why do you set STRICT_ALIGNMENT?  This seems to 
be the original contradiction.  You should use SLOW_UNALIGNED_ACCESS at most.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:02   ` Eric Botcazou
@ 2010-09-30 18:02     ` Daniel Jacobowitz
  2010-09-30 18:03       ` Richard Guenther
                         ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Daniel Jacobowitz @ 2010-09-30 18:02 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Ulrich Weigand, gcc-patches, Richard Guenther

On Thu, Sep 30, 2010 at 03:11:47PM +0200, Eric Botcazou wrote:
> > In experimenting with a STRICT_ALIGNMENT target, I noticed that
> > the MEM rtx passed to the movmisalign expander sometimes has the
> > default mode alignment, even though this is not true (that's why
> > we need to use movmisalign in the first place).
> 
> But if you have movmisalign, why do you set STRICT_ALIGNMENT?  This seems to 
> be the original contradiction.  You should use SLOW_UNALIGNED_ACCESS at most.

On ARM, for example, there are specific things that can be accessed
"misaligned" - or at least with lower alignment requirements.  For
instance, you can load V4SI with the alignment of SI.  But integer
loads are still aligned only; this is a STRICT_ALIGNMENT target.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:02     ` Daniel Jacobowitz
  2010-09-30 18:03       ` Richard Guenther
@ 2010-09-30 18:03       ` Nathan Froyd
  2010-09-30 18:05         ` Bernd Schmidt
  2010-09-30 18:05       ` Eric Botcazou
  2 siblings, 1 reply; 20+ messages in thread
From: Nathan Froyd @ 2010-09-30 18:03 UTC (permalink / raw)
  To: Eric Botcazou, Ulrich Weigand, gcc-patches, Richard Guenther

On Thu, Sep 30, 2010 at 09:52:49AM -0400, Daniel Jacobowitz wrote:
> On Thu, Sep 30, 2010 at 03:11:47PM +0200, Eric Botcazou wrote:
> > > In experimenting with a STRICT_ALIGNMENT target, I noticed that
> > > the MEM rtx passed to the movmisalign expander sometimes has the
> > > default mode alignment, even though this is not true (that's why
> > > we need to use movmisalign in the first place).
> > 
> > But if you have movmisalign, why do you set STRICT_ALIGNMENT?  This seems to 
> > be the original contradiction.  You should use SLOW_UNALIGNED_ACCESS at most.
> 
> On ARM, for example, there are specific things that can be accessed
> "misaligned" - or at least with lower alignment requirements.  For
> instance, you can load V4SI with the alignment of SI.  But integer
> loads are still aligned only; this is a STRICT_ALIGNMENT target.

In a similar fashion--though GCC does not take advantage of this at the
moment--on E500 targets, the vector and FP instructions require
alignment, but integer instructions do not.  E500 is a STRICT_ALIGNMENT
target to cover the vector bits, but it would be beneficial if we could
move away from that.  From Richi's explanation of x86-64, such a thing
is certainly possible...

-Nathan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:02     ` Daniel Jacobowitz
@ 2010-09-30 18:03       ` Richard Guenther
  2010-09-30 18:03       ` Nathan Froyd
  2010-09-30 18:05       ` Eric Botcazou
  2 siblings, 0 replies; 20+ messages in thread
From: Richard Guenther @ 2010-09-30 18:03 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Eric Botcazou, Ulrich Weigand, gcc-patches

On Thu, 30 Sep 2010, Daniel Jacobowitz wrote:

> On Thu, Sep 30, 2010 at 03:11:47PM +0200, Eric Botcazou wrote:
> > > In experimenting with a STRICT_ALIGNMENT target, I noticed that
> > > the MEM rtx passed to the movmisalign expander sometimes has the
> > > default mode alignment, even though this is not true (that's why
> > > we need to use movmisalign in the first place).
> > 
> > But if you have movmisalign, why do you set STRICT_ALIGNMENT?  This seems to 
> > be the original contradiction.  You should use SLOW_UNALIGNED_ACCESS at most.
> 
> On ARM, for example, there are specific things that can be accessed
> "misaligned" - or at least with lower alignment requirements.  For
> instance, you can load V4SI with the alignment of SI.  But integer
> loads are still aligned only; this is a STRICT_ALIGNMENT target.

On x86_64, for example, there are specific things that can only
be accessed aligned in some contexts - like any SSE memory operand
in an instruction that is not an unaligned move.  x86_64 is not
a STRICT_ALIGNMENT target, but we at least now require that such
a target implements movmisalign.

I don't know if this is consistent with ARM, but I think that
maybe our documentation could use some clarification (eventually
with examples).

Richard.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:01         ` Richard Guenther
@ 2010-09-30 18:03           ` Ulrich Weigand
  0 siblings, 0 replies; 20+ messages in thread
From: Ulrich Weigand @ 2010-09-30 18:03 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Michael Matz, gcc-patches

Richard Guenther wrote:
> On Thu, 30 Sep 2010, Ulrich Weigand wrote:
> > I had been thinking of an even more local fix and just set
> > MEM_ALIGN explicitly when building the MEMs for the movmisalign
> > calls only ...
> 
> Sounds like a hack, not a fix.

Probably.  I was just thinking that since the caller has already
computed alignment information (to decide whether movmisalign is
required), it would make more sense to use this information and
store it into MEM_ALIGN, instead of having the set_mem_attributes
routine recompute the same alignment info from the same basic data
in slightly different ways, leading to different results ...

> If going that route I'd suggest
> to explicitly pass alignment information to movmisalign (f.e. using
> a helper in optabs.c if adding an additional operand looks too weird).

Well, my current hack to just get at MEM_EXPR in the movmisalign
expander and recompute the alignment from there.  That works for
me so far, so I don't really need to replace it with another hack
that's not a real fix either.

> But at least making set_mem_attributes_minus_bitpos not re-use
> existing MEM_ATTRs but always re-setting them (eventually
> asserting that MEM_ATTR is NULL at its beginning, fixing up
> callers) sounds like a more reasonable route.

OK, that sound reasonable.  I can try whether this works for me.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:02     ` Daniel Jacobowitz
  2010-09-30 18:03       ` Richard Guenther
  2010-09-30 18:03       ` Nathan Froyd
@ 2010-09-30 18:05       ` Eric Botcazou
  2010-09-30 18:06         ` Daniel Jacobowitz
  2 siblings, 1 reply; 20+ messages in thread
From: Eric Botcazou @ 2010-09-30 18:05 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Ulrich Weigand, gcc-patches, Richard Guenther

> On ARM, for example, there are specific things that can be accessed
> "misaligned" - or at least with lower alignment requirements.  For
> instance, you can load V4SI with the alignment of SI.  But integer
> loads are still aligned only; this is a STRICT_ALIGNMENT target.

OK, but you precisely don't need movmisalign in this case, for example for 
V4SI, because the hardware does it for you, do you?  IOW movmisalign is 
for !STRICT_ALIGNMENT targets that happen to have alignment requirements for 
some modes, but not for STRICT_ALIGNMENT targets that happen to have relaxed 
alignment requiements for some modes.  In the latter case, adjusting the value 
of GET_MODE_ALIGNMENT for the affected modes would be more logical.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:03       ` Nathan Froyd
@ 2010-09-30 18:05         ` Bernd Schmidt
  2010-09-30 18:05           ` Nathan Froyd
  0 siblings, 1 reply; 20+ messages in thread
From: Bernd Schmidt @ 2010-09-30 18:05 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Eric Botcazou, Ulrich Weigand, gcc-patches, Richard Guenther

On 09/30/2010 04:10 PM, Nathan Froyd wrote:
> On Thu, Sep 30, 2010 at 09:52:49AM -0400, Daniel Jacobowitz wrote:
>> On Thu, Sep 30, 2010 at 03:11:47PM +0200, Eric Botcazou wrote:
>>>> In experimenting with a STRICT_ALIGNMENT target, I noticed that
>>>> the MEM rtx passed to the movmisalign expander sometimes has the
>>>> default mode alignment, even though this is not true (that's why
>>>> we need to use movmisalign in the first place).
>>>
>>> But if you have movmisalign, why do you set STRICT_ALIGNMENT?  This seems to 
>>> be the original contradiction.  You should use SLOW_UNALIGNED_ACCESS at most.
>>
>> On ARM, for example, there are specific things that can be accessed
>> "misaligned" - or at least with lower alignment requirements.  For
>> instance, you can load V4SI with the alignment of SI.  But integer
>> loads are still aligned only; this is a STRICT_ALIGNMENT target.
> 
> In a similar fashion--though GCC does not take advantage of this at the
> moment--on E500 targets, the vector and FP instructions require
> alignment, but integer instructions do not.  E500 is a STRICT_ALIGNMENT
> target to cover the vector bits, but it would be beneficial if we could
> move away from that.

Isn't this how it should be, however?  The way I understand it is that
STRICT_ALIGNMENT should prevent the compiler from using unaligned
operands in all insns except movmisalign (which was introduced much
later).  The mere existence of movmisalign does not mean a target
shouldn't set STRICT_ALIGNMENT.

Maybe STRICT_ALIGNMENT should take a mode argument.


Bernd

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:05         ` Bernd Schmidt
@ 2010-09-30 18:05           ` Nathan Froyd
  2010-09-30 18:06             ` Joseph S. Myers
  0 siblings, 1 reply; 20+ messages in thread
From: Nathan Froyd @ 2010-09-30 18:05 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Eric Botcazou, Ulrich Weigand, gcc-patches, Richard Guenther

On Thu, Sep 30, 2010 at 04:29:22PM +0200, Bernd Schmidt wrote:
> On 09/30/2010 04:10 PM, Nathan Froyd wrote:
> > In a similar fashion--though GCC does not take advantage of this at the
> > moment--on E500 targets, the vector and FP instructions require
> > alignment, but integer instructions do not.  E500 is a STRICT_ALIGNMENT
> > target to cover the vector bits, but it would be beneficial if we could
> > move away from that.
> 
> Isn't this how it should be, however?  The way I understand it is that
> STRICT_ALIGNMENT should prevent the compiler from using unaligned
> operands in all insns except movmisalign (which was introduced much
> later).  The mere existence of movmisalign does not mean a target
> shouldn't set STRICT_ALIGNMENT.

Hm, maybe all that needs to be done is some experimentation with
movmisalign{hi,si} for E500, then.

> Maybe STRICT_ALIGNMENT should take a mode argument.

Well, there's SLOW_UNALIGNED_ACCESS.

-Nathan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:05           ` Nathan Froyd
@ 2010-09-30 18:06             ` Joseph S. Myers
  0 siblings, 0 replies; 20+ messages in thread
From: Joseph S. Myers @ 2010-09-30 18:06 UTC (permalink / raw)
  To: Nathan Froyd
  Cc: Bernd Schmidt, Eric Botcazou, Ulrich Weigand, gcc-patches,
	Richard Guenther

On Thu, 30 Sep 2010, Nathan Froyd wrote:

> On Thu, Sep 30, 2010 at 04:29:22PM +0200, Bernd Schmidt wrote:
> > On 09/30/2010 04:10 PM, Nathan Froyd wrote:
> > > In a similar fashion--though GCC does not take advantage of this at the
> > > moment--on E500 targets, the vector and FP instructions require
> > > alignment, but integer instructions do not.  E500 is a STRICT_ALIGNMENT
> > > target to cover the vector bits, but it would be beneficial if we could
> > > move away from that.
> > 
> > Isn't this how it should be, however?  The way I understand it is that
> > STRICT_ALIGNMENT should prevent the compiler from using unaligned
> > operands in all insns except movmisalign (which was introduced much
> > later).  The mere existence of movmisalign does not mean a target
> > shouldn't set STRICT_ALIGNMENT.
> 
> Hm, maybe all that needs to be done is some experimentation with
> movmisalign{hi,si} for E500, then.
> 
> > Maybe STRICT_ALIGNMENT should take a mode argument.
> 
> Well, there's SLOW_UNALIGNED_ACCESS.

And as I noted in 
<http://gcc.gnu.org/ml/gcc-patches/2008-07/msg02216.html> there are some 
places that only check STRICT_ALIGNMENT that are currently needed for E500 
correctness - or at least that were needed for correctness when I added 
those checks.

It may be the case that GCC never really needs to distinguish between 
"very slow" and "doesn't work at all" - in which case all checks on 
STRICT_ALIGNMENT should be replaced by checks using SLOW_UNALIGNED_ACCESS 
and STRICT_ALIGNMENT would serve only to provide a default for 
SLOW_UNALIGNED_ACCESS.  (Better, SLOW_UNALIGNED_ACCESS would become a 
hook, there would be strict-alignment and no-strict-alignment generic 
versions available for targets for which one of those is suitable, and 
other targets would define their own versions.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:05       ` Eric Botcazou
@ 2010-09-30 18:06         ` Daniel Jacobowitz
  2010-10-01  7:56           ` Eric Botcazou
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Jacobowitz @ 2010-09-30 18:06 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Ulrich Weigand, gcc-patches, Richard Guenther

On Thu, Sep 30, 2010 at 04:46:12PM +0200, Eric Botcazou wrote:
> > On ARM, for example, there are specific things that can be accessed
> > "misaligned" - or at least with lower alignment requirements.  For
> > instance, you can load V4SI with the alignment of SI.  But integer
> > loads are still aligned only; this is a STRICT_ALIGNMENT target.
> 
> OK, but you precisely don't need movmisalign in this case, for example for 
> V4SI, because the hardware does it for you, do you?  IOW movmisalign is 
> for !STRICT_ALIGNMENT targets that happen to have alignment requirements for 
> some modes, but not for STRICT_ALIGNMENT targets that happen to have relaxed 
> alignment requiements for some modes.  In the latter case, adjusting the value 
> of GET_MODE_ALIGNMENT for the affected modes would be more logical.

It turns out a bit more complicated than that; you can find the thread
of Julian's recently-approved patch to use movmisalign for NEON if you
want the details.  The NEON case is a bad example because what it
really wants is not movmisalign at all; it wants to distinguish "load
a V4SI value" (requires V4SI alignment) from "load 4 SI values from an
array into a V4SI register" (requires SI alignment).  On big endian
ARM systems, these two use a different element order.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-30 18:06         ` Daniel Jacobowitz
@ 2010-10-01  7:56           ` Eric Botcazou
  2010-10-01 13:51             ` Daniel Jacobowitz
  0 siblings, 1 reply; 20+ messages in thread
From: Eric Botcazou @ 2010-10-01  7:56 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gcc-patches, Ulrich Weigand, Richard Guenther

> It turns out a bit more complicated than that; you can find the thread
> of Julian's recently-approved patch to use movmisalign for NEON if you
> want the details. 

Do you have an URL?  I don't seem to be able to find the thread.

> The NEON case is a bad example because what it  
> really wants is not movmisalign at all; it wants to distinguish "load
> a V4SI value" (requires V4SI alignment) from "load 4 SI values from an
> array into a V4SI register" (requires SI alignment).  On big endian
> ARM systems, these two use a different element order.

That sounds like an unfortunate overloading of movmisalign.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-10-01  7:56           ` Eric Botcazou
@ 2010-10-01 13:51             ` Daniel Jacobowitz
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Jacobowitz @ 2010-10-01 13:51 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, Ulrich Weigand, Richard Guenther

On Fri, Oct 01, 2010 at 09:56:15AM +0200, Eric Botcazou wrote:
> > It turns out a bit more complicated than that; you can find the thread
> > of Julian's recently-approved patch to use movmisalign for NEON if you
> > want the details. 
> 
> Do you have an URL?  I don't seem to be able to find the thread.

http://gcc.gnu.org/ml/gcc-patches/2010-08/msg00214.html

Discussion in November, December, May, June, August, September
(unfortunate that the mail archives split monthly).

> That sounds like an unfortunate overloading of movmisalign.

Yes, unfortunately somewhat intractable to unwind from.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Remove MISALIGNED_INDIRECT_REF
  2010-09-08  4:20 ` H.J. Lu
@ 2010-10-31 19:14   ` H.J. Lu
  0 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2010-10-31 19:14 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

On Tue, Sep 7, 2010 at 5:19 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Sep 3, 2010 at 5:51 AM, Richard Guenther <rguenther@suse.de> wrote:
>>
>> I need to stop with GIMPLE IL changes, so this is the
>> MISALIGNED_INDIRECT_REF removal patch again, which completes the
>> transition to MEM_REF.
>>
>> Compared to the previous versions I sent this picks up a patch
>> from Michael Matz in PR39954 to build aligned variants of a type.
>> This is needed as we can't really get rid of deriving alignment
>> information from types - at least I can't see an easy way without
>> pessimizing too much code.  So the vectorizer, when generating
>> a misaligned access now adjusts the alignment information in
>> the SSA_NAME_PTR_INFO struct and uses a type aligned the same
>> as the vector component type for the respective access.
>>
>> Which means that this doesn't try to fix the issues with
>> aligned attributes not working on STRICT_ALIGNMENT targets.
>>
>> Now all accesses produced by the vectorizer are handled by
>> induction variable optimization and prefetching.
>>
>> Bootstrapped and tested on x86_64-unknown-linux-gnu, I'll leave
>> the patch for comments again until Monday and plan to commit it
>> at that point.
>>
>> Thanks,
>> Richard.
>>
>> 2010-09-02  Richard Guenther  <rguenther@suse.de>
>>
>>        * tree.def (MISALIGNED_INDIRECT_REF): Remove.
>>        * tree.h (INDIRECT_REF_P): Only check for INDIRECT_REF.
>>        (build_aligned_type): Declare.
>>        * tree.c (check_qualified_type): Also compare TYPE_ALIGN.
>>        (check_aligned_type): New function.
>>        (build_aligned_type): Likewise.
>>        * expr.c (expand_assignment): Handle misaligned stores via
>>        TARGET_MEM_REF and MEM_REF using movmisalign_optab.
>>        (expand_expr_real_1): Likewise.
>>        (safe_from_p): Remove MISALIGNED_INDIRECT_REF handling.
>>        * tree-vect-stmts.c (vectorizable_store): Do not build
>>        MISALIGNED_INDIRECT_REF but initialize alignment information.
>>        (vectorizable_load): Likewise.
>>        * builtins.c (get_object_alignment): Remove MISALIGNED_INDIRECT_REF
>>        handling.
>>        * cfgexpand.c (expand_debug_expr): Likewise.
>>        * dwarf2out.c (loc_list_from_tree): Likewise.
>>        * fold-const.c (maybe_lvalue_p): Likewise.
>>        (operand_equal_p): Likewise.
>>        (build_fold_addr_expr_with_type_loc): Likewise.
>>        * gimplify.c (gimplify_addr_expr): Likewise.
>>        (gimplify_expr): Likewise.
>>        * tree-cfg.c (verify_types_in_gimple_min_lval): Likewise.
>>        (verify_gimple_assign_single): Likewise.
>>        * tree-dump.c (dequeue_and_dump): Likewise.
>>        (tree_could_trap_p): Likewise.
>>        * tree-predcom.c (ref_at_iteration): Likewise.
>>        * tree-pretty-print.c (dump_generic_node): Likewise.
>>        (op_code_prio): Likewise.
>>        (op_symbol_code): Likewise.
>>        * tree-ssa-ccp.c (get_value_from_alignment): Likewise.
>>        * tree-ssa-loop-im.c (for_each_index): Likewise.
>>        (gen_lsm_tmp_name): Likewise.
>>        * tree-ssa-loop-ivopts.c (idx_find_step): Likewise.
>>        (find_interesting_uses_address): Likewise.
>>        * tree-ssa-loop-prefetch.c (idx_analyze_ref): Likewise.
>>        * tree-ssa-operands.c (get_expr_operands): Likewise.
>>        * tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
>>        * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
>>        (ao_ref_init_from_vn_reference): Likewise.
>>        * tree.c (staticp): Likewise.
>>        (build1_stat): Likewise.
>>        (reference_alias_ptr_type): Likewise.
>>        * emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
>>
>>        * config/rs6000/rs6000.c (rs6000_check_sdmode): Remove
>>        MISALIGNED_INDIRECT_REF handling.
>>
>
> This caused:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45589
>
>

This also caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46251


-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-10-31 17:50 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-03 12:54 [PATCH] Remove MISALIGNED_INDIRECT_REF Richard Guenther
2010-09-08  4:20 ` H.J. Lu
2010-10-31 19:14   ` H.J. Lu
2010-09-30  8:57 ` Ulrich Weigand
2010-09-30 13:45   ` Richard Guenther
2010-09-30 16:38     ` Michael Matz
2010-09-30 17:36       ` Ulrich Weigand
2010-09-30 18:01         ` Richard Guenther
2010-09-30 18:03           ` Ulrich Weigand
2010-09-30 18:02   ` Eric Botcazou
2010-09-30 18:02     ` Daniel Jacobowitz
2010-09-30 18:03       ` Richard Guenther
2010-09-30 18:03       ` Nathan Froyd
2010-09-30 18:05         ` Bernd Schmidt
2010-09-30 18:05           ` Nathan Froyd
2010-09-30 18:06             ` Joseph S. Myers
2010-09-30 18:05       ` Eric Botcazou
2010-09-30 18:06         ` Daniel Jacobowitz
2010-10-01  7:56           ` Eric Botcazou
2010-10-01 13:51             ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).