https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82192
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at redhat dot com --- Comment #10 from Jeffrey A. Law <law at redhat dot com> --- Does the oddity that shifts truncate on x86, but bit operations do not come into play here? ie, (lshiftrt:SI (subreg:SI (reg:DI 94 [ a ]) 0) (subreg:QI (reg:SI 97) 0)) Has a well defined meaning for the hardware (setting aside the RTL issues momentarily). THe shift count will be truncated in the expected way. When we substitute into: (insn 14 10 15 2 (parallel [ (set (reg:HI 102) (and:HI (subreg:HI (reg:SI 98) 0) (const_int 8191 [0x1fff]))) (clobber (reg:CC 17 flags)) ]) "pr82192-2.c":7 391 {*andhi_1} (expr_list:REG_DEAD (reg:SI 98) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))) Generating: (parallel [ (set (subreg:DI (reg:HI 102) 0) (zero_extract:DI (reg:DI 94 [ a ]) (const_int 13 [0xd]) (zero_extend:SI (subreg:QI (reg:SI 97) 0)))) (clobber (reg:CC 17 flags)) ]) We no longer have the same behavior because we're not emitting a shift, but instead a bit instruction which have different semantics at the hardware level. So maybe what's needed is just guarding the transformation on SHIFT_COUNT_TRUNCATED? I don't really have time to dig into this today, but wanted to get my initial thoughts recorded.