Am 15.07.24 um 19:53 schrieb Richard Sandiford:
Georg-Johann Lay <a...@gjlay.de> writes:
In a test case I see insn combine trying to match such
expressions, which do not make any sense to me, like:

Trying 2 -> 7:
      2: r45:HI=r48:HI
        REG_DEAD r48:HI
      7: {r47:HI=r45:HI|r46:PSI#0;clobber scratch;}
        REG_DEAD r46:PSI
        REG_DEAD r45:HI
Failed to match this instruction:
(parallel [
          (set (reg:HI 47 [ _4 ])
              (ior:HI (clobber:HI (const_int 0 [0]))
                  (reg:HI 48)))
          (clobber (scratch:QI))
      ])

and many other occasions like that.

Is this just insn combine doing its business?

Or should this be some sensible RTL instead?

Seen on target avr with v14 and trunk,
attached test case and dump compiled with

(clobber:M (const_int 0)) is combine's way of representing
"something went wrong here".  And yeah, recog acts as an error
detection mechanism in these cases.  In other words, the idea
is that recog should eventually fail on nonsense rtl like that,
so earlier code doesn't need to check explicitly.

Richard

Hi Richard,

I never saw this before; and the point is that in some functions,
combine is almost exclusively producing these rtxes with clobber
const_int, but almost no meaningful combinations.  Like in:

typedef __UINT32_TYPE__ u32;
typedef __uint24 u24;

u24 ior24_32_8 (u24 a, u32 b)
{
  return a | (u24) b << 8;
}

u24 ior24_24_8 (u24 a, u24 b)
{
  return a | (u24) b << 8;
}

In ior24_24_8() all goes fine: combine tries sensible combinations,
and uses them (provided the backend has patterns for it of course).

With ior24_32_8() however, it is almost only silly combinations
(or "something goes wrong in combine"), even though the assembly
code for either functions could be exactly the same (the only
difference is that hard reg R21 is input to the 1st function).

As an example, for the 2nd function it tries

(set (reg:PSI 47 [ _4 ])
     (ior:PSI (ashift:PSI (reg:PSI 50)
                          (const_int 8 [0x8]))
              (reg:PSI 49)))

but for the 1st function it reads:

(set (reg:PSI 48 [ _5 ])
     (ior:PSI (ashift:PSI (clobber:PSI (const_int 0 [0]))
                          (const_int 8 [0x8]))
              (reg:PSI 50)))


Johann




Reply via email to