https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113474
--- Comment #1 from Robin Dapp <rdapp at gcc dot gnu.org> --- Good catch. Looks like the ifn expander always forces into a register. That's probably necessary on all targets except riscv. diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index a07f25f3aee..e923051d540 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3118,7 +3118,8 @@ expand_vec_cond_mask_optab_fn (internal_fn, gcall *stmt, convert_optab optab) rtx_op2 = expand_normal (op2); mask = force_reg (mask_mode, mask); - rtx_op1 = force_reg (mode, rtx_op1); + if (!insn_operand_matches (icode, 1, rtx_op1)) + rtx_op1 = force_reg (mode, rtx_op1); rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); create_output_operand (&ops[0], target, mode); gives me: foo: .LFB0: .cfi_startproc ble a0,zero,.L5 slli a3,a0,3 add a3,a1,a3 vsetivli zero,4,e32,m1,ta,ma vmv.v.i v3,15 vmv.v.i v2,0 .L3: ld a5,0(a1) addi a4,a5,4 addi a5,a5,20 vle32.v v1,0(a5) vle32.v v0,0(a4) vmseq.vv v0,v0,v3 vmerge.vim v4,v2,1,v0 vse32.v v4,0(a4) vmseq.vv v0,v1,v3 addi a1,a1,8 vmerge.vim v1,v2,1,v0 vse32.v v1,0(a5) bne a1,a3,.L3 .L5: ret