llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.83k stars 11.01k forks source link

[SPIR-V] Redundant and invalid spv_assign_type intrinsics are emitted for null constants #92789

Open michalpaszkowski opened 1 month ago

michalpaszkowski commented 1 month ago

SPIRVEmitIntrinsics pass besides emitting spv_track_constant also emits redundant and invalid spv_assign_type calls for null constants, for instance in case of builtin nulls:

define spir_kernel void @foo() {
  %call1 = call spir_func ptr @_Z29async_work_group_strided_copyPU3AS3hPU3AS1Khmm9ocl_event(ptr null, ptr null, i64 1, i64 1, ptr null)
  %call2 = call spir_func ptr @_Z29async_work_group_strided_copyPU3AS3hPU3AS1Khmm9ocl_event(ptr null, ptr null, i64 1, i64 1, target("spirv.Event") zeroinitializer)
  ret void
}

declare spir_func ptr @_Z29async_work_group_strided_copyPU3AS3hPU3AS1Khmm9ocl_event(ptr, ptr, i64, i64, ptr)
VyacheslavLevytskyy commented 1 month ago

@michalpaszkowski I've started to explore this and found out that it looks like our type inference requires such spv_assign_type calls to properly set types eventually. Without such calls for builtin nulls we are getting complains from spirv-val in tests.

VyacheslavLevytskyy commented 4 weeks ago

@michalpaszkowski With the latest patches it looks now:

*** IR Dump After SPIRV emit intrinsics (emit-intrinsics) ***
; ModuleID = '92789.ll'
source_filename = "92789.ll"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
target triple = "spirv64-unknown-unknown"

define spir_kernel void @foo() {
  call void @llvm.spv.assign.ptr.type.p0(ptr null, metadata i8 poison, i32 0)
  %1 = call ptr @llvm.spv.track.constant.p0.p0(ptr null, metadata ptr null)
  %2 = call ptr @llvm.spv.track.constant.p0.p0(ptr null, metadata ptr null)
  %3 = call i64 @llvm.spv.track.constant.i64.i64(i64 1, metadata i64 1)
  %4 = call i64 @llvm.spv.track.constant.i64.i64(i64 1, metadata i64 1)
  %5 = call ptr @llvm.spv.track.constant.p0.p0(ptr null, metadata ptr null)
  %call1 = call spir_func ptr @_Z29async_work_group_strided_copyPU3AS3hPU3AS1Khmm9ocl_event(ptr %1, ptr %2, i64 %3, i64 %4, ptr %5)
  call void (ptr, ...) @llvm.spv.assign.name.p0(ptr %call1, i32 1819042147, i32 49)
  call void @llvm.spv.assign.ptr.type.p0(ptr %call1, metadata i8 poison, i32 0)
  %6 = call ptr @llvm.spv.track.constant.p0.p0(ptr null, metadata ptr null)
  %7 = call ptr @llvm.spv.track.constant.p0.p0(ptr null, metadata ptr null)
  %8 = call i64 @llvm.spv.track.constant.i64.i64(i64 1, metadata i64 1)
  %9 = call i64 @llvm.spv.track.constant.i64.i64(i64 1, metadata i64 1)
  %10 = call target("spirv.Event") @llvm.spv.track.constant.tspirv.Eventt.tspirv.Eventt(target("spirv.Event") poison, metadata target("spirv.Event") zeroinitializer)
  %call2 = call spir_func ptr @_Z29async_work_group_strided_copyPU3AS3hPU3AS1Khmm9ocl_event(ptr %6, ptr %7, i64 %8, i64 %9, target("spirv.Event") %10)
  call void (ptr, ...) @llvm.spv.assign.name.p0(ptr %call2, i32 1819042147, i32 50)
  call void @llvm.spv.assign.ptr.type.p0(ptr %call2, metadata i8 poison, i32 0)
  ret void
}

declare spir_func ptr @_Z29async_work_group_strided_copyPU3AS3hPU3AS1Khmm9ocl_event(ptr, ptr, i64, i64, ptr)

; Function Attrs: nounwind
declare void @llvm.spv.assign.ptr.type.p0(ptr, metadata, i32 immarg) #0

; Function Attrs: nounwind
declare ptr @llvm.spv.track.constant.p0.p0(ptr, metadata) #0

; Function Attrs: nounwind
declare i64 @llvm.spv.track.constant.i64.i64(i64, metadata) #0

; Function Attrs: nounwind
declare void @llvm.spv.assign.name.p0(ptr, ...) #0

; Function Attrs: nounwind
declare target("spirv.Event") @llvm.spv.track.constant.tspirv.Eventt.tspirv.Eventt(target("spirv.Event"), metadata) #0

attributes #0 = { nounwind }