[SPIRV] Add sign intrinsic part 1 - #101987
Merged
Merged
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
This was referenced Aug 5, 2024
tgymnich
marked this pull request as ready for review
August 5, 2024 14:26
Member
|
@llvm/pr-subscribers-llvm-ir Author: Tim Gymnich (tgymnich) Changespartially fixes #70078 Changes
Related PRsFull diff: https://github.com/llvm/llvm-project/pull/101987.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 3f77ef6bfcdbe..89eacf2ba70f9 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -65,4 +65,5 @@ let TargetPrefix = "spv" in {
[IntrNoMem, IntrWillReturn] >;
def int_spv_length : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [llvm_anyfloat_ty]>;
def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>;
+ def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty]>;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index ed786bd33aa05..47e4b3dd40339 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -28,6 +28,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/Support/Debug.h"
@@ -178,6 +179,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
bool selectRsqrt(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
+ bool selectSign(Register ResVReg, const SPIRVType *ResType,
+ MachineInstr &I) const;
+
void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
int OpIdx) const;
void renderFImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
@@ -1366,6 +1370,52 @@ bool SPIRVInstructionSelector::selectRsqrt(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
}
+bool SPIRVInstructionSelector::selectSign(Register ResVReg,
+ const SPIRVType *ResType,
+ MachineInstr &I) const {
+ assert(I.getNumOperands() == 3);
+ assert(I.getOperand(2).isReg());
+ MachineBasicBlock &BB = *I.getParent();
+ Register InputRegister = I.getOperand(2).getReg();
+ SPIRVType *InputType = GR.getSPIRVTypeForVReg(InputRegister);
+ auto &DL = I.getDebugLoc();
+
+ if (!InputType)
+ report_fatal_error("Input Type could not be determined.");
+
+ bool IsFloatTy = GR.isScalarOrVectorOfType(InputRegister, SPIRV::OpTypeFloat);
+
+ unsigned SignBitWidth = GR.getScalarOrVectorBitWidth(InputType);
+ unsigned ResBitWidth = GR.getScalarOrVectorBitWidth(ResType);
+
+ bool NeedsConversion = IsFloatTy || SignBitWidth != ResBitWidth;
+
+ auto SignOpcode = IsFloatTy ? GL::FSign : GL::SSign;
+ Register SignReg = NeedsConversion
+ ? MRI->createVirtualRegister(&SPIRV::IDRegClass)
+ : ResVReg;
+
+ bool Result =
+ BuildMI(BB, I, DL, TII.get(SPIRV::OpExtInst))
+ .addDef(SignReg)
+ .addUse(GR.getSPIRVTypeID(InputType))
+ .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
+ .addImm(SignOpcode)
+ .addUse(InputRegister)
+ .constrainAllUses(TII, TRI, RBI);
+
+ if (NeedsConversion) {
+ auto ConvertOpcode = IsFloatTy ? SPIRV::OpConvertFToS : SPIRV::OpSConvert;
+ Result |= BuildMI(*I.getParent(), I, DL, TII.get(ConvertOpcode))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(SignReg)
+ .constrainAllUses(TII, TRI, RBI);
+ }
+
+ return Result;
+}
+
bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
@@ -2082,6 +2132,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
return selectFrac(ResVReg, ResType, I);
case Intrinsic::spv_rsqrt:
return selectRsqrt(ResVReg, ResType, I);
+ case Intrinsic::spv_sign:
+ return selectSign(ResVReg, ResType, I);
case Intrinsic::spv_lifetime_start:
case Intrinsic::spv_lifetime_end: {
unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.ll
new file mode 100644
index 0000000000000..52a41c3d3ad64
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.ll
@@ -0,0 +1,143 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
+
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
+
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
+
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
+; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
+
+
+define noundef i32 @sign_half(half noundef %a) {
+entry:
+; CHECK: %[[#float_16_arg:]] = OpFunctionParameter %[[#float_16]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] FSign %[[#float_16_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#int_32]] %[[#fsign]]
+ %elt.sign = call i32 @llvm.spv.sign.f16(half %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_float(float noundef %a) {
+entry:
+; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] FSign %[[#float_32_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#int_32]] %[[#fsign]]
+ %elt.sign = call i32 @llvm.spv.sign.f32(float %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_double(double noundef %a) {
+entry:
+; CHECK: %[[#float_64_arg:]] = OpFunctionParameter %[[#float_64]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#float_64]] %[[#op_ext_glsl]] FSign %[[#float_64_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#int_32]] %[[#fsign]]
+ %elt.sign = call i32 @llvm.spv.sign.f64(double %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_i16(i16 noundef %a) {
+entry:
+; CHECK: %[[#int_16_arg:]] = OpFunctionParameter %[[#int_16]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#int_16]] %[[#op_ext_glsl]] SSign %[[#int_16_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#int_32]] %[[#ssign]]
+ %elt.sign = call i32 @llvm.spv.sign.i16(i16 %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_i32(i32 noundef %a) {
+entry:
+; CHECK: %[[#int_32_arg:]] = OpFunctionParameter %[[#int_32]]
+; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext_glsl]] SSign %[[#int_32_arg]]
+ %elt.sign = call i32 @llvm.spv.sign.i32(i32 %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_i64(i64 noundef %a) {
+entry:
+; CHECK: %[[#int_64_arg:]] = OpFunctionParameter %[[#int_64]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#int_64]] %[[#op_ext_glsl]] SSign %[[#int_64_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#int_32]] %[[#ssign]]
+ %elt.sign = call i32 @llvm.spv.sign.i64(i64 %a)
+ ret i32 %elt.sign
+}
+
+define noundef <4 x i32> @sign_half_vector(<4 x half> noundef %a) {
+entry:
+; CHECK: %[[#vec4_float_16_arg:]] = OpFunctionParameter %[[#vec4_float_16]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] FSign %[[#vec4_float_16_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#vec4_int_32]] %[[#fsign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4f16(<4 x half> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_float_vector(<4 x float> noundef %a) {
+entry:
+; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] FSign %[[#vec4_float_32_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#vec4_int_32]] %[[#fsign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4f32(<4 x float> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_double_vector(<4 x double> noundef %a) {
+entry:
+; CHECK: %[[#vec4_float_64_arg:]] = OpFunctionParameter %[[#vec4_float_64]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext_glsl]] FSign %[[#vec4_float_64_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#vec4_int_32]] %[[#fsign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4f64(<4 x double> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_i16_vector(<4 x i16> noundef %a) {
+entry:
+; CHECK: %[[#vec4_int_16_arg:]] = OpFunctionParameter %[[#vec4_int_16]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext_glsl]] SSign %[[#vec4_int_16_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#vec4_int_32]] %[[#ssign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4i16(<4 x i16> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_i32_vector(<4 x i32> noundef %a) {
+entry:
+; CHECK: %[[#vec4_int_32_arg:]] = OpFunctionParameter %[[#vec4_int_32]]
+; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext_glsl]] SSign %[[#vec4_int_32_arg]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4i32(<4 x i32> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_i64_vector(<4 x i64> noundef %a) {
+entry:
+; CHECK: %[[#vec4_int_64_arg:]] = OpFunctionParameter %[[#vec4_int_64]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext_glsl]] SSign %[[#vec4_int_64_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#vec4_int_32]] %[[#ssign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4i64(<4 x i64> %a)
+ ret <4 x i32> %elt.sign
+}
+
+declare i32 @llvm.spv.sign.f16(half)
+declare i32 @llvm.spv.sign.f32(float)
+declare i32 @llvm.spv.sign.f64(double)
+
+declare i32 @llvm.spv.sign.i16(i16)
+declare i32 @llvm.spv.sign.i32(i32)
+declare i32 @llvm.spv.sign.i64(i64)
+
+declare <4 x i32> @llvm.spv.sign.v4f16(<4 x half>)
+declare <4 x i32> @llvm.spv.sign.v4f32(<4 x float>)
+declare <4 x i32> @llvm.spv.sign.v4f64(<4 x double>)
+
+declare <4 x i32> @llvm.spv.sign.v4i16(<4 x i16>)
+declare <4 x i32> @llvm.spv.sign.v4i32(<4 x i32>)
+declare <4 x i32> @llvm.spv.sign.v4i64(<4 x i64>)
|
Member
|
@llvm/pr-subscribers-backend-spir-v Author: Tim Gymnich (tgymnich) Changespartially fixes #70078 Changes
Related PRsFull diff: https://github.com/llvm/llvm-project/pull/101987.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 3f77ef6bfcdbe..89eacf2ba70f9 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -65,4 +65,5 @@ let TargetPrefix = "spv" in {
[IntrNoMem, IntrWillReturn] >;
def int_spv_length : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [llvm_anyfloat_ty]>;
def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]>;
+ def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty]>;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index ed786bd33aa05..47e4b3dd40339 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -28,6 +28,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/Support/Debug.h"
@@ -178,6 +179,9 @@ class SPIRVInstructionSelector : public InstructionSelector {
bool selectRsqrt(Register ResVReg, const SPIRVType *ResType,
MachineInstr &I) const;
+ bool selectSign(Register ResVReg, const SPIRVType *ResType,
+ MachineInstr &I) const;
+
void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
int OpIdx) const;
void renderFImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
@@ -1366,6 +1370,52 @@ bool SPIRVInstructionSelector::selectRsqrt(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
}
+bool SPIRVInstructionSelector::selectSign(Register ResVReg,
+ const SPIRVType *ResType,
+ MachineInstr &I) const {
+ assert(I.getNumOperands() == 3);
+ assert(I.getOperand(2).isReg());
+ MachineBasicBlock &BB = *I.getParent();
+ Register InputRegister = I.getOperand(2).getReg();
+ SPIRVType *InputType = GR.getSPIRVTypeForVReg(InputRegister);
+ auto &DL = I.getDebugLoc();
+
+ if (!InputType)
+ report_fatal_error("Input Type could not be determined.");
+
+ bool IsFloatTy = GR.isScalarOrVectorOfType(InputRegister, SPIRV::OpTypeFloat);
+
+ unsigned SignBitWidth = GR.getScalarOrVectorBitWidth(InputType);
+ unsigned ResBitWidth = GR.getScalarOrVectorBitWidth(ResType);
+
+ bool NeedsConversion = IsFloatTy || SignBitWidth != ResBitWidth;
+
+ auto SignOpcode = IsFloatTy ? GL::FSign : GL::SSign;
+ Register SignReg = NeedsConversion
+ ? MRI->createVirtualRegister(&SPIRV::IDRegClass)
+ : ResVReg;
+
+ bool Result =
+ BuildMI(BB, I, DL, TII.get(SPIRV::OpExtInst))
+ .addDef(SignReg)
+ .addUse(GR.getSPIRVTypeID(InputType))
+ .addImm(static_cast<uint32_t>(SPIRV::InstructionSet::GLSL_std_450))
+ .addImm(SignOpcode)
+ .addUse(InputRegister)
+ .constrainAllUses(TII, TRI, RBI);
+
+ if (NeedsConversion) {
+ auto ConvertOpcode = IsFloatTy ? SPIRV::OpConvertFToS : SPIRV::OpSConvert;
+ Result |= BuildMI(*I.getParent(), I, DL, TII.get(ConvertOpcode))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(SignReg)
+ .constrainAllUses(TII, TRI, RBI);
+ }
+
+ return Result;
+}
+
bool SPIRVInstructionSelector::selectBitreverse(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
@@ -2082,6 +2132,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
return selectFrac(ResVReg, ResType, I);
case Intrinsic::spv_rsqrt:
return selectRsqrt(ResVReg, ResType, I);
+ case Intrinsic::spv_sign:
+ return selectSign(ResVReg, ResType, I);
case Intrinsic::spv_lifetime_start:
case Intrinsic::spv_lifetime_end: {
unsigned Op = IID == Intrinsic::spv_lifetime_start ? SPIRV::OpLifetimeStart
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.ll
new file mode 100644
index 0000000000000..52a41c3d3ad64
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.ll
@@ -0,0 +1,143 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
+
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
+; CHECK-DAG: %[[#float_64:]] = OpTypeFloat 64
+
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16
+; CHECK-DAG: %[[#int_32:]] = OpTypeInt 32
+; CHECK-DAG: %[[#int_64:]] = OpTypeInt 64
+
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
+; CHECK-DAG: %[[#vec4_float_64:]] = OpTypeVector %[[#float_64]] 4
+
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+; CHECK-DAG: %[[#vec4_int_32:]] = OpTypeVector %[[#int_32]] 4
+; CHECK-DAG: %[[#vec4_int_64:]] = OpTypeVector %[[#int_64]] 4
+
+
+define noundef i32 @sign_half(half noundef %a) {
+entry:
+; CHECK: %[[#float_16_arg:]] = OpFunctionParameter %[[#float_16]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] FSign %[[#float_16_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#int_32]] %[[#fsign]]
+ %elt.sign = call i32 @llvm.spv.sign.f16(half %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_float(float noundef %a) {
+entry:
+; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] FSign %[[#float_32_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#int_32]] %[[#fsign]]
+ %elt.sign = call i32 @llvm.spv.sign.f32(float %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_double(double noundef %a) {
+entry:
+; CHECK: %[[#float_64_arg:]] = OpFunctionParameter %[[#float_64]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#float_64]] %[[#op_ext_glsl]] FSign %[[#float_64_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#int_32]] %[[#fsign]]
+ %elt.sign = call i32 @llvm.spv.sign.f64(double %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_i16(i16 noundef %a) {
+entry:
+; CHECK: %[[#int_16_arg:]] = OpFunctionParameter %[[#int_16]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#int_16]] %[[#op_ext_glsl]] SSign %[[#int_16_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#int_32]] %[[#ssign]]
+ %elt.sign = call i32 @llvm.spv.sign.i16(i16 %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_i32(i32 noundef %a) {
+entry:
+; CHECK: %[[#int_32_arg:]] = OpFunctionParameter %[[#int_32]]
+; CHECK: %[[#]] = OpExtInst %[[#int_32]] %[[#op_ext_glsl]] SSign %[[#int_32_arg]]
+ %elt.sign = call i32 @llvm.spv.sign.i32(i32 %a)
+ ret i32 %elt.sign
+}
+
+define noundef i32 @sign_i64(i64 noundef %a) {
+entry:
+; CHECK: %[[#int_64_arg:]] = OpFunctionParameter %[[#int_64]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#int_64]] %[[#op_ext_glsl]] SSign %[[#int_64_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#int_32]] %[[#ssign]]
+ %elt.sign = call i32 @llvm.spv.sign.i64(i64 %a)
+ ret i32 %elt.sign
+}
+
+define noundef <4 x i32> @sign_half_vector(<4 x half> noundef %a) {
+entry:
+; CHECK: %[[#vec4_float_16_arg:]] = OpFunctionParameter %[[#vec4_float_16]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] FSign %[[#vec4_float_16_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#vec4_int_32]] %[[#fsign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4f16(<4 x half> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_float_vector(<4 x float> noundef %a) {
+entry:
+; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] FSign %[[#vec4_float_32_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#vec4_int_32]] %[[#fsign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4f32(<4 x float> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_double_vector(<4 x double> noundef %a) {
+entry:
+; CHECK: %[[#vec4_float_64_arg:]] = OpFunctionParameter %[[#vec4_float_64]]
+; CHECK: %[[#fsign:]] = OpExtInst %[[#vec4_float_64]] %[[#op_ext_glsl]] FSign %[[#vec4_float_64_arg]]
+; CHECK: %[[#]] = OpConvertFToS %[[#vec4_int_32]] %[[#fsign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4f64(<4 x double> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_i16_vector(<4 x i16> noundef %a) {
+entry:
+; CHECK: %[[#vec4_int_16_arg:]] = OpFunctionParameter %[[#vec4_int_16]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#vec4_int_16]] %[[#op_ext_glsl]] SSign %[[#vec4_int_16_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#vec4_int_32]] %[[#ssign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4i16(<4 x i16> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_i32_vector(<4 x i32> noundef %a) {
+entry:
+; CHECK: %[[#vec4_int_32_arg:]] = OpFunctionParameter %[[#vec4_int_32]]
+; CHECK: %[[#]] = OpExtInst %[[#vec4_int_32]] %[[#op_ext_glsl]] SSign %[[#vec4_int_32_arg]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4i32(<4 x i32> %a)
+ ret <4 x i32> %elt.sign
+}
+
+define noundef <4 x i32> @sign_i64_vector(<4 x i64> noundef %a) {
+entry:
+; CHECK: %[[#vec4_int_64_arg:]] = OpFunctionParameter %[[#vec4_int_64]]
+; CHECK: %[[#ssign:]] = OpExtInst %[[#vec4_int_64]] %[[#op_ext_glsl]] SSign %[[#vec4_int_64_arg]]
+; CHECK: %[[#]] = OpSConvert %[[#vec4_int_32]] %[[#ssign]]
+ %elt.sign = call <4 x i32> @llvm.spv.sign.v4i64(<4 x i64> %a)
+ ret <4 x i32> %elt.sign
+}
+
+declare i32 @llvm.spv.sign.f16(half)
+declare i32 @llvm.spv.sign.f32(float)
+declare i32 @llvm.spv.sign.f64(double)
+
+declare i32 @llvm.spv.sign.i16(i16)
+declare i32 @llvm.spv.sign.i32(i32)
+declare i32 @llvm.spv.sign.i64(i64)
+
+declare <4 x i32> @llvm.spv.sign.v4f16(<4 x half>)
+declare <4 x i32> @llvm.spv.sign.v4f32(<4 x float>)
+declare <4 x i32> @llvm.spv.sign.v4f64(<4 x double>)
+
+declare <4 x i32> @llvm.spv.sign.v4i16(<4 x i16>)
+declare <4 x i32> @llvm.spv.sign.v4i32(<4 x i32>)
+declare <4 x i32> @llvm.spv.sign.v4i64(<4 x i64>)
|
farzonl
reviewed
Aug 11, 2024
tgymnich
force-pushed
the
hlsl-sign-1
branch
2 times, most recently
from
August 29, 2024 18:18
cac6f19 to
87eb441
Compare
tgymnich
force-pushed
the
hlsl-sign-1
branch
from
September 5, 2024 09:28
87eb441 to
58ef468
Compare
farzonl
pushed a commit
that referenced
this pull request
Sep 5, 2024
farzonl
pushed a commit
that referenced
this pull request
Sep 10, 2024
partially fixes #70078 ### Changes - Implemented `sign` clang builtin - Linked `sign` clang builtin with `hlsl_intrinsics.h` - Added sema checks for `sign` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp` - Add codegen for `sign` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp` - Add codegen tests to `clang/test/CodeGenHLSL/builtins/sign.hlsl` - Add sema tests to `clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl` ### Related PRs - #101987 - #101988 ### Discussion - Should there be a `usign` intrinsic that handles the unsigned cases?
farzonl
pushed a commit
that referenced
this pull request
Oct 10, 2024
- Add handling for unsigned integers to hlsl_elementwise_sign - Use `select` instead of adding dx and spirv intrinsics for unsigned integers as [discussed previously ](#101988 (comment)) fixes #70078 ### Related PRs - #101987 - #101988 - #101989 cc @farzonl @pow2clk @bob80905 @bogner @llvm-beanz
DanielCChen
pushed a commit
to DanielCChen/llvm-project
that referenced
this pull request
Oct 16, 2024
- Add handling for unsigned integers to hlsl_elementwise_sign - Use `select` instead of adding dx and spirv intrinsics for unsigned integers as [discussed previously ](llvm#101988 (comment)) fixes llvm#70078 ### Related PRs - llvm#101987 - llvm#101988 - llvm#101989 cc @farzonl @pow2clk @bob80905 @bogner @llvm-beanz
OpenHarmonySCM-noreply
pushed a commit
to openharmony/third_party_llvm-project
that referenced
this pull request
Jul 19, 2026
makes progress on #70078 ### Changes - Added `int_dx_sign` intrinsic in `IntrinsicsDirectX.td` - Added expansion for `int_dx_sign in `DXILIntrinsicExpansion.cpp` - Added DXIL backend test case ### Related PRs - llvm/llvm-project#101987 - llvm/llvm-project#101989
OpenHarmonySCM-noreply
pushed a commit
to openharmony/third_party_llvm-project
that referenced
this pull request
Jul 19, 2026
partially fixes #70078 ### Changes - Implemented `sign` clang builtin - Linked `sign` clang builtin with `hlsl_intrinsics.h` - Added sema checks for `sign` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp` - Add codegen for `sign` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp` - Add codegen tests to `clang/test/CodeGenHLSL/builtins/sign.hlsl` - Add sema tests to `clang/test/SemaHLSL/BuiltIns/sign-errors.hlsl` ### Related PRs - llvm/llvm-project#101987 - llvm/llvm-project#101988 ### Discussion - Should there be a `usign` intrinsic that handles the unsigned cases?
OpenHarmonySCM-noreply
pushed a commit
to openharmony/third_party_llvm-project
that referenced
this pull request
Jul 19, 2026
- Add handling for unsigned integers to hlsl_elementwise_sign - Use `select` instead of adding dx and spirv intrinsics for unsigned integers as [discussed previously ](llvm/llvm-project#101988 (comment)) fixes #70078 ### Related PRs - llvm/llvm-project#101987 - llvm/llvm-project#101988 - llvm/llvm-project#101989 cc @farzonl @pow2clk @bob80905 @bogner @llvm-beanz
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
partially fixes #70078
Changes
int_spv_signintrinsic inIntrinsicsSPIRV.tdint_spv_sign inSPIRVInstructionSelector.cpp`llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sign.llRelated PRs