Browse Source

Correct iteration over users for gather offsets (#3709)

When converting the internal gatherimm intrinsic to the official dxil
variant after validation has been performed, user iteration went over
the edge, resulting in an app verifier problem. This corrects the
iteration.

Fixes #3674
Greg Roth 4 years ago
parent
commit
56370bad8d

+ 2 - 2
lib/HLSL/DxilPreparePasses.cpp

@@ -388,8 +388,8 @@ public:
       if (!F)
         continue;
       Type *Ty = OP::GetOverloadType(fromOpcode, F);
-      for (auto uit = F->user_begin(); uit != F->user_end(); uit++) {
-        CallInst *CI = cast<CallInst>(*uit);
+      for (auto uit = F->user_begin(), E = F->user_end(); uit != E;) {
+        CallInst *CI = cast<CallInst>(*(uit++));
         IRBuilder<> Builder(CI);
         std::vector<Value*> args;
         args.emplace_back(hlslOp->GetU32Const((unsigned)toOpcode));

+ 15 - 0
tools/clang/test/HLSLFileCheck/hlsl/objects/Texture/gatherOffset2.hlsl

@@ -0,0 +1,15 @@
+// RUN: %dxc -T ps_6_0 %s | FileCheck %s
+
+// Test for access violation that previously occured with these gathers
+
+// CHECK: @main
+
+Texture2D<float> shadowMap;
+SamplerComparisonState BilinearClampCmpSampler;
+SamplerState BilinearClampSampler;
+
+float4 main(float3 uv_depth: TEXCOORD0): SV_Target
+{
+    return shadowMap.GatherCmp(BilinearClampCmpSampler, uv_depth.xy, uv_depth.z, int2(0, 0))
+    + shadowMap.GatherRed(BilinearClampSampler, uv_depth.xy, int2(0, 0));
+}