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

            Bug ID: 118901
           Summary: RISC-V: bfloat16-complex.c:(.text.startup+0x5f6):
                    undefined reference to `__divbc3' when zfh or zvfh
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: majin at gcc dot gnu.org
  Target Milestone: ---

$ riscv64-unknown-linux-gnu-gcc gcc/testsuite/gcc.dg/torture/bfloat16-complex.c
-march=rv64gc_zfh -mabi=lp64d -mcmodel=medany

riscv64-unknown-linux-gnu/bin/ld: /tmp/cc3e0Vp7.o: in function `main':
bfloat16-complex.c:(.text+0x79e): undefined reference to `__mulbc3'
riscv64-unknown-linux-gnu/bin/ld: bfloat16-complex.c:(.text+0x842): undefined
reference to `__divbc3'
collect2: error: ld returned 1 exit status


In the floating-point complex test cases, ZFH has led to failures due to
invalid libcalls.

I performed some basic debugging and it seems that the issue is caused by the
function below returning FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. Perhaps someone
here can provide some suggestions.

```
/* Set the value of FLT_EVAL_METHOD.
   ISO/IEC TS 18661-3 defines two values that we'd like to make use of:

    0: evaluate all operations and constants, whose semantic type has at
       most the range and precision of type float, to the range and
       precision of float; evaluate all other operations and constants to
       the range and precision of the semantic type;

    N, where _FloatN is a supported interchange floating type
       evaluate all operations and constants, whose semantic type has at
       most the range and precision of _FloatN type, to the range and
       precision of the _FloatN type; evaluate all other operations and
       constants to the range and precision of the semantic type;

   If we have the zfh/zhinx/zvfh extensions then we support _Float16
   in native precision, so we should set this to 16.  */
static enum flt_eval_method
riscv_excess_precision (enum excess_precision_type type)
{
  switch (type)
    {
    case EXCESS_PRECISION_TYPE_FAST:
    case EXCESS_PRECISION_TYPE_STANDARD:
      return ((TARGET_ZFH || TARGET_ZHINX || TARGET_ZVFH)
                ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
                : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
    case EXCESS_PRECISION_TYPE_IMPLICIT:
    case EXCESS_PRECISION_TYPE_FLOAT16:
      return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
    default:
      gcc_unreachable ();
    }
  return FLT_EVAL_METHOD_UNPREDICTABLE;
}
```

Reply via email to