https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127633

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|tree-optimization           |target

--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #9)
>    2. Peephole2 Mislabeling:
>      In gcc/config/i386/sse.md, the define_peephole2 pattern merging two
>   adjacent 64-bit DFmode memory loads into a 128-bit V2DFmode movupd load
>   matched the adjacent stack loads:
> 
>    1    (define_peephole2
>    2      ...
>    3      [(set (match_dup 2) (match_dup 5))]
>    4      "operands[5] = adjust_address (operands[1], V2DFmode, 0);")
>      adjust_address changes the mode of operands[1] (88(%rsp)) from DFmode to
>   V2DFmode without validating whether the widened 16-byte access exceeds the
>   bounds of the underlying object. As a result, the new 16-byte memory
> reference
>   retained the MEM_EXPR (the spill slot pseudo) and MEM_ALIAS_SET of
>   operands[1].
> 
>    3. Missing Memory Dependence & Uninitialized Read in sched2:
>      Before the load of bv, a store *by = ... initializes bv at 96(%rsp).
> During
>   sched2, alias analysis (nonoverlapping_memrefs_p) was queried between the
>   store through pointer by (alias set 3) and the 16-byte movupd load. Because
>   the 16-byte load retained the MEM_EXPR of the spill slot, alias analysis
>   concluded that the load from the spill slot could never alias with a
> pointer
>   dereference storing to bv. Consequently, sched2 scheduled the 16-byte load
>   before the store to bv, reading uninitialized stack data.
> 
>      The garbage value corrupted the return value of s, leading to a
> mismatched
>   condition in q and triggering the infinite loop in n.
> 
> 
> adjust_address_1 has many conditions under which it clears MEM_EXPR and
> MEM_ALIAS_SET already, so it might be tempting to add one doing this iff
> the new modes size is not equal to the old size (at least MEM_EXPR cannot
> be correct then).

Oh, and there already is

  if (maybe_ne (size, 0))
    {
      /* Drop the object if the new right end is not within its bounds.  */
      if (adjust_object && maybe_gt (offset + size, attrs.size))
        {
          attrs.expr = NULL_TREE;
          attrs.alias = 0;
        }

but this is guarded by adjust_object which is passed as 0.
adjust_bitfield_address would pass 1 which reads

/* Return a memory reference like MEMREF, but with its mode changed  
   to MODE and its address offset by OFFSET bytes.  Assume that it's
   for a bitfield and conservatively drop the underlying object if we
   cannot be sure to stay within its bounds.  */
#define adjust_bitfield_address(MEMREF, MODE, OFFSET) \
  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, 0)

there's also widen_memory_access which might be a better fit here.  I'm
testing a patch.

Reply via email to