Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,8 @@ class SPIRVLegalizePointerCast : public FunctionPass {
auto *GEP = B.CreateIntrinsic(Intrinsic::spv_gep, {Types}, {Args});
GR->buildAssignPtr(B, ElementType, GEP);

const auto *TLI = TM->getSubtargetImpl()->getTargetLowering();
MachineMemOperand::Flags Flags = TLI->getLoadMemOperandFlags(
*BadLoad, BadLoad->getFunction()->getDataLayout());
Instruction *LI = B.CreateIntrinsic(
Intrinsic::spv_load, {BadLoad->getOperand(0)->getType()},
{GEP, B.getInt16(Flags), B.getInt8(BadLoad->getAlign().value())});
LoadInst *LI = B.CreateLoad(ElementType, GEP);
LI->setAlignment(BadLoad->getAlign());
buildAssignType(B, ElementType, LI);
return LI;
}
Expand All @@ -123,6 +119,7 @@ class SPIRVLegalizePointerCast : public FunctionPass {

auto *SAT = dyn_cast<ArrayType>(FromTy);
auto *SVT = dyn_cast<FixedVectorType>(FromTy);
auto *SST = dyn_cast<StructType>(FromTy);
auto *DVT = dyn_cast<FixedVectorType>(ToTy);

B.SetInsertPoint(LI);
Expand All @@ -144,6 +141,11 @@ class SPIRVLegalizePointerCast : public FunctionPass {
// - float3 v3 = vector4;
else if (SVT && DVT)
Output = loadVectorFromVector(B, SVT, DVT, OriginalOperand);
// Destination is the scalar type stored at the start of an aggregate.
// - struct S { float m };
// - float v = s.m;
else if (SST && SST->getTypeAtIndex(0u) == ToTy)
Output = loadFirstValueFromAggregate(B, ToTy, OriginalOperand, LI);
else
llvm_unreachable("Unimplemented implicit down-cast from load.");

Expand All @@ -166,10 +168,11 @@ class SPIRVLegalizePointerCast : public FunctionPass {
continue;
}

IntrinsicInst *Intrin = dyn_cast<IntrinsicInst>(User);
if (Intrin->getIntrinsicID() == Intrinsic::spv_assign_ptr_type) {
DeadInstructions.push_back(Intrin);
continue;
if (IntrinsicInst *Intrin = dyn_cast<IntrinsicInst>(User)) {
if (Intrin->getIntrinsicID() == Intrinsic::spv_assign_ptr_type) {
DeadInstructions.push_back(Intrin);
continue;
}
}

llvm_unreachable("Unsupported ptrcast user. Please fix.");
Expand Down
64 changes: 64 additions & 0 deletions llvm/test/CodeGen/SPIRV/pointers/load-struct.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-vulkan-compute %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %}

; CHECK-DAG: %[[#uint:]] = OpTypeInt 32 0
; CHECK-DAG: %[[#float:]] = OpTypeFloat 32
; CHECK-DAG: %[[#float_fp:]] = OpTypePointer Function %[[#float]]
; CHECK-DAG: %[[#float_pp:]] = OpTypePointer Private %[[#float]]
; CHECK-DAG: %[[#uint_fp:]] = OpTypePointer Function %[[#uint]]
; CHECK-DAG: %[[#uint_0:]] = OpConstant %[[#uint]] 0
; CHECK-DAG: %[[#sf:]] = OpTypeStruct %[[#float]]
; CHECK-DAG: %[[#su:]] = OpTypeStruct %[[#uint]]
; CHECK-DAG: %[[#sfuf:]] = OpTypeStruct %[[#float]] %[[#uint]] %[[#float]]
; CHECK-DAG: %[[#sf_fp:]] = OpTypePointer Function %[[#sf]]
; CHECK-DAG: %[[#su_fp:]] = OpTypePointer Function %[[#su]]
; CHECK-DAG: %[[#sfuf_fp:]] = OpTypePointer Function %[[#sfuf]]
; CHECK-DAG: %[[#sfuf_pp:]] = OpTypePointer Private %[[#sfuf]]

%struct.SF = type { float }
%struct.SU = type { i32 }
%struct.SFUF = type { float, i32, float }

@gsfuf = external addrspace(10) global %struct.SFUF
; CHECK: %[[#gsfuf:]] = OpVariable %[[#sfuf_pp]] Private

define internal spir_func float @foo() {
%1 = alloca %struct.SF, align 4
; CHECK: %[[#var:]] = OpVariable %[[#sf_fp]] Function

%2 = load float, ptr %1, align 4
; CHECK: %[[#tmp:]] = OpAccessChain %[[#float_fp]] %[[#var]] %[[#uint_0]]
; CHECK: %[[#val:]] = OpLoad %[[#float]] %[[#tmp]] Aligned 4

ret float %2
}

define internal spir_func i32 @bar() {
%1 = alloca %struct.SU, align 4
; CHECK: %[[#var:]] = OpVariable %[[#su_fp]] Function

%2 = load i32, ptr %1, align 4
; CHECK: %[[#tmp:]] = OpAccessChain %[[#uint_fp]] %[[#var]] %[[#uint_0]]
; CHECK: %[[#val:]] = OpLoad %[[#uint]] %[[#tmp]] Aligned 4

ret i32 %2
}

define internal spir_func float @baz() {
%1 = alloca %struct.SFUF, align 4
; CHECK: %[[#var:]] = OpVariable %[[#sfuf_fp]] Function

%2 = load float, ptr %1, align 4
; CHECK: %[[#tmp:]] = OpAccessChain %[[#float_fp]] %[[#var]] %[[#uint_0]]
; CHECK: %[[#val:]] = OpLoad %[[#float]] %[[#tmp]] Aligned 4

ret float %2
}

define internal spir_func float @biz() {
%2 = load float, ptr addrspace(10) @gsfuf, align 4
; CHECK: %[[#tmp:]] = OpAccessChain %[[#float_pp]] %[[#gsfuf]] %[[#uint_0]]
; CHECK: %[[#val:]] = OpLoad %[[#float]] %[[#tmp]] Aligned 4

ret float %2
}
Loading