https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107627
Roger Sayle <roger at nextmovesoftware dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |roger at nextmovesoftware dot com --- Comment #4 from Roger Sayle <roger at nextmovesoftware dot com> --- I believe that tweaking i386.md's *concat<mode><dwi>3_? patterns, that call i386-expand.cc's split_double_concat, should resolve/improve the issue. Specifically in this case *concatditi3_[1234]. Currently, these patterns expect the source operands (specifically the zero_extend operand) to be registers, hence combine reports: Trying 10, 9 -> 11: 10: r96:TI=zero_extend([r92:DI+0x8]) REG_DEAD r92:DI 9: {r95:TI=r94:TI<<0x40;clobber flags:CC;} REG_DEAD r94:TI REG_UNUSED flags:CC 11: {r97:TI=r95:TI|r96:TI;clobber flags:CC;} REG_DEAD r96:TI REG_DEAD r95:TI REG_UNUSED flags:CC ... Failed to match this instruction: (set (reg:TI 97) (ior:TI (ashift:TI (reg:TI 94 [ *y_3(D) ]) (const_int 64 [0x40])) (zero_extend:TI (mem:DI (plus:DI (reg/v/f:DI 92 [ yD.1994 ]) (const_int 8 [0x8])) [1 MEM[(const long long unsigned intD.1 6 *)y_3(D) + 8B]+0 S8 A64])))) If *concatditi3_1 allowed a memory_operand for operand 3, it would match. The oversight is that the zero_extendditi2 pattern (in insn #10) accepts memory operands. I suspect changing the predicates for operands 0, 1 and 3 to be nonimmediate_operand, but then providing constraints for each permissible variation should work. Using the <dwi> expansion of these splitters should also fix the (pre-existing) -m32 code generation issue, as pointed out by Jakub in comment #3. Perhaps: (define_insn_and_split "*concat<mode><dwi>3_1" [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r") (any_or_plus:<DWI> (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "r,o,r") (match_operand:<DWI> 2 "const_int_operand")) (zero_extend:<DWI> (match_operand:DWIH 3 "nonimmediate_operand" "r,r,o"))))] I hope this helps.