This is an archive of the discontinued LLVM Phabricator instance.

AMDGPU: Don't error on calls to constexpr casts of functions
AbandonedPublic

Authored by arsenm on Sep 7 2018, 8:31 AM.

Details

Diff Detail

Event Timeline

arsenm created this revision.Sep 7 2018, 8:31 AM
This revision is now accepted and ready to land.Sep 7 2018, 12:25 PM

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_?

I still don't understand exactly when a call is indirect, but when an argument is cast this still seems to fail:

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.

scott.linder requested changes to this revision.Oct 1 2018, 12:06 PM

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.

This revision now requires changes to proceed.Oct 1 2018, 12:06 PM
arsenm abandoned this revision.Apr 27 2022, 2:45 PM

This is totally obsolete

Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2022, 2:45 PM
Herald added a subscriber: kerbowa. · View Herald Transcript