https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108826
--- Comment #9 from Kishan Parmar <kishan at gcc dot gnu.org> --- Created attachment 63762 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=63762&action=edit simplify_shift_const_1 patch 229 Trying 9, 11, 13 -> 14: 230 9: r124:SI=r125:SI 0>>0x6 231 REG_DEAD r125:SI 232 11: {r127:DI=r124:SI#0&0x5;clobber scratch;} 233 REG_DEAD r124:SI 234 13: r129:DI=r127:DI+0xc8 235 REG_DEAD r127:DI 236 14: r130:DI=r129:DI<<0x2 237 REG_DEAD r129:DI 238 Failed to match this instruction: 239 (set (reg:DI 130) 240 (plus:DI (and:DI (ashift:DI (lshiftrt:DI (subreg:DI (reg:SI 125 [ var ]) 0) 241 (const_int 6 [0x6])) 242 (const_int 2 [0x2])) 243 (const_int 20 [0x14])) 244 (const_int 800 [0x320]))) 245 Failed to match this instruction: 246 (set (reg:DI 129) 247 (and:DI (ashift:DI (lshiftrt:DI (subreg:DI (reg:SI 125 [ var ]) 0) 248 (const_int 6 [0x6])) 249 (const_int 2 [0x2])) 250 (const_int 20 [0x14]))) After the patch, i am able combine the shifts, and having new expression as 238 Failed to match this instruction: 239 (set (reg:DI 130) 240 (plus:DI (and:DI (lshiftrt:DI (subreg:DI (reg:SI 125 [ var ]) 0) 241 (const_int 4 [0x4])) 242 (const_int 20 [0x14])) 243 (const_int 800 [0x320]))) 244 Failed to match this instruction: 245 (set (reg:DI 129) 246 (and:DI (lshiftrt:DI (subreg:DI (reg:SI 125 [ var ]) 0) 247 (const_int 4 [0x4])) 248 (const_int 20 [0x14]))) So the shifts are properly simplified. However, the resulting RTL still fails to match. Combine attempts splitting when three insns are combined and the result can be split into two insns. In this case we combine four insns, and the canonical form would require splitting into three, which combine does not handle. Question: Should this be handled in the backend via a define_insn_and_split (matching (and (lshiftrt ...)) and lowering appropriately), or should combine grow logic to handle the case where combining four insns fails to match but can be simplified and split into three?
