diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index a151fd2fbdb7a..599cc35ca2e9d 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -767,6 +767,8 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper( Type *RefTy = deduceElementTypeHelper(Ref->getPointerOperand(), Visited, UnknownElemTypeI8); maybeAssignPtrType(Ty, I, RefTy, UnknownElemTypeI8); + } else if (auto *Ref = dyn_cast(I)) { + maybeAssignPtrType(Ty, I, Ref->getDestTy(), UnknownElemTypeI8); } else if (auto *Ref = dyn_cast(I)) { if (Type *Src = Ref->getSrcTy(), *Dest = Ref->getDestTy(); isPointerTy(Src) && isPointerTy(Dest)) @@ -2149,7 +2151,9 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I, for (const auto &Op : I->operands()) { if (isa(Op) || isa(Op) || // Check GetElementPtrConstantExpr case. - (isa(Op) && isa(Op))) { + (isa(Op) && + (isa(Op) || + (cast(Op)->getOpcode() == CastInst::IntToPtr)))) { setInsertPointSkippingPhis(B, I); Type *OpTy = Op->getType(); if (isa(Op) && OpTy->isAggregateType()) { diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 245e5a2894604..fc87288a4a212 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1210,8 +1210,16 @@ bool SPIRVInstructionSelector::selectUnOp(Register ResVReg, for (MachineRegisterInfo::def_instr_iterator DefIt = MRI->def_instr_begin(SrcReg); DefIt != MRI->def_instr_end(); DefIt = std::next(DefIt)) { - if ((*DefIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE || - (*DefIt).getOpcode() == SPIRV::OpVariable) { + unsigned DefOpCode = DefIt->getOpcode(); + if (DefOpCode == SPIRV::ASSIGN_TYPE) { + // We need special handling to look through the type assignment and see + // if this is a constant or a global + if (auto *VRD = getVRegDef(*MRI, DefIt->getOperand(1).getReg())) + DefOpCode = VRD->getOpcode(); + } + if (DefOpCode == TargetOpcode::G_GLOBAL_VALUE || + DefOpCode == TargetOpcode::G_CONSTANT || + DefOpCode == SPIRV::OpVariable || DefOpCode == SPIRV::OpConstantI) { IsGV = true; break; } @@ -3099,9 +3107,10 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp( SmallPtrSet Visited; if (!OpDefine || !OpType || isConstReg(MRI, OpDefine, Visited) || OpDefine->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST || + OpDefine->getOpcode() == TargetOpcode::G_INTTOPTR || GR.isAggregateType(OpType)) { // The case of G_ADDRSPACE_CAST inside spv_const_composite() is processed - // by selectAddrSpaceCast() + // by selectAddrSpaceCast(), and G_INTTOPTR is processed by selectUnOp() CompositeArgs.push_back(OpReg); continue; } diff --git a/llvm/test/CodeGen/SPIRV/ComparePointers.ll b/llvm/test/CodeGen/SPIRV/ComparePointers.ll index 408b95579502e..bc1514e145cb5 100644 --- a/llvm/test/CodeGen/SPIRV/ComparePointers.ll +++ b/llvm/test/CodeGen/SPIRV/ComparePointers.ll @@ -12,7 +12,7 @@ ;; return; ;; } -; CHECK-SPIRV: OpConvertPtrToU +; CHECK-SPIRV: OpSpecConstantOp %[[#]] ConvertPtrToU ; CHECK-SPIRV: OpConvertPtrToU ; CHECK-SPIRV: OpINotEqual ; CHECK-SPIRV: OpConvertPtrToU diff --git a/llvm/test/CodeGen/SPIRV/complex-constexpr.ll b/llvm/test/CodeGen/SPIRV/complex-constexpr.ll index e2c1d00ba4c0e..a97a124ad2c65 100644 --- a/llvm/test/CodeGen/SPIRV/complex-constexpr.ll +++ b/llvm/test/CodeGen/SPIRV/complex-constexpr.ll @@ -6,7 +6,7 @@ define linkonce_odr hidden spir_func void @test() { entry: ; CHECK: %[[#MinusOne:]] = OpConstant %[[#]] 18446744073709551615 -; CHECK: %[[#Ptr:]] = OpConvertUToPtr %[[#]] %[[#MinusOne]] +; CHECK: %[[#Ptr:]] = OpSpecConstantOp %[[#]] ConvertUToPtr %[[#MinusOne]] ; CHECK: %[[#PtrCast:]] = OpPtrCastToGeneric %[[#]] %[[#]] ; CHECK: %[[#]] = OpFunctionCall %[[#]] %[[#]] %[[#PtrCast]] %[[#Ptr]] diff --git a/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll b/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll new file mode 100644 index 0000000000000..f397030c7bdb1 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll @@ -0,0 +1,49 @@ +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK: %[[Int8Ty:[0-9]+]] = OpTypeInt 8 0 +; CHECK: %[[Int8PtrTy:[0-9]+]] = OpTypePointer Generic %[[Int8Ty]] +; CHECK-DAG: %[[GlobInt8PtrTy:[0-9]+]] = OpTypePointer CrossWorkgroup %[[Int8Ty]] +; CHECK: %[[GlobInt8PtrPtrTy:[0-9]+]] = OpTypePointer CrossWorkgroup %[[GlobInt8PtrTy]] +; CHECK: %[[Int8PtrGlobPtrPtrTy:[0-9]+]] = OpTypePointer Generic %[[GlobInt8PtrPtrTy]] +; CHECK: %[[Int32Ty:[0-9]+]] = OpTypeInt 32 0 +; CHECK: %[[Const5:[0-9]+]] = OpConstant %[[Int32Ty]] 5 +; CHECK: %[[ArrTy:[0-9]+]] = OpTypeArray %[[GlobInt8PtrTy]] %[[Const5]] +; CHECK: %[[VtblTy:[0-9]+]] = OpTypeStruct %[[ArrTy]] %[[ArrTy]] %[[ArrTy]] %[[ArrTy]] %[[ArrTy]] +; CHECK: %[[Int64Ty:[0-9]+]] = OpTypeInt 64 0 +; CHECK: %[[GlobVtblPtrTy:[0-9]+]] = OpTypePointer CrossWorkgroup %[[VtblTy]] +; CHECK: %[[ConstMinus184:[0-9]+]] = OpConstant %[[Int64Ty]] 18446744073709551432 +; CHECK: %[[ConstMinus16:[0-9]+]] = OpConstant %[[Int64Ty]] 18446744073709551600 +; CHECK: %[[Const168:[0-9]+]] = OpConstant %[[Int64Ty]] 168 +; CHECK: %[[Nullptr:[0-9]+]] = OpConstantNull %[[GlobInt8PtrTy]] +; CHECK: %[[Const184:[0-9]+]] = OpConstant %[[Int64Ty]] 184 +; CHECK: %[[Const184toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[Const184]] +; CHECK: %[[Const168toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[Const168]] +; CHECK: %[[ConstMinus16toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[ConstMinus16]] +; CHECK: %[[ConstMinus184toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[ConstMinus184]] +; CHECK: %[[Vtbl012:[0-9]+]] = OpConstantComposite %[[ArrTy]] %[[Const184toPtr]] %[[Nullptr]] %[[Nullptr]] %[[Nullptr]] %[[Nullptr]] +; CHECK: %[[Vtbl3:[0-9]+]] = OpConstantComposite %[[ArrTy]] %[[Const168toPtr]] %[[ConstMinus16toPtr]] %[[Nullptr]] %[[Nullptr]] %[[Nullptr]] +; CHECK: %[[Vtbl4:[0-9]+]] = OpConstantComposite %[[ArrTy]] %[[ConstMinus184toPtr]] %[[ConstMinus184toPtr]] %[[Nullptr]] %[[Nullptr]] %[[Nullptr]] +; CHECK: %[[Vtbl:[0-9]+]] = OpConstantComposite %[[VtblTy]] %[[Vtbl012]] %[[Vtbl012]] %[[Vtbl012]] %[[Vtbl3]] %[[Vtbl4]] +; CHECK: %[[#]] = OpVariable %[[GlobVtblPtrTy]] CrossWorkgroup %[[Vtbl]] + +@vtable = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] } + { [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 184 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null], + [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 184 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null], + [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 184 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null], + [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 168 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null], + [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -184 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -184 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null] } + +define linkonce_odr spir_func void @foo(ptr addrspace(4) %this) { +entry: + %0 = getelementptr inbounds i8, ptr addrspace(4) %this, i64 184 + store ptr addrspace(1) getelementptr inbounds inrange(-24, 16) ({ [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] }, ptr addrspace(1) @vtable, i32 0, i32 0, i32 3), ptr addrspace(4) %this + store ptr addrspace(1) getelementptr inbounds inrange(-24, 16) ({ [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] }, ptr addrspace(1) @vtable, i32 0, i32 1, i32 3), ptr addrspace(4) %this + store ptr addrspace(1) getelementptr inbounds inrange(-24, 16) ({ [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] }, ptr addrspace(1) @vtable, i32 0, i32 2, i32 3), ptr addrspace(4) %this + %add.ptr = getelementptr inbounds i8, ptr addrspace(4) %this, i64 184 + store ptr addrspace(1) getelementptr inbounds inrange(-24, 16) ({ [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] }, ptr addrspace(1) @vtable, i32 0, i32 4, i32 3), ptr addrspace(4) %add.ptr + %add.ptr2 = getelementptr inbounds i8, ptr addrspace(4) %this, i64 16 + store ptr addrspace(1) getelementptr inbounds inrange(-24, 16) ({ [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] }, ptr addrspace(1) @vtable, i32 0, i32 3, i32 3), ptr addrspace(4) %add.ptr2 + + ret void +}