This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/52080] Stores to bitfields introduce a store-data-race on adjacent data


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

--- Comment #4 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-02-01 11:12:41 UTC ---
Btw,

  offset = bitnum / unit;
  bitpos = bitnum % unit;
  byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
                + (offset * UNITS_PER_WORD);

byte_offset is bollocks (or has a really poor name).  On SPARC64 I see

(gdb) p unit
$11 = 8
(gdb) p offset
$12 = 12
(gdb) p bitpos
$13 = 0
(gdb) p byte_offset
$14 = 100

Other than that we are falling into the generic store_fixed_bit_field
routine which at the top does

  unsigned int total_bits = BITS_PER_WORD;

and

      mode = GET_MODE (op0);
      if (GET_MODE_BITSIZE (mode) == 0
          || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
        mode = word_mode;

(now, why we use a BLKmode mem here and not a QImode mem may be
surprising)

get_best_mode still returns DImode because that's the largest mode
the given alignment supports.  After that we're lost.  So it seems
that to fix this case we'd need to figure out some other largest
mode we can pass to get_best_mode.  The only hint would be from
providing a different mode for the initial MEM we create, like with

Index: gcc/expr.c
===================================================================
--- gcc/expr.c  (revision 183791)
+++ gcc/expr.c  (working copy)
@@ -4705,6 +4705,12 @@ expand_assignment (tree to, tree from, b
            to_rtx = adjust_address (to_rtx, mode1, 0);
          else if (GET_MODE (to_rtx) == VOIDmode)
            to_rtx = adjust_address (to_rtx, BLKmode, 0);
+         else if (TREE_CODE (to) == COMPONENT_REF
+                  && DECL_BIT_FIELD (TREE_OPERAND (to, 1))
+                  && DECL_MODE (TREE_OPERAND (to, 1)) != BLKmode)
+           to_rtx = adjust_address (to_rtx,
+                                    TYPE_MODE (DECL_BIT_FIELD_TYPE
+                                       (TREE_OPERAND (to, 1))), 0);
        }

       if (offset != 0)

That avoids the use of QImode we have on the field-decl but also
adjusts MEM_SIZE ...


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]