Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make SRem sign aware like all the other arithmetic ops. #2397

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions reference/shaders-hlsl-no-opt/asm/frag/srem.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
static int oA;
static int A;
static uint B;
static uint oB;
static int C;
static uint D;

struct SPIRV_Cross_Input
{
nointerpolation int A : TEXCOORD0;
nointerpolation uint B : TEXCOORD1;
nointerpolation int C : TEXCOORD2;
nointerpolation uint D : TEXCOORD3;
};

struct SPIRV_Cross_Output
{
int oA : SV_Target0;
uint oB : SV_Target1;
};

void frag_main()
{
oB = uint(A - int(B) * (A / int(B)));
oB = uint(A - C * (A / C));
oB = uint(int(B) - int(D) * (int(B) / int(D)));
oB = uint(int(B) - A * (int(B) / A));
oA = A - int(B) * (A / int(B));
oA = A - C * (A / C);
oA = int(B) - int(D) * (int(B) / int(D));
oA = int(B) - A * (int(B) / A);
}

SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
A = stage_input.A;
B = stage_input.B;
C = stage_input.C;
D = stage_input.D;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.oA = oA;
stage_output.oB = oB;
return stage_output;
}
33 changes: 33 additions & 0 deletions reference/shaders-msl-no-opt/asm/frag/srem.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct main0_out
{
int oA [[color(0)]];
uint oB [[color(1)]];
};

struct main0_in
{
int A [[user(locn0)]];
uint B [[user(locn1)]];
int C [[user(locn2)]];
uint D [[user(locn3)]];
};

fragment main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
out.oB = uint(in.A - int(in.B) * (in.A / int(in.B)));
out.oB = uint(in.A - in.C * (in.A / in.C));
out.oB = uint(int(in.B) - int(in.D) * (int(in.B) / int(in.D)));
out.oB = uint(int(in.B) - in.A * (int(in.B) / in.A));
out.oA = in.A - int(in.B) * (in.A / int(in.B));
out.oA = in.A - in.C * (in.A / in.C);
out.oA = int(in.B) - int(in.D) * (int(in.B) / int(in.D));
out.oA = int(in.B) - in.A * (int(in.B) / in.A);
return out;
}

21 changes: 21 additions & 0 deletions reference/shaders-no-opt/asm/frag/srem.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#version 450

layout(location = 0) out int oA;
layout(location = 0) flat in int A;
layout(location = 1) flat in uint B;
layout(location = 1) out uint oB;
layout(location = 2) flat in int C;
layout(location = 3) flat in uint D;

void main()
{
oB = uint(A - int(B) * (A / int(B)));
oB = uint(A - C * (A / C));
oB = uint(int(B) - int(D) * (int(B) / int(D)));
oB = uint(int(B) - A * (int(B) / A));
oA = A - int(B) * (A / int(B));
oA = A - C * (A / C);
oA = int(B) - int(D) * (int(B) / int(D));
oA = int(B) - A * (int(B) / A);
}

66 changes: 66 additions & 0 deletions shaders-hlsl-no-opt/asm/frag/srem.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 30
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %oA %A %B %oB %C %D
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %oA "oA"
OpName %A "A"
OpName %B "B"
OpName %oB "oB"
OpName %C "C"
OpName %D "D"
OpDecorate %oA Location 0
OpDecorate %A Flat
OpDecorate %A Location 0
OpDecorate %B Flat
OpDecorate %B Location 1
OpDecorate %oB Location 1
OpDecorate %C Flat
OpDecorate %C Location 2
OpDecorate %D Flat
OpDecorate %D Location 3
%void = OpTypeVoid
%10 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Output_int = OpTypePointer Output %int
%oA = OpVariable %_ptr_Output_int Output
%_ptr_Input_int = OpTypePointer Input %int
%A = OpVariable %_ptr_Input_int Input
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%B = OpVariable %_ptr_Input_uint Input
%_ptr_Output_uint = OpTypePointer Output %uint
%oB = OpVariable %_ptr_Output_uint Output
%C = OpVariable %_ptr_Input_int Input
%D = OpVariable %_ptr_Input_uint Input
%main = OpFunction %void None %10
%17 = OpLabel
%18 = OpLoad %int %A
%19 = OpLoad %uint %B
%20 = OpLoad %int %C
%21 = OpLoad %uint %D
%22 = OpSRem %uint %18 %19
OpStore %oB %22
%23 = OpSRem %uint %18 %20
OpStore %oB %23
%24 = OpSRem %uint %19 %21
OpStore %oB %24
%25 = OpSRem %uint %19 %18
OpStore %oB %25
%26 = OpSRem %int %18 %19
OpStore %oA %26
%27 = OpSRem %int %18 %20
OpStore %oA %27
%28 = OpSRem %int %19 %21
OpStore %oA %28
%29 = OpSRem %int %19 %18
OpStore %oA %29
OpReturn
OpFunctionEnd
66 changes: 66 additions & 0 deletions shaders-msl-no-opt/asm/frag/srem.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 30
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %oA %A %B %oB %C %D
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %oA "oA"
OpName %A "A"
OpName %B "B"
OpName %oB "oB"
OpName %C "C"
OpName %D "D"
OpDecorate %oA Location 0
OpDecorate %A Flat
OpDecorate %A Location 0
OpDecorate %B Flat
OpDecorate %B Location 1
OpDecorate %oB Location 1
OpDecorate %C Flat
OpDecorate %C Location 2
OpDecorate %D Flat
OpDecorate %D Location 3
%void = OpTypeVoid
%10 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Output_int = OpTypePointer Output %int
%oA = OpVariable %_ptr_Output_int Output
%_ptr_Input_int = OpTypePointer Input %int
%A = OpVariable %_ptr_Input_int Input
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%B = OpVariable %_ptr_Input_uint Input
%_ptr_Output_uint = OpTypePointer Output %uint
%oB = OpVariable %_ptr_Output_uint Output
%C = OpVariable %_ptr_Input_int Input
%D = OpVariable %_ptr_Input_uint Input
%main = OpFunction %void None %10
%17 = OpLabel
%18 = OpLoad %int %A
%19 = OpLoad %uint %B
%20 = OpLoad %int %C
%21 = OpLoad %uint %D
%22 = OpSRem %uint %18 %19
OpStore %oB %22
%23 = OpSRem %uint %18 %20
OpStore %oB %23
%24 = OpSRem %uint %19 %21
OpStore %oB %24
%25 = OpSRem %uint %19 %18
OpStore %oB %25
%26 = OpSRem %int %18 %19
OpStore %oA %26
%27 = OpSRem %int %18 %20
OpStore %oA %27
%28 = OpSRem %int %19 %21
OpStore %oA %28
%29 = OpSRem %int %19 %18
OpStore %oA %29
OpReturn
OpFunctionEnd
66 changes: 66 additions & 0 deletions shaders-no-opt/asm/frag/srem.asm.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 30
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %oA %A %B %oB %C %D
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %oA "oA"
OpName %A "A"
OpName %B "B"
OpName %oB "oB"
OpName %C "C"
OpName %D "D"
OpDecorate %oA Location 0
OpDecorate %A Flat
OpDecorate %A Location 0
OpDecorate %B Flat
OpDecorate %B Location 1
OpDecorate %oB Location 1
OpDecorate %C Flat
OpDecorate %C Location 2
OpDecorate %D Flat
OpDecorate %D Location 3
%void = OpTypeVoid
%10 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Output_int = OpTypePointer Output %int
%oA = OpVariable %_ptr_Output_int Output
%_ptr_Input_int = OpTypePointer Input %int
%A = OpVariable %_ptr_Input_int Input
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%B = OpVariable %_ptr_Input_uint Input
%_ptr_Output_uint = OpTypePointer Output %uint
%oB = OpVariable %_ptr_Output_uint Output
%C = OpVariable %_ptr_Input_int Input
%D = OpVariable %_ptr_Input_uint Input
%main = OpFunction %void None %10
%17 = OpLabel
%18 = OpLoad %int %A
%19 = OpLoad %uint %B
%20 = OpLoad %int %C
%21 = OpLoad %uint %D
%22 = OpSRem %uint %18 %19
OpStore %oB %22
%23 = OpSRem %uint %18 %20
OpStore %oB %23
%24 = OpSRem %uint %19 %21
OpStore %oB %24
%25 = OpSRem %uint %19 %18
OpStore %oB %25
%26 = OpSRem %int %18 %19
OpStore %oA %26
%27 = OpSRem %int %18 %20
OpStore %oA %27
%28 = OpSRem %int %19 %21
OpStore %oA %28
%29 = OpSRem %int %19 %18
OpStore %oA %29
OpReturn
OpFunctionEnd
17 changes: 14 additions & 3 deletions spirv_glsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13229,13 +13229,24 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
uint32_t op0 = ops[2];
uint32_t op1 = ops[3];

// Needs special handling.
auto &out_type = get<SPIRType>(result_type);

bool forward = should_forward(op0) && should_forward(op1);
auto expr = join(to_enclosed_expression(op0), " - ", to_enclosed_expression(op1), " * ", "(",
to_enclosed_expression(op0), " / ", to_enclosed_expression(op1), ")");
string cast_op0, cast_op1;
auto expected_type = binary_op_bitcast_helper(cast_op0, cast_op1, int_type, op0, op1, false);

// Needs special handling.
auto expr = join(cast_op0, " - ", cast_op1, " * ", "(", cast_op0, " / ", cast_op1, ")");

if (implicit_integer_promotion)
{
expr = join(type_to_glsl(get<SPIRType>(result_type)), '(', expr, ')');
}
else if (out_type.basetype != int_type)
{
expected_type.basetype = int_type;
expr = join(bitcast_glsl_op(out_type, expected_type), '(', expr, ')');
}

emit_op(result_type, result_id, expr, forward);
inherit_expression_dependencies(result_id, op0);
Expand Down
Loading