https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92263
--- Comment #5 from Jim Wilson <wilson at gcc dot gnu.org> --- The patch adds a RISC-V mov<mode>cc pattern. This causes toplev.c to enable flag_tree_cselim. This optimization pass creates a complex long double conditional move via a phi node. complex long double cstore_31; ... <bb 5> [local count: 27903866]: cstore_30 = MEM <complex long double> [(void *)_8]; <bb 6> [local count: 55807731]: # cstore_31 = PHI <__complex__ (0.0, 0.0)(4), cstore_30(5)> MEM <complex long double> [(void *)_8] = cstore_31; When we try to convert gimple to rtl, eliminate_phi calls insert_value_copy_on_edge for the 32-byte long double 0 value. The constant then gets forced to memory, and we end up calling emit_block_move with BLOCK_OP_NO_LIBCALL, which ends up emitting a loop to do the memory to memory copy. Then later in commit_one_edge_insertion we split the edge, insert the code containing the loop, and then trigger an abort because the last instruction inserted is the loop back branch. I don't see where the RISC-V port did anything wrong. The load hoisting code is checking the movcc optab to see if the target supports the operation, but I don't see anything obvious like that in the cselim pass. The only obvious fix I see in the RISC-V back end is to modify riscv_expand_block_move to emit inline non-loop code for a 32-byte memory to memory copy, even when optimizing for size, which I'd rather not do. Maybe it can be fixed in commit_one_edge_insertion by allowing conditional branches but not unconditional branches, but it isn't clear why this is refusing to allow branches here in the first place. I will have to look at other targets to see why they aren't failing.