On 9/29/26 7:56 AM, Richard Biener wrote:
combine's distribute_and_simplify_rtx distributes (and (xor B C) (not A))
to (xor (ior A B) (ior A C)), thereby duplicating A.  When A is a
paradoxical subreg that is spilled the two As can have differing values
which now spill into the result as we can no longer rely on the
XOR/IOR combination to cancel out those bits.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

In the bugzilla audit trail Uros mentions that LRA should spill/reload
paradoxical subregs inconsistently:

Yes it is LRA. Before LRA we have:

(insn 219 218 220 3 (parallel [
             (set (reg:SI 146 [ _47 ])
                 (xor:SI (reg:SI 343 [ df_91 ])
                     (subreg:SI (reg/v:QI 160 [ dl ]) 0)))
             (clobber (reg:CC 17 flags))
         ]) "pr127606.c":180:13 860 {*xorsi_1}
      (expr_list:REG_DEAD (reg:SI 343 [ df_91 ])
         (expr_list:REG_UNUSED (reg:CC 17 flags)
             (nil))))

Which LRA transforms to:

(insn 380 381 365 3 (set (mem/c:QI (plus:DI (reg/f:DI 7 sp)
                 (const_int 4 [0x4])) [11 %sfp+-52 S1 A32])
         (reg/v:QI 4 si [orig:160 dl ] [160])) "pr127606.c":180:13 102
{*movqi_internal}
      (nil))
(insn 365 380 219 3 (set (reg:SI 2 cx [410])
         (mem/c:SI (plus:DI (reg/f:DI 7 sp)
                 (const_int 4 [0x4])) [11 %sfp+-52 S4 A32]))
"pr127606.c":180:13 100 {*movsi_internal}
      (nil))
(insn 219 365 220 3 (parallel [
             (set (reg:SI 1 dx [orig:146 _47 ] [146])
                 (xor:SI (reg:SI 1 dx [orig:343 df_91 ] [343])
                     (reg:SI 2 cx [410])))
             (clobber (reg:CC 17 flags))
         ]) "pr127606.c":180:13 860 {*xorsi_1}
      (nil))

spilling in QImode and reloading in SImode.  Iff to be fixed in
LRA then I think the undefined bits would have to be spilled
and reloaded to guarantee that two uses of the "same" paradoxical
pseudo remain equal.

Vlad says this is entirely undefined but I agree the above is
quite unfortunate (and also bad for performance - a store in
QImode does not forward to a load in SImode).

Jeff/Eric, maybe you know whether it's usual to fend off against
paradoxical subregs for these kind of transforms.

Vlad - I think it's worth fixing the STLF issue and consistently
handle spill/reload -- I'd say spilling/reloading only the
defined parts is OK, but it wouldn't fix things.  spilling/reloading
up to word_mode undefined bits might be another good option
(not sure if we have, say paradoxical XImode ops that we can't spill
because of lack of move instructions).

Richard.

        PR rtl-optimization/127606
        * combine.cc (distribute_and_simplify_rtx): Gate the
        (and (xor B C) (not A)) to (xor (ior A B) (ior A C))
        distribution on A not containing a paradoxical subreg.

        * gcc.dg/pr127606.c: New testcase.
Seems sensible to me as well.

Jeff

Reply via email to