From 87d72e162beeaaad50f69b0f47ef4adbec7f34af Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Mon, 9 Sep 2024 14:27:30 -0700 Subject: [PATCH] [clang][hlsl] Add atan2 intrinsic part 3 Issue: #70096 Changes: - `llvm/docs/GlobalISel/GenericOpcode.rst` - Document the G_FATAN2 opcode - `llvm/include/llvm/Support/TargetOpcodes.def` - Create a G_FATAN2 Opcode handler - `llvm/include/llvm/Target/GenericOpcodes.td` - Define the G_FATAN2 Opcode - `llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp` Map the atan2 intrinsic to G_FATAN2 Opcode - `llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp` - Map the G_FATAN2 opcode to the GLSL 4.5 and openCL atan2 instructions. - `llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp` - Define G_FATAN2 as a legal spirv target opcode. --- llvm/docs/GlobalISel/GenericOpcode.rst | 4 +- llvm/include/llvm/Support/TargetOpcodes.def | 3 ++ llvm/include/llvm/Target/GenericOpcodes.td | 7 +++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 2 + llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 1 + .../GlobalISel/legalizer-info-validation.mir | 4 ++ .../CodeGen/SPIRV/hlsl-intrinsics/atan2.ll | 49 +++++++++++++++++++ 8 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan2.ll diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index bba56d9a5c0ec2c..93f2a987d9160d6 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -628,8 +628,8 @@ G_FCEIL, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT These correspond to the standard C functions of the same name. -G_FCOS, G_FSIN, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +G_FCOS, G_FSIN, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH, G_FATAN2 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These correspond to the standard C trigonometry functions of the same name. diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index a3692a5fb6ebd72..df77c196b0f3ee3 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -815,6 +815,9 @@ HANDLE_TARGET_OPCODE(G_FASIN) /// Floating point arctangent. HANDLE_TARGET_OPCODE(G_FATAN) +/// Floating point arctangent of y/x. +HANDLE_TARGET_OPCODE(G_FATAN2) + /// Floating point hyperbolic cosine. HANDLE_TARGET_OPCODE(G_FCOSH) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index f4934af4563d838..0e15f8679b9cb13 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -1036,6 +1036,13 @@ def G_FATAN : GenericInstruction { let hasSideEffects = false; } +// Floating point arctangent of a value. +def G_FATAN2 : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1, type0:$src2); + let hasSideEffects = false; +} + // Floating point hyperbolic cosine of a value. def G_FCOSH : GenericInstruction { let OutOperandList = (outs type0:$dst); diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index b85087c23845d5b..065c51ffebbd18c 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1885,6 +1885,8 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { return TargetOpcode::G_FASIN; case Intrinsic::atan: return TargetOpcode::G_FATAN; + case Intrinsic::atan2: + return TargetOpcode::G_FATAN2; case Intrinsic::bswap: return TargetOpcode::G_BSWAP; case Intrinsic::bitreverse: diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 1e861da35aaac92..97b8cb286eabd2b 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -546,6 +546,8 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg, return selectExtInst(ResVReg, ResType, I, CL::asin, GL::Asin); case TargetOpcode::G_FATAN: return selectExtInst(ResVReg, ResType, I, CL::atan, GL::Atan); + case TargetOpcode::G_FATAN2: + return selectExtInst(ResVReg, ResType, I, CL::atan2, GL::Atan2); case TargetOpcode::G_FCOSH: return selectExtInst(ResVReg, ResType, I, CL::cosh, GL::Cosh); case TargetOpcode::G_FSINH: diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index 9fe4d8a16bc32a6..9642a60cba62343 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -320,6 +320,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { G_FACOS, G_FASIN, G_FATAN, + G_FATAN2, G_FCOSH, G_FSINH, G_FTANH, diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 62d98a224fa3dd6..63c2855b602d304 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -710,6 +710,10 @@ # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK +# DEBUG-NEXT: G_FATAN2 (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} +# DEBUG-NEXT: .. the first uncovered type index: 1, OK +# DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_FCOSH (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan2.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan2.ll new file mode 100644 index 000000000000000..bdbfc133efa29b0 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan2.ll @@ -0,0 +1,49 @@ +; RUN: llc -verify-machineinstrs -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_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @atan2_float(float noundef %a, float noundef %b) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Atan2 %[[#arg0]] %[[#arg1]] + %elt.atan2 = call float @llvm.atan2.f32(float %a, float %b) + ret float %elt.atan2 +} + +define noundef half @atan2_half(half noundef %a, half noundef %b) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Atan2 %[[#arg0]] %[[#arg1]] + %elt.atan2 = call half @llvm.atan2.f16(half %a, half %b) + ret half %elt.atan2 +} + +define noundef <4 x float> @atan2_float4(<4 x float> noundef %a, <4 x float> noundef %b) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Atan2 %[[#arg0]] %[[#arg1]] + %elt.atan2 = call <4 x float> @llvm.atan2.v4f32(<4 x float> %a, <4 x float> %b) + ret <4 x float> %elt.atan2 +} + +define noundef <4 x half> @atan2_half4(<4 x half> noundef %a, <4 x half> noundef %b) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#arg1:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Atan2 %[[#arg0]] %[[#arg1]] + %elt.atan2 = call <4 x half> @llvm.atan2.v4f16(<4 x half> %a, <4 x half> %b) + ret <4 x half> %elt.atan2 +} + +declare half @llvm.atan2.f16(half, half) +declare float @llvm.atan2.f32(float, float) +declare <4 x half> @llvm.atan2.v4f16(<4 x half>, <4 x half>) +declare <4 x float> @llvm.atan2.v4f32(<4 x float>, <4 x float>)