blob: 9a202f9c319ad57afb362c6b3b47090df9875416 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes=gvn,instnamer -S %s | FileCheck %s
; This test ensures that given spv.resource.getpointer is marked convergent,
; the GVN pass is prevented from sinking these intrinsics out of branches which
; would create phi nodes on the returned ptr.
;
; The CHECK lines below match the input IR exactly, so this test verifies that
; the pass makes no changes to the IR.
%"class.hlsl::RWBuffer" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) }
%"class.hlsl::RWStructuredBuffer" = type { target("spirv.VulkanBuffer", [0 x i32], 12, 1), target("spirv.VulkanBuffer", [0 x i32], 12, 1) }
%__cblayout_c = type <{ i32 }>
@In = internal global %"class.hlsl::RWBuffer" poison, align 4
@.str = private unnamed_addr constant [3 x i8] c"In\00", align 1
@Out0 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
@.str.2 = private unnamed_addr constant [5 x i8] c"Out0\00", align 1
@Out1 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
@.str.4 = private unnamed_addr constant [5 x i8] c"Out1\00", align 1
@c.cb = local_unnamed_addr global target("spirv.VulkanBuffer", %__cblayout_c, 2, 0) poison
@cond = external hidden local_unnamed_addr addrspace(2) global i32, align 4
@c.str = private unnamed_addr constant [2 x i8] c"c\00", align 1
define void @main() local_unnamed_addr {
; CHECK-LABEL: define void @main() local_unnamed_addr {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[I:%.*]] = tail call target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) @llvm.spv.resource.handlefrombinding.tspirv.Image_i32_5_2_0_0_2_1t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
; CHECK-NEXT: store target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) [[I]], ptr @In, align 4
; CHECK-NEXT: [[I1:%.*]] = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
; CHECK-NEXT: store target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I1]], ptr @Out0, align 4
; CHECK-NEXT: store target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I1]], ptr getelementptr inbounds nuw (i8, ptr @Out0, i32 8), align 4
; CHECK-NEXT: [[I2:%.*]] = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 2, i32 1, i32 0, ptr nonnull @.str.4)
; CHECK-NEXT: store target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I2]], ptr @Out1, align 4
; CHECK-NEXT: store target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I2]], ptr getelementptr inbounds nuw (i8, ptr @Out1, i32 8), align 4
; CHECK-NEXT: [[C_CB_H_I_I:%.*]] = tail call target("spirv.VulkanBuffer", [[__CBLAYOUT_C:%.*]], 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_s___cblayout_cs_2_0t(i32 4, i32 0, i32 1, i32 0, ptr nonnull @c.str)
; CHECK-NEXT: store target("spirv.VulkanBuffer", [[__CBLAYOUT_C]], 2, 0) [[C_CB_H_I_I]], ptr @c.cb, align 8
; CHECK-NEXT: [[I3:%.*]] = tail call i32 @llvm.spv.flattened.thread.id.in.group()
; CHECK-NEXT: [[I4:%.*]] = load i32, ptr addrspace(2) @cond, align 4
; CHECK-NEXT: [[LOADEDV_I:%.*]] = trunc nuw i32 [[I4]] to i1
; CHECK-NEXT: br i1 [[LOADEDV_I]], label %[[IF_THEN_I:.*]], label %[[IF_ELSE_I:.*]]
; CHECK: [[IF_THEN_I]]:
; CHECK-NEXT: [[I5:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_1t.i32(target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) [[I]], i32 [[I3]])
; CHECK-NEXT: [[I6:%.*]] = load i32, ptr [[I5]], align 4
; CHECK-NEXT: [[HLSL_WAVE_ACTIVE_SUM_I:%.*]] = tail call i32 @llvm.spv.wave.reduce.sum.i32(i32 [[I6]])
; CHECK-NEXT: [[I7:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I1]], i32 [[I3]])
; CHECK-NEXT: store i32 [[HLSL_WAVE_ACTIVE_SUM_I]], ptr addrspace(11) [[I7]], align 4
; CHECK-NEXT: br label %[[MAIN_EXIT:.*]]
; CHECK: [[IF_ELSE_I]]:
; CHECK-NEXT: [[I8:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_1t.i32(target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) [[I]], i32 [[I3]])
; CHECK-NEXT: [[I9:%.*]] = load i32, ptr [[I8]], align 4
; CHECK-NEXT: [[I10:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I1]], i32 0)
; CHECK-NEXT: store i32 [[I9]], ptr addrspace(11) [[I10]], align 4
; CHECK-NEXT: br label %[[MAIN_EXIT]]
; CHECK: [[MAIN_EXIT]]:
; CHECK-NEXT: [[I11:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_1t.i32(target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) [[I]], i32 [[I3]])
; CHECK-NEXT: [[I12:%.*]] = load i32, ptr [[I11]], align 4
; CHECK-NEXT: [[HLSL_WAVE_ACTIVE_SUM5_I:%.*]] = tail call i32 @llvm.spv.wave.reduce.sum.i32(i32 [[I12]])
; CHECK-NEXT: [[I13:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) [[I1]], i32 [[I3]])
; CHECK-NEXT: store i32 [[HLSL_WAVE_ACTIVE_SUM5_I]], ptr addrspace(11) [[I13]], align 4
; CHECK-NEXT: ret void
;
entry:
%0 = tail call target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) @llvm.spv.resource.handlefrombinding.tspirv.Image_i32_5_2_0_0_2_1t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
store target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) %0, ptr @In, align 4
%1 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 1, i32 1, i32 0, ptr nonnull @.str.2)
store target("spirv.VulkanBuffer", [0 x i32], 12, 1) %1, ptr @Out0, align 4
store target("spirv.VulkanBuffer", [0 x i32], 12, 1) %1, ptr getelementptr inbounds nuw (i8, ptr @Out0, i32 8), align 4
%2 = tail call target("spirv.VulkanBuffer", [0 x i32], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0i32_12_1t(i32 0, i32 2, i32 1, i32 0, ptr nonnull @.str.4)
store target("spirv.VulkanBuffer", [0 x i32], 12, 1) %2, ptr @Out1, align 4
store target("spirv.VulkanBuffer", [0 x i32], 12, 1) %2, ptr getelementptr inbounds nuw (i8, ptr @Out1, i32 8), align 4
%c.cb_h.i.i = tail call target("spirv.VulkanBuffer", %__cblayout_c, 2, 0) @llvm.spv.resource.handlefromimplicitbinding.tspirv.VulkanBuffer_s___cblayout_cs_2_0t(i32 4, i32 0, i32 1, i32 0, ptr nonnull @c.str)
store target("spirv.VulkanBuffer", %__cblayout_c, 2, 0) %c.cb_h.i.i, ptr @c.cb, align 8
%3 = tail call i32 @llvm.spv.flattened.thread.id.in.group()
%4 = load i32, ptr addrspace(2) @cond, align 4
%loadedv.i = trunc nuw i32 %4 to i1
br i1 %loadedv.i, label %if.then.i, label %if.else.i
if.then.i: ; preds = %entry
%5 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_1t.i32(target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) %0, i32 %3)
%6 = load i32, ptr %5, align 4
%hlsl.wave.active.sum.i = tail call i32 @llvm.spv.wave.reduce.sum.i32(i32 %6)
%7 = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %1, i32 %3)
store i32 %hlsl.wave.active.sum.i, ptr addrspace(11) %7, align 4
br label %main.exit
if.else.i: ; preds = %entry
%8 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_1t.i32(target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) %0, i32 %3)
%9 = load i32, ptr %8, align 4
%10 = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %1, i32 0)
store i32 %9, ptr addrspace(11) %10, align 4
br label %main.exit
main.exit: ; preds = %if.then.i, %if.else.i
%11 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_1t.i32(target("spirv.Image", i32, 5, 2, 0, 0, 2, 1) %0, i32 %3)
%12 = load i32, ptr %11, align 4
%hlsl.wave.active.sum5.i = tail call i32 @llvm.spv.wave.reduce.sum.i32(i32 %12)
%13 = tail call noundef nonnull align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.VulkanBuffer_a0i32_12_1t.i32(target("spirv.VulkanBuffer", [0 x i32], 12, 1) %1, i32 %3)
store i32 %hlsl.wave.active.sum5.i, ptr addrspace(11) %13, align 4
ret void
}