-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[SPIR-V] Fix some GEP legalization #150943
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,7 @@ define spir_func void @foo(ptr noundef byval(%tprange) align 8 %_arg_UserRange) | |
%RoundedRangeKernel = alloca %tprange, align 8 | ||
call void @llvm.lifetime.start.p0(i64 72, ptr nonnull %RoundedRangeKernel) | ||
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %RoundedRangeKernel, ptr align 8 %_arg_UserRange, i64 16, i1 false) | ||
%KernelFunc = getelementptr inbounds i8, ptr %RoundedRangeKernel, i64 16 | ||
%KernelFunc = getelementptr inbounds i8, ptr %RoundedRangeKernel, i64 8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you making this change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The size of %tprange is 16 bytes. If you do a GEP to +16, you are doing an out-of-bounds access. Because we have a literal index, we'd generate an out-of-bounds OpInBoundsAccessChain |
||
call void @llvm.lifetime.end.p0(i64 72, ptr nonnull %RoundedRangeKernel) | ||
ret void | ||
} | ||
|
@@ -55,7 +55,7 @@ define spir_func void @bar(ptr noundef byval(%tprange) align 8 %_arg_UserRange) | |
%RoundedRangeKernel = alloca %tprange, align 8 | ||
call void @llvm.lifetime.start.p0(i64 -1, ptr nonnull %RoundedRangeKernel) | ||
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %RoundedRangeKernel, ptr align 8 %_arg_UserRange, i64 16, i1 false) | ||
%KernelFunc = getelementptr inbounds i8, ptr %RoundedRangeKernel, i64 16 | ||
%KernelFunc = getelementptr inbounds i8, ptr %RoundedRangeKernel, i64 8 | ||
call void @llvm.lifetime.end.p0(i64 -1, ptr nonnull %RoundedRangeKernel) | ||
ret void | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
; RUN: llc -verify-machineinstrs -O3 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - | FileCheck %s | ||
; RUN: %if spirv-tools %{ llc -O3 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - -filetype=obj | spirv-val %} | ||
|
||
%struct.S1 = type { <4 x i32>, [10 x <4 x float>], <4 x float> } | ||
%struct.S2 = type { <4 x float>, <4 x i32> } | ||
|
||
@.str = private unnamed_addr constant [3 x i8] c"In\00", align 1 | ||
|
||
define <4 x float> @main() { | ||
entry: | ||
%0 = tail call target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr nonnull @.str) | ||
%3 = tail call noundef align 1 dereferenceable(192) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0) %0, i32 0) | ||
|
||
; CHECK-DAG: %[[#ulong:]] = OpTypeInt 64 0 | ||
; CHECK-DAG: %[[#ulong_1:]] = OpConstant %[[#ulong]] 1 | ||
; CHECK-DAG: %[[#ulong_3:]] = OpConstant %[[#ulong]] 3 | ||
|
||
; CHECK-DAG: %[[#uint:]] = OpTypeInt 32 0 | ||
; CHECK-DAG: %[[#uint_0:]] = OpConstant %[[#uint]] 0 | ||
; CHECK-DAG: %[[#uint_10:]] = OpConstant %[[#uint]] 10 | ||
|
||
; CHECK-DAG: %[[#float:]] = OpTypeFloat 32 | ||
; CHECK-DAG: %[[#v4f:]] = OpTypeVector %[[#float]] 4 | ||
; CHECK-DAG: %[[#arr_v4f:]] = OpTypeArray %[[#v4f]] %[[#uint_10]] | ||
; CHECK-DAG: %[[#S1:]] = OpTypeStruct %[[#]] %[[#arr_v4f]] %[[#]] | ||
; CHECK-DAG: %[[#sb_S1:]] = OpTypePointer StorageBuffer %[[#S1]] | ||
; CHECK-DAG: %[[#sb_v4f:]] = OpTypePointer StorageBuffer %[[#v4f]] | ||
|
||
; CHECK: %[[#tmp:]] = OpAccessChain %[[#sb_S1]] %[[#]] %[[#uint_0]] %[[#uint_0]] | ||
; CHECK: %[[#ptr:]] = OpInBoundsAccessChain %[[#sb_v4f]] %[[#tmp]] %[[#ulong_1]] %[[#ulong_3]] | ||
; This rewritten GEP combined all constant indices into a single value. | ||
; We should make sure the correct indices are retrieved. | ||
%arrayidx.i = getelementptr inbounds nuw i8, ptr addrspace(11) %3, i64 64 | ||
|
||
; CHECK: OpLoad %[[#v4f]] %[[#ptr]] | ||
%4 = load <4 x float>, ptr addrspace(11) %arrayidx.i, align 1 | ||
|
||
ret <4 x float> %4 | ||
} | ||
|
||
declare i32 @llvm.spv.flattened.thread.id.in.group() | ||
declare target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(i32, i32, i32, i32, i1, ptr) | ||
declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0), i32) | ||
|
||
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
; RUN: llc -verify-machineinstrs -O3 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - | FileCheck %s | ||
; RUN: %if spirv-tools %{ llc -O3 -mtriple=spirv1.6-unknown-vulkan1.3-compute %s -o - -filetype=obj | spirv-val %} | ||
|
||
%struct.S1 = type { <4 x i32>, [10 x <4 x float>], <4 x float> } | ||
%struct.S2 = type { <4 x float>, <4 x i32> } | ||
|
||
@.str = private unnamed_addr constant [3 x i8] c"In\00", align 1 | ||
|
||
define <4 x float> @main(i32 %index) { | ||
entry: | ||
%0 = tail call target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr nonnull @.str) | ||
%3 = tail call noundef align 1 dereferenceable(192) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0) %0, i32 0) | ||
|
||
; CHECK-DAG: %[[#ulong:]] = OpTypeInt 64 0 | ||
; CHECK-DAG: %[[#ulong_1:]] = OpConstant %[[#ulong]] 1 | ||
|
||
; CHECK-DAG: %[[#uint:]] = OpTypeInt 32 0 | ||
; CHECK-DAG: %[[#uint_0:]] = OpConstant %[[#uint]] 0 | ||
; CHECK-DAG: %[[#uint_10:]] = OpConstant %[[#uint]] 10 | ||
; CHECK-DAG: %[[#uint_16:]] = OpConstant %[[#uint]] 16 | ||
|
||
; CHECK-DAG: %[[#float:]] = OpTypeFloat 32 | ||
; CHECK-DAG: %[[#v4f:]] = OpTypeVector %[[#float]] 4 | ||
; CHECK-DAG: %[[#arr_v4f:]] = OpTypeArray %[[#v4f]] %[[#uint_10]] | ||
; CHECK-DAG: %[[#S1:]] = OpTypeStruct %[[#]] %[[#arr_v4f]] %[[#]] | ||
; CHECK-DAG: %[[#sb_S1:]] = OpTypePointer StorageBuffer %[[#S1]] | ||
; CHECK-DAG: %[[#sb_arr_v4f:]] = OpTypePointer StorageBuffer %[[#arr_v4f]] | ||
; CHECK-DAG: %[[#sb_v4f:]] = OpTypePointer StorageBuffer %[[#v4f]] | ||
|
||
; CHECK: %[[#a:]] = OpAccessChain %[[#sb_S1]] %[[#]] %[[#uint_0]] %[[#uint_0]] | ||
; CHECK: %[[#b:]] = OpInBoundsAccessChain %[[#sb_arr_v4f]] %[[#a]] %[[#ulong_1]] | ||
%4 = getelementptr inbounds nuw i8, ptr addrspace(11) %3, i64 16 | ||
|
||
; CHECK: %[[#offset:]] = OpIMul %[[#]] %[[#]] %[[#uint_16]] | ||
; Offset is computed in bytes. Make sure we reconvert it back to an index. | ||
%offset = mul i32 %index, 16 | ||
|
||
; CHECK: %[[#index:]] = OpUDiv %[[#]] %[[#offset]] %[[#uint_16]] | ||
; CHECK: %[[#c:]] = OpInBoundsAccessChain %[[#sb_v4f]] %[[#b]] %[[#index]] | ||
%5 = getelementptr inbounds nuw i8, ptr addrspace(11) %4, i32 %offset | ||
|
||
; CHECK: OpLoad %[[#v4f]] %[[#c]] | ||
%6 = load <4 x float>, ptr addrspace(11) %5, align 1 | ||
|
||
ret <4 x float> %6 | ||
} | ||
|
||
declare i32 @llvm.spv.flattened.thread.id.in.group() | ||
declare target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(i32, i32, i32, i32, i1, ptr) | ||
declare ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0s_struct.S1s_12_0t(target("spirv.VulkanBuffer", [0 x %struct.S1], 12, 0), i32) | ||
|
||
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.