Created attachment 64764 [details] pr25754-1a.c With GCC trunk, two binutils ld tests fail: ``` $ grep ^FAIL ld.log FAIL: Run pr25754-1aa (-no-pie -fno-PIE -w) FAIL: Run pr25754-1ba (-no-pie -fPIE -w) ``` test.sh: ``` #!/bin/bash set -x gcc -O3 -fno-PIE pr25754-1a.c -o pr25754-1a.o -c gcc -fno-PIE pr25754-1b.s -o pr25754-1b.o -c gcc -no-pie -z noexecstack pr25754-1a.o pr25754-1b.o -o pr25754-1ba ./pr25754-1ba &> x.txt grep -q "PASS" x.txt && exit 0 exit 1 ``` It works with -O0.
Created attachment 64765 [details] pr25754-1b.s
If I add: else __builtin_printf("p=%p\n", get_bar()); ``` $ ./a.sh || cat x.txt + gcc -O3 -fno-PIE pr25754-1a.c -o pr25754-1a.o -c + gcc -fno-PIE pr25754-1b.s -o pr25754-1b.o -c + gcc -no-pie -z noexecstack pr25754-1a.o pr25754-1b.o -o pr25754-1ba + ./pr25754-1ba + grep -q PASS x.txt + exit 1 p=0x2a ``` It works at -O0.
Interestingly, its siblings pass with e.g. 0xfffffff0U in pr25754-2a.c.
This one is standalone and it fails too: ``` #include <stdint.h> uintptr_t bar; uintptr_t * __attribute__ ((noinline, noclone)) get_bar (void) { return &bar; } int main () { if ((uintptr_t) get_bar () != 42) __builtin_abort(); return 0; } ``` I don't think the optimisation is valid for this variant unless -fno-semantic-interposition is used, because an interposed get_bar could return a pointer to some malloc'd memory that has 42?
(In reply to Sam James from comment #4) > This one is standalone and it fails too: > ... > I don't think the optimisation is valid for this variant unless > -fno-semantic-interposition is used, because an interposed get_bar could > return a pointer to some malloc'd memory that has 42? With trunk, it unconditionally calls abort; in 16, it doesn't.
Most likely `&a` is thought not to be a null pointer and 42 is in the same "page" as the zero page ...
(In reply to Drea Pinski from comment #6) > Most likely `&a` is thought not to be a null pointer and 42 is in the same > "page" as the zero page ... s/a/bar/ but the generic idea stands.
(In reply to Drea Pinski from comment #6) > Most likely `&a` is thought not to be a null pointer and 42 is in the same > "page" as the zero page ... 800 seems a magic number. Below it, get_bar call is optimized out.
--param min-pagesize (ok, meant to only be for warnings) and -fno-delete-null-pointer-checks (supposed to say if you can have a pointer at 0 as well for some targets) don't make a difference.
Note 42 is not aligned. Switching to 40 works.
Basically I think the issue is the testcase. Adding noipa also allows it to work.
Even fails with clang.
(In reply to Drea Pinski from comment #10) > Note 42 is not aligned. > Switching to 40 works. Oh.
I think the testcase is bogus, move back to binutils.