Skip to content

Commit 5d01ec7

Browse files
authored
spirv-opt: Clone decorations when unrolling loops (#6373)
When unrolling a loop, the instructions in the body of the loop are cloned. If an instruction has a decoration, the decoration must be cloned and applied to the new instruction. This change ensures that the decorations are cloned. Fixes #5902
1 parent 1b74d67 commit 5d01ec7

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

source/opt/loop_unroller.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,11 @@ bool LoopUnrollerUtilsImpl::AssignNewResultIds(BasicBlock* basic_block) {
938938
inst.SetResultId(new_id);
939939
def_use_mgr->AnalyzeInstDef(&inst);
940940

941+
// All decorations that can apply to an instruction in a function body
942+
// modify the behaviour of the instruction, and should be on the
943+
// new instruction to keep the same results.
944+
context_->get_decoration_mgr()->CloneDecorations(old_id, new_id);
945+
941946
// Save the mapping of old_id -> new_id.
942947
state_.new_inst[old_id] = inst.result_id();
943948
// Check if this instruction is the induction variable.

test/opt/loop_optimizations/unroll_simple.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3864,6 +3864,81 @@ OpFunctionEnd
38643864
SinglePassRunAndCheck<LoopUnroller>(text, text, false);
38653865
}
38663866

3867+
TEST_F(PassClassTest, ApplyDecorationsToClonedInstructions) {
3868+
const std::string text = R"(
3869+
; CHECK: OpDecorate [[ld1:%\w+]] RelaxedPrecision
3870+
; CHECK: OpDecorate [[mul1:%\w+]] RelaxedPrecision
3871+
; CHECK: OpDecorate [[add1:%\w+]] RelaxedPrecision
3872+
; CHECK: OpDecorate [[ld2:%\w+]] RelaxedPrecision
3873+
; CHECK: OpDecorate [[mul2:%\w+]] RelaxedPrecision
3874+
; CHECK: OpDecorate [[add2:%\w+]] RelaxedPrecision
3875+
; CHECK: OpDecorate [[ld3:%\w+]] RelaxedPrecision
3876+
; CHECK: OpDecorate [[mul3:%\w+]] RelaxedPrecision
3877+
; CHECK: OpDecorate [[add3:%\w+]] RelaxedPrecision
3878+
3879+
; CHECK: [[ld1]] = OpLoad %float
3880+
; CHECK: [[mul1]] = OpFMul %float
3881+
; CHECK: [[add1]] = OpFAdd %float
3882+
; CHECK: [[ld2]] = OpLoad %float
3883+
; CHECK: [[mul2]] = OpFMul %float
3884+
; CHECK: [[add2]] = OpFAdd %float
3885+
; CHECK: [[ld3]] = OpLoad %float
3886+
; CHECK: [[mul3]] = OpFMul %float
3887+
; CHECK: [[add3]] = OpFAdd %float
3888+
3889+
OpCapability Shader
3890+
OpMemoryModel Logical GLSL450
3891+
OpEntryPoint GLCompute %1 "main" %2
3892+
OpExecutionMode %1 LocalSize 1 1 1
3893+
OpDecorate %2 DescriptorSet 0
3894+
OpDecorate %2 Binding 0
3895+
OpDecorate %_runtimearr_float ArrayStride 4
3896+
OpMemberDecorate %_struct_4 0 Offset 0
3897+
OpDecorate %_struct_4 Block
3898+
OpDecorate %5 RelaxedPrecision
3899+
OpDecorate %6 RelaxedPrecision
3900+
OpDecorate %7 RelaxedPrecision
3901+
%int = OpTypeInt 32 1
3902+
%int_0 = OpConstant %int 0
3903+
%int_3 = OpConstant %int 3
3904+
%int_1 = OpConstant %int 1
3905+
%float = OpTypeFloat 32
3906+
%_runtimearr_float = OpTypeRuntimeArray %float
3907+
%_struct_4 = OpTypeStruct %_runtimearr_float
3908+
%_ptr_StorageBuffer__struct_4 = OpTypePointer StorageBuffer %_struct_4
3909+
%uint = OpTypeInt 32 0
3910+
%void = OpTypeVoid
3911+
%16 = OpTypeFunction %void
3912+
%bool = OpTypeBool
3913+
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
3914+
%2 = OpVariable %_ptr_StorageBuffer__struct_4 StorageBuffer
3915+
%1 = OpFunction %void None %16
3916+
%19 = OpLabel
3917+
OpBranch %20
3918+
%20 = OpLabel
3919+
%21 = OpPhi %int %int_0 %19 %22 %23
3920+
%24 = OpSLessThan %bool %21 %int_3
3921+
OpLoopMerge %25 %23 Unroll
3922+
OpBranchConditional %24 %26 %25
3923+
%26 = OpLabel
3924+
%27 = OpBitcast %uint %21
3925+
%28 = OpAccessChain %_ptr_StorageBuffer_float %2 %int_0 %27
3926+
%5 = OpLoad %float %28
3927+
%6 = OpFMul %float %5 %5
3928+
%7 = OpFAdd %float %5 %6
3929+
OpStore %28 %7
3930+
OpBranch %23
3931+
%23 = OpLabel
3932+
%22 = OpIAdd %int %21 %int_1
3933+
OpBranch %20
3934+
%25 = OpLabel
3935+
OpReturn
3936+
OpFunctionEnd
3937+
)";
3938+
SetTargetEnv(SPV_ENV_UNIVERSAL_1_6);
3939+
SinglePassRunAndMatch<LoopUnroller>(text, true);
3940+
}
3941+
38673942
} // namespace
38683943
} // namespace opt
38693944
} // namespace spvtools

0 commit comments

Comments
 (0)