https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122102
Bug ID: 122102
Summary: [RISCV] [Miscompile] GCC - riscv64 target, miscompiles
at -O3 as well as -O2
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: skothadiya at whileone dot in
Target Milestone: ---
Created attachment 62476
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62476&action=edit
Attached reduced testcase
GCC (riscv64 target) produces incorrect output for C program when compiled with
-O2 as well as -O3.
Description:
The C code involves a func with a assignment operation in a loop on an long
long, compiles correctly on x86_64 and produces the expected output. However,
when compiled for the riscv64 architecture, the resulting binary yields an
incorrect value. The expected output is 1, but the program returns 0. This
miscompilation occurs specifically with optimizations enabled at levels -O2 and
-O3.
Compiler flags:
-march=rv64gcv -mrvv-vector-bits=zvl -mrvv-max-lmul=dynamic -O3
Reproduction Steps:
1. Compile the test case with GCC for riscv64 using the -O2 or -O3 flag.
Reduced test-case red.c is attached.
2. Execute the compiled binary.
3. Observe the output.
COMMANDS:
/riscv-gnu-toolchain-build/bin/riscv64-unknown-linux-gnu-gcc -march=rv64gcv
-mrvv-vector-bits=zvl -mrvv-max-lmul=dynamic -O3 ./red.c -o user-config.out
-fsigned-char -fno-strict-aliasing -fwrapv -Wno-unknown-warning-option -Werror
-Wfatal-errors -Wall -Wformat -Wno-int-in-bool-context -Wno-dangling-pointer
-Wno-compare-distinct-pointer-types -Wno-overflow -Wuninitialized
-Warray-bounds -Wreturn-type -Wno-unused-function -Wno-unused-variable
-Wno-unused-but-set-variable -Wno-unused-value -Wno-address -Wno-bool-compare
-Wno-pointer-sign -Wno-bool-operation -Wno-tautological-compare
-Wno-self-assign -Wno-implicit-const-int-float-conversion
-Wno-constant-conversion -Wno-unused-value
-Wno-tautological-constant-out-of-range-compare -Wno-constant-logical-operand
-Wno-parentheses-equality -Wno-pointer-sign
gcc -O1 ./red.c -o native.out -fno-strict-aliasing -fwrapv -w
Running QEMU
QEMU_CPU=rv64,vlen=128,rvv_ta_all_1s=true,rvv_ma_all_1s=true,v=true,vext_spec=v1.0,zve32f=true,zve64f=true
timeout --verbose -k 0.1 4 /riscv-gnu-toolchain-build/bin/qemu-riscv64
user-config.out 1
timeout --verbose -k 0.1 1 ./native.out 1
user-config qemu exit code:
0
native exit code:
0
Exit codes have been locked in, ensuring they match.
Checking for sanitizer errors with clang.
clang -fsanitize=undefined ./red.c -w -o clang-sanitize.out -fsigned-char
-fno-strict-aliasing -fwrapv
timeout --verbose -k 0.1 20 ./clang-sanitize.out
Diff indicated difference
1c1
< 1
---
> 0
Found via fuzzer
First bad commit: 850c1ad7e3cd240e97e41fa3f1e6b38c2700106b