diff --git a/lib/BitcastUtils.cpp b/lib/BitcastUtils.cpp index 1cfd9fc30..39077d4ee 100644 --- a/lib/BitcastUtils.cpp +++ b/lib/BitcastUtils.cpp @@ -893,10 +893,16 @@ bool RemoveCstExprFromFunction(Function *F) { I->setOperand(OperandId, VecNew); } else if (auto CstExpr = dyn_cast(I->getOperand(OperandId))) { - auto Operand = CstExpr->getAsInstruction(); - Operand->insertBefore(InsertBefore); - CheckInstruction(Operand); - I->setOperand(OperandId, Operand); + if (CstExpr->getOpcode() == Instruction::AddrSpaceCast && + isa(CstExpr->getOperand(0))) { + I->setOperand(OperandId, ConstantPointerNull::get( + cast(CstExpr->getType()))); + } else { + auto Operand = CstExpr->getAsInstruction(); + Operand->insertBefore(InsertBefore); + CheckInstruction(Operand); + I->setOperand(OperandId, Operand); + } } } diff --git a/lib/InlineEntryPointsPass.cpp b/lib/InlineEntryPointsPass.cpp index 5c7a32ba3..3ea1f236e 100644 --- a/lib/InlineEntryPointsPass.cpp +++ b/lib/InlineEntryPointsPass.cpp @@ -15,6 +15,7 @@ #include #include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" @@ -91,7 +92,7 @@ bool clspv::InlineEntryPointsPass::RequiresInlining(Module &M) { if (HasGeneric(I.getType())) return true; for (auto *op : I.operand_values()) { - if (HasGeneric(op->getType())) + if (!isa(op) && HasGeneric(op->getType())) return true; } } diff --git a/test/InlineEntryPoints/null_pointer_no_inline.ll b/test/InlineEntryPoints/null_pointer_no_inline.ll new file mode 100644 index 000000000..d4104fe88 --- /dev/null +++ b/test/InlineEntryPoints/null_pointer_no_inline.ll @@ -0,0 +1,29 @@ +; RUN: clspv-opt %s -o %t.ll --passes=inline-entry-points-pass +; RUN: FileCheck %s < %t.ll + +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" +target triple = "spirv32-unknown-vulkan" + +; CHECK-LABEL: define spir_func i32 @bar( +; CHECK-NOT: addrspace(4) +; CHECK: icmp eq ptr %p, null +; CHECK-LABEL: define spir_kernel void @foo( +; CHECK: call spir_func i32 @bar( + +define spir_func i32 @bar(ptr %p, i32 %x) { +entry: + %cmp1 = icmp eq ptr %p, addrspacecast (ptr addrspace(4) null to ptr) + %cmp2 = icmp eq ptr addrspace(4) null, null + %cond = and i1 %cmp1, %cmp2 + %res = select i1 %cond, i32 0, i32 %x + ret i32 %res +} + +define spir_kernel void @foo(ptr addrspace(1) %out, i32 %n) { +entry: + %a = alloca i32, align 4 + store i32 %n, ptr %a, align 4 + %call = call spir_func i32 @bar(ptr %a, i32 %n) + store i32 %call, ptr addrspace(1) %out, align 4 + ret void +}