[clang] [llvm] [HLSL][DirectX] Correct codegen of `dx.load.input`/`dx.store.output` intrinsic calls (PR #212656)
Finn Plummer via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 13:00:09 PDT 2026
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/212656
>From 633294bcfebc861240abbe66dc4987bebeb830ca Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Fri, 24 Jul 2026 23:34:32 +0000
Subject: [PATCH 01/14] remove operands
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 11 ++++------
.../CodeGenHLSL/semantics/SV_Position.ps.hlsl | 4 ++--
.../CodeGenHLSL/semantics/SV_Position.vs.hlsl | 4 ++--
.../CodeGenHLSL/semantics/SV_Target.ps.hlsl | 2 +-
.../CodeGenHLSL/semantics/SV_VertexID.vs.hlsl | 2 +-
.../semantics/semantic.arbitrary.hlsl | 6 +++---
.../CodeGenHLSL/semantics/semantic.array.hlsl | 9 ++++++---
.../semantics/semantic.array.output.hlsl | 9 ++++++---
...antic.explicit-location-output-struct.hlsl | 2 +-
.../semantics/semantic.explicit-location.hlsl | 2 +-
.../semantics/semantic.struct.output.hlsl | 4 ++--
clang/test/CodeGenHLSL/sret_output.hlsl | 2 +-
llvm/include/llvm/IR/IntrinsicsDirectX.td | 20 +++++++++++--------
13 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index f86cb00c204f8..bdb99fad984a9 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1194,10 +1194,9 @@ CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
Twine VariableName = BaseName.concat(Twine(Index.value_or(0)));
// DXIL packing rules etc shall be handled here.
- // FIXME: generate proper sigpoint, index, col, row values.
+ // FIXME: generate proper index, col, row values.
// FIXME: also DXIL loads vectors element by element.
- SmallVector<Value *> Args{B.getInt32(4), B.getInt32(0), B.getInt32(0),
- B.getInt8(0),
+ SmallVector<Value *> Args{B.getInt32(0), B.getInt32(0), B.getInt8(0),
llvm::PoisonValue::get(B.getInt32Ty())};
llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_load_input;
@@ -1219,12 +1218,10 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {
// DXIL packing rules etc shall be handled here.
- // FIXME: generate proper sigpoint, index, col, row values.
- SmallVector<Value *> Args{B.getInt32(4),
- B.getInt32(0),
+ // FIXME: generate proper sigid, index, col, row values.
+ SmallVector<Value *> Args{B.getInt32(0),
B.getInt32(0),
B.getInt8(0),
- llvm::PoisonValue::get(B.getInt32Ty()),
Source};
llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_store_output;
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
index b118ee395f7de..ac695b1f7d5eb 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
@@ -9,9 +9,9 @@ float4 main(float4 p : SV_Position) : A {
// CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]])
// CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @A0, align 4
- // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
// CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
index caab744c1fa98..350b5e3612e32 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
@@ -10,9 +10,9 @@ float4 main(float4 p : SV_Position) : SV_Position {
// CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]])
// CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Position, align 4
- // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
// CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl
index 1ab4df4f61bd7..73255e3a9b939 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl
@@ -9,7 +9,7 @@ float4 main(float4 p : SV_Position) : SV_Target {
// CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 4
// CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl b/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl
index e2c184ac7948c..491f10b530c38 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl
@@ -8,7 +8,7 @@ uint main(uint id : SV_VertexID) : A {
// CHECK-SPIRV: %[[#P:]] = load i32, ptr addrspace(7) @SV_VertexID, align 4
// CHECK-SPIRV: %[[#]] = call spir_func i32 @_Z4mainj(i32 %[[#P]])
- // CHECK-DXIL: %SV_VertexID0 = call i32 @llvm.dx.load.input.i32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %SV_VertexID0 = call i32 @llvm.dx.load.input.i32(i32 0, i32 0, i8 0, i32 poison)
// CHECK-DXIL: %[[#]] = call i32 @_Z4mainj(i32 %SV_VertexID0)
return id;
}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
index 1ea2827660307..720dafcd4f1b6 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
@@ -14,9 +14,9 @@ void main(float a : AAA, int b : B, float2 c : CC) {
// CHECK: define void @main()
-// CHECK-DXIL: %AAA0 = call float @llvm.dx.load.input.f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %B0 = call i32 @llvm.dx.load.input.i32(i32 4, i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL %CC0 = call <2 x float> @llvm.dx.load.input.v2f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %AAA0 = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %B0 = call i32 @llvm.dx.load.input.i32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK-DXIL %CC0 = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 0, i32 poison)
// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %AAA0, i32 %B0, <2 x float> %CC0)
// CHECK-SPIRV: %[[#AAA0:]] = load float, ptr addrspace(7) @AAA0, align 4
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
index c62c4d4a517f2..b50d2da9a0114 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
@@ -12,9 +12,12 @@ struct S0 {
// CHECK-SPIRV: @A2 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]]
// CHECK: define void @main0()
-// CHECK-DXIL: %A0 = call [2 x <4 x float>] @llvm.dx.load.input.a2v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0
-// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#POS0:]] = insertvalue [2 x <4 x float>] poison, <4 x float> %A0, 0
+// CHECK-DXIL: %A1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 1, i8 0, i32 poison)
+// CHECK-DXIL: %[[#POS1:]] = insertvalue [2 x <4 x float>] %[[#POS0]], <4 x float> %A1, 1
+// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#POS1]], 0
+// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1
// CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 4
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
index 18942699aaa2c..9d3afc5e8fba6 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
@@ -12,17 +12,20 @@ struct S0 {
S0 main1(float4 input : A) : B {
// CHECK: %[[#ARG:]] = alloca %struct.S0
// CHECK-SPIRV: %[[#INPUT:]] = load <4 x float>, ptr addrspace(7) @A0, align 4
-// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
// CHECK-DXIL: call void @{{.*}}main1{{.*}}(ptr %[[#ARG]], <4 x float> %A0)
// CHECK-SPIRV: call spir_func void @{{.*}}main1{{.*}}(ptr %[[#ARG]], <4 x float> %[[#INPUT]])
// CHECK: %[[#ST:]] = load %struct.S0, ptr %[[#ARG]]
// CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 0
// CHECK-SPIRV: store [2 x <4 x float>] %[[#TMP]], ptr addrspace(8) @B0, align 4
- // CHECK-DXIL: call void @llvm.dx.store.output.a2v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, [2 x <4 x float>] %[[#TMP]])
+ // CHECK-DXIL: %[[#POS0:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 0
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#POS0]])
+ // CHECK-DXIL: %[[#POS1:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 1
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 1, i8 0, <4 x float> %[[#POS1]])
// CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 1
// CHECK-SPIRV: store <4 x float> %[[#TMP]], ptr addrspace(8) @B2, align 4
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[#TMP]])
S0 output;
output.position[0] = input;
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl
index 8bd8998cdceb5..b24cee7baf8ae 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl
@@ -21,7 +21,7 @@ Output main(float4 p : SV_Position) {
// CHECK: %[[#FIELD:]] = extractvalue %struct.Output %[[#TMP]], 0
// CHECK-SPIRV: store <4 x float> %[[#FIELD]], ptr addrspace(8) @SV_Target0, align 4
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#FIELD]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#FIELD]])
Output o;
o.field = p;
return o;
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl
index 625d5dcb02ec4..2ca0f3fe65a57 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl
@@ -9,7 +9,7 @@
// CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 4
// CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 4, i32 0, i32 0, i8 0, i32 poison, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl
index 0f2444d21724a..426738adfe7ef 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl
@@ -43,10 +43,10 @@ Output main(Input input) {
// CHECK: %[[#TMP:]] = load %struct.Output, ptr %[[#OUTPUT]], align 4
// CHECK: %[[#VAL:]] = extractvalue %struct.Output %[[#TMP]], 0
// CHECK-SPIRV: store float %[[#VAL]], ptr addrspace(8) @A4, align 4
-// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 4, i32 0, i32 0, i8 0, i32 poison, float %[[#VAL]])
+// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[#VAL]])
// CHECK: %[[#VAL:]] = extractvalue %struct.Output %[[#TMP]], 1
// CHECK-SPIRV: store float %[[#VAL]], ptr addrspace(8) @A2, align 4
-// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 4, i32 0, i32 0, i8 0, i32 poison, float %[[#VAL]])
+// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 1, i32 0, i8 0, float %[[#VAL]])
// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]}
// CHECK-SPIRV-DAG: ![[#METADATA_2]] = !{![[#METADATA_3:]]}
diff --git a/clang/test/CodeGenHLSL/sret_output.hlsl b/clang/test/CodeGenHLSL/sret_output.hlsl
index e1aa0973fe5db..325c31541f473 100644
--- a/clang/test/CodeGenHLSL/sret_output.hlsl
+++ b/clang/test/CodeGenHLSL/sret_output.hlsl
@@ -25,7 +25,7 @@ S vs_main() {
// CHECK-VK: call spir_func void @_Z7vs_mainv(ptr %[[#alloca]])
// CHECK: %[[#a:]] = load %struct.S, ptr %[[#alloca]], align 4
// CHECK: %[[#b:]] = extractvalue %struct.S %[[#a]], 0
-// CHECK-DX: call void @llvm.dx.store.output.f32(i32 4, i32 0, i32 0, i8 0, i32 poison, float %[[#b]])
+// CHECK-DX: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[#b]])
// CHECK-VK: store float %3, ptr addrspace(8) @A4, align 4
// CHECK: ret void
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 72835175fded8..fd1b522c5e012 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -324,14 +324,18 @@ def int_dx_group_memory_barrier_with_group_sync
: DefaultAttrsIntrinsic<[], [], [IntrConvergent]>;
def int_dx_load_input
- : DefaultAttrsIntrinsic<[llvm_any_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty],
- [IntrConvergent]>;
+ : DefaultAttrsIntrinsic<
+ [llvm_any_ty],
+ [llvm_i32_ty /*SigElementId*/,
+ llvm_i32_ty /*RowIndex*/, llvm_i8_ty /*ColIndex*/,
+ llvm_i32_ty /*GsVertexOrPrimIndex*/],
+ [IntrConvergent]>;
def int_dx_store_output
- : DefaultAttrsIntrinsic<[],
- [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty, llvm_any_ty],
- [IntrConvergent]>;
+ : DefaultAttrsIntrinsic<
+ [],
+ [llvm_i32_ty /*SigElementId*/,
+ llvm_i32_ty /*RowIndex*/, llvm_i8_ty /*ColIndex*/,
+ llvm_any_ty /*Value*/],
+ [IntrConvergent]>;
}
>From 6654b0b320b14fd692ceaea725923fbe90adcc19 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 28 Jul 2026 20:41:35 +0000
Subject: [PATCH 02/14] assign semantic ids in parse order
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 13 ++++++-------
clang/lib/CodeGen/CGHLSLRuntime.h | 5 +++++
.../test/CodeGenHLSL/semantics/semantic.array.hlsl | 9 +++------
.../semantics/semantic.array.output.hlsl | 5 +----
4 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index bdb99fad984a9..08a13a7e22068 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1194,9 +1194,10 @@ CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
Twine VariableName = BaseName.concat(Twine(Index.value_or(0)));
// DXIL packing rules etc shall be handled here.
- // FIXME: generate proper index, col, row values.
- // FIXME: also DXIL loads vectors element by element.
- SmallVector<Value *> Args{B.getInt32(0), B.getInt32(0), B.getInt8(0),
+ // FIXME: generate proper col, row values, also DXIL loads vectors element by
+ // element.
+ SmallVector<Value *> Args{B.getInt32(DXILInputSemanticIndex++), B.getInt32(0),
+ B.getInt8(0),
llvm::PoisonValue::get(B.getInt32Ty())};
llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_load_input;
@@ -1219,10 +1220,8 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
std::optional<unsigned> Index) {
// DXIL packing rules etc shall be handled here.
// FIXME: generate proper sigid, index, col, row values.
- SmallVector<Value *> Args{B.getInt32(0),
- B.getInt32(0),
- B.getInt8(0),
- Source};
+ SmallVector<Value *> Args{B.getInt32(DXILOutputSemanticIndex++),
+ B.getInt32(0), B.getInt8(0), Source};
llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_store_output;
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index 23b47980f2ef0..aeb33a09c86aa 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -369,6 +369,11 @@ class CGHLSLRuntime {
llvm::DenseMap<const clang::RecordType *, llvm::StructType *> LayoutTypes;
unsigned SPIRVLastAssignedInputSemanticLocation = 0;
unsigned SPIRVLastAssignedOutputSemanticLocation = 0;
+ // DXIL assigns each leaf semantic an index in parse order. Inputs and outputs
+ // are counted independently. Reset in emitEntryFunction before lowering the
+ // semantics of an entry point.
+ unsigned DXILInputSemanticIndex = 0;
+ unsigned DXILOutputSemanticIndex = 0;
};
} // namespace CodeGen
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
index b50d2da9a0114..d395baaa6b335 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
@@ -12,13 +12,10 @@ struct S0 {
// CHECK-SPIRV: @A2 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]]
// CHECK: define void @main0()
-// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#POS0:]] = insertvalue [2 x <4 x float>] poison, <4 x float> %A0, 0
-// CHECK-DXIL: %A1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 1, i8 0, i32 poison)
-// CHECK-DXIL: %[[#POS1:]] = insertvalue [2 x <4 x float>] %[[#POS0]], <4 x float> %A1, 1
-// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#POS1]], 0
+// CHECK-DXIL: %A0 = call [2 x <4 x float>] @llvm.dx.load.input.a2v4f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0
// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1
+// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1
// CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 4
// CHECK-SPIRV: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#A0]], 0
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
index 9d3afc5e8fba6..32b7019b0c630 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
@@ -19,10 +19,7 @@ S0 main1(float4 input : A) : B {
// CHECK: %[[#ST:]] = load %struct.S0, ptr %[[#ARG]]
// CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 0
// CHECK-SPIRV: store [2 x <4 x float>] %[[#TMP]], ptr addrspace(8) @B0, align 4
- // CHECK-DXIL: %[[#POS0:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 0
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#POS0]])
- // CHECK-DXIL: %[[#POS1:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 1
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 1, i8 0, <4 x float> %[[#POS1]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.a2v4f32(i32 0, i32 0, i8 0, [2 x <4 x float>] %[[#TMP]])
// CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 1
// CHECK-SPIRV: store <4 x float> %[[#TMP]], ptr addrspace(8) @B2, align 4
// CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[#TMP]])
>From a26420354afc5cf945e6dfdf0e5cf02afa913320 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 28 Jul 2026 20:53:15 +0000
Subject: [PATCH 03/14] add test cases
---
.../CodeGenHLSL/semantics/semantic.input.hlsl | 55 ++++++++++++++++++
.../semantics/semantic.output.hlsl | 58 +++++++++++++++++++
2 files changed, 113 insertions(+)
create mode 100644 clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
create mode 100644 clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
new file mode 100644
index 0000000000000..e1ea53bf16de9
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
@@ -0,0 +1,55 @@
+// Per-row load.input emission for the range of semantic leaf types:
+// float - scalar -> 1 row
+// float4 - vector -> 1 row (4 columns)
+// float[5] - scalar array -> 5 rows
+// float4[2][3] - vector array -> 6 rows (multidimensional, 4 columns each)
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
+
+struct S {
+ float a : A;
+ float4 b : B;
+ float d[5] : D;
+ float4 e[2][3] : E;
+};
+
+[shader("vertex")]
+void main(S s) {}
+
+// float a : A -> 1 row, 1 column.
+// CHECK: %A0 = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK: %[[#S:]] = insertvalue %struct.S poison, float %A0, 0
+
+// float4 b : B -> 1 row, 4 columns.
+// CHECK: %B0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], <4 x float> %B0, 1
+
+// float d[5] : D -> 5 rows, 1 column each.
+// CHECK: %D0 = call float @llvm.dx.load.input.f32(i32 2, i32 0, i8 0, i32 poison)
+// CHECK: %[[#D:]] = insertvalue [5 x float] poison, float %D0, 0
+// CHECK: %D1 = call float @llvm.dx.load.input.f32(i32 2, i32 1, i8 0, i32 poison)
+// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D1, 1
+// CHECK: %D2 = call float @llvm.dx.load.input.f32(i32 2, i32 2, i8 0, i32 poison)
+// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D2, 2
+// CHECK: %D3 = call float @llvm.dx.load.input.f32(i32 2, i32 3, i8 0, i32 poison)
+// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D3, 3
+// CHECK: %D4 = call float @llvm.dx.load.input.f32(i32 2, i32 4, i8 0, i32 poison)
+// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D4, 4
+// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], [5 x float] %[[#D]], 2
+
+// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
+// CHECK: %E0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 0, i8 0, i32 poison)
+// CHECK: %[[#E0:]] = insertvalue [3 x <4 x float>] poison, <4 x float> %E0, 0
+// CHECK: %E1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 1, i8 0, i32 poison)
+// CHECK: %[[#E0:]] = insertvalue [3 x <4 x float>] %[[#E0]], <4 x float> %E1, 1
+// CHECK: %E2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 2, i8 0, i32 poison)
+// CHECK: %[[#E0:]] = insertvalue [3 x <4 x float>] %[[#E0]], <4 x float> %E2, 2
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] poison, [3 x <4 x float>] %[[#E0]], 0
+// CHECK: %E3 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 3, i8 0, i32 poison)
+// CHECK: %[[#E1:]] = insertvalue [3 x <4 x float>] poison, <4 x float> %E3, 0
+// CHECK: %E4 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 4, i8 0, i32 poison)
+// CHECK: %[[#E1:]] = insertvalue [3 x <4 x float>] %[[#E1]], <4 x float> %E4, 1
+// CHECK: %E5 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 5, i8 0, i32 poison)
+// CHECK: %[[#E1:]] = insertvalue [3 x <4 x float>] %[[#E1]], <4 x float> %E5, 2
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], [3 x <4 x float>] %[[#E1]], 1
+// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], [2 x [3 x <4 x float>]] %[[#E]], 3
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
new file mode 100644
index 0000000000000..2b1d36b140838
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
@@ -0,0 +1,58 @@
+// Per-row store.output emission for the range of semantic leaf types:
+// float - scalar -> 1 row
+// float4 - vector -> 1 row (4 columns)
+// float[5] - scalar array -> 5 rows
+// float4[2][3] - vector array -> 6 rows (multidimensional, 4 columns each)
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
+
+struct S {
+ float a : A;
+ float4 b : B;
+ float d[5] : D;
+ float4 e[2][3] : E;
+};
+
+[shader("vertex")]
+S main() {
+ S s;
+ return s;
+}
+
+// float a : A -> 1 row, 1 column.
+// CHECK: %[[#A:]] = extractvalue %struct.S %[[#S:]], 0
+// CHECK: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[#A]])
+
+// float4 b : B -> 1 row, 4 columns; the whole vector is stored.
+// CHECK: %[[#B:]] = extractvalue %struct.S %[[#S]], 1
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[#B]])
+
+// float d[5] : D -> 5 rows, 1 column each.
+// CHECK: %[[#D:]] = extractvalue %struct.S %[[#S]], 2
+// CHECK: %[[#D0:]] = extractvalue [5 x float] %[[#D]], 0
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 0, i8 0, float %[[#D0]])
+// CHECK: %[[#D1:]] = extractvalue [5 x float] %[[#D]], 1
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 1, i8 0, float %[[#D1]])
+// CHECK: %[[#D2:]] = extractvalue [5 x float] %[[#D]], 2
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 2, i8 0, float %[[#D2]])
+// CHECK: %[[#D3:]] = extractvalue [5 x float] %[[#D]], 3
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 3, i8 0, float %[[#D3]])
+// CHECK: %[[#D4:]] = extractvalue [5 x float] %[[#D]], 4
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 4, i8 0, float %[[#D4]])
+
+// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
+// CHECK: %[[#E:]] = extractvalue %struct.S %[[#S]], 3
+// CHECK: %[[#E0:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0
+// CHECK: %[[#E00:]] = extractvalue [3 x <4 x float>] %[[#E0]], 0
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 0, i8 0, <4 x float> %[[#E00]])
+// CHECK: %[[#E01:]] = extractvalue [3 x <4 x float>] %[[#E0]], 1
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 1, i8 0, <4 x float> %[[#E01]])
+// CHECK: %[[#E02:]] = extractvalue [3 x <4 x float>] %[[#E0]], 2
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 2, i8 0, <4 x float> %[[#E02]])
+// CHECK: %[[#E1:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1
+// CHECK: %[[#E10:]] = extractvalue [3 x <4 x float>] %[[#E1]], 0
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 3, i8 0, <4 x float> %[[#E10]])
+// CHECK: %[[#E11:]] = extractvalue [3 x <4 x float>] %[[#E1]], 1
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 4, i8 0, <4 x float> %[[#E11]])
+// CHECK: %[[#E12:]] = extractvalue [3 x <4 x float>] %[[#E1]], 2
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 5, i8 0, <4 x float> %[[#E12]])
>From be246a4dd457f2720c78c42efe1630494ce2bb4b Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 28 Jul 2026 23:16:48 +0000
Subject: [PATCH 04/14] correct intrin calls
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 175 +++++++++++++++---
clang/lib/CodeGen/CGHLSLRuntime.h | 3 +
.../CodeGenHLSL/semantics/semantic.array.hlsl | 11 +-
.../semantics/semantic.array.output.hlsl | 5 +-
4 files changed, 163 insertions(+), 31 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 08a13a7e22068..cb2be9bbdd0b5 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1186,21 +1186,59 @@ void CGHLSLRuntime::emitSPIRVUserSemanticStore(
VariableName.str());
}
+namespace {
+// Describes how a semantic leaf lowers to signature rows
+struct SemanticShape {
+ unsigned Rows;
+ unsigned Cols;
+ QualType RowType;
+};
+} // namespace
+
+// Returns the QualType of a semantic leaf declarator. For a function the
+// declared return type is used, otherwise the declared type.
+static QualType getSemanticLeafType(const clang::DeclaratorDecl *Decl) {
+ if (const auto *FD = dyn_cast<clang::FunctionDecl>(Decl))
+ return FD->getDeclaredReturnType();
+ return Decl->getType();
+}
+
+// Walks through the surrounding constant array types of \p Ty, accumulating the
+// number of rows, until reaching a scalar, vector, or matrix leaf. The leaf is
+// returned as the row type together with the number of rows.
+static SemanticShape getSemanticShape(ASTContext &Ctx, QualType Ty) {
+ unsigned Rows = 1;
+ while (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(Ty)) {
+ Rows *= CAT->getSize().getZExtValue();
+ Ty = CAT->getElementType();
+ }
+
+ unsigned Cols = 1;
+ if (const auto *VT = Ty->getAs<clang::VectorType>()) {
+ Cols = VT->getNumElements();
+ } else if (const auto *MT = Ty->getAs<clang::ConstantMatrixType>()) {
+ // FIXME: a matrix leaf lowers to one row per matrix row but if column_major
+ // is specified we transpose the num rows and num cols, this depends on
+ // #211977 to resolve
+ Cols = MT->getNumColumns();
+ }
+
+ return {Rows, Cols, Ty};
+}
+
llvm::Value *
CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {
- Twine BaseName = Twine(Semantic->getAttrName()->getName());
- Twine VariableName = BaseName.concat(Twine(Index.value_or(0)));
+ StringRef Name = Semantic->getAttrName()->getName();
+ SemanticShape Shape =
+ getSemanticShape(CGM.getContext(), getSemanticLeafType(Decl));
- // DXIL packing rules etc shall be handled here.
- // FIXME: generate proper col, row values, also DXIL loads vectors element by
- // element.
- SmallVector<Value *> Args{B.getInt32(DXILInputSemanticIndex++), B.getInt32(0),
- B.getInt8(0),
- llvm::PoisonValue::get(B.getInt32Ty())};
+ llvm::Type *RowTy = CGM.getTypes().ConvertTypeForMem(Shape.RowType);
- llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_load_input;
+ llvm::Function *IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
+ B.GetInsertBlock()->getModule(), llvm::Intrinsic::dx_load_input, {RowTy});
SmallVector<OperandBundleDef, 1> OB;
if (auto *Token = getConvergenceToken(*B.GetInsertBlock())) {
@@ -1208,22 +1246,82 @@ CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
OB.emplace_back("convergencectrl", bundleArgs);
}
- llvm::Function *IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
- B.GetInsertBlock()->getModule(), IntrinsicID, {Type});
- llvm::Value *Value = B.CreateCall(IntrFn, Args, OB, VariableName);
- return Value;
+ unsigned SigId = DXILInputSemanticIndex++;
+ unsigned Row = 0;
+
+ // Scalar and vector leaves need no aggregate reconstruction.
+ if (!isa<llvm::ArrayType>(Type)) {
+ SmallVector<Value *> Args{
+ /*SigElementId=*/B.getInt32(SigId),
+ /*RowIndex=*/B.getInt32(Row),
+ /*ColIndex=*/B.getInt8(0),
+ /*GsVertexOrPrimIndex=*/llvm::PoisonValue::get(B.getInt32Ty())};
+ llvm::Value *Result =
+ B.CreateCall(IntrFn, Args, OB, Twine(Name).concat(Twine(Row++)));
+ assert(Row == Shape.Rows && "unexpected number of semantic rows");
+ return Result;
+ }
+
+ struct LoadItem {
+ llvm::ArrayType *Type;
+ llvm::Value *Aggregate;
+ unsigned NextIndex;
+ };
+
+ SmallVector<LoadItem> Worklist;
+ auto *RootTy = cast<llvm::ArrayType>(Type);
+ Worklist.push_back({RootTy, llvm::PoisonValue::get(RootTy), 0});
+
+ llvm::Value *Result = nullptr;
+ while (!Worklist.empty()) {
+ LoadItem &Frame = Worklist.back();
+
+ if (Frame.NextIndex == Frame.Type->getNumElements()) {
+ llvm::Value *Aggregate = Frame.Aggregate;
+ Worklist.pop_back();
+ if (Worklist.empty()) {
+ Result = Aggregate;
+ break;
+ }
+
+ LoadItem &Parent = Worklist.back();
+ Parent.Aggregate =
+ B.CreateInsertValue(Parent.Aggregate, Aggregate, Parent.NextIndex++);
+ continue;
+ }
+
+ llvm::Type *ElementTy = Frame.Type->getElementType();
+ if (auto *AT = dyn_cast<llvm::ArrayType>(ElementTy)) {
+ Worklist.push_back({AT, llvm::PoisonValue::get(AT), 0});
+ continue;
+ }
+
+ SmallVector<Value *> Args{
+ /*SigElementId=*/B.getInt32(SigId),
+ /*RowIndex=*/B.getInt32(Row),
+ /*ColIndex=*/B.getInt8(0),
+ /*GsVertexOrPrimIndex=*/llvm::PoisonValue::get(B.getInt32Ty())};
+ llvm::Value *Elt =
+ B.CreateCall(IntrFn, Args, OB, Twine(Name).concat(Twine(Row++)));
+ Frame.Aggregate =
+ B.CreateInsertValue(Frame.Aggregate, Elt, Frame.NextIndex++);
+ }
+ assert(Row == Shape.Rows && "unexpected number of semantic rows");
+ return Result;
}
void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
llvm::Value *Source,
+ const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {
- // DXIL packing rules etc shall be handled here.
- // FIXME: generate proper sigid, index, col, row values.
- SmallVector<Value *> Args{B.getInt32(DXILOutputSemanticIndex++),
- B.getInt32(0), B.getInt8(0), Source};
+ SemanticShape Shape =
+ getSemanticShape(CGM.getContext(), getSemanticLeafType(Decl));
+ llvm::Type *RowTy = CGM.getTypes().ConvertTypeForMem(Shape.RowType);
- llvm::Intrinsic::ID IntrinsicID = llvm::Intrinsic::dx_store_output;
+ llvm::Function *IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
+ B.GetInsertBlock()->getModule(), llvm::Intrinsic::dx_store_output,
+ {RowTy});
SmallVector<OperandBundleDef, 1> OB;
if (auto *Token = getConvergenceToken(*B.GetInsertBlock())) {
@@ -1231,9 +1329,34 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
OB.emplace_back("convergencectrl", bundleArgs);
}
- llvm::Function *IntrFn = llvm::Intrinsic::getOrInsertDeclaration(
- B.GetInsertBlock()->getModule(), IntrinsicID, {Source->getType()});
- B.CreateCall(IntrFn, Args, OB);
+ unsigned SigId = DXILOutputSemanticIndex++;
+ unsigned Row = 0;
+
+ struct StoreItem {
+ llvm::Value *Aggregate;
+ std::optional<unsigned> Index;
+ };
+
+ SmallVector<StoreItem> Worklist{{Source, std::nullopt}};
+ while (!Worklist.empty()) {
+ StoreItem Item = Worklist.pop_back_val();
+ llvm::Value *Val = Item.Index
+ ? B.CreateExtractValue(Item.Aggregate, *Item.Index)
+ : Item.Aggregate;
+
+ if (auto *AT = dyn_cast<llvm::ArrayType>(Val->getType())) {
+ // Push elements in reverse so index 0 is visited first
+ for (unsigned I = AT->getNumElements(); I-- > 0;)
+ Worklist.push_back({Val, I});
+ continue;
+ }
+
+ SmallVector<Value *> Args{/*SigElementId=*/B.getInt32(SigId),
+ /*RowIndex=*/B.getInt32(Row++),
+ /*ColIndex=*/B.getInt8(0), /*Value=*/Val};
+ B.CreateCall(IntrFn, Args, OB);
+ }
+ assert(Row == Shape.Rows && "unexpected number of semantic rows");
}
llvm::Value *CGHLSLRuntime::emitUserSemanticLoad(
@@ -1244,7 +1367,7 @@ llvm::Value *CGHLSLRuntime::emitUserSemanticLoad(
return emitSPIRVUserSemanticLoad(B, FD, Type, Decl, Semantic, Index);
if (CGM.getTarget().getTriple().isDXIL())
- return emitDXILUserSemanticLoad(B, Type, Semantic, Index);
+ return emitDXILUserSemanticLoad(B, Type, Decl, Semantic, Index);
llvm_unreachable("Unsupported target for user-semantic load.");
}
@@ -1257,7 +1380,7 @@ void CGHLSLRuntime::emitUserSemanticStore(IRBuilder<> &B, llvm::Value *Source,
return emitSPIRVUserSemanticStore(B, Source, Decl, Semantic, Index);
if (CGM.getTarget().getTriple().isDXIL())
- return emitDXILUserSemanticStore(B, Source, Semantic, Index);
+ return emitDXILUserSemanticStore(B, Source, Decl, Semantic, Index);
llvm_unreachable("Unsupported target for user-semantic load.");
}
@@ -1312,7 +1435,7 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
Semantic->getAttrName()->getName(),
/* BuiltIn::FragCoord */ 15);
if (CGM.getTarget().getTriple().isDXIL())
- return emitDXILUserSemanticLoad(B, Type, Semantic, Index);
+ return emitDXILUserSemanticLoad(B, Type, Decl, Semantic, Index);
}
if (ST == Triple::EnvironmentType::Vertex) {
@@ -1327,7 +1450,7 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
Semantic->getAttrName()->getName(),
/* BuiltIn::VertexIndex */ 42);
else
- return emitDXILUserSemanticLoad(B, Type, Semantic, Index);
+ return emitDXILUserSemanticLoad(B, Type, Decl, Semantic, Index);
}
}
@@ -1357,7 +1480,7 @@ void CGHLSLRuntime::emitSystemSemanticStore(IRBuilder<> &B, llvm::Value *Source,
std::string SemanticName = Semantic->getAttrName()->getName().upper();
if (SemanticName == "SV_POSITION") {
if (CGM.getTarget().getTriple().isDXIL()) {
- emitDXILUserSemanticStore(B, Source, Semantic, Index);
+ emitDXILUserSemanticStore(B, Source, Decl, Semantic, Index);
return;
}
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index aeb33a09c86aa..badb6fb867b55 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -340,6 +340,7 @@ class CGHLSLRuntime {
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
llvm::Value *emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
+ const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
llvm::Value *emitUserSemanticLoad(llvm::IRBuilder<> &B,
@@ -353,6 +354,7 @@ class CGHLSLRuntime {
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
void emitDXILUserSemanticStore(llvm::IRBuilder<> &B, llvm::Value *Source,
+ const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
void emitUserSemanticStore(llvm::IRBuilder<> &B, llvm::Value *Source,
@@ -369,6 +371,7 @@ class CGHLSLRuntime {
llvm::DenseMap<const clang::RecordType *, llvm::StructType *> LayoutTypes;
unsigned SPIRVLastAssignedInputSemanticLocation = 0;
unsigned SPIRVLastAssignedOutputSemanticLocation = 0;
+
// DXIL assigns each leaf semantic an index in parse order. Inputs and outputs
// are counted independently. Reset in emitEntryFunction before lowering the
// semantics of an entry point.
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
index d395baaa6b335..5466948bd32bc 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
@@ -12,10 +12,13 @@ struct S0 {
// CHECK-SPIRV: @A2 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]]
// CHECK: define void @main0()
-// CHECK-DXIL: %A0 = call [2 x <4 x float>] @llvm.dx.load.input.a2v4f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %A0, 0
-// CHECK-DXIL: %A2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A2, 1
+// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#POS0:]] = insertvalue [2 x <4 x float>] poison, <4 x float> %A0, 0
+// CHECK-DXIL: %A1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 1, i8 0, i32 poison)
+// CHECK-DXIL: %[[#POS1:]] = insertvalue [2 x <4 x float>] %[[#POS0]], <4 x float> %A1, 1
+// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#POS1]], 0
+// CHECK-DXIL: %A01 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A01, 1
// CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 4
// CHECK-SPIRV: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#A0]], 0
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
index 32b7019b0c630..9d3afc5e8fba6 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
@@ -19,7 +19,10 @@ S0 main1(float4 input : A) : B {
// CHECK: %[[#ST:]] = load %struct.S0, ptr %[[#ARG]]
// CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 0
// CHECK-SPIRV: store [2 x <4 x float>] %[[#TMP]], ptr addrspace(8) @B0, align 4
- // CHECK-DXIL: call void @llvm.dx.store.output.a2v4f32(i32 0, i32 0, i8 0, [2 x <4 x float>] %[[#TMP]])
+ // CHECK-DXIL: %[[#POS0:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 0
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#POS0]])
+ // CHECK-DXIL: %[[#POS1:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 1
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 1, i8 0, <4 x float> %[[#POS1]])
// CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 1
// CHECK-SPIRV: store <4 x float> %[[#TMP]], ptr addrspace(8) @B2, align 4
// CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[#TMP]])
>From 4262438a40b2c112b87035e60217e4651cacabcf Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 29 Jul 2026 15:52:34 +0000
Subject: [PATCH 05/14] clang format
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index cb2be9bbdd0b5..9a378b78144e1 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1226,11 +1226,9 @@ static SemanticShape getSemanticShape(ASTContext &Ctx, QualType Ty) {
return {Rows, Cols, Ty};
}
-llvm::Value *
-CGHLSLRuntime::emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
- const clang::DeclaratorDecl *Decl,
- HLSLAppliedSemanticAttr *Semantic,
- std::optional<unsigned> Index) {
+llvm::Value *CGHLSLRuntime::emitDXILUserSemanticLoad(
+ llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
+ HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) {
StringRef Name = Semantic->getAttrName()->getName();
SemanticShape Shape =
getSemanticShape(CGM.getContext(), getSemanticLeafType(Decl));
>From a78b13c909166d70c964e2c5697c5da7e88bdd2e Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 29 Jul 2026 22:19:34 +0000
Subject: [PATCH 06/14] small note
---
clang/lib/CodeGen/CGHLSLRuntime.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index badb6fb867b55..5ea4afe65100b 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -372,9 +372,8 @@ class CGHLSLRuntime {
unsigned SPIRVLastAssignedInputSemanticLocation = 0;
unsigned SPIRVLastAssignedOutputSemanticLocation = 0;
- // DXIL assigns each leaf semantic an index in parse order. Inputs and outputs
- // are counted independently. Reset in emitEntryFunction before lowering the
- // semantics of an entry point.
+ // FIXME: #57928, storing these here and reseting them in the entry is not
+ // very nice and is a temporary until we accumulate the signatures as part of
unsigned DXILInputSemanticIndex = 0;
unsigned DXILOutputSemanticIndex = 0;
};
>From 29dd572106e7622611e7ab0ab59c8368ee1d1ee8 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 4 Aug 2026 21:23:56 +0000
Subject: [PATCH 07/14] review: fix bool representation
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 16 ++++++++++++++++
.../CodeGenHLSL/semantics/semantic.bool.hlsl | 15 +++++++++++++++
2 files changed, 31 insertions(+)
create mode 100644 clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 9a378b78144e1..34a7d34ed7cee 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1256,6 +1256,14 @@ llvm::Value *CGHLSLRuntime::emitDXILUserSemanticLoad(
/*GsVertexOrPrimIndex=*/llvm::PoisonValue::get(B.getInt32Ty())};
llvm::Value *Result =
B.CreateCall(IntrFn, Args, OB, Twine(Name).concat(Twine(Row++)));
+ // Booleans use their memory representation in DXIL signatures, but direct
+ // function parameters use their value representation.
+ if (Result->getType() != Type) {
+ assert(Shape.RowType->hasBooleanRepresentation() &&
+ "unexpected semantic load type mismatch");
+ Result = B.CreateICmpNE(
+ Result, llvm::Constant::getNullValue(Result->getType()), "loadedv");
+ }
assert(Row == Shape.Rows && "unexpected number of semantic rows");
return Result;
}
@@ -1349,6 +1357,14 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
continue;
}
+ // Booleans use their memory representation in DXIL signatures, but direct
+ // function results use their value representation.
+ if (Val->getType() != RowTy) {
+ assert(Shape.RowType->hasBooleanRepresentation() &&
+ "unexpected semantic store type mismatch");
+ Val = B.CreateZExt(Val, RowTy, "storedv");
+ }
+
SmallVector<Value *> Args{/*SigElementId=*/B.getInt32(SigId),
/*RowIndex=*/B.getInt32(Row++),
/*ColIndex=*/B.getInt8(0), /*Value=*/Val};
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl
new file mode 100644
index 0000000000000..2f9269a553114
--- /dev/null
+++ b/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-vertex -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
+
+[shader("vertex")]
+bool main(bool b : B) : A {
+ return b;
+}
+
+// DXIL signatures represent bool as i32, while the entry implementation uses
+// the i1 value representation.
+// CHECK-LABEL: define void @main()
+// CHECK: %[[INPUT:.*]] = call i32 @llvm.dx.load.input.i32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK: %[[BOOL:.*]] = icmp ne i32 %[[INPUT]], 0
+// CHECK: %[[RESULT:.*]] = call i1 @_Z4mainb(i1 %[[BOOL]])
+// CHECK: %[[OUTPUT:.*]] = zext i1 %[[RESULT]] to i32
+// CHECK: call void @llvm.dx.store.output.i32(i32 0, i32 0, i8 0, i32 %[[OUTPUT]])
>From 9075f78062ffee5ece6c753277d38215913b0f23 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 4 Aug 2026 21:32:34 +0000
Subject: [PATCH 08/14] review: reset the semantic index between counters
had this here to start but must have deleted it by accident before
pushing. These will be replaced in the pr following this anyway
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 3 +++
clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl | 10 ++++++++++
2 files changed, 13 insertions(+)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 34a7d34ed7cee..e131e10a38aea 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1622,6 +1622,9 @@ CGHLSLRuntime::handleSemanticStore(
void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
llvm::Function *Fn) {
+ DXILInputSemanticIndex = 0;
+ DXILOutputSemanticIndex = 0;
+
llvm::Module &M = CGM.getModule();
llvm::LLVMContext &Ctx = M.getContext();
auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false);
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl
index 2f9269a553114..3d46d796b3338 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.bool.hlsl
@@ -13,3 +13,13 @@ bool main(bool b : B) : A {
// CHECK: %[[RESULT:.*]] = call i1 @_Z4mainb(i1 %[[BOOL]])
// CHECK: %[[OUTPUT:.*]] = zext i1 %[[RESULT]] to i32
// CHECK: call void @llvm.dx.store.output.i32(i32 0, i32 0, i8 0, i32 %[[OUTPUT]])
+
+[shader("vertex")]
+bool other(bool b : D) : C {
+ return b;
+}
+
+// Signature element IDs are local to each entry point.
+// CHECK-LABEL: define void @other()
+// CHECK: call i32 @llvm.dx.load.input.i32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK: call void @llvm.dx.store.output.i32(i32 0, i32 0, i8 0, i32 %{{.*}})
>From 0d972c10d2ba8eb530411756ae9871109b068ae8 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 5 Aug 2026 17:45:40 +0000
Subject: [PATCH 09/14] review: fix and clean up typos
---
clang/lib/CodeGen/CGHLSLRuntime.h | 1 +
.../semantics/semantic.arbitrary.hlsl | 18 ++++++++----------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index 5ea4afe65100b..20a8730ab928b 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -374,6 +374,7 @@ class CGHLSLRuntime {
// FIXME: #57928, storing these here and reseting them in the entry is not
// very nice and is a temporary until we accumulate the signatures as part of
+ // the mentioned issue.
unsigned DXILInputSemanticIndex = 0;
unsigned DXILOutputSemanticIndex = 0;
};
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
index 720dafcd4f1b6..f0bf3fff0ab66 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
@@ -5,8 +5,6 @@
// CHECK-SPIRV-DAG: @B0 = external hidden thread_local addrspace(7) externally_initialized constant i32, !spirv.Decorations ![[#METADATA_2:]]
// CHECK-SPIRV-DAG: @CC0 = external hidden thread_local addrspace(7) externally_initialized constant <2 x float>, !spirv.Decorations ![[#METADATA_4:]]
-
-// FIXME: replace `float2 c` with a matrix when available.
void main(float a : AAA, int b : B, float2 c : CC) {
float tmp = a + b + c.x + c.y;
}
@@ -14,15 +12,15 @@ void main(float a : AAA, int b : B, float2 c : CC) {
// CHECK: define void @main()
-// CHECK-DXIL: %AAA0 = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %B0 = call i32 @llvm.dx.load.input.i32(i32 1, i32 0, i8 0, i32 poison)
-// CHECK-DXIL %CC0 = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %AAA0, i32 %B0, <2 x float> %CC0)
+// CHECK-DXIL: %[[#AAA:]] = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#B:]] = call i32 @llvm.dx.load.input.i32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[#CC:]] = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]])
-// CHECK-SPIRV: %[[#AAA0:]] = load float, ptr addrspace(7) @AAA0, align 4
-// CHECK-SPIRV: %[[#B0:]] = load i32, ptr addrspace(7) @B0, align 4
-// CHECK-SPIRV: %[[#CC0:]] = load <2 x float>, ptr addrspace(7) @CC0, align 4
-// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]]) [ "convergencectrl"(token %0) ]
+// CHECK-SPIRV: %[[#AAA:]] = load float, ptr addrspace(7) @AAA0, align 4
+// CHECK-SPIRV: %[[#B:]] = load i32, ptr addrspace(7) @B0, align 4
+// CHECK-SPIRV: %[[#CC:]] = load <2 x float>, ptr addrspace(7) @CC0, align 4
+// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]]) [ "convergencectrl"(token %0) ]
// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]}
>From 6307373f9dddc3e5a156fa359af8b8af1dc43c0f Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 5 Aug 2026 18:05:16 +0000
Subject: [PATCH 10/14] self-review: change from a worklist to row iteration
don't know why I didn't realize this the first time but a fresh look
over it made me realize that imo this is cleaner
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 124 ++++++------------
.../CodeGenHLSL/semantics/semantic.input.hlsl | 14 +-
.../semantics/semantic.output.hlsl | 14 +-
3 files changed, 55 insertions(+), 97 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index e131e10a38aea..a17244ac9a83f 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -1189,9 +1189,16 @@ void CGHLSLRuntime::emitSPIRVUserSemanticStore(
namespace {
// Describes how a semantic leaf lowers to signature rows
struct SemanticShape {
- unsigned Rows;
+ SmallVector<unsigned> Dimensions; // Empty dims denotes a scalar
unsigned Cols;
QualType RowType;
+
+ unsigned getNumRows() const {
+ unsigned Rows = 1;
+ for (unsigned Dimension : Dimensions)
+ Rows *= Dimension;
+ return Rows;
+ }
};
} // namespace
@@ -1203,13 +1210,12 @@ static QualType getSemanticLeafType(const clang::DeclaratorDecl *Decl) {
return Decl->getType();
}
-// Walks through the surrounding constant array types of \p Ty, accumulating the
-// number of rows, until reaching a scalar, vector, or matrix leaf. The leaf is
-// returned as the row type together with the number of rows.
+// Walks through the surrounding constant array types of \p Ty, collecting their
+// dimensions until reaching a scalar, vector, or matrix leaf.
static SemanticShape getSemanticShape(ASTContext &Ctx, QualType Ty) {
- unsigned Rows = 1;
+ SmallVector<unsigned> Dimensions;
while (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(Ty)) {
- Rows *= CAT->getSize().getZExtValue();
+ Dimensions.push_back(CAT->getSize().getZExtValue());
Ty = CAT->getElementType();
}
@@ -1223,7 +1229,7 @@ static SemanticShape getSemanticShape(ASTContext &Ctx, QualType Ty) {
Cols = MT->getNumColumns();
}
- return {Rows, Cols, Ty};
+ return {std::move(Dimensions), Cols, Ty};
}
llvm::Value *CGHLSLRuntime::emitDXILUserSemanticLoad(
@@ -1245,74 +1251,39 @@ llvm::Value *CGHLSLRuntime::emitDXILUserSemanticLoad(
}
unsigned SigId = DXILInputSemanticIndex++;
- unsigned Row = 0;
- // Scalar and vector leaves need no aggregate reconstruction.
- if (!isa<llvm::ArrayType>(Type)) {
+ llvm::Type *LeafTy = CGM.getTypes().ConvertType(Shape.RowType);
+ llvm::Value *Result = llvm::PoisonValue::get(Type);
+
+ SmallVector<unsigned> Indices(Shape.Dimensions.size());
+
+ for (unsigned Row = 0; Row < Shape.getNumRows(); ++Row) {
SmallVector<Value *> Args{
/*SigElementId=*/B.getInt32(SigId),
/*RowIndex=*/B.getInt32(Row),
/*ColIndex=*/B.getInt8(0),
/*GsVertexOrPrimIndex=*/llvm::PoisonValue::get(B.getInt32Ty())};
- llvm::Value *Result =
- B.CreateCall(IntrFn, Args, OB, Twine(Name).concat(Twine(Row++)));
- // Booleans use their memory representation in DXIL signatures, but direct
+ llvm::Value *Value =
+ B.CreateCall(IntrFn, Args, OB, Twine(Name).concat(Twine(Row)));
+ // Booleans use their memory representation in DXIL signatures, but
// function parameters use their value representation.
- if (Result->getType() != Type) {
+ if (Value->getType() != LeafTy) {
assert(Shape.RowType->hasBooleanRepresentation() &&
"unexpected semantic load type mismatch");
- Result = B.CreateICmpNE(
- Result, llvm::Constant::getNullValue(Result->getType()), "loadedv");
+ Value = B.CreateICmpNE(
+ Value, llvm::Constant::getNullValue(Value->getType()), "loadedv");
}
- assert(Row == Shape.Rows && "unexpected number of semantic rows");
- return Result;
- }
- struct LoadItem {
- llvm::ArrayType *Type;
- llvm::Value *Aggregate;
- unsigned NextIndex;
- };
+ Result =
+ Indices.empty() ? Value : B.CreateInsertValue(Result, Value, Indices);
- SmallVector<LoadItem> Worklist;
- auto *RootTy = cast<llvm::ArrayType>(Type);
- Worklist.push_back({RootTy, llvm::PoisonValue::get(RootTy), 0});
-
- llvm::Value *Result = nullptr;
- while (!Worklist.empty()) {
- LoadItem &Frame = Worklist.back();
-
- if (Frame.NextIndex == Frame.Type->getNumElements()) {
- llvm::Value *Aggregate = Frame.Aggregate;
- Worklist.pop_back();
- if (Worklist.empty()) {
- Result = Aggregate;
+ // Advance the multidimensional index
+ for (unsigned I = Indices.size(); I-- > 0;) {
+ if (++Indices[I] < Shape.Dimensions[I])
break;
- }
-
- LoadItem &Parent = Worklist.back();
- Parent.Aggregate =
- B.CreateInsertValue(Parent.Aggregate, Aggregate, Parent.NextIndex++);
- continue;
+ Indices[I] = 0;
}
-
- llvm::Type *ElementTy = Frame.Type->getElementType();
- if (auto *AT = dyn_cast<llvm::ArrayType>(ElementTy)) {
- Worklist.push_back({AT, llvm::PoisonValue::get(AT), 0});
- continue;
- }
-
- SmallVector<Value *> Args{
- /*SigElementId=*/B.getInt32(SigId),
- /*RowIndex=*/B.getInt32(Row),
- /*ColIndex=*/B.getInt8(0),
- /*GsVertexOrPrimIndex=*/llvm::PoisonValue::get(B.getInt32Ty())};
- llvm::Value *Elt =
- B.CreateCall(IntrFn, Args, OB, Twine(Name).concat(Twine(Row++)));
- Frame.Aggregate =
- B.CreateInsertValue(Frame.Aggregate, Elt, Frame.NextIndex++);
}
- assert(Row == Shape.Rows && "unexpected number of semantic rows");
return Result;
}
@@ -1336,26 +1307,11 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
}
unsigned SigId = DXILOutputSemanticIndex++;
- unsigned Row = 0;
- struct StoreItem {
- llvm::Value *Aggregate;
- std::optional<unsigned> Index;
- };
-
- SmallVector<StoreItem> Worklist{{Source, std::nullopt}};
- while (!Worklist.empty()) {
- StoreItem Item = Worklist.pop_back_val();
- llvm::Value *Val = Item.Index
- ? B.CreateExtractValue(Item.Aggregate, *Item.Index)
- : Item.Aggregate;
-
- if (auto *AT = dyn_cast<llvm::ArrayType>(Val->getType())) {
- // Push elements in reverse so index 0 is visited first
- for (unsigned I = AT->getNumElements(); I-- > 0;)
- Worklist.push_back({Val, I});
- continue;
- }
+ SmallVector<unsigned> Indices(Shape.Dimensions.size());
+ for (unsigned Row = 0; Row < Shape.getNumRows(); ++Row) {
+ llvm::Value *Val =
+ Indices.empty() ? Source : B.CreateExtractValue(Source, Indices);
// Booleans use their memory representation in DXIL signatures, but direct
// function results use their value representation.
@@ -1366,11 +1322,17 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
}
SmallVector<Value *> Args{/*SigElementId=*/B.getInt32(SigId),
- /*RowIndex=*/B.getInt32(Row++),
+ /*RowIndex=*/B.getInt32(Row),
/*ColIndex=*/B.getInt8(0), /*Value=*/Val};
B.CreateCall(IntrFn, Args, OB);
+
+ // Advance the multidimensional index
+ for (unsigned I = Indices.size(); I-- > 0;) {
+ if (++Indices[I] < Shape.Dimensions[I])
+ break;
+ Indices[I] = 0;
+ }
}
- assert(Row == Shape.Rows && "unexpected number of semantic rows");
}
llvm::Value *CGHLSLRuntime::emitUserSemanticLoad(
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
index e1ea53bf16de9..bdda150e7d667 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
@@ -39,17 +39,15 @@ void main(S s) {}
// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
// CHECK: %E0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 0, i8 0, i32 poison)
-// CHECK: %[[#E0:]] = insertvalue [3 x <4 x float>] poison, <4 x float> %E0, 0
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] poison, <4 x float> %E0, 0, 0
// CHECK: %E1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 1, i8 0, i32 poison)
-// CHECK: %[[#E0:]] = insertvalue [3 x <4 x float>] %[[#E0]], <4 x float> %E1, 1
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E1, 0, 1
// CHECK: %E2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 2, i8 0, i32 poison)
-// CHECK: %[[#E0:]] = insertvalue [3 x <4 x float>] %[[#E0]], <4 x float> %E2, 2
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] poison, [3 x <4 x float>] %[[#E0]], 0
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E2, 0, 2
// CHECK: %E3 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 3, i8 0, i32 poison)
-// CHECK: %[[#E1:]] = insertvalue [3 x <4 x float>] poison, <4 x float> %E3, 0
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E3, 1, 0
// CHECK: %E4 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 4, i8 0, i32 poison)
-// CHECK: %[[#E1:]] = insertvalue [3 x <4 x float>] %[[#E1]], <4 x float> %E4, 1
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E4, 1, 1
// CHECK: %E5 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 5, i8 0, i32 poison)
-// CHECK: %[[#E1:]] = insertvalue [3 x <4 x float>] %[[#E1]], <4 x float> %E5, 2
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], [3 x <4 x float>] %[[#E1]], 1
+// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E5, 1, 2
// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], [2 x [3 x <4 x float>]] %[[#E]], 3
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
index 2b1d36b140838..726ca82c7d475 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
@@ -42,17 +42,15 @@ S main() {
// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
// CHECK: %[[#E:]] = extractvalue %struct.S %[[#S]], 3
-// CHECK: %[[#E0:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0
-// CHECK: %[[#E00:]] = extractvalue [3 x <4 x float>] %[[#E0]], 0
+// CHECK: %[[#E00:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0, 0
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 0, i8 0, <4 x float> %[[#E00]])
-// CHECK: %[[#E01:]] = extractvalue [3 x <4 x float>] %[[#E0]], 1
+// CHECK: %[[#E01:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0, 1
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 1, i8 0, <4 x float> %[[#E01]])
-// CHECK: %[[#E02:]] = extractvalue [3 x <4 x float>] %[[#E0]], 2
+// CHECK: %[[#E02:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0, 2
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 2, i8 0, <4 x float> %[[#E02]])
-// CHECK: %[[#E1:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1
-// CHECK: %[[#E10:]] = extractvalue [3 x <4 x float>] %[[#E1]], 0
+// CHECK: %[[#E10:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1, 0
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 3, i8 0, <4 x float> %[[#E10]])
-// CHECK: %[[#E11:]] = extractvalue [3 x <4 x float>] %[[#E1]], 1
+// CHECK: %[[#E11:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1, 1
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 4, i8 0, <4 x float> %[[#E11]])
-// CHECK: %[[#E12:]] = extractvalue [3 x <4 x float>] %[[#E1]], 2
+// CHECK: %[[#E12:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1, 2
// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 5, i8 0, <4 x float> %[[#E12]])
>From 3c7bbe3151e5e4b006a2ee625be44b4579a614a9 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 5 Aug 2026 19:09:43 +0000
Subject: [PATCH 11/14] typos whoops
---
.../test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
index f0bf3fff0ab66..295d902011da2 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
@@ -12,15 +12,15 @@ void main(float a : AAA, int b : B, float2 c : CC) {
// CHECK: define void @main()
-// CHECK-DXIL: %[[#AAA:]] = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#B:]] = call i32 @llvm.dx.load.input.i32(i32 1, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#CC:]] = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]])
+// CHECK-DXIL: %[[AAA:.*]] = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[B:.*]] = call i32 @llvm.dx.load.input.i32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[CC:.*]] = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %[[AAA]], i32 %[[B]], <2 x float> %[[CC]])
// CHECK-SPIRV: %[[#AAA:]] = load float, ptr addrspace(7) @AAA0, align 4
// CHECK-SPIRV: %[[#B:]] = load i32, ptr addrspace(7) @B0, align 4
// CHECK-SPIRV: %[[#CC:]] = load <2 x float>, ptr addrspace(7) @CC0, align 4
-// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA0]], i32 %[[#B0]], <2 x float> %[[#CC0]]) [ "convergencectrl"(token %0) ]
+// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA]], i32 %[[#B]], <2 x float> %[[#CC]]) [ "convergencectrl"(token %0) ]
// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]}
>From 814713934de3a71a074acafc993ae2c4e872b27e Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Fri, 7 Aug 2026 19:26:23 +0000
Subject: [PATCH 12/14] review: clean ups
---
clang/lib/CodeGen/CGHLSLRuntime.cpp | 36 ++++++++++++++++-------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index a17244ac9a83f..c47e179a2ebb6 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -50,6 +50,7 @@
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <array>
#include <cstdint>
#include <optional>
@@ -1213,23 +1214,24 @@ static QualType getSemanticLeafType(const clang::DeclaratorDecl *Decl) {
// Walks through the surrounding constant array types of \p Ty, collecting their
// dimensions until reaching a scalar, vector, or matrix leaf.
static SemanticShape getSemanticShape(ASTContext &Ctx, QualType Ty) {
- SmallVector<unsigned> Dimensions;
- while (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(Ty)) {
- Dimensions.push_back(CAT->getSize().getZExtValue());
- Ty = CAT->getElementType();
+ SemanticShape Shape{{}, 1, Ty};
+ while (const ConstantArrayType *CAT =
+ Ctx.getAsConstantArrayType(Shape.RowType)) {
+ Shape.Dimensions.push_back(CAT->getSize().getZExtValue());
+ Shape.RowType = CAT->getElementType();
}
- unsigned Cols = 1;
- if (const auto *VT = Ty->getAs<clang::VectorType>()) {
- Cols = VT->getNumElements();
- } else if (const auto *MT = Ty->getAs<clang::ConstantMatrixType>()) {
+ if (const auto *VT = Shape.RowType->getAs<clang::VectorType>()) {
+ Shape.Cols = VT->getNumElements();
+ } else if (const auto *MT =
+ Shape.RowType->getAs<clang::ConstantMatrixType>()) {
// FIXME: a matrix leaf lowers to one row per matrix row but if column_major
// is specified we transpose the num rows and num cols, this depends on
// #211977 to resolve
- Cols = MT->getNumColumns();
+ Shape.Cols = MT->getNumColumns();
}
- return {std::move(Dimensions), Cols, Ty};
+ return Shape;
}
llvm::Value *CGHLSLRuntime::emitDXILUserSemanticLoad(
@@ -1256,9 +1258,10 @@ llvm::Value *CGHLSLRuntime::emitDXILUserSemanticLoad(
llvm::Value *Result = llvm::PoisonValue::get(Type);
SmallVector<unsigned> Indices(Shape.Dimensions.size());
+ const unsigned NumRows = Shape.getNumRows();
- for (unsigned Row = 0; Row < Shape.getNumRows(); ++Row) {
- SmallVector<Value *> Args{
+ for (unsigned Row = 0; Row < NumRows; ++Row) {
+ std::array<Value *, 4> Args{
/*SigElementId=*/B.getInt32(SigId),
/*RowIndex=*/B.getInt32(Row),
/*ColIndex=*/B.getInt8(0),
@@ -1309,7 +1312,8 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
unsigned SigId = DXILOutputSemanticIndex++;
SmallVector<unsigned> Indices(Shape.Dimensions.size());
- for (unsigned Row = 0; Row < Shape.getNumRows(); ++Row) {
+ const unsigned NumRows = Shape.getNumRows();
+ for (unsigned Row = 0; Row < NumRows; ++Row) {
llvm::Value *Val =
Indices.empty() ? Source : B.CreateExtractValue(Source, Indices);
@@ -1321,9 +1325,9 @@ void CGHLSLRuntime::emitDXILUserSemanticStore(llvm::IRBuilder<> &B,
Val = B.CreateZExt(Val, RowTy, "storedv");
}
- SmallVector<Value *> Args{/*SigElementId=*/B.getInt32(SigId),
- /*RowIndex=*/B.getInt32(Row),
- /*ColIndex=*/B.getInt8(0), /*Value=*/Val};
+ std::array<Value *, 4> Args{/*SigElementId=*/B.getInt32(SigId),
+ /*RowIndex=*/B.getInt32(Row),
+ /*ColIndex=*/B.getInt8(0), /*Value=*/Val};
B.CreateCall(IntrFn, Args, OB);
// Advance the multidimensional index
>From 207640beeae820c4a5b72136ec9cd0817295234d Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Fri, 7 Aug 2026 19:32:17 +0000
Subject: [PATCH 13/14] review: update filechecks to always match
---
.../CodeGenHLSL/semantics/SV_Position.ps.hlsl | 12 ++--
.../CodeGenHLSL/semantics/SV_Position.vs.hlsl | 12 ++--
.../CodeGenHLSL/semantics/SV_Target.ps.hlsl | 9 +--
.../CodeGenHLSL/semantics/SV_VertexID.vs.hlsl | 8 +--
.../semantics/semantic.arbitrary.hlsl | 8 +--
.../CodeGenHLSL/semantics/semantic.array.hlsl | 30 +++++-----
.../semantics/semantic.array.output.hlsl | 30 +++++-----
...antic.explicit-location-output-struct.hlsl | 17 +++---
.../semantics/semantic.explicit-location.hlsl | 9 +--
.../CodeGenHLSL/semantics/semantic.input.hlsl | 56 +++++++++----------
.../semantics/semantic.output.hlsl | 56 +++++++++----------
.../semantics/semantic.struct.output.hlsl | 36 ++++++------
clang/test/CodeGenHLSL/sret_output.hlsl | 14 ++---
13 files changed, 150 insertions(+), 147 deletions(-)
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
index ac695b1f7d5eb..095532863ac5a 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.ps.hlsl
@@ -5,13 +5,13 @@
// CHECK: define void @main() {{.*}} {
float4 main(float4 p : SV_Position) : A {
- // CHECK-SPIRV: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 4
- // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]])
- // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @A0, align 4
+ // CHECK-SPIRV: %[[P:.*]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 4
+ // CHECK-SPIRV: %[[R:.*]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[P]])
+ // CHECK-SPIRV: store <4 x float> %[[R]], ptr addrspace(8) @A0, align 4
- // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
- // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: %[[INPUT:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %[[RESULT:.*]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %[[INPUT]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[RESULT]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
index 350b5e3612e32..c227e8198c964 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Position.vs.hlsl
@@ -6,13 +6,13 @@
// CHECK: define void @main() {{.*}} {
float4 main(float4 p : SV_Position) : SV_Position {
- // CHECK-SPIRV: %[[#P:]] = load <4 x float>, ptr addrspace(7) @SV_Position0, align 4
- // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#P]])
- // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Position, align 4
+ // CHECK-SPIRV: %[[P:.*]] = load <4 x float>, ptr addrspace(7) @SV_Position0, align 4
+ // CHECK-SPIRV: %[[R:.*]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[P]])
+ // CHECK-SPIRV: store <4 x float> %[[R]], ptr addrspace(8) @SV_Position, align 4
- // CHECK-DXIL: %SV_Position0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
- // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: %[[INPUT:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %[[RESULT:.*]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %[[INPUT]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[RESULT]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl
index 73255e3a9b939..ae216d821750c 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_Target.ps.hlsl
@@ -5,11 +5,12 @@
// CHECK: define void @main() {{.*}} {
float4 main(float4 p : SV_Position) : SV_Target {
- // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#]])
- // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 4
+ // CHECK-SPIRV: %[[RESULT:.*]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %{{.*}})
+ // CHECK-SPIRV: store <4 x float> %[[RESULT]], ptr addrspace(8) @SV_Target0, align 4
- // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: %[[INPUT:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %[[RESULT:.*]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %[[INPUT]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[RESULT]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl b/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl
index 491f10b530c38..c965432b923db 100644
--- a/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/SV_VertexID.vs.hlsl
@@ -5,11 +5,11 @@
// CHECK: define void @main() {{.*}} {
uint main(uint id : SV_VertexID) : A {
- // CHECK-SPIRV: %[[#P:]] = load i32, ptr addrspace(7) @SV_VertexID, align 4
- // CHECK-SPIRV: %[[#]] = call spir_func i32 @_Z4mainj(i32 %[[#P]])
+ // CHECK-SPIRV: %[[INPUT:.*]] = load i32, ptr addrspace(7) @SV_VertexID, align 4
+ // CHECK-SPIRV: %[[RESULT:.*]] = call spir_func i32 @_Z4mainj(i32 %[[INPUT]])
- // CHECK-DXIL: %SV_VertexID0 = call i32 @llvm.dx.load.input.i32(i32 0, i32 0, i8 0, i32 poison)
- // CHECK-DXIL: %[[#]] = call i32 @_Z4mainj(i32 %SV_VertexID0)
+ // CHECK-DXIL: %[[INPUT:.*]] = call i32 @llvm.dx.load.input.i32(i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %[[RESULT:.*]] = call i32 @_Z4mainj(i32 %[[INPUT]])
return id;
}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
index 295d902011da2..f1d13cb70c214 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.arbitrary.hlsl
@@ -17,10 +17,10 @@ void main(float a : AAA, int b : B, float2 c : CC) {
// CHECK-DXIL: %[[CC:.*]] = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 0, i32 poison)
// CHECK-DXIL: call void @_Z4mainfiDv2_f(float %[[AAA]], i32 %[[B]], <2 x float> %[[CC]])
-// CHECK-SPIRV: %[[#AAA:]] = load float, ptr addrspace(7) @AAA0, align 4
-// CHECK-SPIRV: %[[#B:]] = load i32, ptr addrspace(7) @B0, align 4
-// CHECK-SPIRV: %[[#CC:]] = load <2 x float>, ptr addrspace(7) @CC0, align 4
-// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[#AAA]], i32 %[[#B]], <2 x float> %[[#CC]]) [ "convergencectrl"(token %0) ]
+// CHECK-SPIRV: %[[AAA:.*]] = load float, ptr addrspace(7) @AAA0, align 4
+// CHECK-SPIRV: %[[B:.*]] = load i32, ptr addrspace(7) @B0, align 4
+// CHECK-SPIRV: %[[CC:.*]] = load <2 x float>, ptr addrspace(7) @CC0, align 4
+// CHECK-SPIRV: call spir_func void @_Z4mainfiDv2_f(float %[[AAA]], i32 %[[B]], <2 x float> %[[CC]]) [ "convergencectrl"(token %{{.*}}) ]
// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
index 5466948bd32bc..524c521913a2a 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.hlsl
@@ -12,23 +12,23 @@ struct S0 {
// CHECK-SPIRV: @A2 = external hidden thread_local addrspace(7) externally_initialized constant <4 x float>, !spirv.Decorations ![[#MD_2:]]
// CHECK: define void @main0()
-// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#POS0:]] = insertvalue [2 x <4 x float>] poison, <4 x float> %A0, 0
-// CHECK-DXIL: %A1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 1, i8 0, i32 poison)
-// CHECK-DXIL: %[[#POS1:]] = insertvalue [2 x <4 x float>] %[[#POS0]], <4 x float> %A1, 1
-// CHECK-DXIL: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#POS1]], 0
-// CHECK-DXIL: %A01 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %A01, 1
+// CHECK-DXIL: %[[A0:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[POS0:.*]] = insertvalue [2 x <4 x float>] poison, <4 x float> %[[A0]], 0
+// CHECK-DXIL: %[[A1:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 1, i8 0, i32 poison)
+// CHECK-DXIL: %[[POS1:.*]] = insertvalue [2 x <4 x float>] %[[POS0]], <4 x float> %[[A1]], 1
+// CHECK-DXIL: %[[TMP0:.*]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[POS1]], 0
+// CHECK-DXIL: %[[A01:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: %[[TMP1:.*]] = insertvalue %struct.S0 %[[TMP0]], <4 x float> %[[A01]], 1
-// CHECK-SPIRV: %[[#A0:]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 4
-// CHECK-SPIRV: %[[#TMP0:]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[#A0]], 0
-// CHECK-SPIRV: %[[#A01:]] = load <4 x float>, ptr addrspace(7) @A2, align 4
-// CHECK-SPIRV: %[[#TMP1:]] = insertvalue %struct.S0 %[[#TMP0]], <4 x float> %[[#A01]], 1
+// CHECK-SPIRV: %[[A0:.*]] = load [2 x <4 x float>], ptr addrspace(7) @A0, align 4
+// CHECK-SPIRV: %[[TMP0:.*]] = insertvalue %struct.S0 poison, [2 x <4 x float>] %[[A0]], 0
+// CHECK-SPIRV: %[[A01:.*]] = load <4 x float>, ptr addrspace(7) @A2, align 4
+// CHECK-SPIRV: %[[TMP1:.*]] = insertvalue %struct.S0 %[[TMP0]], <4 x float> %[[A01]], 1
-// CHECK: %[[#ARG:]] = alloca %struct.S0
-// CHECK: store %struct.S0 %[[#TMP1]], ptr %[[#ARG]]
-// CHECK-DXIL: call void @{{.*}}main0{{.*}}(ptr %[[#ARG]])
-// CHECK-SPIRV: call spir_func void @{{.*}}main0{{.*}}(ptr %[[#ARG]])
+// CHECK: %[[ARG:.*]] = alloca %struct.S0
+// CHECK: store %struct.S0 %[[TMP1]], ptr %[[ARG]]
+// CHECK-DXIL: call void @{{.*}}main0{{.*}}(ptr %[[ARG]])
+// CHECK-SPIRV: call spir_func void @{{.*}}main0{{.*}}(ptr %[[ARG]])
[shader("pixel")]
void main0(S0 p : A) {
float tmp = p.position[0] + p.position[1] + p.color;
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
index 9d3afc5e8fba6..8c8fe6443183e 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.array.output.hlsl
@@ -10,22 +10,22 @@ struct S0 {
[shader("pixel")]
S0 main1(float4 input : A) : B {
-// CHECK: %[[#ARG:]] = alloca %struct.S0
-// CHECK-SPIRV: %[[#INPUT:]] = load <4 x float>, ptr addrspace(7) @A0, align 4
-// CHECK-DXIL: %A0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK-DXIL: call void @{{.*}}main1{{.*}}(ptr %[[#ARG]], <4 x float> %A0)
-// CHECK-SPIRV: call spir_func void @{{.*}}main1{{.*}}(ptr %[[#ARG]], <4 x float> %[[#INPUT]])
+// CHECK: %[[ARG:.*]] = alloca %struct.S0
+// CHECK-SPIRV: %[[INPUT:.*]] = load <4 x float>, ptr addrspace(7) @A0, align 4
+// CHECK-DXIL: %[[INPUT:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK-DXIL: call void @{{.*}}main1{{.*}}(ptr %[[ARG]], <4 x float> %[[INPUT]])
+// CHECK-SPIRV: call spir_func void @{{.*}}main1{{.*}}(ptr %[[ARG]], <4 x float> %[[INPUT]])
- // CHECK: %[[#ST:]] = load %struct.S0, ptr %[[#ARG]]
- // CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 0
- // CHECK-SPIRV: store [2 x <4 x float>] %[[#TMP]], ptr addrspace(8) @B0, align 4
- // CHECK-DXIL: %[[#POS0:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 0
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#POS0]])
- // CHECK-DXIL: %[[#POS1:]] = extractvalue [2 x <4 x float>] %[[#TMP]], 1
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 1, i8 0, <4 x float> %[[#POS1]])
- // CHECK: %[[#TMP:]] = extractvalue %struct.S0 %[[#ST]], 1
- // CHECK-SPIRV: store <4 x float> %[[#TMP]], ptr addrspace(8) @B2, align 4
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[#TMP]])
+ // CHECK: %[[ST:.*]] = load %struct.S0, ptr %[[ARG]]
+ // CHECK: %[[POSITIONS:.*]] = extractvalue %struct.S0 %[[ST]], 0
+ // CHECK-SPIRV: store [2 x <4 x float>] %[[POSITIONS]], ptr addrspace(8) @B0, align 4
+ // CHECK-DXIL: %[[POS0:.*]] = extractvalue [2 x <4 x float>] %[[POSITIONS]], 0
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[POS0]])
+ // CHECK-DXIL: %[[POS1:.*]] = extractvalue [2 x <4 x float>] %[[POSITIONS]], 1
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 1, i8 0, <4 x float> %[[POS1]])
+ // CHECK: %[[COLOR:.*]] = extractvalue %struct.S0 %[[ST]], 1
+ // CHECK-SPIRV: store <4 x float> %[[COLOR]], ptr addrspace(8) @B2, align 4
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[COLOR]])
S0 output;
output.position[0] = input;
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl
index b24cee7baf8ae..60468b179498b 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location-output-struct.hlsl
@@ -10,18 +10,19 @@ struct Output {
// CHECK: define void @main() {{.*}} {
Output main(float4 p : SV_Position) {
- // CHECK: %[[#OUT:]] = alloca %struct.Output
+ // CHECK: %[[OUT:.*]] = alloca %struct.Output
- // CHECK-SPIRV: %[[#IN:]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 4
- // CHECK-SPIRV: call spir_func void @_Z4mainDv4_f(ptr %[[#OUT]], <4 x float> %[[#IN]])
+ // CHECK-SPIRV: %[[IN:.*]] = load <4 x float>, ptr addrspace(7) @SV_Position, align 4
+ // CHECK-SPIRV: call spir_func void @_Z4mainDv4_f(ptr %[[OUT]], <4 x float> %[[IN]])
- // CHECK-DXIL: call void @_Z4mainDv4_f(ptr %[[#OUT]], <4 x float> %SV_Position0)
+ // CHECK-DXIL: %[[IN:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: call void @_Z4mainDv4_f(ptr %[[OUT]], <4 x float> %[[IN]])
- // CHECK: %[[#TMP:]] = load %struct.Output, ptr %[[#OUT]]
- // CHECK: %[[#FIELD:]] = extractvalue %struct.Output %[[#TMP]], 0
+ // CHECK: %[[TMP:.*]] = load %struct.Output, ptr %[[OUT]]
+ // CHECK: %[[FIELD:.*]] = extractvalue %struct.Output %[[TMP]], 0
- // CHECK-SPIRV: store <4 x float> %[[#FIELD]], ptr addrspace(8) @SV_Target0, align 4
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#FIELD]])
+ // CHECK-SPIRV: store <4 x float> %[[FIELD]], ptr addrspace(8) @SV_Target0, align 4
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[FIELD]])
Output o;
o.field = p;
return o;
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl
index 2ca0f3fe65a57..a6e90b29349b9 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.explicit-location.hlsl
@@ -5,11 +5,12 @@
// CHECK: define void @main() {{.*}} {
[[vk::location(2)]] float4 main(float4 p : SV_Position) : SV_Target {
- // CHECK-SPIRV: %[[#R:]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %[[#]])
- // CHECK-SPIRV: store <4 x float> %[[#R]], ptr addrspace(8) @SV_Target0, align 4
+ // CHECK-SPIRV: %[[RESULT:.*]] = call spir_func <4 x float> @_Z4mainDv4_f(<4 x float> %{{.*}})
+ // CHECK-SPIRV: store <4 x float> %[[RESULT]], ptr addrspace(8) @SV_Target0, align 4
- // CHECK-DXIL: %[[#TMP:]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %SV_Position0)
- // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[#TMP]])
+ // CHECK-DXIL: %[[INPUT:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 0, i32 0, i8 0, i32 poison)
+ // CHECK-DXIL: %[[RESULT:.*]] = call <4 x float> @_Z4mainDv4_f(<4 x float> %[[INPUT]])
+ // CHECK-DXIL: call void @llvm.dx.store.output.v4f32(i32 0, i32 0, i8 0, <4 x float> %[[RESULT]])
return p;
}
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
index bdda150e7d667..3c46eace082ee 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.input.hlsl
@@ -17,37 +17,37 @@ struct S {
void main(S s) {}
// float a : A -> 1 row, 1 column.
-// CHECK: %A0 = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
-// CHECK: %[[#S:]] = insertvalue %struct.S poison, float %A0, 0
+// CHECK: %[[A:.*]] = call float @llvm.dx.load.input.f32(i32 0, i32 0, i8 0, i32 poison)
+// CHECK: %[[S0:.*]] = insertvalue %struct.S poison, float %[[A]], 0
// float4 b : B -> 1 row, 4 columns.
-// CHECK: %B0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
-// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], <4 x float> %B0, 1
+// CHECK: %[[B:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 poison)
+// CHECK: %[[S1:.*]] = insertvalue %struct.S %[[S0]], <4 x float> %[[B]], 1
// float d[5] : D -> 5 rows, 1 column each.
-// CHECK: %D0 = call float @llvm.dx.load.input.f32(i32 2, i32 0, i8 0, i32 poison)
-// CHECK: %[[#D:]] = insertvalue [5 x float] poison, float %D0, 0
-// CHECK: %D1 = call float @llvm.dx.load.input.f32(i32 2, i32 1, i8 0, i32 poison)
-// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D1, 1
-// CHECK: %D2 = call float @llvm.dx.load.input.f32(i32 2, i32 2, i8 0, i32 poison)
-// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D2, 2
-// CHECK: %D3 = call float @llvm.dx.load.input.f32(i32 2, i32 3, i8 0, i32 poison)
-// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D3, 3
-// CHECK: %D4 = call float @llvm.dx.load.input.f32(i32 2, i32 4, i8 0, i32 poison)
-// CHECK: %[[#D:]] = insertvalue [5 x float] %[[#D]], float %D4, 4
-// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], [5 x float] %[[#D]], 2
+// CHECK: %[[D0:.*]] = call float @llvm.dx.load.input.f32(i32 2, i32 0, i8 0, i32 poison)
+// CHECK: %[[D_ARRAY0:.*]] = insertvalue [5 x float] poison, float %[[D0]], 0
+// CHECK: %[[D1:.*]] = call float @llvm.dx.load.input.f32(i32 2, i32 1, i8 0, i32 poison)
+// CHECK: %[[D_ARRAY1:.*]] = insertvalue [5 x float] %[[D_ARRAY0]], float %[[D1]], 1
+// CHECK: %[[D2:.*]] = call float @llvm.dx.load.input.f32(i32 2, i32 2, i8 0, i32 poison)
+// CHECK: %[[D_ARRAY2:.*]] = insertvalue [5 x float] %[[D_ARRAY1]], float %[[D2]], 2
+// CHECK: %[[D3:.*]] = call float @llvm.dx.load.input.f32(i32 2, i32 3, i8 0, i32 poison)
+// CHECK: %[[D_ARRAY3:.*]] = insertvalue [5 x float] %[[D_ARRAY2]], float %[[D3]], 3
+// CHECK: %[[D4:.*]] = call float @llvm.dx.load.input.f32(i32 2, i32 4, i8 0, i32 poison)
+// CHECK: %[[D_ARRAY4:.*]] = insertvalue [5 x float] %[[D_ARRAY3]], float %[[D4]], 4
+// CHECK: %[[S2:.*]] = insertvalue %struct.S %[[S1]], [5 x float] %[[D_ARRAY4]], 2
// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
-// CHECK: %E0 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 0, i8 0, i32 poison)
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] poison, <4 x float> %E0, 0, 0
-// CHECK: %E1 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 1, i8 0, i32 poison)
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E1, 0, 1
-// CHECK: %E2 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 2, i8 0, i32 poison)
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E2, 0, 2
-// CHECK: %E3 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 3, i8 0, i32 poison)
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E3, 1, 0
-// CHECK: %E4 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 4, i8 0, i32 poison)
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E4, 1, 1
-// CHECK: %E5 = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 5, i8 0, i32 poison)
-// CHECK: %[[#E:]] = insertvalue [2 x [3 x <4 x float>]] %[[#E]], <4 x float> %E5, 1, 2
-// CHECK: %[[#S:]] = insertvalue %struct.S %[[#S]], [2 x [3 x <4 x float>]] %[[#E]], 3
+// CHECK: %[[E0:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 0, i8 0, i32 poison)
+// CHECK: %[[E_ARRAY0:.*]] = insertvalue [2 x [3 x <4 x float>]] poison, <4 x float> %[[E0]], 0, 0
+// CHECK: %[[E1:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 1, i8 0, i32 poison)
+// CHECK: %[[E_ARRAY1:.*]] = insertvalue [2 x [3 x <4 x float>]] %[[E_ARRAY0]], <4 x float> %[[E1]], 0, 1
+// CHECK: %[[E2:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 2, i8 0, i32 poison)
+// CHECK: %[[E_ARRAY2:.*]] = insertvalue [2 x [3 x <4 x float>]] %[[E_ARRAY1]], <4 x float> %[[E2]], 0, 2
+// CHECK: %[[E3:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 3, i8 0, i32 poison)
+// CHECK: %[[E_ARRAY3:.*]] = insertvalue [2 x [3 x <4 x float>]] %[[E_ARRAY2]], <4 x float> %[[E3]], 1, 0
+// CHECK: %[[E4:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 4, i8 0, i32 poison)
+// CHECK: %[[E_ARRAY4:.*]] = insertvalue [2 x [3 x <4 x float>]] %[[E_ARRAY3]], <4 x float> %[[E4]], 1, 1
+// CHECK: %[[E5:.*]] = call <4 x float> @llvm.dx.load.input.v4f32(i32 3, i32 5, i8 0, i32 poison)
+// CHECK: %[[E_ARRAY5:.*]] = insertvalue [2 x [3 x <4 x float>]] %[[E_ARRAY4]], <4 x float> %[[E5]], 1, 2
+// CHECK: %[[S3:.*]] = insertvalue %struct.S %[[S2]], [2 x [3 x <4 x float>]] %[[E_ARRAY5]], 3
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
index 726ca82c7d475..fdb195899ca97 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.output.hlsl
@@ -20,37 +20,37 @@ S main() {
}
// float a : A -> 1 row, 1 column.
-// CHECK: %[[#A:]] = extractvalue %struct.S %[[#S:]], 0
-// CHECK: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[#A]])
+// CHECK: %[[A:.*]] = extractvalue %struct.S %[[S:.*]], 0
+// CHECK: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[A]])
// float4 b : B -> 1 row, 4 columns; the whole vector is stored.
-// CHECK: %[[#B:]] = extractvalue %struct.S %[[#S]], 1
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[#B]])
+// CHECK: %[[B:.*]] = extractvalue %struct.S %[[S]], 1
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %[[B]])
// float d[5] : D -> 5 rows, 1 column each.
-// CHECK: %[[#D:]] = extractvalue %struct.S %[[#S]], 2
-// CHECK: %[[#D0:]] = extractvalue [5 x float] %[[#D]], 0
-// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 0, i8 0, float %[[#D0]])
-// CHECK: %[[#D1:]] = extractvalue [5 x float] %[[#D]], 1
-// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 1, i8 0, float %[[#D1]])
-// CHECK: %[[#D2:]] = extractvalue [5 x float] %[[#D]], 2
-// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 2, i8 0, float %[[#D2]])
-// CHECK: %[[#D3:]] = extractvalue [5 x float] %[[#D]], 3
-// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 3, i8 0, float %[[#D3]])
-// CHECK: %[[#D4:]] = extractvalue [5 x float] %[[#D]], 4
-// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 4, i8 0, float %[[#D4]])
+// CHECK: %[[D:.*]] = extractvalue %struct.S %[[S]], 2
+// CHECK: %[[D0:.*]] = extractvalue [5 x float] %[[D]], 0
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 0, i8 0, float %[[D0]])
+// CHECK: %[[D1:.*]] = extractvalue [5 x float] %[[D]], 1
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 1, i8 0, float %[[D1]])
+// CHECK: %[[D2:.*]] = extractvalue [5 x float] %[[D]], 2
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 2, i8 0, float %[[D2]])
+// CHECK: %[[D3:.*]] = extractvalue [5 x float] %[[D]], 3
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 3, i8 0, float %[[D3]])
+// CHECK: %[[D4:.*]] = extractvalue [5 x float] %[[D]], 4
+// CHECK: call void @llvm.dx.store.output.f32(i32 2, i32 4, i8 0, float %[[D4]])
// float4 e[2][3] : E -> 6 rows (2 x 3), 4 columns each; row-major flattening.
-// CHECK: %[[#E:]] = extractvalue %struct.S %[[#S]], 3
-// CHECK: %[[#E00:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0, 0
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 0, i8 0, <4 x float> %[[#E00]])
-// CHECK: %[[#E01:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0, 1
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 1, i8 0, <4 x float> %[[#E01]])
-// CHECK: %[[#E02:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 0, 2
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 2, i8 0, <4 x float> %[[#E02]])
-// CHECK: %[[#E10:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1, 0
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 3, i8 0, <4 x float> %[[#E10]])
-// CHECK: %[[#E11:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1, 1
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 4, i8 0, <4 x float> %[[#E11]])
-// CHECK: %[[#E12:]] = extractvalue [2 x [3 x <4 x float>]] %[[#E]], 1, 2
-// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 5, i8 0, <4 x float> %[[#E12]])
+// CHECK: %[[E:.*]] = extractvalue %struct.S %[[S]], 3
+// CHECK: %[[E00:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 0, 0
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 0, i8 0, <4 x float> %[[E00]])
+// CHECK: %[[E01:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 0, 1
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 1, i8 0, <4 x float> %[[E01]])
+// CHECK: %[[E02:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 0, 2
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 2, i8 0, <4 x float> %[[E02]])
+// CHECK: %[[E10:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 1, 0
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 3, i8 0, <4 x float> %[[E10]])
+// CHECK: %[[E11:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 1, 1
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 4, i8 0, <4 x float> %[[E11]])
+// CHECK: %[[E12:.*]] = extractvalue [2 x [3 x <4 x float>]] %[[E]], 1, 2
+// CHECK: call void @llvm.dx.store.output.v4f32(i32 3, i32 5, i8 0, <4 x float> %[[E12]])
diff --git a/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl b/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl
index 426738adfe7ef..7bf54c4984eac 100644
--- a/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl
+++ b/clang/test/CodeGenHLSL/semantics/semantic.struct.output.hlsl
@@ -16,15 +16,15 @@ struct Output {
// CHECK-SPIRV-DAG: @A4 = external hidden thread_local addrspace(8) global float, !spirv.Decorations ![[#METADATA_0:]]
// CHECK-SPIRV-DAG: @A2 = external hidden thread_local addrspace(8) global float, !spirv.Decorations ![[#METADATA_2:]]
-// CHECK: %Idx = getelementptr inbounds nuw %struct.Input, ptr %input, i32 0, i32 0
-// CHECK: %[[#tmp:]] = load float, ptr %Idx, align 1
-// CHECK: %a = getelementptr inbounds nuw %struct.Output, ptr %agg.result, i32 0, i32 0
-// CHECK: store float %[[#tmp]], ptr %a, align 1
+// CHECK: %[[IDX0:.*]] = getelementptr inbounds nuw %struct.Input, ptr %{{.*}}, i32 0, i32 0
+// CHECK: %[[LOAD0:.*]] = load float, ptr %[[IDX0]], align 1
+// CHECK: %[[A:.*]] = getelementptr inbounds nuw %struct.Output, ptr %{{.*}}, i32 0, i32 0
+// CHECK: store float %[[LOAD0]], ptr %[[A]], align 1
-// CHECK: %Idx1 = getelementptr inbounds nuw %struct.Input, ptr %input, i32 0, i32 0
-// CHECK: %[[#tmp:]] = load float, ptr %Idx1, align 1
-// CHECK: %b = getelementptr inbounds nuw %struct.Output, ptr %agg.result, i32 0, i32 1
-// CHECK: store float %[[#tmp]], ptr %b, align 1
+// CHECK: %[[IDX1:.*]] = getelementptr inbounds nuw %struct.Input, ptr %{{.*}}, i32 0, i32 0
+// CHECK: %[[LOAD1:.*]] = load float, ptr %[[IDX1]], align 1
+// CHECK: %[[B:.*]] = getelementptr inbounds nuw %struct.Output, ptr %{{.*}}, i32 0, i32 1
+// CHECK: store float %[[LOAD1]], ptr %[[B]], align 1
Output main(Input input) {
Output o;
@@ -35,18 +35,18 @@ Output main(Input input) {
// Code generated in the entrypoint wrapper:
-// CHECK: %[[#OUTPUT:]] = alloca %struct.Output, align 8
+// CHECK: %[[OUTPUT:.*]] = alloca %struct.Output, align 8
-// CHECK-SPIRV: call spir_func void @_Z4main5Input(ptr %[[#OUTPUT]], ptr %[[#]])
-// CHECK-DXIL: call void @_Z4main5Input(ptr %[[#OUTPUT]], ptr %[[#]])
+// CHECK-SPIRV: call spir_func void @_Z4main5Input(ptr %[[OUTPUT]], ptr %{{.*}})
+// CHECK-DXIL: call void @_Z4main5Input(ptr %[[OUTPUT]], ptr %{{.*}})
-// CHECK: %[[#TMP:]] = load %struct.Output, ptr %[[#OUTPUT]], align 4
-// CHECK: %[[#VAL:]] = extractvalue %struct.Output %[[#TMP]], 0
-// CHECK-SPIRV: store float %[[#VAL]], ptr addrspace(8) @A4, align 4
-// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[#VAL]])
-// CHECK: %[[#VAL:]] = extractvalue %struct.Output %[[#TMP]], 1
-// CHECK-SPIRV: store float %[[#VAL]], ptr addrspace(8) @A2, align 4
-// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 1, i32 0, i8 0, float %[[#VAL]])
+// CHECK: %[[TMP:.*]] = load %struct.Output, ptr %[[OUTPUT]], align 4
+// CHECK: %[[VAL0:.*]] = extractvalue %struct.Output %[[TMP]], 0
+// CHECK-SPIRV: store float %[[VAL0]], ptr addrspace(8) @A4, align 4
+// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[VAL0]])
+// CHECK: %[[VAL1:.*]] = extractvalue %struct.Output %[[TMP]], 1
+// CHECK-SPIRV: store float %[[VAL1]], ptr addrspace(8) @A2, align 4
+// CHECK-DXIL: call void @llvm.dx.store.output.f32(i32 1, i32 0, i8 0, float %[[VAL1]])
// CHECK-SPIRV-DAG: ![[#METADATA_0]] = !{![[#METADATA_1:]]}
// CHECK-SPIRV-DAG: ![[#METADATA_2]] = !{![[#METADATA_3:]]}
diff --git a/clang/test/CodeGenHLSL/sret_output.hlsl b/clang/test/CodeGenHLSL/sret_output.hlsl
index 325c31541f473..2f8b17d337424 100644
--- a/clang/test/CodeGenHLSL/sret_output.hlsl
+++ b/clang/test/CodeGenHLSL/sret_output.hlsl
@@ -20,13 +20,13 @@ S vs_main() {
return s;
};
-// CHECK: %[[#alloca:]] = alloca %struct.S, align 8
-// CHECK-DX: call void @_Z7vs_mainv(ptr %[[#alloca]])
-// CHECK-VK: call spir_func void @_Z7vs_mainv(ptr %[[#alloca]])
-// CHECK: %[[#a:]] = load %struct.S, ptr %[[#alloca]], align 4
-// CHECK: %[[#b:]] = extractvalue %struct.S %[[#a]], 0
-// CHECK-DX: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[#b]])
-// CHECK-VK: store float %3, ptr addrspace(8) @A4, align 4
+// CHECK: %[[ALLOCA:.*]] = alloca %struct.S, align 8
+// CHECK-DX: call void @_Z7vs_mainv(ptr %[[ALLOCA]])
+// CHECK-VK: call spir_func void @_Z7vs_mainv(ptr %[[ALLOCA]])
+// CHECK: %[[S:.*]] = load %struct.S, ptr %[[ALLOCA]], align 4
+// CHECK: %[[A:.*]] = extractvalue %struct.S %[[S]], 0
+// CHECK-DX: call void @llvm.dx.store.output.f32(i32 0, i32 0, i8 0, float %[[A]])
+// CHECK-VK: store float %[[A]], ptr addrspace(8) @A4, align 4
// CHECK: ret void
// CHECK-VK: ![[#ATTR0]] = !{![[#ATTR1:]]}
>From b3a5e05a6246d9860f53260a4d9617d1dcd0c380 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Fri, 7 Aug 2026 19:58:33 +0000
Subject: [PATCH 14/14] conflict review: update lowering to account for removed
sigpoint operand
---
llvm/lib/Target/DirectX/DXIL.td | 8 ++----
.../Target/DirectX/DXILIntrinsicExpansion.cpp | 28 ++++++++-----------
llvm/test/CodeGen/DirectX/LoadInput.ll | 8 +++---
llvm/test/CodeGen/DirectX/StoreOutput.ll | 8 +++---
4 files changed, 22 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td
index 842c1b48efecf..c2d1b0ad4300c 100644
--- a/llvm/lib/Target/DirectX/DXIL.td
+++ b/llvm/lib/Target/DirectX/DXIL.td
@@ -414,9 +414,7 @@ class DXILOp<int opcode, DXILOpClass opclass> {
def LoadInput : DXILOp<4, loadInput> {
let Doc = "Loads a scalar value from a shader input register component.";
- let intrinsics = [IntrinSelect<int_dx_load_input,
- [IntrinArgIndex<1>, IntrinArgIndex<2>, IntrinArgIndex<3>,
- IntrinArgIndex<4>]>];
+ let intrinsics = [IntrinSelect<int_dx_load_input>];
// inputSigId, rowIndex, colIndex, gsVertexOrPrimIndex
let arguments = [Int32Ty, Int32Ty, Int8Ty, Int32Ty];
let result = OverloadTy;
@@ -427,9 +425,7 @@ def LoadInput : DXILOp<4, loadInput> {
def StoreOutput : DXILOp<5, storeOutput> {
let Doc = "Stores a scalar value to a shader output register component.";
- let intrinsics = [IntrinSelect<int_dx_store_output,
- [IntrinArgIndex<1>, IntrinArgIndex<2>, IntrinArgIndex<3>,
- IntrinArgIndex<4>]>];
+ let intrinsics = [IntrinSelect<int_dx_store_output>];
// outputSigId, rowIndex, colIndex, value
let arguments = [Int32Ty, Int32Ty, Int8Ty, OverloadTy];
let result = VoidTy;
diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
index c5b8b4efee956..73867d6e344a2 100644
--- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
+++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
@@ -1218,7 +1218,7 @@ static Value *expandMatrixTranspose(CallInst *Orig) {
// The DXIL StoreOutput op is per-component; vector intrinsics are split here
// so that DXILOpLowering sees only scalar variants.
static bool expandStoreOutput(CallInst *Orig) {
- auto *VT = dyn_cast<FixedVectorType>(Orig->getArgOperand(4)->getType());
+ auto *VT = dyn_cast<FixedVectorType>(Orig->getArgOperand(3)->getType());
if (!VT)
return false; // already scalar, nothing to expand
@@ -1229,11 +1229,10 @@ static bool expandStoreOutput(CallInst *Orig) {
Type *ScalarTy = VT->getElementType();
unsigned NumElems = VT->getNumElements();
- Value *SigpointId = Orig->getArgOperand(0);
- Value *SigElementId = Orig->getArgOperand(1);
- Value *RowIndex = Orig->getArgOperand(2);
- Value *StartCol = Orig->getArgOperand(3); // i8
- Value *Data = Orig->getArgOperand(4);
+ Value *SigElementId = Orig->getArgOperand(0);
+ Value *RowIndex = Orig->getArgOperand(1);
+ Value *StartCol = Orig->getArgOperand(2); // i8
+ Value *Data = Orig->getArgOperand(3);
Value *StartColI32 = Builder.CreateZExt(StartCol, Int32Ty);
Function *ScalarFn = Intrinsic::getOrInsertDeclaration(
@@ -1245,8 +1244,7 @@ static bool expandStoreOutput(CallInst *Orig) {
Value *ColIdx =
Builder.CreateAdd(StartColI32, ConstantInt::get(Int32Ty, I));
Value *ColI8 = Builder.CreateTrunc(ColIdx, Int8Ty);
- Builder.CreateCall(ScalarFn,
- {SigpointId, SigElementId, RowIndex, ColI8, Scalar});
+ Builder.CreateCall(ScalarFn, {SigElementId, RowIndex, ColI8, Scalar});
}
Orig->eraseFromParent();
@@ -1267,11 +1265,10 @@ static Value *expandLoadInput(CallInst *Orig) {
Type *ScalarTy = VT->getElementType();
unsigned NumElems = VT->getNumElements();
- Value *SigpointId = Orig->getArgOperand(0);
- Value *SigElementId = Orig->getArgOperand(1);
- Value *RowIndex = Orig->getArgOperand(2);
- Value *StartCol = Orig->getArgOperand(3); // i8
- Value *GsVertexOrPrimIndex = Orig->getArgOperand(4);
+ Value *SigElementId = Orig->getArgOperand(0);
+ Value *RowIndex = Orig->getArgOperand(1);
+ Value *StartCol = Orig->getArgOperand(2); // i8
+ Value *GsVertexOrPrimIndex = Orig->getArgOperand(3);
Value *StartColI32 = Builder.CreateZExt(StartCol, Int32Ty);
Function *ScalarFn = Intrinsic::getOrInsertDeclaration(
@@ -1282,9 +1279,8 @@ static Value *expandLoadInput(CallInst *Orig) {
Value *ColIdx =
Builder.CreateAdd(StartColI32, ConstantInt::get(Int32Ty, I));
Value *ColI8 = Builder.CreateTrunc(ColIdx, Int8Ty);
- Value *Scalar =
- Builder.CreateCall(ScalarFn, {SigpointId, SigElementId, RowIndex, ColI8,
- GsVertexOrPrimIndex});
+ Value *Scalar = Builder.CreateCall(
+ ScalarFn, {SigElementId, RowIndex, ColI8, GsVertexOrPrimIndex});
Vec =
Builder.CreateInsertElement(Vec, Scalar, ConstantInt::get(Int32Ty, I));
}
diff --git a/llvm/test/CodeGen/DirectX/LoadInput.ll b/llvm/test/CodeGen/DirectX/LoadInput.ll
index b29167d2dfb27..7eaed85b2df2c 100644
--- a/llvm/test/CodeGen/DirectX/LoadInput.ll
+++ b/llvm/test/CodeGen/DirectX/LoadInput.ll
@@ -8,7 +8,7 @@ define float @load_scalar_f32() {
; CHECK: [[V:%.*]] = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 1, i8 2, i32 0)
; CHECK-NEXT: ret float [[V]]
; CHECK-NOT: llvm.dx.load.input
- %v = call float @llvm.dx.load.input.f32(i32 99, i32 0, i32 1, i8 2, i32 0)
+ %v = call float @llvm.dx.load.input.f32(i32 0, i32 1, i8 2, i32 0)
ret float %v
}
@@ -24,7 +24,7 @@ define <4 x float> @load_v4f32() {
; CHECK: [[S3:%.*]] = call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 3, i32 0)
; CHECK-NEXT: insertelement {{.*}}, float [[S3]], i32 3
; CHECK-NOT: llvm.dx.load.input
- %v = call <4 x float> @llvm.dx.load.input.v4f32(i32 99, i32 1, i32 0, i8 0, i32 0)
+ %v = call <4 x float> @llvm.dx.load.input.v4f32(i32 1, i32 0, i8 0, i32 0)
ret <4 x float> %v
}
@@ -36,7 +36,7 @@ define <2 x float> @load_v2f32_col2() {
; CHECK: [[S1:%.*]] = call float @dx.op.loadInput.f32(i32 4, i32 2, i32 0, i8 3, i32 0)
; CHECK-NEXT: insertelement {{.*}}, float [[S1]], i32 1
; CHECK-NOT: llvm.dx.load.input
- %v = call <2 x float> @llvm.dx.load.input.v2f32(i32 99, i32 2, i32 0, i8 2, i32 0)
+ %v = call <2 x float> @llvm.dx.load.input.v2f32(i32 2, i32 0, i8 2, i32 0)
ret <2 x float> %v
}
@@ -46,6 +46,6 @@ define i32 @load_scalar_i32() {
; CHECK: [[V:%.*]] = call i32 @dx.op.loadInput.i32(i32 4, i32 2, i32 0, i8 0, i32 0)
; CHECK-NEXT: ret i32 [[V]]
; CHECK-NOT: llvm.dx.load.input
- %v = call i32 @llvm.dx.load.input.i32(i32 99, i32 2, i32 0, i8 0, i32 0)
+ %v = call i32 @llvm.dx.load.input.i32(i32 2, i32 0, i8 0, i32 0)
ret i32 %v
}
diff --git a/llvm/test/CodeGen/DirectX/StoreOutput.ll b/llvm/test/CodeGen/DirectX/StoreOutput.ll
index 04970a1488710..e67c972941ba4 100644
--- a/llvm/test/CodeGen/DirectX/StoreOutput.ll
+++ b/llvm/test/CodeGen/DirectX/StoreOutput.ll
@@ -7,7 +7,7 @@ target triple = "dxil-pc-shadermodel6.0-pixel"
define void @store_scalar_f32(float %val) {
; CHECK: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 1, i8 2, float %val)
; CHECK-NOT: llvm.dx.store.output
- call void @llvm.dx.store.output.f32(i32 99, i32 0, i32 1, i8 2, float %val)
+ call void @llvm.dx.store.output.f32(i32 0, i32 1, i8 2, float %val)
ret void
}
@@ -23,7 +23,7 @@ define void @store_v4f32(<4 x float> %val) {
; CHECK-NEXT: [[E3:%.*]] = extractelement <4 x float> %val, i32 3
; CHECK-NEXT: call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 3, float [[E3]])
; CHECK-NOT: llvm.dx.store.output
- call void @llvm.dx.store.output.v4f32(i32 99, i32 1, i32 0, i8 0, <4 x float> %val)
+ call void @llvm.dx.store.output.v4f32(i32 1, i32 0, i8 0, <4 x float> %val)
ret void
}
@@ -35,7 +35,7 @@ define void @store_v2f32_col2(<2 x float> %val) {
; CHECK-NEXT: [[E1:%.*]] = extractelement <2 x float> %val, i32 1
; CHECK-NEXT: call void @dx.op.storeOutput.f32(i32 5, i32 2, i32 0, i8 3, float [[E1]])
; CHECK-NOT: llvm.dx.store.output
- call void @llvm.dx.store.output.v2f32(i32 99, i32 2, i32 0, i8 2, <2 x float> %val)
+ call void @llvm.dx.store.output.v2f32(i32 2, i32 0, i8 2, <2 x float> %val)
ret void
}
@@ -44,6 +44,6 @@ define void @store_v2f32_col2(<2 x float> %val) {
define void @store_scalar_i32(i32 %val) {
; CHECK: call void @dx.op.storeOutput.i32(i32 5, i32 2, i32 0, i8 0, i32 %val)
; CHECK-NOT: llvm.dx.store.output
- call void @llvm.dx.store.output.i32(i32 99, i32 2, i32 0, i8 0, i32 %val)
+ call void @llvm.dx.store.output.i32(i32 2, i32 0, i8 0, i32 %val)
ret void
}
More information about the llvm-commits
mailing list