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

Uroš Bizjak <ubizjak at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
             Status|RESOLVED                    |REOPENED
          Component|target                      |rtl-optimization
         Resolution|FIXED                       |---

--- Comment #14 from Uroš Bizjak <ubizjak at gmail dot com> ---
Reopening, this should be fixed in a target-independent way:

When *two or more* volatile memory operands get combined into a single RTX
pattern, we don't know the order of operands anymore. x86 example is e.g.
*add<dwi>3_doubleword_concat that swaps and mixes two possibly volatile
operands, with a counter example of double mode add that has *one* possibly
volatile volatile operand. If middle-end ensures that only one volatile operand
gets propagated into
RTX (please note that combine won't propagate memory over other memory), then
volatile accesses won't get reordered.

This requirement is currently violated in several x86 concat patterns.

To illustrate the above, let's analyze how (unpatched) compiler
combines testcase from pr127851 (x and y are both volatiles):

    5: r99:SI=[`x']
    6: r100:SI=[`y']
    7: flags:CCGC=cmp(r99:SI,r100:SI)
      REG_DEAD r100:SI
      REG_DEAD r99:SI

combine pass:

Trying 5 -> 7:
    5: r99:SI=[`x']
    7: flags:CCGC=cmp(r99:SI,r100:SI)
      REG_DEAD r100:SI
      REG_DEAD r99:SI

Can't combine i2 into i3   <- i2 passes insn 6, a volatile read, so
already rejected by combine.

Trying 6 -> 7:
    6: r100:SI=[`y']
    7: flags:CCGC=cmp(r99:SI,r100:SI)
      REG_DEAD r100:SI
      REG_DEAD r99:SI
Successfully matched this instruction:
(set (reg:CCGC 17 flags)
    (compare:CCGC (reg/v:SI 99 [ a ])
        (mem/v/c:SI (symbol_ref:DI ("y") [flags 0x40]  <var_decl 0x7fd1a93d6ed8
y>) [1 y+0 S4 A32])))

allowing combination of insns 6 and 7  <- OK

Trying 5 -> 7:
    5: r99:SI=[`x']
    7: flags:CCGC=cmp(r99:SI,[`y'])
      REG_DEAD r99:SI
Successfully matched this instruction:
(set (reg:CCGC 17 flags)
    (compare:CCGC (mem/v/c:SI (symbol_ref:DI ("x") [flags 0x40]
<var_decl 0x7fd1a93d6e40 x>) [1 x+0 S4 A32])
        (mem/v/c:SI (symbol_ref:DI ("y") [flags 0x40]  <var_decl
0x7fd1a93d6ed8 y>) [1 y+0 S4 A32])))

allowing combination of insns 5 and 7  <- this should *NOT* be allowed, there
is already volatile read in the RTX, so combination with another volatile read
should be rejected.

IMO rejecting the last combination in the middle-end would resolve this class
of problems for all targets.

Reply via email to