Skip to content

[SPIR-V] Fix unsupported downcast in LegalizePointerCast pass #145002

Open
@Keenuts

Description

@Keenuts

The following pattern is generated from some offload test suite:

; RUN: llc -O0 -mtriple=spirv1.6-unknown-vulkan1.3-compute -o - %s

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G10"
target triple = "spirv1.6-unknown-vulkan1.3-compute"

@.str = private unnamed_addr constant [3 x i8] c"In\00", align 1

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
define void @main() local_unnamed_addr #0 {
entry:
  %4 = tail call target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0v4f16_12_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str)
  call void @llvm.spv.assign.type.tspirv.VulkanBuffer_a0v4f16_12_0t(target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) %4, metadata target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) poison)
  %8 = tail call noundef align 8 dereferenceable(8) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0v4f16_12_0t(target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) %4, i32 1)
  call void @llvm.spv.assign.ptr.type.p11(ptr addrspace(11) %8, metadata <4 x half> poison, i32 11)
  %9 = load <4 x half>, ptr addrspace(11) %8, align 8

  %15 = call ptr addrspace(11) @llvm.spv.ptrcast.p11.p11(ptr addrspace(11) %8, metadata i8 poison, i32 11)
  call void @llvm.spv.assign.ptr.type.p11(ptr addrspace(11) %8, metadata i8 poison, i32 11)

  %16 = call ptr addrspace(11) (i1, ptr addrspace(11), ...) @llvm.spv.gep.p11.p11(i1 true, ptr addrspace(11) %8, i64 2)
  call void @llvm.spv.assign.ptr.type.p11(ptr addrspace(11) %16, metadata i8 poison, i32 11)

  %17 = call ptr addrspace(11) @llvm.spv.ptrcast.p11.p11(ptr addrspace(11) %16, metadata half poison, i32 11)
  call void @llvm.spv.assign.ptr.type.p11(ptr addrspace(11) %17, metadata half poison, i32 11)

  %18 = load half, ptr addrspace(11) %17, align 2
  ret void
}

declare target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0v4f16_12_0t(i32 %0, i32 %1, i32 %2, i32 %3, i1 %4, ptr %5) #1
declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0v4f16_12_0t(target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) %0, i32 %1) #1

declare void @llvm.spv.assign.type.tspirv.VulkanBuffer_a0v4f16_12_0t(target("spirv.VulkanBuffer", [0 x <4 x half>], 12, 0) %0, metadata %1) nounwind
declare void @llvm.spv.assign.ptr.type.p11(ptr addrspace(11) %0, metadata %1, i32 immarg %2) nounwind
declare ptr addrspace(11) @llvm.spv.ptrcast.p11.p11(ptr addrspace(11) %0, metadata %1, i32 immarg %2) nounwind
declare ptr addrspace(11) @llvm.spv.gep.p11.p11(i1 immarg %0, ptr addrspace(11) %1, ...) nounwind

attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="true" "frame-pointer"="all" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }

Removing the intermediate ptrcast solves the issue. For some reason, the assign.ptr.type intrinsics are generated on already refined types. In this sample, the first load helps the backend correctly determine the pointer to be a <4 x half>*. A subsequent load also determines the type to be a half*, and this reconciliation is correctly handled by the pass. But in the middle, a i8* type is added because of the GEP.
Maybe the type scavenger should be fixed so the GEP type is correctly found?

@s-perron

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions