Skip to content

Commit b75a988

Browse files
authored
[spirv] Translate HLSL round to RoundEven (#4515)
The specification for the HLSL round intrinsic function states "Rounds the specified value to the nearest integer. Halfway cases are rounded to the nearest even.", so translate it to RoundEven SPIR-V extended instruction rather than Round. Fixes #4368
1 parent 20ddfe8 commit b75a988

3 files changed

Lines changed: 12 additions & 11 deletions

File tree

docs/SPIR-V.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2364,7 +2364,7 @@ HLSL Intrinsic Function GLSL Extended Instruction
23642364
``pow`` ``Pow``
23652365
``reflect`` ``Reflect``
23662366
``refract`` ``Refract``
2367-
``round`` ``Round``
2367+
``round`` ``RoundEven``
23682368
``rsqrt`` ``InverseSqrt``
23692369
``saturate`` ``FClamp``
23702370
``sign`` ``SSign``/``FSign``

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8109,7 +8109,7 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
81098109
INTRINSIC_SPIRV_OP_CASE(fmod, FRem, true);
81108110
INTRINSIC_SPIRV_OP_CASE(fwidth, Fwidth, true);
81118111
INTRINSIC_SPIRV_OP_CASE(reversebits, BitReverse, false);
8112-
INTRINSIC_OP_CASE(round, Round, true);
8112+
INTRINSIC_OP_CASE(round, RoundEven, true);
81138113
INTRINSIC_OP_CASE(uabs, SAbs, true);
81148114
INTRINSIC_OP_CASE_INT_FLOAT(abs, SAbs, FAbs, true);
81158115
INTRINSIC_OP_CASE(acos, Acos, true);

tools/clang/test/CodeGenSPIRV/intrinsics.round.hlsl

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// According to HLSL reference:
44
// The 'round' function can only operate on float, vector of float, and matrix of float.
5+
// Rounds the specified value to the nearest integer. Halfway cases are rounded to the nearest even.
56

67
// CHECK: [[glsl:%\d+]] = OpExtInstImport "GLSL.std.450"
78

@@ -13,48 +14,48 @@ void main() {
1314
float3x2 result3x2;
1415

1516
// CHECK: [[a:%\d+]] = OpLoad %float %a
16-
// CHECK-NEXT: [[round_a:%\d+]] = OpExtInst %float [[glsl]] Round [[a]]
17+
// CHECK-NEXT: [[round_a:%\d+]] = OpExtInst %float [[glsl]] RoundEven [[a]]
1718
// CHECK-NEXT: OpStore %result [[round_a]]
1819
float a;
1920
result = round(a);
2021

2122
// CHECK-NEXT: [[b:%\d+]] = OpLoad %float %b
22-
// CHECK-NEXT: [[round_b:%\d+]] = OpExtInst %float [[glsl]] Round [[b]]
23+
// CHECK-NEXT: [[round_b:%\d+]] = OpExtInst %float [[glsl]] RoundEven [[b]]
2324
// CHECK-NEXT: OpStore %result [[round_b]]
2425
float1 b;
2526
result = round(b);
2627

2728
// CHECK-NEXT: [[c:%\d+]] = OpLoad %v3float %c
28-
// CHECK-NEXT: [[round_c:%\d+]] = OpExtInst %v3float [[glsl]] Round [[c]]
29+
// CHECK-NEXT: [[round_c:%\d+]] = OpExtInst %v3float [[glsl]] RoundEven [[c]]
2930
// CHECK-NEXT: OpStore %result3 [[round_c]]
3031
float3 c;
3132
result3 = round(c);
3233

3334
// CHECK-NEXT: [[d:%\d+]] = OpLoad %float %d
34-
// CHECK-NEXT: [[round_d:%\d+]] = OpExtInst %float [[glsl]] Round [[d]]
35+
// CHECK-NEXT: [[round_d:%\d+]] = OpExtInst %float [[glsl]] RoundEven [[d]]
3536
// CHECK-NEXT: OpStore %result [[round_d]]
3637
float1x1 d;
3738
result = round(d);
3839

3940
// CHECK-NEXT: [[e:%\d+]] = OpLoad %v2float %e
40-
// CHECK-NEXT: [[round_e:%\d+]] = OpExtInst %v2float [[glsl]] Round [[e]]
41+
// CHECK-NEXT: [[round_e:%\d+]] = OpExtInst %v2float [[glsl]] RoundEven [[e]]
4142
// CHECK-NEXT: OpStore %result2 [[round_e]]
4243
float1x2 e;
4344
result2 = round(e);
4445

4546
// CHECK-NEXT: [[f:%\d+]] = OpLoad %v4float %f
46-
// CHECK-NEXT: [[round_f:%\d+]] = OpExtInst %v4float [[glsl]] Round [[f]]
47+
// CHECK-NEXT: [[round_f:%\d+]] = OpExtInst %v4float [[glsl]] RoundEven [[f]]
4748
// CHECK-NEXT: OpStore %result4 [[round_f]]
4849
float4x1 f;
4950
result4 = round(f);
5051

5152
// CHECK-NEXT: [[g:%\d+]] = OpLoad %mat3v2float %g
5253
// CHECK-NEXT: [[g_row0:%\d+]] = OpCompositeExtract %v2float [[g]] 0
53-
// CHECK-NEXT: [[round_g_row0:%\d+]] = OpExtInst %v2float [[glsl]] Round [[g_row0]]
54+
// CHECK-NEXT: [[round_g_row0:%\d+]] = OpExtInst %v2float [[glsl]] RoundEven [[g_row0]]
5455
// CHECK-NEXT: [[g_row1:%\d+]] = OpCompositeExtract %v2float [[g]] 1
55-
// CHECK-NEXT: [[round_g_row1:%\d+]] = OpExtInst %v2float [[glsl]] Round [[g_row1]]
56+
// CHECK-NEXT: [[round_g_row1:%\d+]] = OpExtInst %v2float [[glsl]] RoundEven [[g_row1]]
5657
// CHECK-NEXT: [[g_row2:%\d+]] = OpCompositeExtract %v2float [[g]] 2
57-
// CHECK-NEXT: [[round_g_row2:%\d+]] = OpExtInst %v2float [[glsl]] Round [[g_row2]]
58+
// CHECK-NEXT: [[round_g_row2:%\d+]] = OpExtInst %v2float [[glsl]] RoundEven [[g_row2]]
5859
// CHECK-NEXT: [[round_matrix:%\d+]] = OpCompositeConstruct %mat3v2float [[round_g_row0]] [[round_g_row1]] [[round_g_row2]]
5960
// CHECK-NEXT: OpStore %result3x2 [[round_matrix]]
6061
float3x2 g;

0 commit comments

Comments
 (0)