From e0ec755d08d5d52453640360046814b52dc8d228 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:24:18 +0000 Subject: [PATCH 1/5] Initial plan From d0d701cc53975d3caa49babd462e4ea19adfee9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:57:50 +0000 Subject: [PATCH 2/5] Fix createHandleFromBinding index validation and add test (issue #7019) Add validation in BuildResMap() to check that the index parameter of createHandleFromBinding falls within the range [rangeLowerBound, rangeUpperBound] from the ResBind parameter. This matches the existing validation done for createHandle. Add a LIT test that verifies the validator catches an out-of-range index (index 0 with rangeLowerBound=1, rangeUpperBound=1). Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- lib/DxilValidation/DxilValidationUtils.cpp | 25 +++++++++++ ...ateHandleFromBinding-index-out-of-range.ll | 45 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll diff --git a/lib/DxilValidation/DxilValidationUtils.cpp b/lib/DxilValidation/DxilValidationUtils.cpp index f0f85fcd26..28a8250b1d 100644 --- a/lib/DxilValidation/DxilValidationUtils.cpp +++ b/lib/DxilValidation/DxilValidationUtils.cpp @@ -15,6 +15,7 @@ #include "dxc/DXIL/DxilInstructions.h" #include "dxc/DXIL/DxilModule.h" #include "dxc/DXIL/DxilOperations.h" +#include "dxc/DXIL/DxilResourceBinding.h" #include "dxc/DXIL/DxilUtil.h" #include "dxc/Support/Global.h" @@ -229,6 +230,30 @@ void ValidationContext::BuildResMap() { } const ShaderModel &SM = *DxilMod.GetShaderModel(); + // Scan all createHandleFromBinding for index validation. + for (auto &it : + hlslOP->GetOpFuncList(DXIL::OpCode::CreateHandleFromBinding)) { + Function *F = it.second; + if (!F) + continue; + for (User *U : F->users()) { + CallInst *CI = cast(U); + DxilInst_CreateHandleFromBinding hdl(CI); + ConstantInt *cIndex = dyn_cast(hdl.get_index()); + if (cIndex) { + DxilResourceBinding B = + resource_helper::loadBindingFromCreateHandleFromBinding( + hdl, hlslOP->GetHandleType(), SM); + unsigned index = cIndex->getLimitedValue(); + if (index < B.rangeLowerBound || index > B.rangeUpperBound) { + // index out of range. + EmitInstrError(CI, ValidationRule::InstrOpConstRange); + continue; + } + } + } + } + for (auto &it : hlslOP->GetOpFuncList(DXIL::OpCode::AnnotateHandle)) { Function *F = it.second; if (!F) diff --git a/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll b/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll new file mode 100644 index 0000000000..f105415650 --- /dev/null +++ b/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll @@ -0,0 +1,45 @@ +; REQUIRES: dxil-1-8 +; RUN: not %dxv %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +%dx.types.Handle = type { i8* } +%dx.types.ResBind = type { i32, i32, i32, i8 } +%dx.types.ResourceProperties = type { i32, i32 } +%struct.RWByteAddressBuffer = type { i32 } + +; CHECK: error: Constant values must be in-range for operation. +; CHECK: note: at '%1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 0, i1 false)' in block '#0' of function 'main'. + +define void @main() { + ; Binding has rangeLowerBound=1, rangeUpperBound=1, but index is 0 (below lower bound) + %1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 0, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex) + %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer + ret void +} + +; Function Attrs: nounwind readnone +declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #0 + +; Function Attrs: nounwind readnone +declare %dx.types.Handle @dx.op.createHandleFromBinding(i32, %dx.types.ResBind, i32, i1) #0 + +attributes #0 = { nounwind readnone } + +!llvm.ident = !{!0} +!dx.version = !{!1} +!dx.valver = !{!1} +!dx.shaderModel = !{!2} +!dx.resources = !{!3} +!dx.entryPoints = !{!6} + +!0 = !{!"dxc(private) 1.8.0.15017 (main, 4e0f5364a-dirty)"} +!1 = !{i32 1, i32 8} +!2 = !{!"cs", i32 6, i32 8} +!3 = !{null, !4, null, null} +!4 = !{!5} +!5 = !{i32 0, %struct.RWByteAddressBuffer* undef, !"", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null} +!6 = !{void ()* @main, !"main", null, !3, !7} +!7 = !{i32 0, i64 8589934608, i32 4, !8} +!8 = !{i32 4, i32 1, i32 1} From c7801480fd1bc1f8369a4a9aebd2152f43b97d8f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:01:15 +0000 Subject: [PATCH 3/5] Add test for index above upper bound in createHandleFromBinding validation Extend the test to cover both edge cases: index below rangeLowerBound (0 < 1) and index above rangeUpperBound (4 > 3). Uses a range of [1,3] to ensure both boundaries are tested independently. Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- .../createHandleFromBinding-index-out-of-range.ll | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll b/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll index f105415650..b1b86acd4b 100644 --- a/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll +++ b/tools/clang/test/LitDXILValidation/createHandleFromBinding-index-out-of-range.ll @@ -9,13 +9,18 @@ target triple = "dxil-ms-dx" %dx.types.ResourceProperties = type { i32, i32 } %struct.RWByteAddressBuffer = type { i32 } -; CHECK: error: Constant values must be in-range for operation. -; CHECK: note: at '%1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 0, i1 false)' in block '#0' of function 'main'. +; CHECK-DAG: error: Constant values must be in-range for operation. +; CHECK-DAG: note: at '%1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 3, i32 0, i8 1 }, i32 0, i1 false)' in block '#0' of function 'main'. +; CHECK-DAG: error: Constant values must be in-range for operation. +; CHECK-DAG: note: at '%3 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 3, i32 0, i8 1 }, i32 4, i1 false)' in block '#0' of function 'main'. define void @main() { - ; Binding has rangeLowerBound=1, rangeUpperBound=1, but index is 0 (below lower bound) - %1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 0, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex) + ; Binding has rangeLowerBound=1, rangeUpperBound=3, but index is 0 (below lower bound) + %1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 3, i32 0, i8 1 }, i32 0, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex) %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer + ; Binding has rangeLowerBound=1, rangeUpperBound=3, but index is 4 (above upper bound) + %3 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 3, i32 0, i8 1 }, i32 4, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex) + %4 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %3, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer ret void } @@ -39,7 +44,7 @@ attributes #0 = { nounwind readnone } !2 = !{!"cs", i32 6, i32 8} !3 = !{null, !4, null, null} !4 = !{!5} -!5 = !{i32 0, %struct.RWByteAddressBuffer* undef, !"", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null} +!5 = !{i32 0, %struct.RWByteAddressBuffer* undef, !"", i32 0, i32 1, i32 3, i32 11, i1 false, i1 false, i1 false, null} !6 = !{void ()* @main, !"main", null, !3, !7} !7 = !{i32 0, i64 8589934608, i32 4, !8} !8 = !{i32 4, i32 1, i32 1} From 5dc365f0b747f053bacc5afacc49e78d06453a15 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:00:53 +0000 Subject: [PATCH 4/5] Add release note for CreateHandleFromBinding index validation fix Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- docs/ReleaseNotes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index d426b955f2..9dd79054a5 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -39,6 +39,7 @@ line upon naming the release. Refer to previous for appropriate section names. #### Other Changes - Fixed mesh shader semantics that were incorrectly case sensitive. +- Added index range validation for `CreateHandleFromBinding` to match existing `CreateHandle` validation. ### Version 1.9.2602 From da8d8c3b9fa3b80ae872c78678a8149d7cc67182 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:03:32 +0000 Subject: [PATCH 5/5] Update release note to identify DXIL validation change Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- docs/ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 9dd79054a5..58977360ca 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -39,7 +39,7 @@ line upon naming the release. Refer to previous for appropriate section names. #### Other Changes - Fixed mesh shader semantics that were incorrectly case sensitive. -- Added index range validation for `CreateHandleFromBinding` to match existing `CreateHandle` validation. +- DXIL validation: added index range validation for `CreateHandleFromBinding` to match existing `CreateHandle` validation. ### Version 1.9.2602