llvm / llvm-project

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

[AMDGCN] can't select `fpow` when the second arg is non-constant #59313

Open DataCorrupted opened 1 year ago

DataCorrupted commented 1 year ago

When compiling the following code with amdgcn (godbolt), the compiler fails. It seems as long as one of the argument is non constant, instruction selection will fail.

I am wondering if this is a feature in AMDGCN, or a missing pattern?

source_filename = "poc.ll"

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare double @llvm.pow.f64(double, double) #0

define double @f(double %G) {
BB:
  %C1 = call double @llvm.pow.f64(double 2.0, double %G)
  ret double %C1
}

Here is the stack trace:

define double @f(double %G) #1 {
BB:
  %C1 = call double @llvm.pow.f64(double 2.000000e+00, double %G)
  ret double %C1
}
LLVM ERROR: Cannot select: t8: f64 = fpow # D:1 ConstantFP:f64<2.000000e+00>, t6
  t7: f64 = ConstantFP<2.000000e+00>
  t6: f64 = bitcast # D:1 t5
    t5: i64 = build_pair # D:1 t2, t4
      t2: i32,ch = CopyFromReg # D:1 t0, Register:i32 %0
        t1: i32 = Register %0
      t4: i32,ch = CopyFromReg # D:1 t0, Register:i32 %1
        t3: i32 = Register %1
In function: f
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: ./bin/llc -mtriple=amdgcn crash/amdgcn/0/poc.ll
1.      Running pass 'CallGraph Pass Manager' on module 'crash/amdgcn/0/poc.ll'.
2.      Running pass 'AMDGPU DAG->DAG Pattern Instruction Selection' on function '@f'
 #0 0x00007fda9a32d4ba llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Support/Unix/Signals.inc:567:11
 #1 0x00007fda9a32d66b PrintStackTraceSignalHandler(void*) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Support/Unix/Signals.inc:641:1
 #2 0x00007fda9a32bcc6 llvm::sys::RunSignalHandlers() /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Support/Signals.cpp:104:5
 #3 0x00007fda9a32dd95 SignalHandler(int) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Support/Unix/Signals.inc:412:1
 #4 0x00007fda98aeb980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
 #5 0x00007fda97de7e87 raise /build/glibc-CVJwZb/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
 #6 0x00007fda97de97f1 abort /build/glibc-CVJwZb/glibc-2.27/stdlib/abort.c:81:0
 #7 0x00007fda9a1a2884 llvm::report_fatal_error(llvm::Twine const&, bool) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Support/ErrorHandling.cpp:125:5
 #8 0x00007fda9ab3709b /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:3780:3
 #9 0x00007fda9ab34632 llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:3682:9
#10 0x00007fdaabbea149 AMDGPUDAGToDAGISel::SelectCode(llvm::SDNode*) /home/peter/aflplusplus-isel/llvm-fix/build-debug/lib/Target/AMDGPU/AMDGPUGenDAGISel.inc:226553:1
#11 0x00007fdaabbd8f3a AMDGPUDAGToDAGISel::Select(llvm::SDNode*) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp:704:1
#12 0x00007fda9ab28139 llvm::SelectionDAGISel::DoInstructionSelection() /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1166:5
#13 0x00007fda9ab2718a llvm::SelectionDAGISel::CodeGenAndEmitDAG() /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:937:3
#14 0x00007fda9ab25b5d llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, false, true>, llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, false, true>, bool&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:689:1
#15 0x00007fda9ab255fb llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1604:11
#16 0x00007fda9ab22ba6 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:468:3
#17 0x00007fdaabbd578a AMDGPUDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp:136:3
#18 0x00007fda9dabbc35 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/CodeGen/MachineFunctionPass.cpp:91:8
#19 0x00007fda9cc739e6 llvm::FPPassManager::runOnFunction(llvm::Function&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/IR/LegacyPassManager.cpp:1430:23
#20 0x00007fda9f508eed (anonymous namespace)::CGPassManager::RunPassOnSCC(llvm::Pass*, llvm::CallGraphSCC&, llvm::CallGraph&, bool&, bool&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Analysis/CallGraphSCCPass.cpp:179:20
#21 0x00007fda9f50887e (anonymous namespace)::CGPassManager::RunAllPassesOnSCC(llvm::CallGraphSCC&, llvm::CallGraph&, bool&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Analysis/CallGraphSCCPass.cpp:476:10
#22 0x00007fda9f5081ff (anonymous namespace)::CGPassManager::runOnModule(llvm::Module&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/Analysis/CallGraphSCCPass.cpp:542:18
#23 0x00007fda9cc742b9 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/IR/LegacyPassManager.cpp:1545:23
#24 0x00007fda9cc73e2d llvm::legacy::PassManagerImpl::run(llvm::Module&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/IR/LegacyPassManager.cpp:535:16
#25 0x00007fda9cc78af1 llvm::legacy::PassManager::run(llvm::Module&) /home/peter/aflplusplus-isel/llvm-fix/llvm/lib/IR/LegacyPassManager.cpp:1672:3
#26 0x00000000004199ac compileModule(char**, llvm::LLVMContext&) /home/peter/aflplusplus-isel/llvm-fix/llvm/tools/llc/llc.cpp:736:41
#27 0x0000000000417d52 main /home/peter/aflplusplus-isel/llvm-fix/llvm/tools/llc/llc.cpp:417:13
#28 0x00007fda97dcac87 __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:344:0
#29 0x000000000041755a _start (./bin/llc+0x41755a)
Aborted
llvmbot commented 1 year ago

@llvm/issue-subscribers-backend-amdgpu

arsenm commented 1 year ago

I'm surprised any cases select for this. f64 fpow is not implemented

DataCorrupted commented 1 year ago

I think the problem is... should it be implemented? If we should, I'll leave it here for future reference. If it shouldn't because the hardware specification says its not supported, shouldn't we at least lower it so the compiler doesn't crash?

arsenm commented 1 year ago

I would like if we could directly handle all the math intrinsics. We currently rely on an IR library implementation here https://github.com/RadeonOpenCompute/ROCm-Device-Libs/blob/amd-stg-open/ocml/src/powD_base.h

To implement the intrinsic, we would need to write an expansion that produces equivalent code (which could be a lot), or somehow support libcall legalization

DataCorrupted commented 1 year ago

Ah, thanks for the clarification.