AMDGPU: Don't error on calls to null or undef

Calls to constants should probably be generally handled.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375356 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/AMDGPU/SIISelLowering.cpp b/lib/Target/AMDGPU/SIISelLowering.cpp
index d6362e6..80eb2be 100644
--- a/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -2688,6 +2688,15 @@
   bool IsThisReturn = false;
   MachineFunction &MF = DAG.getMachineFunction();
 
+  if (Callee.isUndef() || isNullConstant(Callee)) {
+    if (!CLI.IsTailCall) {
+      for (unsigned I = 0, E = CLI.Ins.size(); I != E; ++I)
+        InVals.push_back(DAG.getUNDEF(CLI.Ins[I].VT));
+    }
+
+    return Chain;
+  }
+
   if (IsVarArg) {
     return lowerUnhandledCall(CLI, InVals,
                               "unsupported call to variadic function ");
diff --git a/test/CodeGen/AMDGPU/call-constant.ll b/test/CodeGen/AMDGPU/call-constant.ll
new file mode 100644
index 0000000..19aadfc
--- /dev/null
+++ b/test/CodeGen/AMDGPU/call-constant.ll
@@ -0,0 +1,45 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa < %s | FileCheck -check-prefix=GCN %s
+
+; FIXME: Emitting unnecessary flat_scratch setup
+
+; GCN-LABEL: {{^}}test_call_undef:
+; GCN: s_mov_b32 s8, s7
+; GCN: s_mov_b32 flat_scratch_lo, s5
+; GCN: s_add_u32 s4, s4, s8
+; GCN: s_lshr_b32
+; GCN: s_endpgm
+define amdgpu_kernel void @test_call_undef() #0 {
+  %val = call i32 undef(i32 1)
+  %op = add i32 %val, 1
+  store volatile i32 %op, i32 addrspace(1)* undef
+  ret void
+}
+
+; GCN-LABEL: {{^}}test_tail_call_undef:
+; GCN: s_waitcnt
+; GCN-NEXT: .Lfunc_end
+define i32 @test_tail_call_undef() #0 {
+  %call = tail call i32 undef(i32 1)
+  ret i32 %call
+}
+
+; GCN-LABEL: {{^}}test_call_null:
+; GCN: s_mov_b32 s8, s7
+; GCN: s_mov_b32 flat_scratch_lo, s5
+; GCN: s_add_u32 s4, s4, s8
+; GCN: s_lshr_b32
+; GCN: s_endpgm
+define amdgpu_kernel void @test_call_null() #0 {
+  %val = call i32 null(i32 1)
+  %op = add i32 %val, 1
+  store volatile i32 %op, i32 addrspace(1)* null
+  ret void
+}
+
+; GCN-LABEL: {{^}}test_tail_call_null:
+; GCN: s_waitcnt
+; GCN-NEXT: .Lfunc_end
+define i32 @test_tail_call_null() #0 {
+  %call = tail call i32 null(i32 1)
+  ret i32 %call
+}
diff --git a/test/CodeGen/AMDGPU/unsupported-calls.ll b/test/CodeGen/AMDGPU/unsupported-calls.ll
index 303a0d6..3cff627 100644
--- a/test/CodeGen/AMDGPU/unsupported-calls.ll
+++ b/test/CodeGen/AMDGPU/unsupported-calls.ll
@@ -74,3 +74,13 @@
   %call = call i32 @defined_function(i32 0)
   ret i32 %call
 }
+
+; FIXME: Bad error message
+; GCN: error: <unknown>:0:0: in function test_call_absolute void (): unsupported indirect call to function <unknown>
+; R600: error: <unknown>:0:0: in function test_call_absolute void (): unsupported call to function <unknown>
+define amdgpu_kernel void @test_call_absolute() #0 {
+  %val = call i32 inttoptr (i64 1234 to i32(i32)*) (i32 1)
+  %op = add i32 %val, 1
+  store volatile i32 %op, i32 addrspace(1)* undef
+  ret void
+}