On Thu, Dec 17, 2020 at 12:51:52AM +0100, Luc Van Oostenryck wrote: > > But replacing a trunc + zext by the corresponding masking, very > little, if anything is done for such 'mixed-width' expressions. > So, I'm even a bit surprised by the not.8 but well ... This bothered me a bit and kept me awake, so I had to check. I think that the situation is caused by some premature optimization for the ~ operator in expression.c:cast_to(). It saves the allocation and initialization of one expression but makes things more complicated at linearization and simplification. If this is disabled, then the IR simplification returns what I was expecting: maskout: zext.32 %r2 <- (8) %arg1 shl.32 %r5 <- $1, %arg2 not.32 %r6 <- %r5 and.32 %r9 <- %r6, $255 and.32 %r10 <- %r2, %r9 trunc.8 %r11 <- (32) %r10 ret.8 %r11 and some reassociation patches (coming soon) will simplify away the masking with $255 and the trunc.8 -- Luc