Skip to content

Commit

Permalink
[SPIR-V] Fix cast elision with initializer lists (#6992)
Browse files Browse the repository at this point in the history
When an a chain of casts were performed in an initializer list, only the
source and destination types were considered. This means float -> uint
was the same as float -> int -> uint. This however is not correct:
intermediate casts can change the result.

Removing the shortcut we took solves this issue.

Fixes #6975

Signed-off-by: Nathan Gauër <[email protected]>
  • Loading branch information
Keenuts authored Nov 1, 2024
1 parent 5704c47 commit ac36a79
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 43 deletions.
5 changes: 0 additions & 5 deletions tools/clang/lib/SPIRV/InitListHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,6 @@ void InitListHandler::flatten(const InitListExpr *expr) {
const Expr *init = expr->getInit(i);
if (const auto *subInitList = dyn_cast<InitListExpr>(init)) {
flatten(subInitList);
} else if (const auto *subInitList = dyn_cast<InitListExpr>(
// Ignore constructor casts which are no-ops
// For cases like: <type>(<initializer-list>)
init->IgnoreParenNoopCasts(theEmitter.getASTContext()))) {
flatten(subInitList);
} else {
auto *initializer = theEmitter.loadIfGLValue(init);
if (!initializer) {
Expand Down
38 changes: 38 additions & 0 deletions tools/clang/test/CodeGenSPIRV/init.list.cast.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: %dxc -T cs_6_6 -E main -fcgl %s -spirv | FileCheck %s

RWStructuredBuffer<float> buffer;
RWStructuredBuffer<float4> buffer4;

[numthreads(1, 1, 1)]
void main() {
{
// CHECK: [[f:%[0-9]+]] = OpLoad %float {{.*}}
// CHECK: [[s:%[0-9]+]] = OpConvertFToS %int [[f]]
// CHECK: [[u:%[0-9]+]] = OpBitcast %uint [[s]]
// CHECK: OpStore {{.*}} [[u]]
uint p = uint(int(buffer[0]));
}

{
// CHECK: [[f:%[0-9]+]] = OpLoad %v4float {{.*}}
// CHECK: [[s:%[0-9]+]] = OpConvertFToS %v4int [[f]]
// CHECK: [[u:%[0-9]+]] = OpBitcast %v4uint [[s]]
// CHECK: OpStore {{.*}} [[u]]
uint4 p4 = uint4(int4(buffer4[0]));
}

{
// CHECK: [[f:%[0-9]+]] = OpLoad %v4float {{.*}}
// CHECK: [[s:%[0-9]+]] = OpConvertFToS %v4int [[f]]
// CHECK: [[u:%[0-9]+]] = OpBitcast %v4uint [[s]]
// CHECK: OpStore {{.*}} [[u]]
uint4 p4 = int4(buffer4[0]);
}

{
// CHECK: [[f:%[0-9]+]] = OpLoad %v4float {{.*}}
// CHECK: [[u:%[0-9]+]] = OpConvertFToU %v4uint [[f]]
// CHECK: OpStore {{.*}} [[u]]
uint4 p4 = uint4(uint4(buffer4[0]));
}
}
44 changes: 26 additions & 18 deletions tools/clang/test/CodeGenSPIRV/shader.debug.line.composite.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -45,71 +45,79 @@ void main() {

int4 a = {
float2(1, 0),
// CHECK: DebugLine [[src]] %uint_50 %uint_50 %uint_7 %uint_19
// CHECK: OpFunctionCall %int4_bool_float3_0 %test_struct
// CHECK: DebugLine [[src]] %uint_51 %uint_51 %uint_7 %uint_19
// CHECK-NEXT: OpFunctionCall %int4_bool_float3_0 %test_struct
// CHECK: OpVectorShuffle %v2float
test_struct().c.zx
// CHECK: OpCompositeExtract %float {{%[0-9]+}} 0
// CHECK: DebugLine [[src]] %uint_46 %uint_46 %uint_12 %uint_12
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 0
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 1
// CHECK-NEXT: DebugLine [[src]] %uint_46 %uint_46 %uint_12 %uint_12
// CHECK-NEXT: OpConvertFToS %int
// CHECK-NEXT: OpConvertFToS %int
// CHECK: DebugLine [[src]] %uint_51 %uint_51 %uint_7 %uint_23
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 0
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 1
// CHECK: DebugLine [[src]] %uint_46 %uint_46 %uint_12 %uint_12
// CHECK-NEXT: OpConvertFToS %int
// CHECK-NEXT: OpConvertFToS %int
// CHECK: DebugLine [[src]] %uint_46 %uint_65 %uint_12 %uint_3
// CHECK: OpCompositeConstruct %v4int
};

// CHECK: OpFDiv %float {{%[0-9]+}} %float_2
// CHECK-NEXT: DebugLine [[src]] %uint_64 %uint_64 %uint_16 %uint_57
// CHECK-NEXT: DebugLine [[src]] %uint_72 %uint_72 %uint_16 %uint_57
// CHECK-NEXT: [[first:%[0-9]+]] = OpCompositeConstruct %v2float {{%[0-9]+}} {{%[0-9]+}}
// CHECK-NEXT: [[second:%[0-9]+]] = OpCompositeConstruct %v2float {{%[0-9]+}} {{%[0-9]+}}
// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %mat2v2float [[first]] [[second]]
float2x2 b = float2x2(a.x, b._m00, 2 + a.y, b._m11 / 2);

// CHECK: DebugLine [[src]] %uint_69 %uint_69 %uint_12 %uint_14
// CHECK: DebugLine [[src]] %uint_77 %uint_77 %uint_12 %uint_14
// CHECK-NEXT: [[y:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int4_bool_float3 %CONSTANTS %int_0
// CHECK-NEXT: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform_v4int [[y]] %int_0
int4 c = y.a;

// CHECK: DebugLine [[src]] %uint_76 %uint_76 %uint_3 %uint_3
// CHECK: DebugLine [[src]] %uint_84 %uint_84 %uint_3 %uint_3
// CHECK-NEXT: [[z:%[0-9]+]] = OpLoad %type_2d_image %z
// CHECK-NEXT: [[z_0:%[0-9]+]] = OpImageRead %v4int [[z]] {{%[0-9]+}} None
// CHECK-NEXT: [[z_1:%[0-9]+]] = OpVectorShuffle %v3int [[z_0]] [[z_0]] 0 1 2
// CHECK: {{%[0-9]+}} = OpCompositeInsert %v3int %int_16 [[z_1]] 0
z[uint2(2, 3)].x = 16;

// CHECK: DebugLine [[src]] %uint_82 %uint_82 %uint_3 %uint_4
// CHECK: DebugLine [[src]] %uint_90 %uint_90 %uint_3 %uint_4
// CHECK-NEXT: OpLoad %mat2v2float %b
// CHECK: DebugLine [[src]] %uint_82 %uint_82 %uint_3 %uint_4
// CHECK: DebugLine [[src]] %uint_90 %uint_90 %uint_3 %uint_4
// CHECK-NEXT: OpFSub %v2float
b--;

int2x2 d;
// CHECK: DebugLine [[src]] %uint_91 %uint_91 %uint_8 %uint_8
// CHECK: DebugLine [[src]] %uint_99 %uint_99 %uint_8 %uint_8
// CHECK-NEXT: OpLoad %mat2v2float %b
// CHECK-NEXT: DebugLine [[src]] %uint_91 %uint_91 %uint_3 %uint_12
// CHECK-NEXT: DebugLine [[src]] %uint_99 %uint_99 %uint_3 %uint_12
// CHECK-NEXT: OpCompositeExtract %v2float
// CHECK: OpCompositeConstruct %_arr_v2int_uint_2
// CHECK-NEXT: OpStore %d
modf(b, d);

// CHECK-TODO: DebugLine [[src]] %uint_95 %uint_95 %uint_3 %uint_11
// CHECK-TODO: DebugLine [[src]] %uint_103 %uint_103 %uint_3 %uint_11
// CHECK-NEXT-TODO: OpFunctionCall %void %S_inc %foo
// TODO(greg-lunarg): foo.inc();

// CHECK-TODO: DebugLine [[src]] %uint_99 %uint_99 %uint_3 %uint_14
// CHECK-TODO: DebugLine [[src]] %uint_107 %uint_107 %uint_3 %uint_14
// CHECK-NEXT-TODO: OpFunctionCall %void %S_inc %temp_var_S
// TODO(greg-lunarg): getS().inc();

// CHECK: DebugLine [[src]] %uint_105 %uint_105 %uint_19 %uint_19
// CHECK: DebugLine [[src]] %uint_113 %uint_113 %uint_19 %uint_19
// CHECK-NEXT: OpLoad %init %bar
// CHECK: DebugLine [[src]] %uint_105 %uint_105 %uint_12 %uint_12
// CHECK: DebugLine [[src]] %uint_113 %uint_113 %uint_12 %uint_12
// CHECK-NEXT: OpConvertFToS %int
int4 e = {1, 2, bar};

// CHECK: DebugLine [[src]] %uint_111 %uint_111 %uint_7 %uint_25
// CHECK: DebugLine [[src]] %uint_119 %uint_119 %uint_7 %uint_25
// CHECK-NEXT: OpCompositeConstruct %v2float %float_1 %float_2
// CHECK-NEXT: DebugLine [[src]] %uint_111 %uint_111 %uint_22 %uint_22
// CHECK-NEXT: DebugLine [[src]] %uint_119 %uint_119 %uint_22 %uint_22
// CHECK-NEXT: OpCompositeExtract %int
b = float2x2(1, 2, bar);
// CHECK: DebugLine [[src]] %uint_111 %uint_111 %uint_3 %uint_25
// CHECK: DebugLine [[src]] %uint_119 %uint_119 %uint_3 %uint_25
// CHECK-NEXT: OpStore %b

// TODO(jaebaek): Update InitListHandler to properly emit debug info.
Expand Down
34 changes: 19 additions & 15 deletions tools/clang/test/CodeGenSPIRV/spirv.debug.opline.composite.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -53,63 +53,67 @@ void main() {
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 1
// CHECK-NEXT: OpConvertFToS %int
// CHECK-NEXT: OpConvertFToS %int
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 0
// CHECK-NEXT: OpCompositeExtract %float {{%[0-9]+}} 1
// CHECK-NEXT: OpConvertFToS %int
// CHECK-NEXT: OpConvertFToS %int
// CHECK-NEXT: OpCompositeConstruct %v4int
};

// CHECK: OpFDiv %float {{%[0-9]+}} %float_2
// CHECK-NEXT: OpLine [[file]] 64 24
// CHECK-NEXT: OpLine [[file]] 68 24
// CHECK-NEXT: [[first:%[0-9]+]] = OpCompositeConstruct %v2float {{%[0-9]+}} {{%[0-9]+}}
// CHECK-NEXT: [[second:%[0-9]+]] = OpCompositeConstruct %v2float {{%[0-9]+}} {{%[0-9]+}}
// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %mat2v2float [[first]] [[second]]
float2x2 b = float2x2(a.x, b._m00, 2 + a.y, b._m11 / 2);

// CHECK: OpLine [[file]] 69 12
// CHECK: OpLine [[file]] 73 12
// CHECK-NEXT: [[y:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int4_bool_float3 %CONSTANTS %int_0
// CHECK-NEXT: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform_v4int [[y]] %int_0
int4 c = y.a;

// CHECK: OpLine [[file]] 76 3
// CHECK: OpLine [[file]] 80 3
// CHECK-NEXT: [[z:%[0-9]+]] = OpLoad %type_2d_image %z
// CHECK-NEXT: [[z_0:%[0-9]+]] = OpImageRead %v4int [[z]] {{%[0-9]+}} None
// CHECK-NEXT: [[z_1:%[0-9]+]] = OpVectorShuffle %v3int [[z_0]] [[z_0]] 0 1 2
// CHECK-NEXT: {{%[0-9]+}} = OpCompositeInsert %v3int %int_16 [[z_1]] 0
z[uint2(2, 3)].x = 16;

// CHECK: OpLine [[file]] 82 3
// CHECK: OpLine [[file]] 86 3
// CHECK-NEXT: OpLoad %mat2v2float %b
// CHECK: OpLine [[file]] 82 4
// CHECK: OpLine [[file]] 86 4
// CHECK-NEXT: OpFSub %v2float
b--;

int2x2 d;
// CHECK: OpLine [[file]] 91 8
// CHECK: OpLine [[file]] 95 8
// CHECK-NEXT: OpLoad %mat2v2float %b
// CHECK-NEXT: OpLine [[file]] 91 3
// CHECK-NEXT: OpLine [[file]] 95 3
// CHECK-NEXT: OpCompositeExtract %v2float
// CHECK: OpLine [[file]] 91 11
// CHECK: OpLine [[file]] 95 11
// CHECK: OpStore %d
modf(b, d);

// CHECK: OpLine [[file]] 95 7
// CHECK: OpLine [[file]] 99 7
// CHECK-NEXT: OpFunctionCall %void %S_inc %foo
foo.inc();

// CHECK: OpLine [[file]] 99 10
// CHECK: OpLine [[file]] 103 10
// CHECK-NEXT: OpFunctionCall %void %S_inc %temp_var_S
getS().inc();

// CHECK: OpLine [[file]] 105 19
// CHECK: OpLine [[file]] 109 19
// CHECK-NEXT: OpLoad %init %bar
// CHECK: OpLine [[file]] 105 12
// CHECK: OpLine [[file]] 109 12
// CHECK-NEXT: OpConvertFToS %int
int4 e = {1, 2, bar};

// CHECK: OpLine [[file]] 111 15
// CHECK: OpLine [[file]] 115 15
// CHECK-NEXT: OpCompositeConstruct %v2float %float_1 %float_2
// CHECK-NEXT: OpLine [[file]] 111 22
// CHECK-NEXT: OpLine [[file]] 115 22
// CHECK-NEXT: OpCompositeExtract %int
b = float2x2(1, 2, bar);
// CHECK: OpLine [[file]] 111 3
// CHECK: OpLine [[file]] 115 3
// CHECK-NEXT: OpStore %b

// TODO(jaebaek): Update InitListHandler to properly emit debug info.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %dxc -T ps_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s

// CHECK: [[const:%[0-9]+]] = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
struct A {};

template <typename T0, typename T1 = A>
Expand All @@ -9,7 +10,8 @@ struct B {
};

float4 main() : SV_Target {
// CHECK: {{%[0-9]+}} = OpCompositeConstruct %v4float %float_1 %float_2 %float_3 %float_4
// CHECK: [[A:%[0-9]+]] = OpCompositeConstruct %A
// CHECK: {{%[0-9]+}} = OpCompositeConstruct %B [[const]] [[A]]
B<float4> b = { float4(1, 2, 3, 4) };
return b.m0;
}
14 changes: 10 additions & 4 deletions tools/clang/test/CodeGenSPIRV/var.init.matrix.mxn.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
// TODO: optimize to generate constant composite for suitable initializers
// TODO: decompose matrix in initializer

// CHECK: [[v3fc1:%[0-9]+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
// CHECK-NEXT: [[v3fc0:%[0-9]+]] = OpConstantComposite %v3float %float_0 %float_0 %float_0
// CHECK-DAG: [[v3fc0:%[0-9]+]] = OpConstantComposite %v3float %float_0 %float_0 %float_0
// CHECK-DAG: [[f2_1_2:%[0-9]+]] = OpConstantComposite %v2float %float_1 %float_2
// CHECK-DAG: [[i2_1_2:%[0-9]+]] = OpConstantComposite %v2int %int_1 %int_2
// CHECK-DAG: [[v3fc1:%[0-9]+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1

void main() {
// CHECK-LABEL: %bb_entry = OpLabel
Expand Down Expand Up @@ -58,7 +60,9 @@ void main() {
// CHECK-NEXT: [[ce05:%[0-9]+]] = OpCompositeExtract %float [[vec2a]] 0
// CHECK-NEXT: [[ce06:%[0-9]+]] = OpCompositeExtract %float [[vec2a]] 1
// CHECK-NEXT: [[cc15:%[0-9]+]] = OpCompositeConstruct %v4float [[ce02]] [[ce03]] [[ce04]] [[ce05]]
// CHECK-NEXT: [[cc16:%[0-9]+]] = OpCompositeConstruct %v4float [[ce06]] %float_1 %float_2 %float_3
// CHECK-NEXT: [[f_1:%[0-9]+]] = OpCompositeExtract %float [[f2_1_2]] 0
// CHECK-NEXT: [[f_2:%[0-9]+]] = OpCompositeExtract %float [[f2_1_2]] 1
// CHECK-NEXT: [[cc16:%[0-9]+]] = OpCompositeConstruct %v4float [[ce06]] [[f_1]] [[f_2]] %float_3
// CHECK-NEXT: [[cc17:%[0-9]+]] = OpCompositeConstruct %mat4v4float [[cc14]] [[cc15]] [[cc16]] [[vec4]]
// CHECK-NEXT: OpStore %mat5 [[cc17]]
float4x4 mat5 = {scalar, vec1, vec2, // [0]
Expand Down Expand Up @@ -193,7 +197,9 @@ void main() {
// CHECK-NEXT: [[ce05_0:%[0-9]+]] = OpCompositeExtract %int [[vec2a_0]] 0
// CHECK-NEXT: [[ce06_0:%[0-9]+]] = OpCompositeExtract %int [[vec2a_0]] 1
// CHECK-NEXT: [[cc15_0:%[0-9]+]] = OpCompositeConstruct %v4int [[ce02_0]] [[ce03_0]] [[ce04_0]] [[ce05_0]]
// CHECK-NEXT: [[cc16_0:%[0-9]+]] = OpCompositeConstruct %v4int [[ce06_0]] %int_1 %int_2 %int_3
// CHECK-NEXT: [[i_1:%[0-9]+]] = OpCompositeExtract %int [[i2_1_2]] 0
// CHECK-NEXT: [[i_2:%[0-9]+]] = OpCompositeExtract %int [[i2_1_2]] 1
// CHECK-NEXT: [[cc16_0:%[0-9]+]] = OpCompositeConstruct %v4int [[ce06_0]] [[i_1]] [[i_2]] %int_3
// CHECK-NEXT: [[cc17_0:%[0-9]+]] = OpCompositeConstruct %_arr_v4int_uint_4 [[cc14_0]] [[cc15_0]] [[cc16_0]] [[vec4_0]]
// CHECK-NEXT: OpStore %imat5 [[cc17_0]]
int4x4 imat5 = {intScalar, intVec1, intVec2, // [0]
Expand Down

0 comments on commit ac36a79

Please sign in to comment.