https://github.com/michalpaszkowski updated https://github.com/llvm/llvm-project/pull/214096
>From c2b5a7514813b8cd96ba81571182f8170d60bffb Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Fri, 31 Jul 2026 03:04:47 -0700 Subject: [PATCH 01/11] 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() >From 894f62684c38cd7f4170d72ea02886a27b161e37 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Thu, 20 Aug 2026 13:51:16 +0000 Subject: [PATCH 02/11] Change ordering, add links to PISA spec --- llvm/include/llvm/IR/IntrinsicsPISA.td | 16 +++++++++++++--- llvm/include/llvm/IR/PISAIntrinsicUtils.h | 8 ++++++++ llvm/include/llvm/Support/PISAAddrSpace.h | 2 ++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index ba3dab8cecf90..2047754a8ec23 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -10,11 +10,12 @@ // //===----------------------------------------------------------------------===// -// Pointer type definitions. +// Pointer type definitions. See the PISA address-space specification: +// https://intel.github.io/pisa/spaces_types.html#address-spaces +def pisa_generic_ptr_ty : LLVMQualPointerType<0>; // (generic)* 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 = [], @@ -53,7 +54,8 @@ defvar MAX_WORK_DIM = 3; defvar MAX_LOCAL_SIZE = 65536; defvar MAX_SUB_GROUP_SIZE = 32; -// Helper classes for common ArgInfo patterns. +// Helper classes for common ArgInfo patterns. See the PISA rounding modes: +// https://intel.github.io/pisa/floating_point.html#rounding-mode 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">]>; @@ -92,6 +94,7 @@ class PISAFloatIntrinsic<LLVMType ret_ty, list<LLVMType> operand_types> //===----------------------------------------------------------------------===// // 1. Special Registers +// https://intel.github.io/pisa/special_registers.html //===----------------------------------------------------------------------===// defm int_pisa_local_id : PISAIntrinsicXYZ<[llvm_i32_ty], [], [IntrNoMem, Range<RetIndex, 0, MAX_LOCAL_SIZE>], "local_id">; @@ -115,6 +118,7 @@ def int_pisa_activemask : PISAIntrinsicClang<[llvm_i32_ty], [], [IntrNo //===----------------------------------------------------------------------===// // 2. Integer Arithmetic +// https://intel.github.io/pisa/instructions_arithmetic.html //===----------------------------------------------------------------------===// def int_pisa_dp4a_uu : PISADefaultAttrsIntrinsic<[llvm_i32_ty], @@ -139,6 +143,7 @@ def int_pisa_smad : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], //===----------------------------------------------------------------------===// // 3. Floating Point +// https://intel.github.io/pisa/instructions_floating_point.html //===----------------------------------------------------------------------===// def int_pisa_fabs : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; @@ -180,6 +185,7 @@ def int_pisa_log10_rnd : PISAUnaryRndIntrinsic; //===----------------------------------------------------------------------===// // 4. Logic and Shift +// https://intel.github.io/pisa/instructions_logical.html //===----------------------------------------------------------------------===// def int_pisa_bfi : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], @@ -194,6 +200,7 @@ def int_pisa_bfn : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], //===----------------------------------------------------------------------===// // 5. Data Movement and Conversion +// https://intel.github.io/pisa/instructions_data_movement.html //===----------------------------------------------------------------------===// // Conversions with explicit rounding mode (metadata). @@ -218,6 +225,7 @@ def int_pisa_isaddr_global : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [pis //===----------------------------------------------------------------------===// // 6. Subgroup Communication +// https://intel.github.io/pisa/instructions_cross_lane.html //===----------------------------------------------------------------------===// def int_pisa_shfl : PISADefaultAttrsIntrinsic<[llvm_i32_ty], @@ -239,6 +247,7 @@ def int_pisa_redfirstidx : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [llvm_i //===----------------------------------------------------------------------===// // 7. Memory and Atomics +// https://intel.github.io/pisa/instructions_memory.html //===----------------------------------------------------------------------===// def int_pisa_cas_fatom : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], @@ -247,6 +256,7 @@ def int_pisa_cas_fatom : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], //===----------------------------------------------------------------------===// // 8. Synchronization +// https://intel.github.io/pisa/instructions_synchronization.html //===----------------------------------------------------------------------===// def int_pisa_workgroup_barrier : PISAIntrinsicBarrier<"workgroup_barrier">; diff --git a/llvm/include/llvm/IR/PISAIntrinsicUtils.h b/llvm/include/llvm/IR/PISAIntrinsicUtils.h index 76a4bd17a9781..1ec2e9060ceca 100644 --- a/llvm/include/llvm/IR/PISAIntrinsicUtils.h +++ b/llvm/include/llvm/IR/PISAIntrinsicUtils.h @@ -20,6 +20,8 @@ namespace pisa { // The enum values must match the Clang preprocessor definitions in // lib/Frontend/InitPreprocessor.cpp. +// See the PISA memory-scope specification: +// https://intel.github.io/pisa/virtual_machine.html#memory-scope namespace MemoryScope { enum : unsigned { none = 255, @@ -31,6 +33,8 @@ enum : unsigned { }; } // namespace MemoryScope +// Integer reduction operations: +// https://intel.github.io/pisa/instructions_cross_lane.html#ired namespace IRedOp { enum : unsigned { SUM = 0, @@ -46,10 +50,14 @@ enum : unsigned { }; } // namespace IRedOp +// Floating-point reduction operations: +// https://intel.github.io/pisa/instructions_cross_lane.html#fred namespace FRedOp { enum : unsigned { MIN = 0, MAX = 1, ABSMAX = 2, Last }; } // namespace FRedOp +// Sub-group shuffle modes: +// https://intel.github.io/pisa/instructions_cross_lane.html#shfl namespace SHFLMode { enum : unsigned { UP = 0, DOWN = 1, XOR = 2, IDX = 3, Last }; } // namespace SHFLMode diff --git a/llvm/include/llvm/Support/PISAAddrSpace.h b/llvm/include/llvm/Support/PISAAddrSpace.h index 426904f9bc7b7..2c0279d86f489 100644 --- a/llvm/include/llvm/Support/PISAAddrSpace.h +++ b/llvm/include/llvm/Support/PISAAddrSpace.h @@ -12,6 +12,8 @@ namespace llvm { namespace PISAAS { +// See the PISA address-space specification: +// https://intel.github.io/pisa/spaces_types.html#address-spaces enum class AddressSpace : unsigned { GENERIC = 0, GLOBAL = 1, >From 9835f6aaa9827bbe149ff6afaa9acd3e29474768 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 08:53:51 +0000 Subject: [PATCH 03/11] Remove the default case from printRoundingMode --- llvm/lib/IR/PISAIntrinsicUtils.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/IR/PISAIntrinsicUtils.cpp b/llvm/lib/IR/PISAIntrinsicUtils.cpp index 46c72a31681e8..f5ac0af37d128 100644 --- a/llvm/lib/IR/PISAIntrinsicUtils.cpp +++ b/llvm/lib/IR/PISAIntrinsicUtils.cpp @@ -24,9 +24,6 @@ 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; @@ -42,6 +39,8 @@ void pisa::printRoundingMode(raw_ostream &OS, const Constant *ImmArgVal) { case RoundingMode::NearestTiesToAway: OS << ".rna"; break; + case RoundingMode::Dynamic: + break; case RoundingMode::Invalid: OS << "none"; break; >From b85c690ab64fe71a2db18357bc30c91db5e01183 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 08:58:26 +0000 Subject: [PATCH 04/11] Remove unused MemoryScope --- llvm/include/llvm/IR/PISAIntrinsicUtils.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/llvm/include/llvm/IR/PISAIntrinsicUtils.h b/llvm/include/llvm/IR/PISAIntrinsicUtils.h index 1ec2e9060ceca..bd49fafc63199 100644 --- a/llvm/include/llvm/IR/PISAIntrinsicUtils.h +++ b/llvm/include/llvm/IR/PISAIntrinsicUtils.h @@ -18,21 +18,6 @@ namespace llvm { namespace pisa { -// The enum values must match the Clang preprocessor definitions in -// lib/Frontend/InitPreprocessor.cpp. -// See the PISA memory-scope specification: -// https://intel.github.io/pisa/virtual_machine.html#memory-scope -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 - // Integer reduction operations: // https://intel.github.io/pisa/instructions_cross_lane.html#ired namespace IRedOp { >From 38c48441263ef6281cd5e3d9db184264793be8dc Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 09:05:55 +0000 Subject: [PATCH 05/11] Change int_pisa_activemask to PISADefaultAttrsIntrinsicClang --- llvm/include/llvm/IR/IntrinsicsPISA.td | 2 +- llvm/test/CodeGen/PISA/intrinsics-attributes.ll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index 2047754a8ec23..62df4c92a0ab6 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -114,7 +114,7 @@ def int_pisa_subgroup_size : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [], 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">; +def int_pisa_activemask : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [], [IntrNoMem, IntrConvergent], "activemask">; //===----------------------------------------------------------------------===// // 2. Integer Arithmetic diff --git a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll index 58ececb5d47cf..bc69f7d79f340 100644 --- a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll +++ b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll @@ -19,6 +19,6 @@ define void @test() { ; 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 [[CONVMEM]] = { convergent nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK-DAG: attributes [[NOMEM]] = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK-DAG: attributes [[CONV]] = { convergent nounwind } >From 3b7a04786743a784d4781cdf2ba60a0b20ec81a1 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 09:17:00 +0000 Subject: [PATCH 06/11] Use printMemoryOrdering in int_pisa_cas_fatom --- llvm/include/llvm/IR/IntrinsicsPISA.td | 8 ++++++-- llvm/lib/IR/PISAIntrinsicUtils.cpp | 6 +++--- llvm/test/CodeGen/PISA/intrinsics-attributes.ll | 13 +++++++++---- llvm/test/CodeGen/PISA/intrinsics.ll | 8 ++++++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index 62df4c92a0ab6..b13e4e911af24 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -250,9 +250,13 @@ def int_pisa_redfirstidx : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], [llvm_i // https://intel.github.io/pisa/instructions_memory.html //===----------------------------------------------------------------------===// -def int_pisa_cas_fatom : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], +def int_pisa_cas_fatom : PISAIntrinsic<[llvm_anyfloat_ty], [llvm_anyptr_ty, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i8_ty], - [IntrHasSideEffects, ImmArg<ArgIndex<3>>]>; + [IntrArgMemOnly, NoCapture<ArgIndex<0>>, + IntrNoCallback, IntrNoFree, IntrWillReturn, + ImmArg<ArgIndex<3>>, + ArgInfo<ArgIndex<3>, [ArgName<"order">, + ImmArgPrinter<"printMemoryOrdering">]>]>; //===----------------------------------------------------------------------===// // 8. Synchronization diff --git a/llvm/lib/IR/PISAIntrinsicUtils.cpp b/llvm/lib/IR/PISAIntrinsicUtils.cpp index f5ac0af37d128..dd8144959d0d2 100644 --- a/llvm/lib/IR/PISAIntrinsicUtils.cpp +++ b/llvm/lib/IR/PISAIntrinsicUtils.cpp @@ -14,10 +14,10 @@ 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)) + uint64_t Val = CI->getZExtValue(); + if (!isValidAtomicOrdering(Val)) return; // invalid value, print nothing - OS << toIRString(AO); + OS << toIRString(static_cast<AtomicOrdering>(Val)); } void pisa::printRoundingMode(raw_ostream &OS, const Constant *ImmArgVal) { diff --git a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll index bc69f7d79f340..d70619ae093f9 100644 --- a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll +++ b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll @@ -1,18 +1,20 @@ -; Verify that the PISA work-item / control intrinsics are materialized with the -; attributes declared in IntrinsicsPISA.td. +; Verify that the PISA intrinsics are materialized with the attributes declared +; in IntrinsicsPISA.td. ; RUN: opt -S < %s | FileCheck %s -define void @test() { -; CHECK-LABEL: define void @test() +define void @test(ptr %addr) { +; 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() + %cas = call float @llvm.pisa.cas.fatom.f32.p0(ptr %addr, float 0.0, float 1.0, i8 2) call void @llvm.pisa.workgroup.barrier() ret void } +; CHECK: declare float @llvm.pisa.cas.fatom.f32.p0(ptr captures(none), float, float, i8 immarg) [[ATOM:#[0-9]+]] ; 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]] @@ -20,5 +22,8 @@ define void @test() { ; CHECK: declare void @llvm.pisa.workgroup.barrier() [[CONV:#[0-9]+]] ; CHECK-DAG: attributes [[CONVMEM]] = { convergent nocallback nofree nosync nounwind willreturn memory(none) } +; CHECK-DAG: attributes [[ATOM]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ; CHECK-DAG: attributes [[NOMEM]] = { nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK-DAG: attributes [[CONV]] = { convergent nounwind } + +declare float @llvm.pisa.cas.fatom.f32.p0(ptr, float, float, i8 immarg) diff --git a/llvm/test/CodeGen/PISA/intrinsics.ll b/llvm/test/CodeGen/PISA/intrinsics.ll index 5754c7f15183d..5dec3614ad54f 100644 --- a/llvm/test/CodeGen/PISA/intrinsics.ll +++ b/llvm/test/CodeGen/PISA/intrinsics.ll @@ -14,6 +14,14 @@ define void @test() { ret void } +define float @test_cas_fatom(ptr %addr, float %compare, float %value) { +; CHECK-LABEL: define float @test_cas_fatom( + %result = call float @llvm.pisa.cas.fatom.f32.p0(ptr %addr, float %compare, float %value, i8 2) +; CHECK: call float @llvm.pisa.cas.fatom.f32.p0(ptr %addr, float %compare, float %value, /* order=monotonic */ i8 2) + ret float %result +} + declare i32 @llvm.pisa.lane.id() declare i32 @llvm.pisa.subgroup.size() declare i32 @llvm.pisa.work.dim() +declare float @llvm.pisa.cas.fatom.f32.p0(ptr, float, float, i8 immarg) >From 10360086fa15ab3279ba44b2fbc64a4da502f7bc Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 09:38:32 +0000 Subject: [PATCH 07/11] Removed redundant IntrWillReturn from dp4a intrinsics --- llvm/include/llvm/IR/IntrinsicsPISA.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index b13e4e911af24..0ffffec214a10 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -123,19 +123,19 @@ def int_pisa_activemask : PISADefaultAttrsIntrinsicClang<[llvm_i32_ty], 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>>, + [IntrNoMem, 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>>, + [IntrNoMem, 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>>, + [IntrNoMem, 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>>, + [IntrNoMem, ImmArg<ArgIndex<3>>, SaturationArgInfo<ArgIndex<3>>]>; def int_pisa_smad : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], >From 41dfc778d1ae28a358a3651d5b25ac9584d03713 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 09:48:59 +0000 Subject: [PATCH 08/11] Add Commutative to int_pisa_fadd, int_pisa_fmul, int_pisa_fma, int_pisa_smad. Extended PISAFloatIntrinsic to accept optional properties --- llvm/include/llvm/IR/IntrinsicsPISA.td | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index 0ffffec214a10..995b334281f88 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -74,7 +74,8 @@ class PISABinaryRndIntrinsic [IntrNoMem, ImmArg<ArgIndex<2>>]>; // Helper class for float operations with rounding mode + saturation flag. -class PISAFloatIntrinsic<LLVMType ret_ty, list<LLVMType> operand_types> +class PISAFloatIntrinsic<LLVMType ret_ty, list<LLVMType> operand_types, + list<IntrinsicProperty> intr_properties = []> : PISADefaultAttrsIntrinsic<[ret_ty], [], []> { defvar num_params = !size(operand_types); let ParamTypes = !listconcat( @@ -82,13 +83,14 @@ class PISAFloatIntrinsic<LLVMType ret_ty, list<LLVMType> 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)>> - ]; + let IntrProperties = !listconcat( + [IntrNoMem, + ImmArg<ArgIndex<num_params>>, + ImmArg<ArgIndex<!add(num_params, 1)>>, + RoundingModeArgInfo<ArgIndex<num_params>>, + SaturationArgInfo<ArgIndex<!add(num_params, 1)>>], + intr_properties + ); } @@ -139,7 +141,8 @@ def int_pisa_dp4a_ss : PISADefaultAttrsIntrinsic<[llvm_i32_ty], SaturationArgInfo<ArgIndex<3>>]>; def int_pisa_smad : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; + [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem, Commutative]>; //===----------------------------------------------------------------------===// // 3. Floating Point @@ -161,10 +164,10 @@ def int_pisa_fmax_sat : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], 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_fadd : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>], [Commutative]>; 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>]>; +def int_pisa_fmul : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>], [Commutative]>; +def int_pisa_fma : PISAFloatIntrinsic<llvm_anyfloat_ty, [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [Commutative]>; // Binary float operations with explicit rounding mode. def int_pisa_fdiv_rnd : PISABinaryRndIntrinsic; >From 2aca47667933baec34f85d302bd7ea3b260171f3 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 09:53:03 +0000 Subject: [PATCH 09/11] Removed unused global, constant, and shared aliases in IntrinsicsPISA.td --- llvm/include/llvm/IR/IntrinsicsPISA.td | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index 995b334281f88..176caabc4019d 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -10,12 +10,9 @@ // //===----------------------------------------------------------------------===// -// Pointer type definitions. See the PISA address-space specification: +// Generic pointer type. See the PISA address-space specification: // https://intel.github.io/pisa/spaces_types.html#address-spaces def pisa_generic_ptr_ty : LLVMQualPointerType<0>; // (generic)* -def pisa_global_ptr_ty : LLVMQualPointerType<1>; // (global)* -def pisa_constant_ptr_ty : LLVMQualPointerType<2>; // (constant)* -def pisa_shared_ptr_ty : LLVMQualPointerType<3>; // (shared)* // Base classes. class PISAIntrinsic<list<LLVMType> ret_types, list<LLVMType> param_types = [], >From db9d63ab89db7711b9c660c18ecb2179a9e82368 Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 10:00:09 +0000 Subject: [PATCH 10/11] Add IntrNoCallback, IntrNoFree, IntrWillReturn to PISAIntrinsicBarrier --- llvm/include/llvm/IR/IntrinsicsPISA.td | 5 ++++- llvm/test/CodeGen/PISA/intrinsics-attributes.ll | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index 176caabc4019d..d57ede801638f 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -59,7 +59,10 @@ 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>; + : PISAIntrinsicClang<[], param_types, + [IntrNoMem, IntrHasSideEffects, IntrConvergent, + IntrNoCallback, IntrNoFree, IntrWillReturn], + ClangName>; // Helper class for unary float operations with rounding mode. class PISAUnaryRndIntrinsic diff --git a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll index d70619ae093f9..eb62570ae732a 100644 --- a/llvm/test/CodeGen/PISA/intrinsics-attributes.ll +++ b/llvm/test/CodeGen/PISA/intrinsics-attributes.ll @@ -24,6 +24,6 @@ define void @test(ptr %addr) { ; CHECK-DAG: attributes [[CONVMEM]] = { convergent nocallback nofree nosync nounwind willreturn memory(none) } ; CHECK-DAG: attributes [[ATOM]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ; CHECK-DAG: attributes [[NOMEM]] = { nocallback nofree nosync nounwind willreturn memory(none) } -; CHECK-DAG: attributes [[CONV]] = { convergent nounwind } +; CHECK-DAG: attributes [[CONV]] = { convergent nocallback nofree nounwind willreturn } declare float @llvm.pisa.cas.fatom.f32.p0(ptr, float, float, i8 immarg) >From 33c0cba27879ed2df46fb97a208bb79b1e24d6aa Mon Sep 17 00:00:00 2001 From: Michal Paszkowski <[email protected]> Date: Mon, 21 Sep 2026 10:07:27 +0000 Subject: [PATCH 11/11] Add RoundingModeArgInfo to PISAUnaryRndIntrinsic, PISABinaryRndIntrinsic, int_pisa_fptosi_rnd, int_pisa_fptoui_rnd --- llvm/include/llvm/IR/IntrinsicsPISA.td | 13 +++++++++---- llvm/test/CodeGen/PISA/intrinsics.ll | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsPISA.td b/llvm/include/llvm/IR/IntrinsicsPISA.td index d57ede801638f..310d4ff584027 100644 --- a/llvm/include/llvm/IR/IntrinsicsPISA.td +++ b/llvm/include/llvm/IR/IntrinsicsPISA.td @@ -66,12 +66,15 @@ class PISAIntrinsicBarrier<string ClangName, list<LLVMType> param_types = []> // Helper class for unary float operations with rounding mode. class PISAUnaryRndIntrinsic - : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>; + : PISADefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i8_ty], + [IntrNoMem, ImmArg<ArgIndex<1>>, + RoundingModeArgInfo<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>>]>; + [IntrNoMem, ImmArg<ArgIndex<2>>, + RoundingModeArgInfo<ArgIndex<2>>]>; // Helper class for float operations with rounding mode + saturation flag. class PISAFloatIntrinsic<LLVMType ret_ty, list<LLVMType> operand_types, @@ -212,9 +215,11 @@ def int_pisa_fptoui_md : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfl // 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>>]>; + [IntrNoMem, ImmArg<ArgIndex<1>>, + RoundingModeArgInfo<ArgIndex<1>>]>; def int_pisa_fptoui_rnd : PISADefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i8_ty], - [IntrNoMem, ImmArg<ArgIndex<1>>]>; + [IntrNoMem, ImmArg<ArgIndex<1>>, + RoundingModeArgInfo<ArgIndex<1>>]>; // Conversions with rounding mode + saturation flag. def int_pisa_sitofp : PISAFloatIntrinsic<llvm_anyfloat_ty, [llvm_anyint_ty]>; diff --git a/llvm/test/CodeGen/PISA/intrinsics.ll b/llvm/test/CodeGen/PISA/intrinsics.ll index 5dec3614ad54f..5a43a67173d3a 100644 --- a/llvm/test/CodeGen/PISA/intrinsics.ll +++ b/llvm/test/CodeGen/PISA/intrinsics.ll @@ -21,7 +21,21 @@ define float @test_cas_fatom(ptr %addr, float %compare, float %value) { ret float %result } +define i32 @test_rounding_mode_printer(float %x, float %y) { +; CHECK-LABEL: define i32 @test_rounding_mode_printer( + %sqrt = call float @llvm.pisa.fsqrt.rnd.f32(float %x, i8 0) +; CHECK: call float @llvm.pisa.fsqrt.rnd.f32(float %x, /* round=.rz */ i8 0) + %div = call float @llvm.pisa.fdiv.rnd.f32(float %x, float %y, i8 1) +; CHECK: call float @llvm.pisa.fdiv.rnd.f32(float %x, float %y, /* round=.re */ i8 1) + %conv = call i32 @llvm.pisa.fptosi.rnd.i32.f32(float %div, i8 2) +; CHECK: call i32 @llvm.pisa.fptosi.rnd.i32.f32(float %div, /* round=.ru */ i8 2) + ret i32 %conv +} + declare i32 @llvm.pisa.lane.id() declare i32 @llvm.pisa.subgroup.size() declare i32 @llvm.pisa.work.dim() declare float @llvm.pisa.cas.fatom.f32.p0(ptr, float, float, i8 immarg) +declare float @llvm.pisa.fsqrt.rnd.f32(float, i8 immarg) +declare float @llvm.pisa.fdiv.rnd.f32(float, float, i8 immarg) +declare i32 @llvm.pisa.fptosi.rnd.i32.f32(float, i8 immarg) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
