Open Quuxplusone opened 6 years ago
Attached progressmeter-2c5082.zip
(331560 bytes, application/zip): Preprocessed source and associated run script
This seems to be an issue with legalization somehow creating both i32 and i1
setcc nodes. I haven't dug into how this happens yet, but we create the
following node:
t21: i32 = setcc t19, Constant:i64<1>, setugt:ch
and when we call IntegerExpandSetCCOperands(), we end up with the new LHS being
a select with a different type (since we've created i1 setcc nodes):
t47: i1 = setcc t42, Constant:i32<0>, seteq:ch
t43: i1 = setcc t41, Constant:i32<1>, setugt:ch
t45: i1 = setcc t42, Constant:i32<0>, setne:ch
t48: i1 = select t47, t43, t45
In any case, this reproduces with the following minimal test case:
float test(long long a) {
return a;
}
Compiled with:
clang -O2 --target=powerpc-portbld-freebsd11.1 a.c -S -mcpu=970
I think the problem is in our handling of int->float conversion. We
unconditionally emit i32 setcc nodes rather than asking TargetLowering what
result type to use. Since we use a different type depending on whether we've
got CRBits or not, it seems that we should actually be querying that when
emitting setcc nodes.
This certainly seems to fix the problem and is likely the right thing to do
(although incomplete as there are other places we unconditionally emit an i32
setcc) - what do you think Hal:
Index: lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelLowering.cpp (revision 323454)
+++ lib/Target/PowerPC/PPCISelLowering.cpp (working copy)
@@ -7128,7 +7128,9 @@
SINT, DAG.getConstant(53, dl, MVT::i32));
Cond = DAG.getNode(ISD::ADD, dl, MVT::i64,
Cond, DAG.getConstant(1, dl, MVT::i64));
- Cond = DAG.getSetCC(dl, MVT::i32,
+ EVT SVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
+ MVT::i32);
+ Cond = DAG.getSetCC(dl, SVT,
Cond, DAG.getConstant(1, dl, MVT::i64), ISD::SETUGT);
SINT = DAG.getNode(ISD::SELECT, dl, MVT::i64, Cond, Round, SINT);
I hit this exact assertion when building sqlite3 as part of the FreeBSD buildworld, but only when targeting e5500 CPU.
My assertion failure is with LLVM 9.0.1, not 5.0.1 as the OP.
I'm also finding this issue (or something similar to it) using Clang 10.0 on
Linux using a Power9 CPU.
Have tried the patch in the comments from Nemanja Ivanovic, but am still
getting the same problem.
The following is from trying to compile musl libc:
fatal error: error in backend: Cannot select: 0x14b06a9d0: i32 = fp_to_sint
0x14b06ad78
0x14b06ad78: f64,ch = strict_fsub 0x14b06b598:1, 0x14b083248, 0x14b06a900
0x14b083248: f64,ch = CopyFromReg 0x7fff8639dde8, Register:f64 %279
0x14b083860: f64 = Register %279
0x14b06a900: f64 = select 0x14b06a968, ConstantFP:f64<0.000000e+00>, 0x14b06b390
0x14b06a968: i1 = setcc 0x14b083248, 0x14b06b390, setlt:ch
0x14b083248: f64,ch = CopyFromReg 0x7fff8639dde8, Register:f64 %279
0x14b083860: f64 = Register %279
0x14b06b390: f64,ch = load<(load 4 from constant-pool), anyext from f32> 0x7fff8639dde8, 0x14b082f08, undef:i64
0x14b082f08: i64,ch = PPCISD::TOC_ENTRY<(load 8 from got)> TargetConstantPool:i64<float 0x41E0000000000000> 0, Register:i64 $x2
0x14b06a830: i64 = TargetConstantPool<float 0x41E0000000000000> 0
0x14b083cd8: i64 = Register $x2
0x14b0834b8: i64 = undef
0x14b06b050: f64 = ConstantFP<0.000000e+00>
0x14b06b390: f64,ch = load<(load 4 from constant-pool), anyext from f32> 0x7fff8639dde8, 0x14b082f08, undef:i64
0x14b082f08: i64,ch = PPCISD::TOC_ENTRY<(load 8 from got)> TargetConstantPool:i64<float 0x41E0000000000000> 0, Register:i64 $x2
0x14b06a830: i64 = TargetConstantPool<float 0x41E0000000000000> 0
0x14b083cd8: i64 = Register $x2
0x14b0834b8: i64 = undef
In function: printf_core
Stack dump:
0. Program arguments: cc -std=c99 -std=c99 -nostdinc -ffreestanding -
frounding-math -Wa,--noexecstack -D_XOPEN_SOURCE=700 -I./arch/powerpc64 -
I./arch/generic -Iobj/src/internal -I./src/include -I./src/internal -
Iobj/include -I./include -Os -pipe -fomit-frame-pointer -fno-unwind-tables -fno-
asynchronous-unwind-tables -ffunction-sections -fdata-sections -Werror=implicit-
function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-
arith -Qunused-arguments -fno-pic -c -o obj/src/stdio/vfprintf.o
src/stdio/vfprintf.c
1. <eof> parser at end of file
2. Code generation
3. Running pass 'Function Pass Manager' on module 'src/stdio/vfprintf.c'.
4. Running pass 'PowerPC DAG->DAG Pattern Instruction Selection' on
function '@printf_core'
clang-10: error: clang frontend command failed with exit code 70 (use -v to see
invocation)
clang version 10.0.0
Target: powerpc64le-unknown-linux-musl
Thread model: posix
InstalledDir: /usr/bin
Does https://reviews.llvm.org/rG3e53bf5781e01784dedb7885867f39d09201ec88
fix the problem?
@Nemanja Ivanovic, applying that patch does not fix the problem for me. Same (or very similar) errors when building musl.
Interesting. Are you able to send a pre-processed reproducer? Or better yet, a
reproducer in LLVM IR.
You should be able to get that by adding:
-S -emit-llvm -o reproducer.ll
to your clang command line for the offending test case.
The issue should then be reproducible using
llc reproducer.ll
Attached reproducer.ll
(7435 bytes, text/plain): reproducer.ll from clang 10 build of musl on linux 5.5.8 ppc64le
Command used for compilation:
clang -std=c99 -nostdinc -ffreestanding -frounding-math -Wa,--noexecstack -
D_XOPEN_SOURCE=700 -I./arch/powerpc64 -I./arch/generic -Iobj/src/internal -
I./src/include -I./src/internal -Iobj/include -I./include -Os -pipe -fomit-
frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-
sections -fdata-sections -Werror=implicit-function-declaration -Werror=implicit-
int -Werror=
pointer-sign -Werror=pointer-arith -Qunused-arguments -fPIC -c -o
obj/src/complex/catan.lo -S -emit-llvm -o reproducer.ll src/complex/catan.c
Thank you so much for providing a reproducer. Hi Qiu, I know you have been looking at some of the Strict FP nodes. Do you think this might be something you can tackle?
The attached test case hits an assert in the legalizer when trying to expand STRICT_FSETCCS.
(In reply to Nemanja Ivanovic from comment #11)
Thank you so much for providing a reproducer. Hi Qiu, I know you have been looking at some of the Strict FP nodes. Do you think this might be something you can tackle?
The attached test case hits an assert in the legalizer when trying to expand STRICT_FSETCCS.
Sure. From reproducer.ll, the reason should be that we don't have correct handling for constrained instrinsics of fcmp
, fptosi
and sitofp
.
I no longer have this issue when testing with 11.0.0rc2 - musl libc now builds OK for me with the clang/llvm toolchain on Linux powerpc64le/power9.
To confirm though, reproducer.ll still shows the same error when running with 11.0.0rc2.
(In reply to James Davies from comment #14)
> To confirm though, reproducer.ll still shows the same error when running
> with 11.0.0rc2.
I checked, the fix about reproducer.ll did not catch up with LLVM 11.0 rc2 tag.
https://github.com/llvm/llvm-project/commit/a5b7b8
Does the original crash still exist in latest clang? I can't reproduce by --target=powerpc-portbld-freebsd11.1 -mcpu=970 -S -O2 progressmeter-2c5082.c
.
progressmeter-2c5082.zip
(331560 bytes, application/zip)reproducer.ll
(7435 bytes, text/plain)