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 --