Index: lib/Target/AMDGPU/SIISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/SIISelLowering.cpp +++ lib/Target/AMDGPU/SIISelLowering.cpp @@ -2191,8 +2191,11 @@ if (!CLI.CS) return; - const Function *CalleeFunc = CLI.CS.getCalledFunction(); - assert(CalleeFunc); + const Function *CalleeFunc + = dyn_cast(CLI.CS.getCalledValue()->stripPointerCasts()); + if (!CalleeFunc) + return; + SelectionDAG &DAG = CLI.DAG; const SDLoc &DL = CLI.DL; @@ -2392,8 +2395,11 @@ if (!CLI.CS.getInstruction()) report_fatal_error("unsupported libcall legalization"); - if (!CLI.CS.getCalledFunction()) { + const Value *CalleeVal = CLI.CS.getCalledValue()->stripPointerCasts(); + if (!isa(CalleeVal)) { return lowerUnhandledCall(CLI, InVals, + isa(CalleeVal) ? + "unsupported call to constant " : "unsupported indirect call to function "); } Index: test/CodeGen/AMDGPU/call-constexpr.ll =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/call-constexpr.ll @@ -0,0 +1,64 @@ +; RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s + +define i32 @ret_i32() #0 { + ret i32 4 +} + +; GCN-LABEL: {{^}}test_bitcast_return_type: +; GCN: s_getpc_b64 +; GCN: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, ret_i32@rel32@lo+4 +; GCN: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, ret_i32@rel32@hi+4 +; GCN: s_swappc_b64 +define amdgpu_kernel void @test_bitcast_return_type() #0 { + %val = call float bitcast (i32()* @ret_i32 to float()*)() + %op = fadd float %val, 1.0 + store volatile float %op, float addrspace(1)* undef + ret void +} + +; GCN-LABEL: {{^}}use_workitem_id_x: +; GCN: s_waitcnt +; GCN-NEXT: v_add_i32_e32 v0, vcc, v0, v1 +; GCN-NEXT: s_setpc_b64 +define i32 @use_workitem_id_x(i32 %arg0) #0 { + %id = call i32 @llvm.amdgcn.workitem.id.x() + %op = add i32 %id, %arg0 + ret i32 %op +} + +; GCN-LABEL: {{^}}test_bitcast_use_workitem_id_x: +; GCN: v_mov_b32_e32 v1, v0 +; GCN: s_getpc_b64 +; GCN: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, use_workitem_id_x@rel32@lo+4 +; GCN: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, use_workitem_id_x@rel32@hi+4 +; GCN: v_mov_b32_e32 v0, 9 +; GCN: s_swappc_b64 +; GCN: v_add_f32_e32 +define amdgpu_kernel void @test_bitcast_use_workitem_id_x() #0 { + %val = call float bitcast (i32(i32)* @use_workitem_id_x to float(i32)*)(i32 9) + %op = fadd float %val, 1.0 + store volatile float %op, float addrspace(1)* undef + ret void +} + +declare i32 @extern_variadic(...) + +; GCN-LABEL: {{^}}test_tail_call_bitcast_extern_variadic: +; GCN: v_add_f32_e32 v0, +; GCN: v_add_f32_e32 v1, +; GCN: v_add_f32_e32 v2, +; GCN: v_add_f32_e32 v3, +; GCN: s_getpc_b64 +; GCN: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, extern_variadic@rel32@lo+4 +; GCN: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, extern_variadic@rel32@hi+4 +; GCN: s_setpc_b64 +define i32 @test_tail_call_bitcast_extern_variadic(<4 x float> %arg0, <4 x float> %arg1, i32 %arg2) { + %add = fadd <4 x float> %arg0, %arg1 + %call = tail call i32 bitcast (i32 (...)* @extern_variadic to i32 (<4 x float>)*)(<4 x float> %add) + ret i32 %call +} + +declare i32 @llvm.amdgcn.workitem.id.x() #1 + +attributes #0 = { nounwind noinline } +attributes #1 = { nounwind readnone speculatable } Index: test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll =================================================================== --- test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll +++ test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll @@ -1,8 +1,4 @@ -; RUN: not llc -march=amdgcn < %s 2>&1 | FileCheck %s - -; FIXME: Error is misleading because it's not an indirect call. - -; CHECK: error: :0:0: in function crash_call_constexpr_cast void (): unsupported indirect call to function foo +; RUN: opt -data-layout=A5 -S -mtriple=amdgcn-unknown-unknown -amdgpu-promote-alloca -disable-promote-alloca-to-vector < %s | FileCheck %s ; Make sure that AMDGPUPromoteAlloca doesn't crash if the called ; function is a constantexpr cast of a function. @@ -10,14 +6,18 @@ declare void @foo(float addrspace(5)*) #0 declare void @foo.varargs(...) #0 -; XCHECK: in function crash_call_constexpr_cast{{.*}}: unsupported call to function foo +; CHECK-LABEL: @crash_call_constexpr_cast( +; CHECK: alloca +; CHECK: call void define amdgpu_kernel void @crash_call_constexpr_cast() #0 { %alloca = alloca i32, addrspace(5) call void bitcast (void (float addrspace(5)*)* @foo to void (i32 addrspace(5)*)*)(i32 addrspace(5)* %alloca) #0 ret void } -; XCHECK: in function crash_call_constexpr_cast{{.*}}: unsupported call to function foo.varargs +; CHECK-LABEL: @crash_call_constexpr_cast_varargs( +; CHECK: alloca +; CHECK: call void define amdgpu_kernel void @crash_call_constexpr_cast_varargs() #0 { %alloca = alloca i32, addrspace(5) call void bitcast (void (...)* @foo.varargs to void (i32 addrspace(5)*)*)(i32 addrspace(5)* %alloca) #0 Index: test/CodeGen/AMDGPU/unsupported-calls.ll =================================================================== --- test/CodeGen/AMDGPU/unsupported-calls.ll +++ test/CodeGen/AMDGPU/unsupported-calls.ll @@ -51,16 +51,6 @@ ret void } -declare i32 @extern_variadic(...) - -; GCN: in function test_tail_call_bitcast_extern_variadic{{.*}}: unsupported indirect call to function extern_variadic -; R600: in function test_tail_call_bitcast_extern_variadic{{.*}}: unsupported call to function extern_variadic -define i32 @test_tail_call_bitcast_extern_variadic(<4 x float> %arg0, <4 x float> %arg1, i32 %arg2) { - %add = fadd <4 x float> %arg0, %arg1 - %call = tail call i32 bitcast (i32 (...)* @extern_variadic to i32 (<4 x float>)*)(<4 x float> %add) - ret i32 %call -} - ; GCN: :0:0: in function test_indirect_call void (void ()*): unsupported indirect call to function ; R600: in function test_indirect_call{{.*}}: unsupported call to function define void @test_indirect_call(void()* %fptr) { @@ -75,8 +65,7 @@ ret i32 %call } -; FIXME: Bad error message -; GCN: error: :0:0: in function test_call_absolute void (): unsupported indirect call to function +; GCN: error: :0:0: in function test_call_absolute void (): unsupported call to constant ; R600: error: :0:0: in function test_call_absolute void (): unsupported call to function define amdgpu_kernel void @test_call_absolute() #0 { %val = call i32 inttoptr (i64 1234 to i32(i32)*) (i32 1)