From b41944be8ec0a70686464689ae7ba7b0b28ebc74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 22:12:42 +0000 Subject: [PATCH 1/3] Initial plan From 14224ea7c9b96c12a2b943c11979347f9c2d8270 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 22:42:13 +0000 Subject: [PATCH 2/3] Fix mul with double vectors producing invalid DXIL dot intrinsic The Dot2/3/4 DXIL operations only support half and float (overload bitmask 0x3), not double. When mul(double_vector, double_vector) was called, TranslateFDot would generate an invalid dx.op.dot4.f64 call. Fix: In TranslateFDot, detect double type and expand the dot product using FMul and FMad (which supports double) via ExpandDot, instead of using the unsupported Dot2/3/4 intrinsics. Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- lib/HLSL/HLOperationLower.cpp | 7 +++++ .../hlsl/intrinsics/mul/mul_double.hlsl | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index 4f22a4598d..84d0c5b36a 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -2590,6 +2590,13 @@ Value *ExpandDot(Value *arg0, Value *arg1, unsigned vecSize, hlsl::OP *hlslOP, Value *TranslateFDot(Value *arg0, Value *arg1, unsigned vecSize, hlsl::OP *hlslOP, IRBuilder<> &Builder) { + // Dot2/3/4 DXIL operations only support half and float, not double. + // For double vectors, expand the dot product using FMul and FMad. + if (arg0->getType()->getScalarType()->isDoubleTy()) { + return ExpandDot(arg0, arg1, vecSize, hlslOP, Builder, + DXIL::OpCode::FMad); + } + switch (vecSize) { case 2: return TrivialDotOperation(OP::OpCode::Dot2, arg0, arg1, hlslOP, Builder); diff --git a/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl new file mode 100644 index 0000000000..c71c02e8f2 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl @@ -0,0 +1,29 @@ +// RUN: %dxc -T cs_6_0 -E main -DDIM=4 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DDIM=3 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DDIM=2 %s | FileCheck %s + +// Verify that mul of double vectors does not produce invalid DXIL dot +// intrinsics (Dot2/3/4 only support half and float). Instead, the dot +// product should be expanded using FMul and FMad. + +// CHECK-NOT: call double @dx.op.dot2.f64 +// CHECK-NOT: call double @dx.op.dot3.f64 +// CHECK-NOT: call double @dx.op.dot4.f64 +// CHECK: fmul fast double +// CHECK: call double @dx.op.tertiary.f64(i32 46, + +#if DIM == 4 +typedef double4 DVec; +#elif DIM == 3 +typedef double3 DVec; +#else +typedef double2 DVec; +#endif + +RWStructuredBuffer In; +RWStructuredBuffer Out; + +[numthreads(1, 1, 1)] +void main() { + Out[0] = mul(In[0], In[1]); +} From 45f72a90376f75c6168861ee2b666c81c8618d95 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 23:24:19 +0000 Subject: [PATCH 3/3] Expand test to cover both mul and dot with double vectors Add dot() test cases alongside mul() for double2/3/4 vectors since both share the TranslateFDot codepath. Both fail validation without the fix and pass with it. The %dxc RUN lines implicitly validate DXIL since dxc runs the validator by default. Co-authored-by: damyanp <8118402+damyanp@users.noreply.github.com> --- .../hlsl/intrinsics/mul/mul_double.hlsl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl index c71c02e8f2..f4f33487ca 100644 --- a/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl +++ b/tools/clang/test/HLSLFileCheck/hlsl/intrinsics/mul/mul_double.hlsl @@ -1,10 +1,14 @@ -// RUN: %dxc -T cs_6_0 -E main -DDIM=4 %s | FileCheck %s -// RUN: %dxc -T cs_6_0 -E main -DDIM=3 %s | FileCheck %s -// RUN: %dxc -T cs_6_0 -E main -DDIM=2 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DFUNC=mul -DDIM=4 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DFUNC=mul -DDIM=3 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DFUNC=mul -DDIM=2 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DFUNC=dot -DDIM=4 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DFUNC=dot -DDIM=3 %s | FileCheck %s +// RUN: %dxc -T cs_6_0 -E main -DFUNC=dot -DDIM=2 %s | FileCheck %s -// Verify that mul of double vectors does not produce invalid DXIL dot -// intrinsics (Dot2/3/4 only support half and float). Instead, the dot -// product should be expanded using FMul and FMad. +// Verify that mul and dot of double vectors do not produce invalid DXIL Dot +// intrinsics (Dot2/3/4 only support half and float). Instead, the dot product +// should be expanded using FMul and FMad. +// %dxc runs validation, so the test implicitly verifies DXIL validity. // CHECK-NOT: call double @dx.op.dot2.f64 // CHECK-NOT: call double @dx.op.dot3.f64 @@ -25,5 +29,5 @@ RWStructuredBuffer Out; [numthreads(1, 1, 1)] void main() { - Out[0] = mul(In[0], In[1]); + Out[0] = FUNC(In[0], In[1]); }