On Mon, Aug 20, 2018 at 06:27:45PM +0100, Ramsay Jones wrote: > > > On 16/08/18 23:12, Luc Van Oostenryck wrote: > > In an expression like this, if the inner constant (K) and > > the mask are disjoint ((K & M) == 0), then the OR with > > the constant is unneeded and can be optimized away since > > the constant will be 'cleared' by the mask, giving: OP(x, K) > > > > For example, code like: > > int foo(int x) > > { > > return (x | 0xfffff000) & 0xfff; > > } > > Sorry to be dense, but I'm lost again. The above example implies > to me that OP == &, C == 0xfffff000, K == 0xfff. So what is M? > Yes ((K & C) == 0) leaving OP(x, K) => (x & 0xfff). > > Again where is M coming from? Yes, sorry, it seems that I changed my mind about using C or K and ended with things wrong. In the title OP((x | C), K), 'K' is the real constant of the operation (or the new instruction size if OP is TRUNC). In the description, I wrongly used 'K' instead of 'C' and so ((K & M) == 0) should have been ((C & M) == 0). The whole description here above should be: In an expression like this, where OP is AND, the effective mask M is K itself. Then if this mask and the inner constant (C) are disjoint ((C & M) == 0), then OR instruction is unneeded and can be optimized away since the constant will be 'cleared' by the mask, giving: AND(x, M) Much more consise (and clear!): if (C & M) = 0 then (x | C) & M = (x & M) Thanks for noticing this. -- Luc