Closed tkoenig1 closed 1 year ago
The cause appears to be the use of vectors in the IR, e.g.: %4 = insertelement <2 x i64> <i64 poison, i64 0>, i64 %count.030, i32 0 This may be because header files used indicate the target has vector support. For example: "/home/tkoenig/lib/gcc/powerpc64le-unknown-linux-gnu/13.0.0/include/stddef.h" was used. Another possibility is that the clang definition of the My66000 ABI indicates vector support by error.
It's not a header issue. I have reduced the test case, see below.
What is a bit funny is that the gsl_permutation_inversions function needs to be there, or the ICE goes away.
typedef long unsigned int size_t;
enum {
GSL_SUCCESS = 0,
GSL_FAILURE = -1,
GSL_CONTINUE = -2,
GSL_EDOM = 1,
GSL_ERANGE = 2,
GSL_EFAULT = 3,
GSL_EINVAL = 4,
GSL_EFAILED = 5,
GSL_EFACTOR = 6,
GSL_ESANITY = 7,
GSL_ENOMEM = 8,
GSL_EBADFUNC = 9,
GSL_ERUNAWAY = 10,
GSL_EMAXITER = 11,
GSL_EZERODIV = 12,
GSL_EBADTOL = 13,
GSL_ETOL = 14,
GSL_EUNDRFLW = 15,
GSL_EOVRFLW = 16,
GSL_ELOSS = 17,
GSL_EROUND = 18,
GSL_EBADLEN = 19,
GSL_ENOTSQR = 20,
GSL_ESING = 21,
GSL_EDIVERGE = 22,
GSL_EUNSUP = 23,
GSL_EUNIMPL = 24,
GSL_ECACHE = 25,
GSL_ETABLE = 26,
GSL_ENOPROG = 27,
GSL_ENOPROGJ = 28,
GSL_ETOLF = 29,
GSL_ETOLX = 30,
GSL_ETOLG = 31,
GSL_EOF = 32
} ;
void gsl_error (const char * reason, const char * file, int line,
int gsl_errno);
extern int gsl_check_range;
struct gsl_permutation_struct
{
size_t size;
size_t *data;
};
typedef struct gsl_permutation_struct gsl_permutation;
int gsl_permutation_linear_to_canonical (gsl_permutation * q, const gsl_permutation * p);
inline
size_t
gsl_permutation_get (const gsl_permutation * p, const size_t i)
{
return p->data[i];
}
int
gsl_permutation_linear_to_canonical (gsl_permutation * q,
const gsl_permutation * p)
{
const size_t n = p->size;
size_t i, k, s;
size_t t = n;
const size_t *const pp = p->data;
size_t *const qq = q->data;
if (q->size != p->size)
{
do { gsl_error ("size of q does not match size of p", "canonical.c", 42, GSL_EINVAL) ; return GSL_EINVAL ; } while (0);
}
for (i = 0; i < n; i++)
{
k = pp[i];
s = 1;
while (k > i)
{
k = pp[k];
s++;
}
if (k < i)
continue;
t -= s;
qq[t] = i;
k = pp[i];
s = 1;
while (k > i)
{
qq[t + s] = k;
k = pp[k];
s++;
}
if (t == 0)
break;
}
return GSL_SUCCESS;
}
size_t
gsl_permutation_inversions (const gsl_permutation * p)
{
size_t count = 0;
size_t i, j;
const size_t size = p->size;
for (i = 0; i < size - 1; i++)
{
for (j = i + 1; j < size; j++)
{
if (p->data[i] > p->data[j])
{
count++;
}
}
}
return count;
}
We might have two different test cases here. The first ones in canonical.zip had a file canonical_opt.bc which when run through llvm-dis contained source_filename = "canonical.c" target datalayout = "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512" target triple = "powerpc64le-unknown-linux-gnu" The IR contained vectors because of the wrong target machine. The new test case probably had a different error, I suspect the same as issue #5. I have fixed that and now this new test case works. I will push the fix soon.
What should I use to deselect vectorization? With canonical.i, I now get a new error message, with the compilation script
#! /bin/bash
a=${1%%.[ci]}
b=${a}_opt
clang -c -O3 -fno-vectorize -fno-slp-vectorize -emit-llvm -fno-unroll-loops $1
opt -disable-loop-unrolling -O3 --march=my66000 --frame-pointer=none --enable-vvm $a.bc > $b.bc
llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $b.bc
it is now
bb.6.for.end:
; predecessors: %bb.5, %bb.1
$r1 = COPY %19:gregs
RET implicit $r1
# End machine code for function gsl_permutation_linear_cycles.
*** Bad machine code: Reading virtual register without a def ***
- function: gsl_permutation_linear_cycles
- basic block: %bb.5 while.end (0x23ba6ac0)
- instruction: %14:gregs = SRLri %12:gregs, 1, 11
- operand 1: %12:gregs
LLVM ERROR: Found 1 machine code errors.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0. Program arguments: llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 canonical_opt.bc
1. Running pass 'Function Pass Manager' on module 'canonical_opt.bc'.
2. Running pass 'Live Interval Analysis' on function '@gsl_permutation_linear_cycles'
Use "clang --target=my66000 ..."
Use "clang --target=my66000 ..."
OK, I did that, and got the same result as in my last comment. Compilation script is now
#! /bin/bash
a=${1%%.[ci]}
b=${a}_opt
clang -c -march=my66000 -O3 -fno-vectorize -fno-slp-vectorize -emit-llvm -fno-unroll-loops $1
opt -disable-loop-unrolling -O3 --march=my66000 --frame-pointer=none --enable-vvm $a.bc > $b.bc
llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $b.bc
Actually, --target=my66000 does not work:
[tkoenig@gcc135 GSL]$ clang -c --target=my66000 -O3 -fno-vectorize -fno-slp-vectorize -emit-llvm -fno-unroll-loops canonical.i
error: unknown target triple 'my66000', please use -triple or -arch
Is this just a misconfiguration that I did when compiling the compiler? clang accepts -march, but seems to ignore it.
Make sure you are running the clang built from the llvm-my66000 tree. If you have pulled the tree into DIR then cd $DIR/llvm mkdir build cd build cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_LLD=true \ # can omit this, but it does speed things up -DLLVM_ENABLE_PROJECTS="clang" \ -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF \ -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="My66000" \ $DIR/llvm nice make -j4 opt llc clang
I tried what you described on the POWER system I usually use, but that didn't work any more (possibly due to an update on the gcc that I used).
I then set this up on another machine, with a previously empty home directory. This resulted in the attached configuration.
Compilation worked well, but now that clang does not understand -march=my66000:
tkoenig@gcc188:~> clang -emit-llvm -S -march=my66000 foo.c
error: unknown target CPU 'my66000'
note: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, icelake-server, tigerlake, sapphirerapids, alderlake, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, x86-64, x86-64-v2, x86-64-v3, x86-64-v4
and it is the recently built clang:
tkoenig@gcc188:~> clang --version
clang version 12.0.0 (https://github.com/bagel99/llvm-my66000.git 9fb868de1043964594da55f145454316ba42a5ab)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/tkoenig/bin
So, I'm not sure what to do now.
For clang try "--target=my66000" NOT "-march=..."
I finally managed to do this (thanks for your patience) and there is no ICE when compiled for my66000 with clang.
Compiling GSL, I get
canonical.zip
Preprocessed source and bc file are attached.