Skip to content

Commit 8b24477

Browse files
authored
Propagate precise from formal parameter to actual parameter (microsoft#6058)
It is unclear what should happen if an input parameter on a function is marked as precise. I am choosing to propagate it to the actual parameters. Note that it is not wrong to propagate precise more than we should since it will only stop some optimizations.
1 parent 748a54b commit 8b24477

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

tools/clang/lib/SPIRV/PreciseVisitor.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,5 +251,19 @@ bool PreciseVisitor::visit(SpirvExtInst *inst) {
251251
return true;
252252
}
253253

254+
bool PreciseVisitor::visit(SpirvFunctionCall *call) {
255+
// If a formal parameter for the function is precise, then the corresponding
256+
// actual parameter should be marked as precise.
257+
auto function = call->getFunction();
258+
for (uint32_t i = 0; i < call->getArgs().size(); ++i) {
259+
auto formalParameter = function->getParameters()[i];
260+
if (!formalParameter->isPrecise()) {
261+
continue;
262+
}
263+
call->getArgs()[i]->setPrecise();
264+
}
265+
return true;
266+
}
267+
254268
} // end namespace spirv
255269
} // end namespace clang

tools/clang/lib/SPIRV/PreciseVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class PreciseVisitor : public Visitor {
3939
bool visit(SpirvNonUniformBinaryOp *) override;
4040
bool visit(SpirvNonUniformUnaryOp *) override;
4141
bool visit(SpirvExtInst *) override;
42+
bool visit(SpirvFunctionCall *) override;
4243

4344
using Visitor::visit;
4445

tools/clang/test/CodeGenSPIRV/decoration.no-contraction.hlsl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ float func4(float i, float j, precise out float k);
1313
// CHECK-NEXT: OpDecorate [[aw_mul_bw:%[0-9]+]] NoContraction
1414
// CHECK-NEXT: OpDecorate [[cw_mul_dw:%[0-9]+]] NoContraction
1515
// CHECK-NEXT: OpDecorate [[awbw_plus_cwdw:%[0-9]+]] NoContraction
16+
// CHECK-NEXT: OpDecorate [[func_ax_mul_bx:%[0-9]+]] NoContraction
17+
// CHECK-NEXT: OpDecorate [[func_cx_mul_dx:%[0-9]+]] NoContraction
1618
// CHECK-NEXT: OpDecorate [[func2_e_mul_f:%[0-9]+]] NoContraction
1719
// CHECK-NEXT: OpDecorate [[func2_g_mul_h:%[0-9]+]] NoContraction
1820
// CHECK-NEXT: OpDecorate [[func2_ef_plus_gh:%[0-9]+]] NoContraction
@@ -63,7 +65,13 @@ void main() {
6365
// Even though v.x is precise, values computed inside func4 are not forced to
6466
// be precise. Meaning, precise-ness does not cross function boundary.
6567
v.x = func3(a.x, b.x, c.x, d.x);
66-
68+
69+
// Because the precise keyword is on the output parameter in func4, the formal input parameters will get marked as precise as well. This should propagate to the actual parameters.
70+
// CHECK: [[func_ax_mul_bx]] = OpFMul
71+
// CHECK: OpStore %param_var_i [[func_ax_mul_bx]]
72+
// CHECK: [[func_cx_mul_dx]] = OpFMul
73+
// CHECK: OpStore %param_var_j [[func_cx_mul_dx]]
74+
// CHECK: OpFunctionCall %float %func4 %param_var_i %param_var_j
6775
func4(a.x * b.x, c.x * d.x, v.x);
6876
}
6977

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %dxc -T vs_6_0 -E VSMain %s -fcgl -spirv | FileCheck %s
2+
3+
struct VSInput
4+
{
5+
float4 pos : ATTRIBUTE0;
6+
};
7+
8+
float4x4 Proj;
9+
10+
precise float4 MakePrecise(precise float4 v) { return v; }
11+
12+
// CHECK: OpDecorate [[mul:%[0-9]+]] NoContraction
13+
14+
void VSMain(VSInput input, out precise float4 OutputPos : SV_Position)
15+
{
16+
// CHECK: [[mul]] = OpMatrixTimesVector
17+
// CHECK: OpStore %param_var_v [[mul]]
18+
// CHECK: OpFunctionCall %v4float %MakePrecise %param_var_v
19+
OutputPos = MakePrecise(mul(input.pos, Proj));
20+
}

0 commit comments

Comments
 (0)