https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127633
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |uros at gcc dot gnu.org
--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
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).
There are multiple define_peephole2 affected and the issue is surely latent.