https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128223

            Bug ID: 128223
           Summary: Widening FP subtraction with broadcasted element wrong
                    on RISC-V?
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

This started an an LLM question for this pattern:

(define_insn "@pred_single_widen_<plus_minus:optab><mode>_scalar"
  [(set (match_operand:VWEXTF 0 "register_operand"                "=vd, vd, vr,
vr")
        (if_then_else:VWEXTF
          (unspec:<VM>
            [(match_operand:<VM> 1 "vector_mask_operand"          " vm,
vm,Wc1,Wc1")
             (match_operand 5 "vector_length_operand"            
"rvl,rvl,rvl,rvl")
             (match_operand 6 "const_int_operand"                 "  i,  i,  i,
 i")
             (match_operand 7 "const_int_operand"                 "  i,  i,  i,
 i")
             (match_operand 8 "const_int_operand"                 "  i,  i,  i,
 i")
             (match_operand 9 "const_int_operand"                 "  i,  i,  i,
 i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)
             (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
          (plus_minus:VWEXTF
            (vec_duplicate:VWEXTF
              (float_extend:<VEL>
                (match_operand:<VSUBEL> 4 "register_operand"      "  f,  f,  f,
 f")))
            (match_operand:VWEXTF 3 "register_operand"            " vr, vr, vr,
vr"))
          (match_operand:VWEXTF 2 "vector_merge_operand"          " vu,  0, vu,
 0")))]
  "TARGET_VECTOR"
  "vfw<insn>.wf\t%0,%3,%4%p1"
  [(set_attr "type" "vf<widen_binop_insn_type>")
   (set_attr "mode" "<V_DOUBLE_TRUNC>")
   (set (attr "frm_mode")
        (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])

In particular concerns that the assembly does not match the RTL.

/* { dg-do run { target riscv_v_ok } } */
/* { dg-options "-O2 -march=rv64gcv -mabi=lp64d" } */

#include <riscv_vector.h>

__attribute__ ((noinline, noclone))
double f (double x, float y)
{
  double out;
  vfloat64m2_t a = __riscv_vfmv_v_f_f64m2 (x, 1);
  vfloat64m2_t r = __riscv_vfrsub_vf_f64m2 (a, (double) y, 1);
  __riscv_vse64_v_f64m2 (&out, r, 1);
  return out;
}

int main (void)
{
  /* vfrsub computes rs1 - vs2, so 3.0 - 10.0.  */
  if (f (10.0, 3.0f) != -7.0)
    __builtin_abort ();

  __builtin_exit (0);
}

It's LLM discovered and LLM generated testcase.  So salt strongly recommended.

Reply via email to