From 3020d4d3bd4d592ec94e6ded057071a59c6b6dd3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:25:31 +0000 Subject: [PATCH 1/7] Initial plan From a05bd445f0825eb229a59626a67ca951009b5141 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:56:18 +0000 Subject: [PATCH 2/7] Add validation for odd-sized integer types in DXIL instruction operands and results Extends the existing i8 check in the instruction validation loop to also reject integer types with non-standard widths (anything other than i1/i8/i16/i32/i64). This catches cases where optimizations produce odd-sized types like i25 that are not valid DXIL types. Adds a LIT test that verifies i25 types are rejected by the validator. Fixes microsoft/DirectXShaderCompiler#6563 Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- lib/DxilValidation/DxilValidation.cpp | 18 ++++- .../LitDXILValidation/int-width-validation.ll | 70 +++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 tools/clang/test/LitDXILValidation/int-width-validation.ll diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index 2236dd11f7..43ec9e990f 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -3388,10 +3388,17 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) { } } if (IntegerType *IT = dyn_cast(op->getType())) { - if (IT->getBitWidth() == 8) { + unsigned BW = IT->getBitWidth(); + if (BW == 8) { // We always fail if we see i8 as operand type of a non-lifetime // instruction. ValCtx.EmitInstrError(&I, ValidationRule::TypesI8); + } else if (BW != 1 && BW != 16 && BW != 32 && BW != 64) { + std::string O; + raw_string_ostream OSS(O); + IT->print(OSS); + ValCtx.EmitInstrFormatError(&I, ValidationRule::TypesIntWidth, + {OSS.str()}); } } } @@ -3402,12 +3409,19 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) { while (isa(Ty)) Ty = Ty->getArrayElementType(); if (IntegerType *IT = dyn_cast(Ty)) { - if (IT->getBitWidth() == 8) { + unsigned BW = IT->getBitWidth(); + if (BW == 8) { // Allow i8* cast for llvm.lifetime.* intrinsics. if (!SupportsLifetimeIntrinsics || !isa(I) || !onlyUsedByLifetimeMarkers(&I)) { ValCtx.EmitInstrError(&I, ValidationRule::TypesI8); } + } else if (BW != 1 && BW != 16 && BW != 32 && BW != 64) { + std::string O; + raw_string_ostream OSS(O); + IT->print(OSS); + ValCtx.EmitInstrFormatError(&I, ValidationRule::TypesIntWidth, + {OSS.str()}); } } diff --git a/tools/clang/test/LitDXILValidation/int-width-validation.ll b/tools/clang/test/LitDXILValidation/int-width-validation.ll new file mode 100644 index 0000000000..5a13eca440 --- /dev/null +++ b/tools/clang/test/LitDXILValidation/int-width-validation.ll @@ -0,0 +1,70 @@ +; RUN: not %dxv %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +%dx.types.Handle = type { i8* } +%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 } +%"$Globals" = type { i32 } + +define void @main() { + %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex) + %2 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %1, i32 0) ; CBufferLoadLegacy(handle,regIndex) + %3 = extractvalue %dx.types.CBufRet.i32 %2, 0 + %4 = icmp ult i32 %3, 25 + br i1 %4, label %5, label %11 + +;