Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/dxil-spirv.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-07-25 15:19:32 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-07-25 15:25:01 +0300
commit594f61d52a2ab99fc6fa44af5ae0661ae1bdaf3b (patch)
tree1dbeac649cec023d980395add75449ad4fd1d7e2
parent570adfd3d362f40553e6b2cfc1b9d3c4f824e3c1 (diff)
Don't consider adding fake succs to outer infinite loops.
-rw-r--r--cfg_structurizer.cpp5
-rw-r--r--reference/shaders/control-flow/loop-inside-infinite-loop-2.frag323
-rw-r--r--reference/shaders/control-flow/loop-inside-infinite-loop.frag217
-rw-r--r--shaders/control-flow/loop-inside-infinite-loop-2.frag44
-rw-r--r--shaders/control-flow/loop-inside-infinite-loop.frag44
5 files changed, 632 insertions, 1 deletions
diff --git a/cfg_structurizer.cpp b/cfg_structurizer.cpp
index 41f224e..269328f 100644
--- a/cfg_structurizer.cpp
+++ b/cfg_structurizer.cpp
@@ -1660,8 +1660,11 @@ void CFGStructurizer::backwards_visit()
}
else
{
+ // Only consider exits that are themselves backwards reachable.
+ // Otherwise, we'll be adding fake succs that resolve to outer infinite loops again.
for (auto *f : exits)
- node->pred_back_edge->add_fake_branch(f);
+ if (f->backward_visited)
+ node->pred_back_edge->add_fake_branch(f);
}
need_revisit = true;
}
diff --git a/reference/shaders/control-flow/loop-inside-infinite-loop-2.frag b/reference/shaders/control-flow/loop-inside-infinite-loop-2.frag
new file mode 100644
index 0000000..3a5f8e7
--- /dev/null
+++ b/reference/shaders/control-flow/loop-inside-infinite-loop-2.frag
@@ -0,0 +1,323 @@
+#version 460
+
+layout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;
+
+layout(location = 0) flat in uvec4 V;
+layout(location = 0) out vec4 SV_Target;
+
+void main()
+{
+ uint _71;
+ uint _72;
+ uint _73;
+ uint _74;
+ if (V.x < 10u)
+ {
+ uint _37;
+ _37 = V.x;
+ bool _42;
+ for (;;)
+ {
+ uint _41 = imageAtomicAdd(_8, int(0u), _37);
+ _42 = V.y == 0u;
+ if (!_42)
+ {
+ uint _50 = _37 & 3u;
+ bool ladder_phi_16;
+ uint _54 = _50;
+ uint _55 = 0u;
+ for (;;)
+ {
+ if (_54 == 0u)
+ {
+ if (!((_37 & 7u) == 0u))
+ {
+ ladder_phi_16 = false;
+ break;
+ }
+ uint _69 = imageAtomicAdd(_8, int(0u), _37);
+ uint _56 = _55 + 1u;
+ if (_56 < V.y)
+ {
+ _54 = 0u;
+ _55 = _56;
+ continue;
+ }
+ else
+ {
+ ladder_phi_16 = false;
+ break;
+ }
+ }
+ else
+ {
+ ladder_phi_16 = true;
+ break;
+ }
+ }
+ if (ladder_phi_16)
+ {
+ break;
+ }
+ }
+ uint _49 = imageAtomicAdd(_8, int(0u), _37);
+ _37++;
+ continue;
+ }
+ _71 = _37;
+ _72 = V.y;
+ _73 = V.z;
+ _74 = V.w;
+ }
+ else
+ {
+ uint _35 = V.y ^ 4294967295u;
+ uint _43;
+ _43 = V.x ^ 4294967295u;
+ bool _47;
+ for (;;)
+ {
+ uint _46 = imageAtomicAdd(_8, int(0u), _43);
+ _47 = V.y == 4294967295u;
+ if (!_47)
+ {
+ uint _53 = _43 & 3u;
+ bool ladder_phi_19;
+ uint _58 = _53;
+ uint _59 = 0u;
+ for (;;)
+ {
+ if (_58 == 0u)
+ {
+ if (!((_43 & 7u) == 0u))
+ {
+ ladder_phi_19 = false;
+ break;
+ }
+ uint _85 = imageAtomicAdd(_8, int(0u), _43);
+ uint _60 = _59 + 1u;
+ if (_60 < _35)
+ {
+ _58 = 0u;
+ _59 = _60;
+ continue;
+ }
+ else
+ {
+ ladder_phi_19 = false;
+ break;
+ }
+ }
+ else
+ {
+ ladder_phi_19 = true;
+ break;
+ }
+ }
+ if (ladder_phi_19)
+ {
+ break;
+ }
+ }
+ uint _52 = imageAtomicAdd(_8, int(0u), _43);
+ _43++;
+ continue;
+ }
+ _71 = _43;
+ _72 = _35;
+ _73 = V.z ^ 4294967295u;
+ _74 = V.w ^ 4294967295u;
+ }
+ SV_Target.x = float(_71);
+ SV_Target.y = float(_72);
+ SV_Target.z = float(_73);
+ SV_Target.w = float(_74);
+}
+
+
+#if 0
+// SPIR-V disassembly
+; SPIR-V
+; Version: 1.3
+; Generator: Unknown(30017); 21022
+; Bound: 120
+; Schema: 0
+OpCapability Shader
+OpCapability ImageBuffer
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %3 "main" %11 %15
+OpExecutionMode %3 OriginUpperLeft
+OpName %3 "main"
+OpName %11 "V"
+OpName %15 "SV_Target"
+OpName %87 "ladder_phi_16"
+OpName %90 "ladder_phi_19"
+OpDecorate %8 DescriptorSet 0
+OpDecorate %8 Binding 0
+OpDecorate %11 Flat
+OpDecorate %11 Location 0
+OpDecorate %15 Location 0
+%1 = OpTypeVoid
+%2 = OpTypeFunction %1
+%5 = OpTypeInt 32 0
+%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui
+%7 = OpTypePointer UniformConstant %6
+%8 = OpVariable %7 UniformConstant
+%9 = OpTypeVector %5 4
+%10 = OpTypePointer Input %9
+%11 = OpVariable %10 Input
+%12 = OpTypeFloat 32
+%13 = OpTypeVector %12 4
+%14 = OpTypePointer Output %13
+%15 = OpVariable %14 Output
+%17 = OpTypePointer Input %5
+%19 = OpConstant %5 0
+%22 = OpConstant %5 1
+%25 = OpConstant %5 2
+%28 = OpConstant %5 3
+%30 = OpTypeBool
+%32 = OpConstant %5 10
+%34 = OpConstant %5 4294967295
+%39 = OpTypePointer Image %5
+%63 = OpConstant %5 7
+%79 = OpTypePointer Output %12
+%88 = OpConstantFalse %30
+%89 = OpConstantTrue %30
+%3 = OpFunction %1 None %2
+%4 = OpLabel
+OpBranch %91
+%91 = OpLabel
+%16 = OpLoad %6 %8
+%18 = OpAccessChain %17 %11 %19
+%20 = OpLoad %5 %18
+%21 = OpAccessChain %17 %11 %22
+%23 = OpLoad %5 %21
+%24 = OpAccessChain %17 %11 %25
+%26 = OpLoad %5 %24
+%27 = OpAccessChain %17 %11 %28
+%29 = OpLoad %5 %27
+%31 = OpULessThan %30 %20 %32
+OpSelectionMerge %115 None
+OpBranchConditional %31 %105 %92
+%105 = OpLabel
+OpBranch %106
+%106 = OpLabel
+%37 = OpPhi %5 %20 %105 %38 %118
+%40 = OpImageTexelPointer %39 %8 %19 %19
+%41 = OpAtomicIAdd %5 %40 %22 %19 %37
+%42 = OpIEqual %30 %23 %19
+OpLoopMerge %114 %118 None
+OpBranch %107
+%107 = OpLabel
+OpSelectionMerge %117 None
+OpBranchConditional %42 %117 %108
+%108 = OpLabel
+%50 = OpBitwiseAnd %5 %37 %28
+OpBranch %109
+%109 = OpLabel
+%54 = OpPhi %5 %50 %108 %19 %112
+%55 = OpPhi %5 %19 %108 %56 %112
+%57 = OpIEqual %30 %54 %19
+OpLoopMerge %113 %112 None
+OpBranchConditional %57 %110 %113
+%110 = OpLabel
+%62 = OpBitwiseAnd %5 %37 %63
+%64 = OpIEqual %30 %62 %19
+OpSelectionMerge %111 None
+OpBranchConditional %64 %111 %113
+%111 = OpLabel
+OpBranch %112
+%112 = OpLabel
+%68 = OpImageTexelPointer %39 %8 %19 %19
+%69 = OpAtomicIAdd %5 %68 %22 %19 %37
+%56 = OpIAdd %5 %55 %22
+%70 = OpULessThan %30 %56 %23
+OpBranchConditional %70 %109 %113
+%113 = OpLabel
+%87 = OpPhi %30 %88 %110 %88 %112 %89 %109
+OpSelectionMerge %116 None
+OpBranchConditional %87 %114 %116
+%116 = OpLabel
+OpBranch %117
+%117 = OpLabel
+OpBranch %118
+%118 = OpLabel
+%48 = OpImageTexelPointer %39 %8 %19 %19
+%49 = OpAtomicIAdd %5 %48 %22 %19 %37
+%38 = OpIAdd %5 %37 %22
+OpBranch %106
+%114 = OpLabel
+OpBranch %115
+%92 = OpLabel
+%33 = OpBitwiseXor %5 %20 %34
+%35 = OpBitwiseXor %5 %23 %34
+%36 = OpBitwiseXor %5 %26 %34
+OpBranch %93
+%93 = OpLabel
+%43 = OpPhi %5 %33 %92 %44 %104
+%45 = OpImageTexelPointer %39 %8 %19 %19
+%46 = OpAtomicIAdd %5 %45 %22 %19 %43
+%47 = OpIEqual %30 %23 %34
+OpLoopMerge %101 %104 None
+OpBranch %94
+%94 = OpLabel
+OpSelectionMerge %103 None
+OpBranchConditional %47 %103 %95
+%95 = OpLabel
+%53 = OpBitwiseAnd %5 %43 %28
+OpBranch %96
+%96 = OpLabel
+%58 = OpPhi %5 %53 %95 %19 %99
+%59 = OpPhi %5 %19 %95 %60 %99
+%61 = OpIEqual %30 %58 %19
+OpLoopMerge %100 %99 None
+OpBranchConditional %61 %97 %100
+%97 = OpLabel
+%65 = OpBitwiseAnd %5 %43 %63
+%66 = OpIEqual %30 %65 %19
+OpSelectionMerge %98 None
+OpBranchConditional %66 %98 %100
+%98 = OpLabel
+OpBranch %99
+%99 = OpLabel
+%84 = OpImageTexelPointer %39 %8 %19 %19
+%85 = OpAtomicIAdd %5 %84 %22 %19 %43
+%60 = OpIAdd %5 %59 %22
+%86 = OpULessThan %30 %60 %35
+OpBranchConditional %86 %96 %100
+%100 = OpLabel
+%90 = OpPhi %30 %88 %97 %88 %99 %89 %96
+OpSelectionMerge %102 None
+OpBranchConditional %90 %101 %102
+%102 = OpLabel
+OpBranch %103
+%103 = OpLabel
+OpBranch %104
+%104 = OpLabel
+%51 = OpImageTexelPointer %39 %8 %19 %19
+%52 = OpAtomicIAdd %5 %51 %22 %19 %43
+%44 = OpIAdd %5 %43 %22
+OpBranch %93
+%101 = OpLabel
+%67 = OpBitwiseXor %5 %29 %34
+OpBranch %115
+%115 = OpLabel
+%71 = OpPhi %5 %37 %114 %43 %101
+%72 = OpPhi %5 %23 %114 %35 %101
+%73 = OpPhi %5 %26 %114 %36 %101
+%74 = OpPhi %5 %29 %114 %67 %101
+%75 = OpConvertUToF %12 %71
+%76 = OpConvertUToF %12 %72
+%77 = OpConvertUToF %12 %73
+%78 = OpConvertUToF %12 %74
+%80 = OpAccessChain %79 %15 %19
+OpStore %80 %75
+%81 = OpAccessChain %79 %15 %22
+OpStore %81 %76
+%82 = OpAccessChain %79 %15 %25
+OpStore %82 %77
+%83 = OpAccessChain %79 %15 %28
+OpStore %83 %78
+OpReturn
+OpFunctionEnd
+#endif
diff --git a/reference/shaders/control-flow/loop-inside-infinite-loop.frag b/reference/shaders/control-flow/loop-inside-infinite-loop.frag
new file mode 100644
index 0000000..6a0a0c7
--- /dev/null
+++ b/reference/shaders/control-flow/loop-inside-infinite-loop.frag
@@ -0,0 +1,217 @@
+#version 460
+
+layout(set = 0, binding = 0, r32ui) uniform uimageBuffer _8;
+
+layout(location = 0) flat in uvec4 V;
+layout(location = 0) out vec4 SV_Target;
+
+void main()
+{
+ float _33;
+ float _36;
+ float _38;
+ float _40;
+ if (V.x < 10u)
+ {
+ uint _47;
+ _47 = V.x;
+ bool _52;
+ for (;;)
+ {
+ uint _51 = imageAtomicAdd(_8, int(0u), _47);
+ _52 = V.y == 0u;
+ if (!_52)
+ {
+ uint _55 = _47 & 3u;
+ bool ladder_phi_10;
+ uint _56 = _55;
+ uint _57 = 0u;
+ for (;;)
+ {
+ if (_56 == 0u)
+ {
+ if (!((_47 & 7u) == 0u))
+ {
+ ladder_phi_10 = false;
+ break;
+ }
+ uint _64 = imageAtomicAdd(_8, int(0u), _47);
+ uint _58 = _57 + 1u;
+ if (_58 < V.y)
+ {
+ _56 = 0u;
+ _57 = _58;
+ continue;
+ }
+ else
+ {
+ ladder_phi_10 = false;
+ break;
+ }
+ }
+ else
+ {
+ ladder_phi_10 = true;
+ break;
+ }
+ }
+ if (ladder_phi_10)
+ {
+ break;
+ }
+ }
+ uint _54 = imageAtomicAdd(_8, int(0u), _47);
+ _47++;
+ continue;
+ }
+ _33 = float(_47);
+ _36 = float(V.y);
+ _38 = float(V.z);
+ _40 = float(V.w);
+ }
+ else
+ {
+ _33 = 0.0;
+ _36 = 0.0;
+ _38 = 0.0;
+ _40 = 0.0;
+ }
+ SV_Target.x = _33;
+ SV_Target.y = _36;
+ SV_Target.z = _38;
+ SV_Target.w = _40;
+}
+
+
+#if 0
+// SPIR-V disassembly
+; SPIR-V
+; Version: 1.3
+; Generator: Unknown(30017); 21022
+; Bound: 85
+; Schema: 0
+OpCapability Shader
+OpCapability ImageBuffer
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %3 "main" %11 %15
+OpExecutionMode %3 OriginUpperLeft
+OpName %3 "main"
+OpName %11 "V"
+OpName %15 "SV_Target"
+OpName %66 "ladder_phi_10"
+OpDecorate %8 DescriptorSet 0
+OpDecorate %8 Binding 0
+OpDecorate %11 Flat
+OpDecorate %11 Location 0
+OpDecorate %15 Location 0
+%1 = OpTypeVoid
+%2 = OpTypeFunction %1
+%5 = OpTypeInt 32 0
+%6 = OpTypeImage %5 Buffer 0 0 0 2 R32ui
+%7 = OpTypePointer UniformConstant %6
+%8 = OpVariable %7 UniformConstant
+%9 = OpTypeVector %5 4
+%10 = OpTypePointer Input %9
+%11 = OpVariable %10 Input
+%12 = OpTypeFloat 32
+%13 = OpTypeVector %12 4
+%14 = OpTypePointer Output %13
+%15 = OpVariable %14 Output
+%17 = OpTypePointer Input %5
+%19 = OpConstant %5 0
+%22 = OpConstant %5 1
+%25 = OpConstant %5 2
+%28 = OpConstant %5 3
+%30 = OpTypeBool
+%32 = OpConstant %5 10
+%35 = OpConstant %12 0
+%42 = OpTypePointer Output %12
+%49 = OpTypePointer Image %5
+%61 = OpConstant %5 7
+%67 = OpConstantFalse %30
+%68 = OpConstantTrue %30
+%3 = OpFunction %1 None %2
+%4 = OpLabel
+OpBranch %69
+%69 = OpLabel
+%16 = OpLoad %6 %8
+%18 = OpAccessChain %17 %11 %19
+%20 = OpLoad %5 %18
+%21 = OpAccessChain %17 %11 %22
+%23 = OpLoad %5 %21
+%24 = OpAccessChain %17 %11 %25
+%26 = OpLoad %5 %24
+%27 = OpAccessChain %17 %11 %28
+%29 = OpLoad %5 %27
+%31 = OpULessThan %30 %20 %32
+OpSelectionMerge %80 None
+OpBranchConditional %31 %70 %80
+%70 = OpLabel
+OpBranch %71
+%71 = OpLabel
+%47 = OpPhi %5 %20 %70 %48 %83
+%50 = OpImageTexelPointer %49 %8 %19 %19
+%51 = OpAtomicIAdd %5 %50 %22 %19 %47
+%52 = OpIEqual %30 %23 %19
+OpLoopMerge %79 %83 None
+OpBranch %72
+%72 = OpLabel
+OpSelectionMerge %82 None
+OpBranchConditional %52 %82 %73
+%73 = OpLabel
+%55 = OpBitwiseAnd %5 %47 %28
+OpBranch %74
+%74 = OpLabel
+%56 = OpPhi %5 %55 %73 %19 %77
+%57 = OpPhi %5 %19 %73 %58 %77
+%59 = OpIEqual %30 %56 %19
+OpLoopMerge %78 %77 None
+OpBranchConditional %59 %75 %78
+%75 = OpLabel
+%60 = OpBitwiseAnd %5 %47 %61
+%62 = OpIEqual %30 %60 %19
+OpSelectionMerge %76 None
+OpBranchConditional %62 %76 %78
+%76 = OpLabel
+OpBranch %77
+%77 = OpLabel
+%63 = OpImageTexelPointer %49 %8 %19 %19
+%64 = OpAtomicIAdd %5 %63 %22 %19 %47
+%58 = OpIAdd %5 %57 %22
+%65 = OpULessThan %30 %58 %23
+OpBranchConditional %65 %74 %78
+%78 = OpLabel
+%66 = OpPhi %30 %67 %75 %67 %77 %68 %74
+OpSelectionMerge %81 None
+OpBranchConditional %66 %79 %81
+%81 = OpLabel
+OpBranch %82
+%82 = OpLabel
+OpBranch %83
+%83 = OpLabel
+%53 = OpImageTexelPointer %49 %8 %19 %19
+%54 = OpAtomicIAdd %5 %53 %22 %19 %47
+%48 = OpIAdd %5 %47 %22
+OpBranch %71
+%79 = OpLabel
+%34 = OpConvertUToF %12 %47
+%37 = OpConvertUToF %12 %23
+%39 = OpConvertUToF %12 %26
+%41 = OpConvertUToF %12 %29
+OpBranch %80
+%80 = OpLabel
+%33 = OpPhi %12 %35 %69 %34 %79
+%36 = OpPhi %12 %35 %69 %37 %79
+%38 = OpPhi %12 %35 %69 %39 %79
+%40 = OpPhi %12 %35 %69 %41 %79
+%43 = OpAccessChain %42 %15 %19
+OpStore %43 %33
+%44 = OpAccessChain %42 %15 %22
+OpStore %44 %36
+%45 = OpAccessChain %42 %15 %25
+OpStore %45 %38
+%46 = OpAccessChain %42 %15 %28
+OpStore %46 %40
+OpReturn
+OpFunctionEnd
+#endif
diff --git a/shaders/control-flow/loop-inside-infinite-loop-2.frag b/shaders/control-flow/loop-inside-infinite-loop-2.frag
new file mode 100644
index 0000000..39e2e38
--- /dev/null
+++ b/shaders/control-flow/loop-inside-infinite-loop-2.frag
@@ -0,0 +1,44 @@
+StructuredBuffer<uint> RO : register(t0);
+RWStructuredBuffer<uint> RW : register(u0);
+
+void inc(inout uint v)
+{
+ uint ov;
+ InterlockedAdd(RW[0], v, v);
+ v = ov;
+}
+
+float4 inner_main(uint4 v)
+{
+ for (;;)
+ {
+ inc(v.x);
+ for (int i = 0; i < v.y; i++)
+ {
+ if (v.x & 3)
+ return float4(v);
+ if (v.x & 7)
+ break;
+ inc(v.x);
+ }
+ inc(v.x);
+ v.x++;
+ }
+ return float4(v);
+}
+
+float4 main(uint4 v : V) : SV_Target
+{
+ float4 ov;
+ [branch]
+ if (v.x < 10)
+ {
+ ov = inner_main(v);
+ }
+ else
+ {
+ ov = inner_main(~v);
+ //ov = 0.0.xxxx;
+ }
+ return ov;
+}
diff --git a/shaders/control-flow/loop-inside-infinite-loop.frag b/shaders/control-flow/loop-inside-infinite-loop.frag
new file mode 100644
index 0000000..d4d438b
--- /dev/null
+++ b/shaders/control-flow/loop-inside-infinite-loop.frag
@@ -0,0 +1,44 @@
+StructuredBuffer<uint> RO : register(t0);
+RWStructuredBuffer<uint> RW : register(u0);
+
+void inc(inout uint v)
+{
+ uint ov;
+ InterlockedAdd(RW[0], v, v);
+ v = ov;
+}
+
+float4 inner_main(uint4 v)
+{
+ for (;;)
+ {
+ inc(v.x);
+ for (int i = 0; i < v.y; i++)
+ {
+ if (v.x & 3)
+ return float4(v);
+ if (v.x & 7)
+ break;
+ inc(v.x);
+ }
+ inc(v.x);
+ v.x++;
+ }
+ return float4(v);
+}
+
+float4 main(uint4 v : V) : SV_Target
+{
+ float4 ov;
+ [branch]
+ if (v.x < 10)
+ {
+ ov = inner_main(v);
+ }
+ else
+ {
+ //ov = inner_main(~v);
+ ov = 0.0.xxxx;
+ }
+ return ov;
+}