https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101129
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I think this is a bug in the swaps rs6000 specific pass. It in particular changes (insn 20 19 21 2 (set (reg:DI 155) (mult:DI (reg:DI 224) - (subreg:DI (reg:V16QI 148) 0))) "pr101129.c":14:8 154 {muldi3} + (subreg:DI (reg:V16QI 148) 8))) "pr101129.c":14:8 154 {muldi3} (nil)) (insn 21 20 22 2 (set (reg:DI 156) (subreg:DI (mult:TI (zero_extend:TI (reg:DI 224)) - (zero_extend:TI (subreg:DI (reg:V16QI 148) 0))) 8)) "pr101129.c":14:8 166 {umuldi3_highpart_le} + (zero_extend:TI (subreg:DI (reg:V16QI 148) 8))) 0)) "pr101129.c":14:8 166 {umuldi3_highpart_le} (nil)) The SUBREG_BYTE changes in subregs of pseudo 148 look reasonable as the pass removed a xxswapd_v16qi that was swapping the value set to that pseudo. But the 8 to 0 change of SUBREG_BYTE with SUBREG_REG of MULT looks wrong, that wouldn't even match unless simplified and turns a highpart multiply into lowpart multiply. So either the swaps pass needs to be fixed not to do that, or the highpart multiply instructions should be changed to e.g. use lshiftrt by 64 instead of highpart subreg of the result.