forked from KhronosGroup/SPIRV-LLVM-Translator
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix OpFMod, implement OpSMod and add SPIR-V assembly tests
OpFMod(a, b) was implemented as copysign(frem(a, b), b), which is not a remainder as described in §2.2.3 Computation of the SPIR-V specification. For example, OpFMod(-1.0, 100.0) resulted in 1.0, but the correct result is 99.0. Likewise, OpFMod(1.0, -100.0) should result in -99.0, not -1.0. Fix this by adding the divisor ('b') if the signs of the operands differ and the result of frem(a, b) is non-zero. As frem(a, b) returns a result of the same sign as the dividend ('a'), the sign can be compared by taking the result of frem(a, b), copying the sign of the divisor to the result, and performing a test for equality to determine whether copying the sign modifies the value. If the divisor is infinity, then the result of the OpFMod operation will also be infinity. If either operand is a NaN, then the result will also be a NaN. If the result is infinity, a NaN, or zero, then it will have the correct sign (i.e. the sign of the dividend). This also implements OpSMod(a, b) in terms of srem(a, b). In this case, the sign is compared by comparing (a ^ b) < 0, which is true if and only if the sign bits differ.
- Loading branch information
1 parent
99e0a01
commit 4de4935
Showing
8 changed files
with
169 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
; REQUIRES: spirv-as | ||
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s | ||
; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s | ||
OpCapability Addresses | ||
OpCapability Kernel | ||
OpMemoryModel Physical32 OpenCL | ||
OpEntryPoint Kernel %1 "testFMod_f32" | ||
OpName %a "a" | ||
OpName %b "b" | ||
%void = OpTypeVoid | ||
%float = OpTypeFloat 32 | ||
%5 = OpTypeFunction %void %float %float | ||
%1 = OpFunction %void None %5 | ||
%a = OpFunctionParameter %float | ||
%b = OpFunctionParameter %float | ||
%6 = OpLabel | ||
%7 = OpFMod %float %a %b | ||
OpReturn | ||
OpFunctionEnd | ||
|
||
; CHECK-DAG: %frem.res = frem float %a, %b | ||
; CHECK-DAG: %copysign.res = call float @llvm.copysign.f32(float %frem.res, float %b) | ||
; CHECK-DAG: %fadd.res = fadd float {{%frem\.res, %b|%b, %frem\.res}} | ||
; CHECK-DAG: %cmp.res = fcmp one float {{%frem\.res, %copysign\.res|%copysign\.res, %frem\.res}} | ||
; CHECK: select i1 %cmp.res, float %fadd.res, float %copysign.res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
; REQUIRES: spirv-as | ||
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s | ||
; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s | ||
OpCapability Addresses | ||
OpCapability Kernel | ||
OpCapability Float16 | ||
OpMemoryModel Physical32 OpenCL | ||
OpEntryPoint Kernel %1 "testFMod_v2f16" | ||
OpName %a "a" | ||
OpName %b "b" | ||
%void = OpTypeVoid | ||
%half = OpTypeFloat 16 | ||
%half2 = OpTypeVector %half 2 | ||
%5 = OpTypeFunction %void %half2 %half2 | ||
%1 = OpFunction %void None %5 | ||
%a = OpFunctionParameter %half2 | ||
%b = OpFunctionParameter %half2 | ||
%6 = OpLabel | ||
%7 = OpFMod %half2 %a %b | ||
OpReturn | ||
OpFunctionEnd | ||
|
||
; CHECK-DAG: %frem.res = frem <2 x half> %a, %b | ||
; CHECK-DAG: %copysign.res = call <2 x half> @llvm.copysign.v2f16(<2 x half> %frem.res, <2 x half> %b) | ||
; CHECK-DAG: %fadd.res = fadd <2 x half> {{%frem\.res, %b|%b, %frem\.res}} | ||
; CHECK-DAG: %cmp.res = fcmp one <2 x half> {{%frem\.res, %copysign\.res|%copysign\.res, %frem\.res}} | ||
; CHECK: select <2 x i1> %cmp.res, <2 x half> %fadd.res, <2 x half> %copysign.res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
; REQUIRES: spirv-as | ||
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s | ||
; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s | ||
OpCapability Addresses | ||
OpCapability Kernel | ||
OpMemoryModel Physical32 OpenCL | ||
OpEntryPoint Kernel %1 "testSMod_i32" | ||
OpName %a "a" | ||
OpName %b "b" | ||
%void = OpTypeVoid | ||
%uint = OpTypeInt 32 0 | ||
%5 = OpTypeFunction %void %uint %uint | ||
%1 = OpFunction %void None %5 | ||
%a = OpFunctionParameter %uint | ||
%b = OpFunctionParameter %uint | ||
%6 = OpLabel | ||
%7 = OpSMod %uint %a %b | ||
OpReturn | ||
OpFunctionEnd | ||
|
||
; CHECK-DAG: %srem.res = srem i32 %a, %b | ||
; CHECK-DAG: %xor.res = xor i32 {{%a, %b|%b, %a}} | ||
; CHECK-DAG: %cmpsign.res = icmp slt i32 %xor.res, 0 | ||
; CHECK-DAG: %cmpsrem.res = icmp ne i32 {{%srem\.res, 0|0, %srem\.res}} | ||
; CHECK-DAG: %add.res = add nsw i32 {{%srem\.res, %b|%b, %srem\.res}} | ||
; CHECK-DAG: %cmp.res = and i1 {{%cmpsign\.res, %cmpsrem\.res|%cmpsrem\.res, %cmpsign\.res}} | ||
; CHECK: select i1 %cmp.res, i32 %add.res, i32 %srem.res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
; REQUIRES: spirv-as | ||
; RUN: spirv-as --target-env spv1.0 -o %t.spv %s | ||
; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s | ||
OpCapability Addresses | ||
OpCapability Kernel | ||
OpCapability Int16 | ||
OpMemoryModel Physical32 OpenCL | ||
OpEntryPoint Kernel %1 "testSMod_v2i16" | ||
OpName %a "a" | ||
OpName %b "b" | ||
%void = OpTypeVoid | ||
%ushort = OpTypeInt 16 0 | ||
%ushort2 = OpTypeVector %ushort 2 | ||
%5 = OpTypeFunction %void %ushort2 %ushort2 | ||
%1 = OpFunction %void None %5 | ||
%a = OpFunctionParameter %ushort2 | ||
%b = OpFunctionParameter %ushort2 | ||
%6 = OpLabel | ||
%7 = OpSMod %ushort2 %a %b | ||
OpReturn | ||
OpFunctionEnd | ||
|
||
; CHECK-DAG: %srem.res = srem <2 x i16> %a, %b | ||
; CHECK-DAG: %xor.res = xor <2 x i16> {{%a, %b|%b, %a}} | ||
; CHECK-DAG: %cmpsign.res = icmp slt <2 x i16> %xor.res, zeroinitializer | ||
; CHECK-DAG: %cmpsrem.res = icmp ne <2 x i16> {{%srem\.res, zeroinitializer|zeroinitializer, %srem\.res}} | ||
; CHECK-DAG: %add.res = add nsw <2 x i16> {{%srem\.res, %b|%b, %srem\.res}} | ||
; CHECK-DAG: %cmp.res = and <2 x i1> {{%cmpsign\.res, %cmpsrem\.res|%cmpsrem\.res, %cmpsign\.res}} | ||
; CHECK: select <2 x i1> %cmp.res, <2 x i16> %add.res, <2 x i16> %srem.res |