CMSIS-DSP icon indicating copy to clipboard operation
CMSIS-DSP copied to clipboard

GCC error - missing cast in MVE arm_biquad_cascade_df1_q15

Open kjbracey opened this issue 3 years ago • 12 comments

We've had a report that GCC doesn't like the MVE version of arm_biquad_cascade_df1_q15. And its complaint seems valid:

https://github.com/ARM-software/CMSIS-DSP/blob/302897a523f5abae63fae9bdb3bbfc1e3089a55a/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c#L105-L108

arm_biquad_cascade_df1_q15.c:106:13: error: incompatible types when assigning to type 'q15x8_t' {aka 'int16x8_t'} from type 'int32x4_t'

I'd say you need an explicit (q15x8_t) cast on the output of vsetq_lane_s32.

What's not clear to me is why armclang accepts it, which it does. Indeed, armclang doesn't seem to require the existing (q31x4_t) casts either, at least within that C file.

Pasting the same function into some other C++ code I had handy made armclang produce the equivalent error, unless you have 3 casts. Is it performing implicit conversion in C mode, maybe? Intentionally? Possible armclang bug?

kjbracey avatar Oct 19 '22 14:10 kjbracey

While looking around build systems, I've just noticed that GCC's behaviour here is configurable via -flax-vector-conversions.

kjbracey avatar Oct 25 '22 11:10 kjbracey

It is advised to use -flax-vector-conversions because there are some cases where the use of the intrinsic is valid but gcc is nevertheless generating a warning.

But, I'll look at above case because I think it needs the cast.

christophe0606 avatar Oct 26 '22 04:10 christophe0606

Any thoughts on the C vs C++ difference in armclang (if that's what it is)? I don't see such a thing documented. Can you control it?

There were no other reports from our customer of GCC problems without the -flax-vector-conversions, so it's possible that GCC is better than it used to be.

kjbracey avatar Oct 26 '22 05:10 kjbracey

I don't know the differences between C and C++ for handling the intrinsics.

So you confirm that for the arm_biquad_cascade_df1_q15, you get cast warnings in C++ with armclang but none from C ?

Can you share the compilation options you used ? I'll try to reproduce and then check with our compiler team.

christophe0606 avatar Oct 27 '22 04:10 christophe0606

Yes, I've stripped it down, and confirm that it's a C/C++ difference

Given this source:

#include "arm_mve.h"

int16x8_t test(int32x4_t a)
{
    return a;
}

That's accepted without warnings if it's input as C:

armclang --target=arm-arm-none-eabi -mcpu=cortex-m55 -O2 -S vectest.c

But rejected with the type error (not warning) if it comes in as vectest.cpp. Compiler version 6.18.

Conceptually I see no reason for C to be more lax here, and I've not found this documented as being by design. Sure, C++ is more type strict on a few scalar things, like enums and bools, but C has always been just as strict as C++ on aggregates, which these vectors effectively are.

(GCC 11.3 rejects it as either C or C++, unless you have -flax-vector-conversions.)

kjbracey avatar Oct 27 '22 06:10 kjbracey

Compiler team tells me that the C and C++ standards are not managing implicit casts in the same way. But otherwise, for this specific example they can't say more.

christophe0606 avatar Oct 27 '22 09:10 christophe0606

Arm C Language Extensions document just says that such implicit conversions are not portable (for C or C++) - and to use vreinterpretq. (It doesn't actually say explicit conversions via casts are portable.)

So the C compiler is free to give the error, and I think it would be far more helpful if it did. Was trying to check whether this has changed since armcc, but don't have a copy to hand.

kjbracey avatar Oct 27 '22 10:10 kjbracey

Minor update, as I found some discussion elsewhere - clang and armclang do also have the -flax-vector-conversions flag, slightly extended to support three options: =none, =int, =all.

Documentation for clang says the default is -flax-vector-conversions=int = -flax-vector-conversions, but as we saw above, the default is actually none for C++.

You can get armclang to reject the above code in C by adding -flax-vector-conversions=none or -fno-lax-vector-conversions. I'll be adding that to my own projects. (I've made too many mistakes from its absence!)

Which in turn means that the change in #65 technically needs to also be applied for armclang. If someone has made vectors strict in the global CMake compile flags (or a future clang has tightened up), it needs to be overridden for the CMSIS-DSP target.

kjbracey avatar Mar 06 '23 14:03 kjbracey

@kjbracey Thanks for the feedback !

christophe0606 avatar Mar 06 '23 15:03 christophe0606

@kjbracey I have added a cmake option to enable / disable lax vector conversions when building for Helium with gcc or ArmClang. By default it is ON since currently some parts of the library won't build without it.

christophe0606 avatar Mar 09 '23 08:03 christophe0606

You could scale that back a bit, as I assume you don't actually need "=all", as that's not the default for clang (since clang 10), and it's laxer than gcc, which only permits the integer->integer laxness. So you can set clang to "=integer", or just use the same simple flags as gcc.

"=all" is the clang-9-and-earlier default behaviour and what -flax-vector-conversions used to mean for it, but they changed it to match gcc.

https://releases.llvm.org/10.0.0/tools/clang/docs/ReleaseNotes.html

kjbracey avatar Mar 09 '23 08:03 kjbracey

@kjbracey You're right. It build without problems with integer. I have just pushed the change.

christophe0606 avatar Mar 09 '23 09:03 christophe0606