https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122853

            Bug ID: 122853
           Summary: RISC-V: Wrong code with RVV loop vectorization:
                    vwsubu.vv used producing wrong results
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: chenzhongyao.hit at gmail dot com
                CC: law at gcc dot gnu.org, rdapp at gcc dot gnu.org
  Target Milestone: ---
            Target: riscv

GCC trunk's loop vectorizer uses vwsubu.vv (unsigned widening subtract) for
(uint8_t - uint8_t), producing wrong results when minuend < subtrahend.

The following test case is extracted from SPEC CPU 2017 525.x264_r.


--- compiler flags ---
PASS: -O3 -march=rv64gcv -fno-tree-loop-vectorize -static 
FAIL: -O3 -march=rv64gcv -static 


--- testcase.c ---
#include <stdint.h>
#include <stdio.h>

static inline uint32_t abs2(uint32_t a) {
    uint32_t s = ((a>>15)&0x10001)*0xffff;
    return (a+s)^s;
}

__attribute__((noipa))
int test_func(uint8_t *p1, int stride, uint8_t *p2) {
    int sum = 0;
    for (int i = 0; i < 2; i++, p1 += stride, p2 += stride) {
        uint32_t a0 = (p1[0]-p2[0]) + ((p1[4]-p2[4])<<16);
        uint32_t a1 = (p1[1]-p2[1]) + ((p1[5]-p2[5])<<16);
        uint32_t a2 = (p1[2]-p2[2]) + ((p1[6]-p2[6])<<16);
        uint32_t a3 = (p1[3]-p2[3]) + ((p1[7]-p2[7])<<16);
        sum += abs2(a0) + abs2(a1) + abs2(a2) + abs2(a3);
    }
    return sum;
}

int main(void) {
    uint8_t p1[16] = {0,5,0,11,0,0,0,0, 1,8,0,0,7,7,12,0};
    uint8_t p2[16] = {0,16,0,13,0,0,2,10, 20,8,6,19,6,14,32,5};
    int r = test_func(p1, 8, p2);
    printf("Result: %d, Expected: 2949177, %s\n", r, r==2949177 ? "PASS" :
"FAIL");
    return r != 2949177;
}

--- qemu-riscv64 ./testcase results ---
With -fno-tree-loop-vectorize: Result: 2949177, Expected: 2949177, PASS
Without -fno-tree-loop-vectorize: Result: 3735609, Expected: 2949177, FAIL

Reply via email to