[Bug target/97349] New: Incorrect types for some Neon vdupq_n_<...> intrinsics

2020-10-09 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97349

Bug ID: 97349
   Summary: Incorrect types for some Neon vdupq_n_<...> intrinsics
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.spickett at linaro dot org
  Target Milestone: ---

Created attachment 49337
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49337&action=edit
test C file

The attached file has function pointers with the expected types for these
intrinsics as shown in the ACLE. 

https://developer.arm.com/architectures/instruction-sets/simd-isas/neon/intrinsics?search=vdupq_n_

This fails to compile because some of the intrinsic types are incorrect.
(I haven't included all the vdupq_n_, just the ones that have issues)

$ ./aarch64-none-elf-gcc -v
Using built-in specs.
COLLECT_GCC=./aarch64-none-elf-gcc
COLLECT_LTO_WRAPPER=/arm/pdtl/builds/fsf-trunk.2226/installed/rhe6x86_64/aarch64-none-elf/bin/../libexec/gcc/aarch64-none-elf/11.0.0/lto-wrapper
Target: aarch64-none-elf
Configured with:
/tmp/dgboter/bbs/rhev-vm4--rhe6x86_64/buildbot/rhe6x86_64--aarch64-none-elf/build/src/gcc/configure
--target=aarch64-none-elf
--prefix=/tmp/dgboter/bbs/rhev-vm4--rhe6x86_64/buildbot/rhe6x86_64--aarch64-none-elf/build/build-aarch64-none-elf/install//
--with-gmp=/tmp/dgboter/bbs/rhev-vm4--rhe6x86_64/buildbot/rhe6x86_64--aarch64-none-elf/build/build-aarch64-none-elf/host-tools
--with-mpfr=/tmp/dgboter/bbs/rhev-vm4--rhe6x86_64/buildbot/rhe6x86_64--aarch64-none-elf/build/build-aarch64-none-elf/host-tools
--with-mpc=/tmp/dgboter/bbs/rhev-vm4--rhe6x86_64/buildbot/rhe6x86_64--aarch64-none-elf/build/build-aarch64-none-elf/host-tools
--with-isl=/tmp/dgboter/bbs/rhev-vm4--rhe6x86_64/buildbot/rhe6x86_64--aarch64-none-elf/build/build-aarch64-none-elf/host-tools
--disable-shared --disable-nls --disable-threads --disable-tls
--enable-checking=yes --enable-languages=c,c++,fortran --with-newlib
--with-pkgversion=fsf-trunk.2226
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 11.0.0 20200609 (experimental) (fsf-trunk.2226)

$ ./aarch64-none-elf-gcc /tmp/test.c -Wall -Wextra -c -o /dev/null
/tmp/test.c:3:32: warning: initialization of 'poly16x8_t (*)(poly16_t)' {aka
'poly16x8_t (*)(__Poly16_t)'} from incompatible pointer type 'poly16x8_t
(*)(uint32_t)' {aka 'poly16x8_t (*)(unsigned int)'}
[-Wincompatible-pointer-types]
3 | poly16x8_t  (*fp0)(poly16_t) = vdupq_n_p16;
  |^~~
/tmp/test.c:4:32: warning: initialization of 'poly64x2_t (*)(poly64_t)' {aka
'poly64x2_t (*)(__Poly64_t)'} from incompatible pointer type 'poly64x2_t
(*)(uint64_t)' {aka 'poly64x2_t (*)(long unsigned int)'}
[-Wincompatible-pointer-types]
4 | poly64x2_t  (*fp1)(poly64_t) = vdupq_n_p64;
  |^~~
/tmp/test.c:5:32: warning: initialization of 'poly8x16_t (*)(poly8_t)' {aka
'poly8x16_t (*)(__Poly8_t)'} from incompatible pointer type 'poly8x16_t
(*)(uint32_t)' {aka 'poly8x16_t (*)(unsigned int)'}
[-Wincompatible-pointer-types]
5 | poly8x16_t  (*fp2)(poly8_t)  = vdupq_n_p8;
  |^~
/tmp/test.c:6:32: warning: initialization of 'int16x8_t (*)(int16_t)' {aka
'int16x8_t (*)(short int)'} from incompatible pointer type 'int16x8_t
(*)(int32_t)' {aka 'int16x8_t (*)(int)'} [-Wincompatible-pointer-types]
6 | int16x8_t   (*fp3)(int16_t)  = vdupq_n_s16;
  |^~~
/tmp/test.c:7:32: warning: initialization of 'int8x16_t (*)(int8_t)' {aka
'int8x16_t (*)(signed char)'} from incompatible pointer type 'int8x16_t
(*)(int32_t)' {aka 'int8x16_t (*)(int)'} [-Wincompatible-pointer-types]
7 | int8x16_t   (*fp4)(int8_t)   = vdupq_n_s8;
  |^~
/tmp/test.c:8:32: warning: initialization of 'uint16x8_t (*)(uint16_t)' {aka
'uint16x8_t (*)(short unsigned int)'} from incompatible pointer type
'uint16x8_t (*)(uint32_t)' {aka 'uint16x8_t (*)(unsigned int)'}
[-Wincompatible-pointer-types]
8 | uint16x8_t  (*fp5)(uint16_t) = vdupq_n_u16;
  |^~~
/tmp/test.c:9:32: warning: initialization of 'uint8x16_t (*)(uint8_t)' {aka
'uint8x16_t (*)(unsigned char)'} from incompatible pointer type 'uint8x16_t
(*)(uint32_t)' {aka 'uint8x16_t (*)(unsigned int)'}
[-Wincompatible-pointer-types]
9 | uint8x16_t  (*fp6)(uint8_t)  = vdupq_n_u8;
  |^~

[Bug c++/108642] New: ACLE function __arm_wsr missing when compiling in C++ mode for AArch64

2023-02-02 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108642

Bug ID: 108642
   Summary: ACLE function __arm_wsr missing when compiling in C++
mode for AArch64
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.spickett at linaro dot org
  Target Milestone: ---

This was found by a user trying to compile llvm's libc (which is largely
written in c++) using g++ 8.5.0 for AArch64. I then tried versions up to 12.2.0
and a recent trunk build.

https://godbolt.org/z/qxaYxdTcv, and I've copied the details below.

The following source:
```
#include 
#include 

void writeStatusWord(uint32_t fpsr) { __arm_wsr("fpsr", fpsr); }
```

When compiled with g++ gives the error:
```
:4:39: error: '__arm_wsr' was not declared in this scope
4 | void writeStatusWord(uint32_t fpsr) { __arm_wsr("fpsr", fpsr); }
  |   ^
```

When compiled as C, there is instead a warning and it does compile:
```
:4:39: warning: implicit declaration of function '__arm_wsr'
[-Wimplicit-function-declaration]
4 | void writeStatusWord(uint32_t fpsr) { __arm_wsr("fpsr", fpsr); }
  |   ^
```

The expected result would be that in either mode, we can compile without errors
or warnings.

This __arm_wsr function should be present after including arm_acle.h according
to https://github.com/ARM-software/acle/releases/tag/r2022Q4 (acle-2022Q4.pdf
). See "11.1 Special register intrinsics".

I looked in the arm_acle.h gcc/g++ is including and see no reference to it.
Which makes me wonder if it's a compiler builtin that somehow isn't present for
C++.

Over in clang there is a builtin for it, that is then #defined into the
__arm_wsr name in the header.

[Bug target/108642] ACLE function __arm_wsr missing for AArch64

2023-02-02 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108642

--- Comment #4 from David Spickett  ---
Of course, I was just looking at at assembly output in compiler explorer and
then locally I didn't link the object. That's why it seemed to work.

Compiling and linking I get:
$ ./bin/aarch64-none-linux-gnu-gcc /tmp/test.c -o /tmp/test.o
/tmp/test.c: In function ‘writeStatusWord’:
/tmp/test.c:4:39: warning: implicit declaration of function ‘__arm_wsr’
[-Wimplicit-function-declaration]
4 | void writeStatusWord(uint32_t fpsr) { __arm_wsr("fpsr", fpsr); }
  |   ^
<...>aarch64-none-linux-gnu/bin/ld: /tmp/ccLie8Sh.o: in function
`writeStatusWord':
test.c:(.text+0x18): undefined reference to `__arm_wsr'
collect2: error: ld returned 1 exit status

Which makes more sense.

[Bug target/108642] ACLE function __arm_wsr missing for AArch64

2023-02-03 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108642

--- Comment #6 from David Spickett  ---
Thanks for the link, we'll try to use those when we detect g++.

[Bug c/108691] New: ICE when compiling for AArch64 with BTI protection at -O1

2023-02-07 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108691

Bug ID: 108691
   Summary: ICE when compiling for AArch64 with BTI protection at
-O1
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.spickett at linaro dot org
  Target Milestone: ---

Created attachment 54416
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54416&action=edit
Output from -freport-bug

This code:
```
extern int __attribute__((returns_twice)) setjmp(void*);

void bbb(void) {
  int (*fnptr)(void*) = setjmp;
  fnptr(0);
}
```
Causes an ICE when compiled with gcc trunk.
```
during GIMPLE pass: cddce
: In function 'bbb':
:6:1: internal compiler error: in eliminate_unnecessary_stmts, at
tree-ssa-dce.cc:1512
6 | }
  | ^
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
See  for instructions.
Compiler returned: 1
```

https://godbolt.org/z/6dEMEbEG8

Compiling at -O0, or calling setjmp directly avoids the crash. There is no
crash with gcc 12.2.

Also calling setjmp directly after using the function pointer avoids the crash.
One thing that is happening here is that gcc is converting the indirect call
into a direct one. Perhaps when that is the only call in the function, that's
the problematic situation.

For context, this is not from real code. It's a clang test case for bti
protection of returns twice calls. Either way, the compiler shouldn't crash and
if there's something wrong with the source it should say so.

[Bug c/108691] ICE when compiling for AArch64 with BTI protection at -O1

2023-02-07 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108691

--- Comment #1 from David Spickett  ---
Output from freport-bug attached.

[Bug tree-optimization/108691] [13 Regression] ICE with function ptr and setjmp/returns twice at -O1

2023-02-13 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108691

--- Comment #7 from David Spickett  ---
> That still leaves us with missing abnormal edges - David, was this reduced 
> from an actual program?

No, it's a simplified version of the C used to generate an LLVM IR test case:
extern int setjmp(ptr);
extern void notsetjmp(void);

void bbb(void) {
  setjmp(0);
  int (*fnptr)(ptr) = setjmp;
  fnptr(0);
  notsetjmp();
}

The test is checking that llvm follows each call to a returns twice function
with a branch target identifier instruction. In case the function returns using
a jump instead of the normal ret. That's probably beside the point for this bug
though.

The "real code" that motivated the feature was not doing indirect calls. I just
tested that because there's no reason it shouldn't also work.

I don't know of a use case for code like this. Like you said, if the compiler
doesn't know what the indirect call target is, it won't know it's return twice.
If it does know what you're calling, you could probably just call it directly.

So I was just shuffling statements around to test clang and compare against gcc
and found the ICE that way.

[Bug tree-optimization/108691] [13 Regression] ICE with function ptr and setjmp/returns twice at -O1

2023-02-15 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108691

--- Comment #11 from David Spickett  ---
Thanks for the quick fix!

> That still leaves us with missing abnormal edges - David, was this reduced 
> from an actual program?

Further to this, someone pointed out to me that an indirect call to setjmp is
undefined behaviour:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/setjmp.html

So even if this was real code, it's undefined behaviour.

(it just so happens that llvm's IR is able to represent that situation)

[Bug testsuite/109146] New: Tail call prevention in frame-address.c is not correct

2023-03-15 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109146

Bug ID: 109146
   Summary: Tail call prevention in frame-address.c is not correct
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: testsuite
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.spickett at linaro dot org
  Target Milestone: ---

With recent changes over in clang, it's now able to see through the tail call
prevention used in
https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.c-torture/execute/frame-address.c.

The fix is pretty simple, `==` instead of `!=` will prevent the tail call.

Briefly, clang is now able to work out that if the called function returns 0,
the caller also returns 0, same for 1. Therefore, you can tail call the callee.

check_fa_work returns 0, 0 != 0 is False, so check_fa_mid returns 0
check_fa_work returns 1, 1 != 0 is True, so check_fa_mid returns 1

As far as I can tell, gcc does not do this, yet:
https://godbolt.org/z/v36zGP7f3

So it's worth fixing before gcc also starts to do this.

[Bug testsuite/109146] Tail call prevention in frame-address.c is not correct

2023-03-15 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109146

--- Comment #1 from David Spickett  ---
Correction. https://godbolt.org/z/fW5nsWE5e shows the issue when "!=" is used,
the previous link used "==" instead.

[Bug testsuite/109146] Tail call prevention in frame-address.c is not correct

2023-03-16 Thread david.spickett at linaro dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109146

--- Comment #2 from David Spickett  ---
A detail that might be useful. The callee function uses UB because it compares
pointers that don't point to the same object.

https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf 6.5.8 Relational
operators, if we follow item 6, I think we end up at "In all other cases, the
behavior is undefined.".

So if codegen changes for the tail call you may need to double check that the
UB is still doing the same as before.

(it being UB at all seems fine, I don't know how else you'd check the address
of stack frames)