Details
- Reviewers
rampitec scott.linder
Diff Detail
Event Timeline
I still don't understand exactly when a call is indirect, but when an argument is cast this still seems to fail:
%foo = type opaque define i64 @bar(i64 addrspace(1)* %p) { ret i64 1 } define void @test_cast_to_opaque(%foo addrspace(1)* %out) { %1 = call i64 bitcast (i64 (i64 addrspace(1)*)* @bar to i64 (%foo addrspace(1)*)*)(%foo addrspace(1)* %out) ret void }
gives:
error: <unknown>:0:0: in function test_cast_to_opaque void (%foo addrspace(1)*): unsupported indirect call to function bar
test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll | ||
---|---|---|
9 | Maybe rename these without the crash_? |
If the function pointer is a variable, not a constant. Your example works for me with this patch
Sorry; I just checked again and llc had not been rebulit for some reason. I deleted it and ran the build again and that example does compile fine.
I still see asserts related to bitcasted function calls, but I haven't gotten to the bottom of why; an example:
%struct.foo = type { i64, i64, i64, [104 x i8], [1 x i8] } %struct.pluto = type opaque define void @wombat() { bb: call void bitcast (void (%struct.foo addrspace(1)*, i64, i32, i32)* @barney to void (%struct.foo addrspace(1)*, %struct.pluto addrspace(1)*, i32, i32)*)(%struct.foo addrspace(1)* undef, %struct.pluto addrspace(1)* undef, i32 4, i32 4) ret void } define void @barney(%struct.foo addrspace(1)* nocapture %arg, i64 %arg1, i32 %arg2, i32 %arg3) { bb: ret void }
Results in:
llc: llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h:164: const llvm::AMDGPUFunctionArgInfo &llvm::AMDGPUArgumentUsageInfo::lookupFuncArgInfo(const llvm::Function &) const: Assertion `F.isDeclaration()' failed. Stack dump: 0. Program arguments: llvm/bin/llc -march=amdgcn -mcpu=gfx900 meta.ll 1. Running pass 'CallGraph Pass Manager' on module 'meta.ll'. 2. Running pass 'AMDGPU DAG->DAG Pattern Instruction Selection' on function '@wombat' ... #9 0x0000000000bc6ae5 llvm::AMDGPUArgumentUsageInfo::lookupFuncArgInfo(llvm::Function const&) const llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h:0:7 #10 0x0000000000b8c78f llvm::SITargetLowering::passSpecialInputs(llvm::TargetLowering::CallLoweringInfo&, llvm::CCState&, llvm::SIMachineFunctionInfo const&, llvm::SmallVectorImpl<std::pair<unsigned int, llvm::SDValue> >&, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SDValue) const llvm/lib/Target/AMDGPU/SIISelLowering.cpp:2204:32 #11 0x0000000000b8f055 llvm::SITargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const llvm/lib/Target/AMDGPU/SIISelLowering.cpp:2573:8 ...
However, the following gets past lowering fine:
%struct.foo = type { i64, i64, i64, [104 x i8], [1 x i8] } %struct.pluto = type opaque define void @wombat() { bb: call void bitcast (void (%struct.foo addrspace(1)*, i64, i32, i32)* @barney to void (%struct.foo addrspace(1)*, %struct.pluto addrspace(1)*, i32, i32)*)(%struct.foo addrspace(1)* undef, %struct.pluto addrspace(1)* undef, i32 4, i32 4) ret void } declare void @barney(%struct.foo addrspace(1)* nocapture %arg, i64 %arg1, i32 %arg2, i32 %arg3)
Seems to be related to the order; this succeeds:
%struct.foo = type { i64, i64, i64, [104 x i8], [1 x i8] } %struct.pluto = type opaque define void @barney(%struct.foo addrspace(1)* nocapture %arg, i64 %arg1, i32 %arg2, i32 %arg3) { bb: ret void } define void @wombat() { bb: call void bitcast (void (%struct.foo addrspace(1)*, i64, i32, i32)* @barney to void (%struct.foo addrspace(1)*, %struct.pluto addrspace(1)*, i32, i32)*)(%struct.foo addrspace(1)* undef, %struct.pluto addrspace(1)* undef, i32 4, i32 4) ret void }
It seems like if SelectionDAGBuilder does LowerCall for the caller before it does LowerFormalArguments for the callee we fail in SITargetLowering::passSpecialInputs because we have not filled in ArgInfoMap for the callee yet. Without the bitcast is this dependency somehow enforced?
It looks like to make this change we need to update CallGraph as well; it currently just uses .getCalledFunction(), so the graph doesn't have the edge created by the bitcasted call.
This patch requires changes to CallGraph, and doesn't address inlining through bitcasts. I think https://reviews.llvm.org/D52741 can supercede it, and if we still want to make those changes to CallGraph they can be done independently.
Maybe rename these without the crash_?