This problem showed up in a PDP10 C version of GCC I'm responsible for and took a good while to track down. The fix is in generic gcc code so even though my PDP10 compiler is not an official gcc version and I haven't been successful at creating a failing program on the Intel compiler it seems like it should cause problems elsewhere so I figured I should pass it on.

Here's a union that allows referencing bits in a word in different ways (the PDP10 has a 36 bit word, but that doesn't seem to be an issue here)

   union {
       int word;
       struct {
           unsigned long w0 : 32;
           unsigned long pad : 4;
       } i32;
       struct {
           unsigned long s0 : 16;
           unsigned long s1 : 16;
           unsigned long pad : 4;
       } i16;
       struct {
           unsigned long b0 : 8;
           unsigned long b1 : 8;
           unsigned long b2 : 8;
           unsigned long b3 : 8;
           unsigned long pad : 4;
       } i8;
   } u32;


u32.word = .... ;

/* in a subsequent different basic block which is guaranteed to be reached with u32 unchanged */
u32.i8.b1 = ... ;
... = u32.word ;

CSE detects that the same subexpression is used in two places and substitutes a reaching register for the reference to u32.word without noticing that the memory has been modified by the bit field reference. Adding a call to invalidate_any_buried_refs(dest) flags the memory reference in such a way that it is not ignored and the erroneous CSE optimization is not done.


--- gcse.c      (revision 156482)
+++ gcse.c      (working copy)
@@ -4783,7 +4783,12 @@ compute_ld_motion_mems (void)
                     else
                       ptr->invalid = 1;
                   }
-               }
+          else
+            {
+              /* Make sure there isn't a buried store somewhere.  */
+              invalidate_any_buried_refs (dest);
+            }
+       }
             else
               invalidate_any_buried_refs (PATTERN (insn));
           }


Thanks to anyone who can help determine whether this is a problem for other gcc versions and getting a fix into the gcc source.

Martin Chaney
XKL, LLC






Reply via email to