Closed
Description
I am emitting machine code using half precision for arm but I am hitting the following assert:
assert((Size == 32 || Size == 64) &&
"i32 or i64 is expected after legalization.");
I have create a reproducible example: https://godbolt.org/z/d5aa5cxrK
IR & Back trace for posterity
## IR:target triple = "aarch64-unknown-linux-gnu"
define noalias noundef ptr @fn(ptr nocapture readonly %in, ptr nocapture readonly %out) local_unnamed_addr {
fn:
%1 = load <4 x half>, ptr %in, align 16
%2 = fcmp one <4 x half> %1, zeroinitializer
%3 = uitofp <4 x i1> %2 to <4 x half>
store <4 x half> %3, ptr %out, align 16
%23 = getelementptr inbounds nuw i8, ptr %in, i64 8
%24 = load half, ptr %23, align 4
%25 = fcmp one half %24, 0xH0000
%26 = uitofp i1 %25 to half
%27 = call half @llvm.copysign.f16(half %26, half %24)
%30 = getelementptr inbounds nuw i8, ptr %out, i64 8
store half %27, ptr %30, align 8
ret ptr null
}
Backtrace:
llc: /root/llvm-project/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp:2376: virtual bool llvm::AArch64TargetLowering::targetShrinkDemandedConstant(llvm::SDValue, const llvm::APInt&, const llvm::APInt&, llvm::TargetLowering::TargetLoweringOpt&) const: Assertion `(Size == 32 || Size == 64) && "i32 or i64 is expected after legalization."' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/llc -o /app/output.s -x86-asm-syntax=intel <source>
1. Running pass 'Function Pass Manager' on module '<source>'.
2. Running pass 'AArch64 Instruction Selection' on function '@fn'
#0 0x0000000003cb2f68 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3cb2f68)
#1 0x0000000003cb096c SignalHandler(int) Signals.cpp:0:0
#2 0x00007419e5442520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#3 0x00007419e54969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
#4 0x00007419e5442476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
#5 0x00007419e54287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
#6 0x00007419e542871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
#7 0x00007419e5439e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#8 0x0000000000ca1cf7 llvm::AArch64TargetLowering::targetShrinkDemandedConstant(llvm::SDValue, llvm::APInt const&, llvm::APInt const&, llvm::TargetLowering::TargetLoweringOpt&) const (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0xca1cf7)
#9 0x0000000003a84eca llvm::TargetLowering::ShrinkDemandedConstant(llvm::SDValue, llvm::APInt const&, llvm::APInt const&, llvm::TargetLowering::TargetLoweringOpt&) const (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3a84eca)
#10 0x0000000003ac6e34 llvm::TargetLowering::SimplifyDemandedBits(llvm::SDValue, llvm::APInt const&, llvm::APInt const&, llvm::KnownBits&, llvm::TargetLowering::TargetLoweringOpt&, unsigned int, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3ac6e34)
#11 0x0000000003880beb (anonymous namespace)::DAGCombiner::SimplifyDemandedBits(llvm::SDValue, llvm::APInt const&) DAGCombiner.cpp:0:0
#12 0x0000000003881527 (anonymous namespace)::DAGCombiner::visitFCOPYSIGN(llvm::SDNode*) DAGCombiner.cpp:0:0
#13 0x00000000038fd99d (anonymous namespace)::DAGCombiner::visit(llvm::SDNode*) DAGCombiner.cpp:0:0
#14 0x00000000038ffc4c (anonymous namespace)::DAGCombiner::combine(llvm::SDNode*) DAGCombiner.cpp:0:0
#15 0x0000000003901538 (anonymous namespace)::DAGCombiner::Run(llvm::CombineLevel) DAGCombiner.cpp:0:0
#16 0x0000000003903e4b llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AAResults*, llvm::CodeGenOptLevel) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3903e4b)
#17 0x0000000003a661b5 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3a661b5)
#18 0x0000000003a699d9 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3a699d9)
#19 0x0000000003a6ac90 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3a6ac90)
#20 0x0000000003a5b5ef llvm::SelectionDAGISelLegacy::runOnMachineFunction(llvm::MachineFunction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3a5b5ef)
#21 0x0000000002be6b09 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
#22 0x00000000031f259f llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x31f259f)
#23 0x00000000031f2951 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x31f2951)
#24 0x00000000031f31f1 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x31f31f1)
#25 0x00000000008a0c90 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#26 0x00000000007898be main (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x7898be)
#27 0x00007419e5429d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#28 0x00007419e5429e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#29 0x0000000000897565 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x897565)
Program terminated with signal: SIGSEGV
Compiler returned: 139
I think it is possible that the assert is wrong, I believe it may just be there to check the following logic is correct:
unsigned NewOpc;
switch (Op.getOpcode()) {
default:
return false;
case ISD::AND:
NewOpc = Size == 32 ? AArch64::ANDWri : AArch64::ANDXri;
break;
case ISD::OR:
NewOpc = Size == 32 ? AArch64::ORRWri : AArch64::ORRXri;
break;
case ISD::XOR:
NewOpc = Size == 32 ? AArch64::EORWri : AArch64::EORXri;
break;
}
which could be updated to check for Size <= 32
: use W
registers else use the X
registers (maybe sign-extending if necessary?), I can create a PR for this change if someone can confirm I am correct, thanks!