llvm / llvm-project

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

[SLPVectorizer][RISC-V] rv64gcv miscompile with `slp-vectorizer` pass #89988

Closed patrick-rivos closed 6 months ago

patrick-rivos commented 6 months ago

Testcase:

int d = 16;
unsigned a = 3;
short e[18], f[18];
unsigned short *g = e;
int main() {
  for (long h = 0; h < 8; ++h) {
    e[h] = -1;
    f[h] = -2;
  }
  for (short h = 1; h; h += 5)
    for (int i = 0; i < d; i += 4)
      a = ({
        int j = 40 ? g[i] <= (unsigned)(1 ? f[i] : 0) : 0;
        a < j ? 0 : j;
      });
  __builtin_printf("%u\n", a);
}

Commands:

> /scratch/tc-testing/tc-apr-23/build-rv64gcv/build-llvm-linux/bin/clang -fno-strict-aliasing -march=rv64gcv -flto -O3 red.c -o red.out
> /scratch/tc-testing/tc-apr-23/build-rv64gcv/bin/qemu-riscv64 red.out
0
> /scratch/tc-testing/tc-apr-23/build-rv64gcv/build-llvm-linux/bin/clang -fno-strict-aliasing red.c -o red.out
> /scratch/tc-testing/tc-apr-23/build-rv64gcv/bin/qemu-riscv64 red.out
1

Reduced LLVM IR:

target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

@.str = constant [4 x i8] c"%u\0A\00"

define i32 @main(ptr %a, ptr %f, i16 %0) #0 {
for.cond6.preheader.us.preheader:
  %1 = load i16, ptr %f, align 2

  %zext.0 = zext i16 %1 to i32
  %sext.0 = sext i16 %0 to i32

  %zext.1 = zext i16 0 to i32
  %sext.1 = sext i16 0 to i32
  %zext.2 = zext i16 0 to i32
  %sext.2 = sext i16 0 to i32
  %zext.3 = zext i16 0 to i32
  %sext.3 = sext i16 0 to i32

  %cmp.0 = icmp ule i32 %zext.0, %sext.0
  %cmp.1 = icmp ule i32 %zext.1, %sext.1
  %cmp.2 = icmp ule i32 %zext.2, %sext.2
  %cmp.3 = icmp ule i32 %zext.3, %sext.3

  %and.0 = and i1 %cmp.0, %cmp.1
  %and.1 = and i1 %and.0, %cmp.2
  %and.2 = and i1 %and.1, %cmp.3

  %zext.4 = zext i1 %and.2 to i32

  %call = tail call i32 (ptr, ...) @printf(ptr @.str, i32 %zext.4)
  ret i32 0
}

declare i32 @printf(ptr, ...)

attributes #0 = { "target-features"="+64bit,+a,+v" }

Commands:

/scratch/tc-testing/tc-apr-23/build-rv64gcv/build-llvm-linux/bin/clang $1 -o baseline.out

/scratch/tc-testing/tc-apr-23/build-rv64gcv/build-llvm-linux/bin/opt -passes=slp-vectorizer $1 > opt.bc
/scratch/tc-testing/tc-apr-23/build-rv64gcv/build-llvm-linux/bin/clang opt.bc -o opt.out

/scratch/tc-testing/tc-apr-23/build-rv64gcv/bin/qemu-riscv64 opt.out
0
/scratch/tc-testing/tc-apr-23/build-rv64gcv/bin/qemu-riscv64 baseline.out
1

Found via fuzzer

@alexey-bataev

patrick-rivos commented 6 months ago

Updated to rename/format the LLVM IR. Godbolt: https://godbolt.org/z/4bd9E583d

alexey-bataev commented 6 months ago

Fixed in f758bb66e8acfe0daa1725ab4d87ae944a4c53d2