https://github.com/michalpaszkowski updated https://github.com/llvm/llvm-project/pull/214096
>From cfa6e07e3b49b63a9b676829225a771143fb82ca Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Fri, 31 Jul 2026 03:04:47 -0700 Subject: [PATCH] Add PISA IR intrinsics and address-space utilities This patch adds the PISA IR intrinsics definitions, address space utilities, and basic tests. --- llvm/include/llvm/IR/CMakeLists.txt | 1 + llvm/include/llvm/IR/Intrinsics.td | 1 + llvm/include/llvm/IR/IntrinsicsPISA.td | 252 ++++++++++++++++++ llvm/include/llvm/IR/PISAIntrinsicUtils.h | 72 +++++ llvm/include/llvm/Support/PISAAddrSpace.h | 59 ++++ llvm/lib/IR/CMakeLists.txt | 1 + llvm/lib/IR/Intrinsics.cpp | 2 + llvm/lib/IR/PISAIntrinsicUtils.cpp | 121 +++++++++ .../CodeGen/PISA/intrinsics-address-space.ll | 20 ++ .../CodeGen/PISA/intrinsics-attributes.ll | 24 ++ llvm/test/CodeGen/PISA/intrinsics.ll | 19 ++ 11 files changed, 572 insertions(+) create mode 100644 llvm/include/llvm/IR/IntrinsicsPISA.td create mode 100644 llvm/include/llvm/IR/PISAIntrinsicUtils.h create mode 100644 llvm/include/llvm/Support/PISAAddrSpace.h create mode 100644 llvm/lib/IR/PISAIntrinsicUtils.cpp create mode 100644 llvm/test/CodeGen/PISA/intrinsics-address-space.ll create mode 100644 llvm/test/CodeGen/PISA/intrinsics-attributes.ll create mode 100644 llvm/test/CodeGen/PISA/intrinsics.ll diff --git a/llvm/include/llvm/IR/CMakeLists.txt b/llvm/include/llvm/IR/CMakeLists.txt index 5a7676b968589..1d6658030215a 100644 --- a/llvm/include/llvm/IR/CMakeLists.txt +++ b/llvm/include/llvm/IR/CMakeLists.txt @@ -26,4 +26,5 @@ tablegen(LLVM IntrinsicsWebAssembly.h -gen-intrinsic-enums -intrinsic-prefix=was tablegen(LLVM IntrinsicsX86.h -gen-intrinsic-enums -intrinsic-prefix=x86) tablegen(LLVM IntrinsicsXCore.h -gen-intrinsic-enums -intrinsic-prefix=xcore) tablegen(LLVM IntrinsicsVE.h -gen-intrinsic-enums -intrinsic-prefix=ve) +tablegen(LLVM IntrinsicsPISA.h -gen-intrinsic-enums -intrinsic-prefix=pisa) add_public_tablegen_target(intrinsics_gen) diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 083b933e77d16..4e2a820101457 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -3225,5 +3225,6 @@ include "llvm/IR/IntrinsicsSPIRV.td" include "llvm/IR/IntrinsicsVE.td" include "llvm/IR/IntrinsicsDirectX.td" include "llvm/IR/IntrinsicsLoongArch.td" +include "llvm/IR/IntrinsicsPISA.td" #endif // TEST_INTRINSICS_SUPPRESS_DEFS diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td new file mode 100644 index 0000000000000..ba3dab8cecf90 --- /dev/null +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -0,0 +1,252 @@ +//===- IntrinsicsPISA.td - Defines PISA intrinsics ---------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines all of the PISA-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +// Pointer type definitions. +def pisa_global_ptr_ty : LLVMQualPointerType<1>; // (global)* +def pisa_constant_ptr_ty : LLVMQualPointerType<2>; // (constant)* +def pisa_shared_ptr_ty : LLVMQualPointerType<3>; // (shared)* +def pisa_generic_ptr_ty : LLVMQualPointerType<0>; // (generic)* + +// Base classes. +class PISAIntrinsic<list<LLVMType> ret_types, list<LLVMType> param_types = [], + list<IntrinsicProperty> intr_properties = [], string name = ""> + : Intrinsic<ret_types, param_types, intr_properties, name> { + let TargetPrefix = "pisa"; +} + +class PISADefaultAttrsIntrinsic<list<LLVMType> ret_types, list<LLVMType> param_types = [], + list<IntrinsicProperty> intr_properties = [], string name = ""> + : DefaultAttrsIntrinsic<ret_types, param_types, intr_properties, name> { + let TargetPrefix = "pisa"; +} + +class PISAIntrinsicClang<list<LLVMType> RetTypes, list<LLVMType> ParamTypes = [], + list<IntrinsicProperty> IntrProperties = [], string ClangName, string Name = ""> + : PISAIntrinsic<RetTypes, ParamTypes, IntrProperties, Name>, + ClangBuiltin<!strconcat("__builtin_pisa_", ClangName)>; + +class PISADefaultAttrsIntrinsicClang<list<LLVMType> RetTypes, list<LLVMType> ParamTypes = [], + list<IntrinsicProperty> IntrProperties = [], + string ClangName, string Name = ""> + : PISADefaultAttrsIntrinsic<RetTypes, ParamTypes, IntrProperties, Name>, + ClangBuiltin<!strconcat("__builtin_pisa_", ClangName)>; + +// Multiclass for XYZ dimension variants. +multiclass PISAIntrinsicXYZ<list<LLVMType> RetTypes, list<LLVMType> ParamTypes = [], + list<IntrinsicProperty> IntrProperties = [], string ClangName> { + def _x : PISADefaultAttrsIntrinsicClang<RetTypes, ParamTypes, IntrProperties, !strconcat(ClangName, "_x")>; + def _y : PISADefaultAttrsIntrinsicClang<RetTypes, ParamTypes, IntrProperties, !strconcat(ClangName, "_y")>; + def _z : PISADefaultAttrsIntrinsicClang<RetTypes, ParamTypes, IntrProperties, !strconcat(ClangName, "_z")>; +} + +// Constants. +defvar MAX_WORK_DIM = 3; +defvar MAX_LOCAL_SIZE = 65536; +defvar MAX_SUB_GROUP_SIZE = 32; + +// Helper classes for common ArgInfo patterns. +class RoundingModeArgInfo<ArgIndex idx> : ArgInfo<idx, [ArgName<"round">, ImmArgPrinter<"printRoundingMode">]>; +class SaturationArgInfo<ArgIndex idx> : ArgInfo<idx, [ArgName<"saturation">]>; +class NanPropagateArgInfo<ArgIndex idx> : ArgInfo<idx, [ArgName<"nanp">]>; + +// Helper class for barrier intrinsics. +class PISAIntrinsicBarrier<string ClangName, list<LLVMType> param_types = []> + : PISAIntrinsicClang<[], param_types, [IntrNoMem, IntrHasSideEffects, IntrConvergent], ClangName>; + +// Helper class for unary float operations with rounding mode. +class PISAUnaryRndIntrinsic + : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>; + +// Helper class for binary float operations with rounding mode. +class PISABinaryRndIntrinsic + : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i8_ty], + [IntrNoMem, ImmArg<ArgIndex<2>>]>; + +// Helper class for float operations with rounding mode + saturation flag. +class PISAFloatIntrinsic<LLVMType ret_ty, list<LLVMType> operand_types> + : PISADefaultAttrsIntrinsic<[ret_ty], [], []> { + defvar num_params = !size(operand_types); + let ParamTypes = !listconcat( + operand_types, + [llvm_i8_ty, // rounding mode + llvm_i1_ty] // saturation flag + ); + let IntrProperties = [ + IntrNoMem, + ImmArg<ArgIndex<num_params>>, + ImmArg<ArgIndex<!add(num_params, 1)>>, + RoundingModeArgInfo<ArgIndex<num_params>>, + SaturationArgInfo<ArgIndex<!add(num_params, 1)>> + ]; +} + + +//===----------------------------------------------------------------------===// +// 1. Special Registers +//===----------------------------------------------------------------------===// + +defm int_pisa_local_id : PISAIntrinsicXYZ<[llvm_i32_ty], [], [IntrNoMem, Range<RetIndex, 0, MAX_LOCAL_SIZE>], "local_id">; +defm int_pisa_local_size : PISAIntrinsicXYZ<[llvm_i32_ty], [], [IntrNoMem, Range<RetIndex, 1, !add(MAX_LOCAL_SIZE, 1)>], "local_size">; +defm int_pisa_enqueued_local_size : PISAIntrinsicXYZ<[llvm_i32_ty], [], [IntrNoMem, Range<RetIndex, 1, !add(MAX_LOCAL_SIZE, 1)>], + "enqueued_local_size">; +defm int_pisa_group_id : PISAIntrinsicXYZ<[llvm_i32_ty], [], [IntrNoMem], "group_id">; +defm int_pisa_group_count : PISAIntrinsicXYZ<[llvm_i32_ty], [], [IntrNoMem], "group_count">; +defm int_pisa_global_size : PISAIntrinsicXYZ<[llvm_i64_ty], [], [IntrNoMem], "global_size">; +defm int_pisa_global_offset : PISAIntrinsicXYZ<[llvm_i64_ty], [], [IntrNoMem], "global_offset">; + +def int_pisa_lane_id : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [], + [IntrNoMem, Range<RetIndex, 0, MAX_SUB_GROUP_SIZE>], "lane_id">; +def int_pisa_subgroup_size : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [], + [IntrNoMem, Range<RetIndex, MAX_SUB_GROUP_SIZE, !add(MAX_SUB_GROUP_SIZE, 1)>], + "subgroup_size">; +def int_pisa_work_dim : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [], + [IntrNoMem, Range<RetIndex, 1, !add(MAX_WORK_DIM, 1)>], "work_dim">; + +def int_pisa_activemask : PISAIntrinsicClang<[llvm_i32_ty], [], [IntrNoMem, IntrConvergent], "activemask">; + +//===----------------------------------------------------------------------===// +// 2. Integer Arithmetic +//===----------------------------------------------------------------------===// + +def int_pisa_dp4a_uu : PISADefaultAttrsIntrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty], + [IntrNoMem, IntrWillReturn, ImmArg<ArgIndex<3>>, + SaturationArgInfo<ArgIndex<3>>]>; +def int_pisa_dp4a_us : PISADefaultAttrsIntrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty], + [IntrNoMem, IntrWillReturn, ImmArg<ArgIndex<3>>, + SaturationArgInfo<ArgIndex<3>>]>; +def int_pisa_dp4a_su : PISADefaultAttrsIntrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty], + [IntrNoMem, IntrWillReturn, ImmArg<ArgIndex<3>>, + SaturationArgInfo<ArgIndex<3>>]>; +def int_pisa_dp4a_ss : PISADefaultAttrsIntrinsic<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty], + [IntrNoMem, IntrWillReturn, ImmArg<ArgIndex<3>>, + SaturationArgInfo<ArgIndex<3>>]>; + +def int_pisa_smad : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; + +//===----------------------------------------------------------------------===// +// 3. Floating Point +//===----------------------------------------------------------------------===// + +def int_pisa_fabs : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; +def int_pisa_frcp : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; +def int_pisa_frsqrt : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; +def int_pisa_frc : PISADefaultAttrsIntrinsicClang<[llvm_float_ty], [llvm_float_ty], [IntrNoMem], "frcf">; + +def int_pisa_fmin_sat : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty], + [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>, + NanPropagateArgInfo<ArgIndex<2>>]>; +def int_pisa_fmax_sat : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty], + [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>, + NanPropagateArgInfo<ArgIndex<2>>]>; + +// Float operations with rounding mode + saturation flag. +def int_pisa_fadd : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>]>; +def int_pisa_fsub : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>]>; +def int_pisa_fmul : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>]>; +def int_pisa_fma : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>; + +// Binary float operations with explicit rounding mode. +def int_pisa_fdiv_rnd : PISABinaryRndIntrinsic; +def int_pisa_pow_rnd : PISABinaryRndIntrinsic; + +// Unary float operations with explicit rounding mode. +def int_pisa_fsqrt_rnd : PISAUnaryRndIntrinsic; +def int_pisa_frnd_rnd : PISAUnaryRndIntrinsic; +def int_pisa_frcp_rnd : PISAUnaryRndIntrinsic; +def int_pisa_sin_rnd : PISAUnaryRndIntrinsic; +def int_pisa_cos_rnd : PISAUnaryRndIntrinsic; +def int_pisa_tanh_rnd : PISAUnaryRndIntrinsic; +def int_pisa_exp_rnd : PISAUnaryRndIntrinsic; +def int_pisa_exp2_rnd : PISAUnaryRndIntrinsic; +def int_pisa_log_rnd : PISAUnaryRndIntrinsic; +def int_pisa_log2_rnd : PISAUnaryRndIntrinsic; +def int_pisa_log10_rnd : PISAUnaryRndIntrinsic; + +//===----------------------------------------------------------------------===// +// 4. Logic and Shift +//===----------------------------------------------------------------------===// + +def int_pisa_bfi : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem], "bfi">; +def int_pisa_ubfe : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem], "ubfe">; +def int_pisa_sbfe : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], + [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem], "sbfe">; +def int_pisa_bfn : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], + [llvm_i8_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem, ImmArg<ArgIndex<0>>]>; + +//===----------------------------------------------------------------------===// +// 5. Data Movement and Conversion +//===----------------------------------------------------------------------===// + +// Conversions with explicit rounding mode (metadata). +def int_pisa_fptosi_md : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_metadata_ty], [IntrNoMem]>; +def int_pisa_fptoui_md : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_metadata_ty], [IntrNoMem]>; + +// Conversions with explicit rounding mode (i8 immediate). +def int_pisa_fptosi_rnd : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<ArgIndex<1>>]>; +def int_pisa_fptoui_rnd : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i8_ty], + [IntrNoMem, ImmArg<ArgIndex<1>>]>; + +// Conversions with rounding mode + saturation flag. +def int_pisa_sitofp : PISAFloatIntrinsic<llvm_anyfloat_ty, [llvm_anyint_ty]>; +def int_pisa_uitofp : PISAFloatIntrinsic<llvm_anyfloat_ty, [llvm_anyint_ty]>; +def int_pisa_ftrunc : PISAFloatIntrinsic<llvm_anyfloat_ty, [llvm_anyfloat_ty]>; + +// Address space checks. +def int_pisa_isaddr_private : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [pisa_generic_ptr_ty], [IntrNoMem], "isaddr_private">; +def int_pisa_isaddr_shared : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [pisa_generic_ptr_ty], [IntrNoMem], "isaddr_shared">; +def int_pisa_isaddr_global : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [pisa_generic_ptr_ty], [IntrNoMem], "isaddr_global">; + +//===----------------------------------------------------------------------===// +// 6. Subgroup Communication +//===----------------------------------------------------------------------===// + +def int_pisa_shfl : PISADefaultAttrsIntrinsic<[llvm_i32_ty], + [llvm_i8_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty], + [IntrNoMem, IntrConvergent, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<5>>, + ArgInfo<ArgIndex<0>, [ArgName<"mode">, ImmArgPrinter<"printSHFLMode">]>, + ArgInfo<ArgIndex<5>, [ArgName<"sg">]>]>; +def int_pisa_ired : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], + [llvm_i8_ty, LLVMMatchType<0>, llvm_i32_ty, LLVMMatchType<0>], + [IntrNoMem, IntrConvergent, ImmArg<ArgIndex<0>>, + ArgInfo<ArgIndex<0>, [ArgName<"op">, ImmArgPrinter<"printIRedOp">]>]>; +def int_pisa_fred : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], + [llvm_i8_ty, LLVMMatchType<0>, llvm_i32_ty, LLVMMatchType<0>, llvm_i1_ty], + [IntrNoMem, IntrConvergent, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<4>>, + ArgInfo<ArgIndex<0>, [ArgName<"op">, ImmArgPrinter<"printFRedOp">]>, + NanPropagateArgInfo<ArgIndex<4>>]>; +def int_pisa_redfirstidx : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [llvm_i32_ty], + [IntrNoMem, IntrConvergent], "redfirstidx">; + +//===----------------------------------------------------------------------===// +// 7. Memory and Atomics +//===----------------------------------------------------------------------===// + +def int_pisa_cas_fatom : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], + [llvm_anyptr_ty, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i8_ty], + [IntrHasSideEffects, ImmArg<ArgIndex<3>>]>; + +//===----------------------------------------------------------------------===// +// 8. Synchronization +//===----------------------------------------------------------------------===// + +def int_pisa_workgroup_barrier : PISAIntrinsicBarrier<"workgroup_barrier">; diff --git a/llvm/include/llvm/IR/PISAIntrinsicUtils.h b/llvm/include/llvm/IR/PISAIntrinsicUtils.h new file mode 100644 index 0000000000000..76a4bd17a9781 --- /dev/null +++ b/llvm/include/llvm/IR/PISAIntrinsicUtils.h @@ -0,0 +1,72 @@ +//===-- PISAIntrinsicUtils.h ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_PISAINTRINSICUTILS_H +#define LLVM_IR_PISAINTRINSICUTILS_H +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsPISA.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace pisa { + +// The enum values must match the Clang preprocessor definitions in +// lib/Frontend/InitPreprocessor.cpp. +namespace MemoryScope { +enum : unsigned { + none = 255, + system = 0, // __MEMORY_SCOPE_SYSTEM + gpu = 1, // __MEMORY_SCOPE_DEVICE + workgroup = 2, // __MEMORY_SCOPE_WRKGRP + subgroup = 3, // __MEMORY_SCOPE_WVFRNT + total_scopes +}; +} // namespace MemoryScope + +namespace IRedOp { +enum : unsigned { + SUM = 0, + SMIN = 1, + SMAX = 2, + UMIN = 3, + UMAX = 4, + AND = 5, + OR = 6, + XOR = 7, + ABSMAX = 8, + Last +}; +} // namespace IRedOp + +namespace FRedOp { +enum : unsigned { MIN = 0, MAX = 1, ABSMAX = 2, Last }; +} // namespace FRedOp + +namespace SHFLMode { +enum : unsigned { UP = 0, DOWN = 1, XOR = 2, IDX = 3, Last }; +} // namespace SHFLMode + +// Print a string corresponding to various immediate arguments to OS. +// +// If the value is invalid/unsupported, the functions print nothing; no errors +// are raised. This is because these functions may be called during printing of +// invalid IR, which should not crash the compiler. Other code (like the PISA +// Verifier) is responsible for reporting errors on invalid IR. + +LLVM_ABI void printMemoryOrdering(raw_ostream &OS, const Constant *ImmArgVal); +LLVM_ABI void printRoundingMode(raw_ostream &OS, const Constant *ImmArgVal); +LLVM_ABI void printIRedOp(raw_ostream &OS, const Constant *ImmArgVal); +LLVM_ABI void printFRedOp(raw_ostream &OS, const Constant *ImmArgVal); +LLVM_ABI void printSHFLMode(raw_ostream &OS, const Constant *ImmArgVal); + +} // namespace pisa +} // namespace llvm +#endif // LLVM_IR_PISAINTRINSICUTILS_H diff --git a/llvm/include/llvm/Support/PISAAddrSpace.h b/llvm/include/llvm/Support/PISAAddrSpace.h new file mode 100644 index 0000000000000..426904f9bc7b7 --- /dev/null +++ b/llvm/include/llvm/Support/PISAAddrSpace.h @@ -0,0 +1,59 @@ +//===-- PISAAddrSpace.h ---------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_PISAADDRSPACE_H +#define LLVM_SUPPORT_PISAADDRSPACE_H + +namespace llvm { + +namespace PISAAS { +enum class AddressSpace : unsigned { + GENERIC = 0, + GLOBAL = 1, + CONSTANT = 2, + SHARED = 3, + PRIVATE = 4, +}; + +// DWARFAddressSpace for PISA, this will be emitted as DW_AT_address_class +// attribute for variables and parameters. +enum class DWARF_AddressSpace : unsigned { + DWARF_ADDR_global_shared = 0, + DWARF_ADDR_shared_local = 1, + DWARF_ADDR_private = 2, +}; + +constexpr int mapToDWARFAddrSpace(unsigned LLVMAddrSpace) { + int dwarfAddrSpace = -1; + + switch (static_cast<AddressSpace>(LLVMAddrSpace)) { + case AddressSpace::PRIVATE: + dwarfAddrSpace = static_cast<int>(DWARF_AddressSpace::DWARF_ADDR_private); + break; + case AddressSpace::GLOBAL: + case AddressSpace::CONSTANT: + dwarfAddrSpace = + static_cast<int>(DWARF_AddressSpace::DWARF_ADDR_global_shared); + break; + case AddressSpace::SHARED: + dwarfAddrSpace = + static_cast<int>(DWARF_AddressSpace::DWARF_ADDR_shared_local); + break; + default: + // default is generic space, do not emit anything + break; + } + + return dwarfAddrSpace; +} + +} // end namespace PISAAS + +} // end namespace llvm + +#endif // LLVM_SUPPORT_PISAADDRSPACE_H diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 3037f01083308..85d235cacdfde 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -44,6 +44,7 @@ add_llvm_component_library(LLVMCore Instruction.cpp Instructions.cpp IntrinsicInst.cpp + PISAIntrinsicUtils.cpp LLVMContext.cpp LLVMContextImpl.cpp LLVMRemarkStreamer.cpp diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp index 266af8e06a230..b2e1337da1aec 100644 --- a/llvm/lib/IR/Intrinsics.cpp +++ b/llvm/lib/IR/Intrinsics.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/IntrinsicsLoongArch.h" #include "llvm/IR/IntrinsicsMips.h" #include "llvm/IR/IntrinsicsNVPTX.h" +#include "llvm/IR/IntrinsicsPISA.h" #include "llvm/IR/IntrinsicsPowerPC.h" #include "llvm/IR/IntrinsicsR600.h" #include "llvm/IR/IntrinsicsRISCV.h" @@ -33,6 +34,7 @@ #include "llvm/IR/IntrinsicsXCore.h" #include "llvm/IR/Module.h" #include "llvm/IR/NVVMIntrinsicUtils.h" +#include "llvm/IR/PISAIntrinsicUtils.h" #include "llvm/IR/Type.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" diff --git a/llvm/lib/IR/PISAIntrinsicUtils.cpp b/llvm/lib/IR/PISAIntrinsicUtils.cpp new file mode 100644 index 0000000000000..46c72a31681e8 --- /dev/null +++ b/llvm/lib/IR/PISAIntrinsicUtils.cpp @@ -0,0 +1,121 @@ +//===-- PISAIntrinsicUtils.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/PISAIntrinsicUtils.h" +#include "llvm/Support/AtomicOrdering.h" + +using namespace llvm; +using namespace llvm::pisa; + +void pisa::printMemoryOrdering(raw_ostream &OS, const Constant *ImmArgVal) { + auto *CI = cast<ConstantInt>(ImmArgVal); + auto AO = static_cast<AtomicOrdering>(CI->getZExtValue()); + if (static_cast<unsigned>(AO) > static_cast<unsigned>(AtomicOrdering::LAST)) + return; // invalid value, print nothing + OS << toIRString(AO); +} + +void pisa::printRoundingMode(raw_ostream &OS, const Constant *ImmArgVal) { + auto *CI = cast<ConstantInt>(ImmArgVal); + int64_t Val = CI->getSExtValue(); + switch (static_cast<RoundingMode>(Val)) { + default: + // invalid/unsupported value, print nothing + break; + case RoundingMode::TowardZero: + OS << ".rz"; + break; + case RoundingMode::NearestTiesToEven: + OS << ".re"; + break; + case RoundingMode::TowardPositive: + OS << ".ru"; + break; + case RoundingMode::TowardNegative: + OS << ".rd"; + break; + case RoundingMode::NearestTiesToAway: + OS << ".rna"; + break; + case RoundingMode::Invalid: + OS << "none"; + break; + } +} + +void pisa::printIRedOp(raw_ostream &OS, const Constant *ImmArgVal) { + auto *CI = cast<ConstantInt>(ImmArgVal); + int64_t Val = CI->getSExtValue(); + switch (Val) { + case IRedOp::SUM: + OS << ".sum"; + break; + case IRedOp::SMIN: + OS << ".smin"; + break; + case IRedOp::SMAX: + OS << ".smax"; + break; + case IRedOp::UMIN: + OS << ".umin"; + break; + case IRedOp::UMAX: + OS << ".umax"; + break; + case IRedOp::AND: + OS << ".and"; + break; + case IRedOp::OR: + OS << ".or"; + break; + case IRedOp::XOR: + OS << ".xor"; + break; + case IRedOp::ABSMAX: + OS << ".absmax"; + break; + } + // invalid value, print nothing +} + +void pisa::printFRedOp(raw_ostream &OS, const Constant *ImmArgVal) { + auto *CI = cast<ConstantInt>(ImmArgVal); + int64_t Val = CI->getSExtValue(); + switch (Val) { + case FRedOp::MIN: + OS << ".min"; + break; + case FRedOp::MAX: + OS << ".max"; + break; + case FRedOp::ABSMAX: + OS << ".absmax"; + break; + } + // invalid value, print nothing +} + +void pisa::printSHFLMode(raw_ostream &OS, const Constant *ImmArgVal) { + auto *CI = cast<ConstantInt>(ImmArgVal); + int64_t Val = CI->getSExtValue(); + switch (Val) { + case SHFLMode::UP: + OS << ".up"; + break; + case SHFLMode::DOWN: + OS << ".down"; + break; + case SHFLMode::XOR: + OS << ".xor"; + break; + case SHFLMode::IDX: + OS << ".idx"; + break; + } + // invalid value, print nothing +} diff --git a/llvm/test/CodeGen/PISA/intrinsics-address-space.ll b/llvm/test/CodeGen/PISA/intrinsics-address-space.ll new file mode 100644 index 0000000000000..45a31eed4d5d9 --- /dev/null +++ b/llvm/test/CodeGen/PISA/intrinsics-address-space.ll @@ -0,0 +1,20 @@ +; The PISA address-space query intrinsics take a generic (addrspace 0) pointer +; and return an i32 predicate. Verify they round-trip through the IR verifier +; and that the pointer operand type is preserved. + +; RUN: opt -S < %s | FileCheck %s + +define void @test(ptr %p) { +; CHECK-LABEL: define void @test(ptr %p) + %g = call i32 @llvm.pisa.isaddr.global(ptr %p) +; CHECK: call i32 @llvm.pisa.isaddr.global(ptr %p) + %s = call i32 @llvm.pisa.isaddr.shared(ptr %p) +; CHECK: call i32 @llvm.pisa.isaddr.shared(ptr %p) + %pr = call i32 @llvm.pisa.isaddr.private(ptr %p) +; CHECK: call i32 @llvm.pisa.isaddr.private(ptr %p) + ret void +} + +; CHECK: declare i32 @llvm.pisa.isaddr.global(ptr) +; CHECK: declare i32 @llvm.pisa.isaddr.private(ptr) +; CHECK: declare i32 @llvm.pisa.isaddr.shared(ptr) diff --git a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll new file mode 100644 index 0000000000000..58ececb5d47cf --- /dev/null +++ b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll @@ -0,0 +1,24 @@ +; Verify that the PISA work-item / control intrinsics are materialized with the +; attributes declared in IntrinsicsPISA.td. + +; RUN: opt -S < %s | FileCheck %s + +define void @test() { +; CHECK-LABEL: define void @test() + %lane = call i32 @llvm.pisa.lane.id() + %sg = call i32 @llvm.pisa.subgroup.size() + %wd = call i32 @llvm.pisa.work.dim() + %am = call i32 @llvm.pisa.activemask() + call void @llvm.pisa.workgroup.barrier() + ret void +} + +; CHECK: declare i32 @llvm.pisa.activemask() [[CONVMEM:#[0-9]+]] +; CHECK: declare range(i32 0, 32) i32 @llvm.pisa.lane.id() [[NOMEM:#[0-9]+]] +; CHECK: declare range(i32 32, 33) i32 @llvm.pisa.subgroup.size() [[NOMEM]] +; CHECK: declare range(i32 1, 4) i32 @llvm.pisa.work.dim() [[NOMEM]] +; CHECK: declare void @llvm.pisa.workgroup.barrier() [[CONV:#[0-9]+]] + +; CHECK-DAG: attributes [[CONVMEM]] = { convergent nounwind memory(none) } +; CHECK-DAG: attributes [[NOMEM]] = { nocallback nofree nosync nounwind willreturn memory(none) } +; CHECK-DAG: attributes [[CONV]] = { convergent nounwind } diff --git a/llvm/test/CodeGen/PISA/intrinsics.ll b/llvm/test/CodeGen/PISA/intrinsics.ll new file mode 100644 index 0000000000000..5754c7f15183d --- /dev/null +++ b/llvm/test/CodeGen/PISA/intrinsics.ll @@ -0,0 +1,19 @@ +; Verify that the PISA target intrinsics are registered in the IR layer and +; round-trip through the verifier/assembler. + +; RUN: opt -S < %s | FileCheck %s + +define void @test() { +; CHECK-LABEL: define void @test() + %lane = call i32 @llvm.pisa.lane.id() +; CHECK: call i32 @llvm.pisa.lane.id() + %sgsize = call i32 @llvm.pisa.subgroup.size() +; CHECK: call i32 @llvm.pisa.subgroup.size() + %wdim = call i32 @llvm.pisa.work.dim() +; CHECK: call i32 @llvm.pisa.work.dim() + ret void +} + +declare i32 @llvm.pisa.lane.id() +declare i32 @llvm.pisa.subgroup.size() +declare i32 @llvm.pisa.work.dim() _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
