[PATCH] Fix PR71510 (re-do PR71310 fix)

Richard Biener rguenther@suse.de
Tue Jun 14 07:26:00 GMT 2016


The following fixes th PR71310 fix to do what expand does and thus
follow the C++ memory model correctly.  It also reportedly fixes
PR71510 (probably the effective negative bitoffset thing).

Bootstrapped and tested on x86_64-unknown-linux-gnu, inspected the
PR71310 testcase on a ppc64le cross.

Installed on trunk.

Richard.

2016-06-14  Richard Biener  <rguenther@suse.de>

	PR middle-end/71310
	PR bootstrap/71510
	* expr.h (get_bit_range): Declare.
	* expr.c (get_bit_range): Export.
	* fold-const.c (optimize_bit_field_compare): Use get_bit_range and
	word_mode again to constrain the bitfield access.

Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 237372)
--- gcc/expr.c	(working copy)
*************** optimize_bitfield_assignment_op (unsigne
*** 4795,4801 ****
     If the access does not need to be restricted, 0 is returned in both
     *BITSTART and *BITEND.  */
  
! static void
  get_bit_range (unsigned HOST_WIDE_INT *bitstart,
  	       unsigned HOST_WIDE_INT *bitend,
  	       tree exp,
--- 4795,4801 ----
     If the access does not need to be restricted, 0 is returned in both
     *BITSTART and *BITEND.  */
  
! void
  get_bit_range (unsigned HOST_WIDE_INT *bitstart,
  	       unsigned HOST_WIDE_INT *bitend,
  	       tree exp,
Index: gcc/expr.h
===================================================================
*** gcc/expr.h	(revision 237372)
--- gcc/expr.h	(working copy)
*************** extern rtx push_block (rtx, int, int);
*** 242,247 ****
--- 242,251 ----
  extern bool emit_push_insn (rtx, machine_mode, tree, rtx, unsigned int,
  			    int, rtx, int, rtx, rtx, int, rtx, bool);
  
+ /* Extract the accessible bit-range from a COMPONENT_REF.  */
+ extern void get_bit_range (unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
+ 			   tree, HOST_WIDE_INT *, tree *);
+ 
  /* Expand an assignment that stores the value of FROM into TO.  */
  extern void expand_assignment (tree, tree, bool);
  
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 237372)
--- gcc/fold-const.c	(working copy)
*************** optimize_bit_field_compare (location_t l
*** 3904,3927 ****
         return 0;
     }
  
!   /* Don't use a larger mode for reading the bit field than we will
!      use in other places accessing the bit field.  */
!   machine_mode largest_mode = word_mode;
    if (TREE_CODE (lhs) == COMPONENT_REF)
      {
!       tree field = TREE_OPERAND (lhs, 1);
!       tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
!       if (repr)
! 	largest_mode = DECL_MODE (repr);
      }
  
    /* See if we can find a mode to refer to this field.  We should be able to,
       but fail if we can't.  */
!   nmode = get_best_mode (lbitsize, lbitpos, 0, 0,
  			 const_p ? TYPE_ALIGN (TREE_TYPE (linner))
  			 : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
  				TYPE_ALIGN (TREE_TYPE (rinner))),
! 			 largest_mode, false);
    if (nmode == VOIDmode)
      return 0;
  
--- 3904,3926 ----
         return 0;
     }
  
!   /* Honor the C++ memory model and mimic what RTL expansion does.  */
!   unsigned HOST_WIDE_INT bitstart = 0;
!   unsigned HOST_WIDE_INT bitend = 0;
    if (TREE_CODE (lhs) == COMPONENT_REF)
      {
!       get_bit_range (&bitstart, &bitend, lhs, &lbitpos, &offset);
!       if (offset != NULL_TREE)
! 	return 0;
      }
  
    /* See if we can find a mode to refer to this field.  We should be able to,
       but fail if we can't.  */
!   nmode = get_best_mode (lbitsize, lbitpos, bitstart, bitend,
  			 const_p ? TYPE_ALIGN (TREE_TYPE (linner))
  			 : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
  				TYPE_ALIGN (TREE_TYPE (rinner))),
! 			 word_mode, false);
    if (nmode == VOIDmode)
      return 0;
  



More information about the Gcc-patches mailing list