llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.01k stars 11.96k forks source link

subtraction of unsigned offset overflow false alarm at -O2 and -O3 #98445

Open bi6c opened 4 months ago

bi6c commented 4 months ago
#include<stdio.h>
#include<stdint.h>

static int32_t a = 0xD7953644L;
static uint32_t b = 0x97812A3CL;

static int8_t  func_1(void)
{
    int32_t *c[4];
    int32_t j = 0xB7161AB6L;
    int i;
    for (i = 0; i < 4; i++)
      c[i] = &a;
p:
    --b;
    for (j = 0; (j != 20); j++)
    {
        uint32_t d = 0xE0C863CCL;
        uint64_t e = 0x95E2DE4BF748DC16LL;
        ++d;
        --e;
    }
    if (j)
        goto p;
    return a;
}

void main()
{
    func_1();
    printf("%d", b);
}

Hello, we are using clang to compile the above code in Ubuntu 22.04.3 LTS. We found a case that there are discrepancies when compiling with llvmorg-14.0.6 at -O2 and -O3. Is the discrepancy caused by infinite loop in the program? since the behavior is undefined before P2809.

$ ../compiler-builds/llvmorg-14.0.6_build/bin/clang -fsanitize=undefined -fsanitize=address --rtlib=compiler-rt -g -lgcc_s -O2 testcase.c -o exec

$ timeout 1s ./exec 2>exec.err
testcase.c:13:7: runtime error: subtraction of unsigned offset from 0x7ffe760240e0 overflowed to 0x7ffe760240f8 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior analysis/test960851-m.c:13:7 in AddressSanitizer:DEADLYSIGNAL ================================================================= ==351086==ERROR: AddressSanitizer: SEGV on unknown address 0x000041b58ab3 (pc 0x000041b58ab3 bp 0x7ffe76024190 sp 0x7ffe760240c8 T0) ==351086==The signal is caused by a READ memory access. AddressSanitizer:DEADLYSIGNAL AddressSanitizer: nested bug in the same thread, aborting.

$ ../compiler-builds/llvmorg-13.0.1_build/bin/clang -fsanitize=undefined -fsanitize=address --rtlib=compiler-rt -g -lgcc_s -O2 testcase.c -o exec

$ timeout 1s ./exec 2>exec.err
EugeneZelenko commented 4 months ago

Could you please try 18 or main branch? https://godbolt.org should be helpful.

dtcxzyw commented 4 months ago

Could you please try 18 or main branch? https://godbolt.org should be helpful.

I cannot reproduce this with clang-19.

dtcxzyw@dtcxzyw:~/WorkSpace/Projects/compilers/LLVM/llvm-build$ clang -O2 -fsanitize=undefined -fsanitize=address --rtlib=compiler-rt -g -lgcc_s -O2 test.c
test.c:28:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
   28 | void main()
      | ^
test.c:28:1: note: change return type to 'int'
   28 | void main()
      | ^~~~
      | int
1 warning generated.
dtcxzyw@dtcxzyw:~/WorkSpace/Projects/compilers/LLVM/llvm-build$ ./a.out 
dtcxzyw@dtcxzyw:~/WorkSpace/Projects/compilers/LLVM/llvm-build$ echo $?
88
dtcxzyw@dtcxzyw:~/WorkSpace/Projects/compilers/LLVM/llvm-build$ clang -v
Ubuntu clang version 19.0.0 (++20240701042455+8598bcb9934d-1~exp1~20240701042602.1778)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm-19/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/12
Candidate multilib: .;@m64
Selected multilib: .;@m64
Found CUDA installation: /usr/local/cuda-11.7, version 11.7
dtcxzyw@dtcxzyw:~/WorkSpace/Projects/compilers/LLVM/llvm-build$
bi6c commented 4 months ago

Could you please try 18 or main branch? https://godbolt.org should be helpful.

I tried clang-14 and trunk here https://godbolt.org/z/WKsav9387

bi6c commented 4 months ago

Sorry, the runtime error message is in exec.err. Here is the updated console.

$ ../compiler-builds/llvmorg-14.0.6_build/bin/clang -fsanitize=undefined -fsanitize=address --rtlib=compiler-rt -g -lgcc_s -O2 testcase.c -o exec
$ timeout 1s ./exec 2>exec.err

$ cat exec.err
testcase.c:13:7: runtime error: subtraction of unsigned offset from 0x7ffe760240e0 overflowed to 0x7ffe760240f8 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior analysis/test960851-m.c:13:7 in AddressSanitizer:DEADLYSIGNAL ================================================================= ==351086==ERROR: AddressSanitizer: SEGV on unknown address 0x000041b58ab3 (pc 0x000041b58ab3 bp 0x7ffe76024190 sp 0x7ffe760240c8 T0) ==351086==The signal is caused by a READ memory access. AddressSanitizer:DEADLYSIGNAL AddressSanitizer: nested bug in the same thread, aborting.

$ ../compiler-builds/llvmorg-13.0.1_build/bin/clang -fsanitize=undefined -fsanitize=address --rtlib=compiler-rt -g -lgcc_s -O2 testcase.c -o exec
$ timeout 1s ./exec 2>exec.err

$ cat exec.err
EugeneZelenko commented 4 months ago

Even 18 is near end of maintenance.

bi6c commented 4 months ago

It seems to me that the infinite loop affected UBSAN to report undefined behaviors in clang-14. However, the behavior of infinite loop is undefined before P2809. Then, can we still consider whether UBSAN reported incorrectly in clang-14?