I've a IA-32 backend question on the intended behaviour of the functions
ix86_binary_operator_ok and ix86_fixup_binary_operands.

My confusion is that these functions currently allow arithmetic
operations of the form "reg = op(mem,immed)" even though this
shape isn't supported by x86 ISA.  For example, the following
simple test code,

int foo(int x)
{
  return x | 4;
}

generates the following RTL in combine:

(insn 11 4 16 0 (parallel [
            (set (reg:SI 60)
                (ior:SI (mem/f:SI (reg/f:SI 16 argp) [2 x+0 S4 A32])
                    (const_int 4 [0x4])))
            (clobber (reg:CC 17 flags))
        ]) 209 {*iorsi_1} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

which is then later fixed up by postreload.


My first question is whether this is intentional or an oversight?

The reason I ask/noticed this was that I'm working on a RTL patch to
canonicalize shifts vs. arithmetic operations, such that we always
perform the shift first.  This should be a big win on ARM, but will
also allow us to simplify code such as:

        x ^= 8;
        x >>= 2;
        x ^= 1;

where by reordering the arithmetic operations relative to the
shifts, we can catch more simplifications in combine.

The catch is that currently i386.md allows combine to first
combine commutative arithmetic operations with memory, creating
reg = xor(mem,8); reg = rshift(reg,2), but then inconsistently
won't allow a memory as the first operand in the non-commutative
shift operation, i.e. we're not allowed to create reg = rshift(mem,2).

Clearly there's an inconsistency.  So the options include to either
allow reg = op(mem,immed) for non-commutative operators to also be
fixed by postreload, if the current behaviour is intentional and serves
some useful purpose, or alternatively to change ix86_binary_operator_ok
so that we only allow valid instructions at this point.

Many thanks in advance,

Roger
--

Reply via email to