Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion flang/lib/Optimizer/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3202,7 +3202,8 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {

if (global.getDataAttr() &&
*global.getDataAttr() == cuf::DataAttribute::Shared)
g.setAddrSpace(mlir::NVVM::NVVMMemorySpace::kSharedMemorySpace);
g.setAddrSpace(
static_cast<unsigned>(mlir::NVVM::NVVMMemorySpace::Shared));

rewriter.eraseOp(global);
return mlir::success();
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Optimizer/Transforms/CUFGPUToLLVMConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ static mlir::Value createAddressOfOp(mlir::ConversionPatternRewriter &rewriter,
gpu::GPUModuleOp gpuMod,
std::string &sharedGlobalName) {
auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(
rewriter.getContext(), mlir::NVVM::NVVMMemorySpace::kSharedMemorySpace);
rewriter.getContext(),
static_cast<unsigned>(mlir::NVVM::NVVMMemorySpace::Shared));
if (auto g = gpuMod.lookupSymbol<fir::GlobalOp>(sharedGlobalName))
return mlir::LLVM::AddressOfOp::create(rewriter, loc, llvmPtrTy,
g.getSymName());
Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class LLVM_Attr<string name, string attrMnemonic,

def LLVM_AddressSpaceAttr :
LLVM_Attr<"AddressSpace", "address_space", [
LLVM_LLVMAddrSpaceAttrInterface,
DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
]> {
let summary = "LLVM address space";
Expand Down
8 changes: 8 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ class TBAANodeAttr : public Attribute {
using cconv::CConv;
using linkage::Linkage;
using tailcallkind::TailCallKind;

namespace detail {
/// Checks whether the given type is an LLVM type that can be loaded or stored.
bool isValidLoadStoreImpl(Type type, ptr::AtomicOrdering ordering,
std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError);
} // namespace detail
} // namespace LLVM
} // namespace mlir

Expand Down
18 changes: 18 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,24 @@ def LLVM_DIRecursiveTypeAttrInterface
];
}

def LLVM_LLVMAddrSpaceAttrInterface :
AttrInterface<"LLVMAddrSpaceAttrInterface"> {
let description = [{
An interface for attributes that represent LLVM address spaces.
Implementing attributes should provide access to the address space value
as an unsigned integer.
}];
let cppNamespace = "::mlir::LLVM";
let methods = [
InterfaceMethod<
/*description=*/"Returns the address space as an unsigned integer.",
/*retTy=*/"unsigned",
/*methodName=*/"getAddressSpace",
/*args=*/(ins)
>
];
}

def LLVM_TargetAttrInterface
: AttrInterface<"TargetAttrInterface", [DLTIQueryInterface]> {
let description = [{
Expand Down
35 changes: 14 additions & 21 deletions mlir/include/mlir/Dialect/LLVMIR/NVVMDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/NVVMRequiresSMTraits.h"
#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/Interfaces/InferIntRangeInterface.h"
Expand All @@ -30,31 +31,23 @@

namespace mlir {
namespace NVVM {
/// Utility functions to compare NVVMMemorySpace with unsigned values.
inline bool operator==(unsigned as, NVVMMemorySpace memSpace) {
return as == static_cast<unsigned>(memSpace);
}
inline bool operator==(NVVMMemorySpace memSpace, unsigned as) {
return static_cast<unsigned>(memSpace) == as;
}
inline bool operator!=(unsigned as, NVVMMemorySpace memSpace) {
return as != static_cast<unsigned>(memSpace);
}
inline bool operator!=(NVVMMemorySpace memSpace, unsigned as) {
return static_cast<unsigned>(memSpace) != as;
}

// Shared memory has 128-bit alignment
constexpr int kSharedMemoryAlignmentBit = 128;

/// NVVM memory space identifiers.
enum NVVMMemorySpace {
/// Generic memory space identifier.
kGenericMemorySpace = 0,
/// Global memory space identifier.
kGlobalMemorySpace = 1,
/// Shared memory space identifier.
kSharedMemorySpace = 3,
/// Constant memory space identifier.
kConstantMemorySpace = 4,
/// Local memory space identifier.
kLocalMemorySpace = 5,
/// Tensor memory space identifier.
/// Tensor memory is available only in arch-accelerated
/// variants from sm100 onwards.
kTensorMemorySpace = 6,
/// Distributed shared memory space identifier.
/// Distributed shared memory is available only in sm90+.
kSharedClusterMemorySpace = 7,
};

/// A pair type of LLVM's Intrinsic ID and args (which are llvm values).
/// This type is returned by the getIntrinsicIDAndArgs() methods.
using IDArgPair =
Expand Down
37 changes: 36 additions & 1 deletion mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ include "mlir/IR/EnumAttr.td"
include "mlir/Dialect/GPU/IR/CompilationAttrInterfaces.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
include "mlir/Dialect/LLVMIR/NVVMRequiresSMTraits.td"
include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.td"
include "mlir/Interfaces/InferIntRangeInterface.td"
Expand Down Expand Up @@ -192,6 +193,40 @@ def CacheEvictionPriorityAttr : EnumAttr<NVVM_Dialect, CacheEvictionPriority,
let assemblyFormat = "$value";
}

// Memory Space enum definitions
/// Generic memory space identifier.
def MemSpaceGeneric : I32EnumCase<"Generic", 0, "generic">;
/// Global memory space identifier.
def MemSpaceGlobal : I32EnumCase<"Global", 1, "global">;
/// Shared memory space identifier.
def MemSpaceShared : I32EnumCase<"Shared", 3, "shared">;
/// Constant memory space identifier.
def MemSpaceConstant : I32EnumCase<"Constant", 4, "constant">;
/// Local memory space identifier.
def MemSpaceLocal : I32EnumCase<"Local", 5, "local">;
/// Tensor memory space identifier.
/// Tensor memory is available only in arch-accelerated
/// variants from sm100 onwards.
def MemSpaceTensor : I32EnumCase<"Tensor", 6, "tensor">;
/// Distributed shared memory space identifier.
/// Distributed shared memory is available only in sm90+.
def MemSpaceSharedCluster : I32EnumCase<"SharedCluster", 7, "shared_cluster">;

def NVVMMemorySpace : I32Enum<"NVVMMemorySpace", "NVVM Memory Space",
[MemSpaceGeneric, MemSpaceGlobal, MemSpaceShared,
MemSpaceConstant, MemSpaceLocal, MemSpaceTensor,
MemSpaceSharedCluster]> {
let cppNamespace = "::mlir::NVVM";
}

def NVVMMemorySpaceAttr :
EnumAttr<NVVM_Dialect, NVVMMemorySpace, "memory_space", [
DeclareAttrInterfaceMethods<LLVM_LLVMAddrSpaceAttrInterface>,
DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
]> {
let assemblyFormat = "`<` $value `>`";
}

//===----------------------------------------------------------------------===//
// NVVM intrinsic operations
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -3592,7 +3627,7 @@ def NVVM_MapaOp: NVVM_Op<"mapa",
string llvmBuilder = [{
int addrSpace = llvm::cast<LLVMPointerType>(op.getA().getType()).getAddressSpace();

bool isSharedMemory = addrSpace == NVVM::NVVMMemorySpace::kSharedMemorySpace;
bool isSharedMemory = addrSpace == static_cast<int> (NVVM::NVVMMemorySpace::Shared);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabianmcg is this supposed to be a static_cast<unsigned>? If not, why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right, that should be an unsigned cast, line 3628 also should be changed to unsigned.


auto intId = isSharedMemory? llvm::Intrinsic::nvvm_mapa_shared_cluster : llvm::Intrinsic::nvvm_mapa;
$res = createIntrinsicCall(builder, intId, {$a, $b});
Expand Down
10 changes: 4 additions & 6 deletions mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,16 +451,14 @@ void mlir::configureGpuToNVVMTypeConverter(LLVMTypeConverter &converter) {
converter, [](gpu::AddressSpace space) -> unsigned {
switch (space) {
case gpu::AddressSpace::Global:
return static_cast<unsigned>(
NVVM::NVVMMemorySpace::kGlobalMemorySpace);
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Global);
case gpu::AddressSpace::Workgroup:
return static_cast<unsigned>(
NVVM::NVVMMemorySpace::kSharedMemorySpace);
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Shared);
case gpu::AddressSpace::Private:
return 0;
}
llvm_unreachable("unknown address space enum value");
return 0;
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Generic);
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change modifies the control flow by adding a return statement in the default case. This could affect performance profiling data by changing the execution path from an unreachable code path to a valid return.

Copilot generated this review using guidance from repository custom instructions.

});
// Lowering for MMAMatrixType.
converter.addConversion([&](gpu::MMAMatrixType type) -> Type {
Expand Down Expand Up @@ -648,7 +646,7 @@ void mlir::populateGpuToNVVMConversionPatterns(
GPUFuncOpLoweringOptions{
/*allocaAddrSpace=*/0,
/*workgroupAddrSpace=*/
static_cast<unsigned>(NVVM::NVVMMemorySpace::kSharedMemorySpace),
static_cast<unsigned>(NVVM::NVVMMemorySpace::Shared),
StringAttr::get(&converter.getContext(),
NVVM::NVVMDialect::getKernelFuncAttrName()),
StringAttr::get(&converter.getContext(),
Expand Down
10 changes: 4 additions & 6 deletions mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,16 +405,14 @@ struct ConvertNVGPUToNVVMPass
converter, [](gpu::AddressSpace space) -> unsigned {
switch (space) {
case gpu::AddressSpace::Global:
return static_cast<unsigned>(
NVVM::NVVMMemorySpace::kGlobalMemorySpace);
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Global);
case gpu::AddressSpace::Workgroup:
return static_cast<unsigned>(
NVVM::NVVMMemorySpace::kSharedMemorySpace);
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Shared);
case gpu::AddressSpace::Private:
return 0;
}
llvm_unreachable("unknown address space enum value");
return 0;
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Generic);
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change modifies the control flow by adding a return statement in the default case. This could affect performance profiling data by changing the execution path from an unreachable code path to a valid return.

Copilot generated this review using guidance from repository custom instructions.

});
/// device-side async tokens cannot be materialized in nvvm. We just
/// convert them to a dummy i32 type in order to easily drop them during
Expand Down Expand Up @@ -677,7 +675,7 @@ struct NVGPUAsyncCopyLowering
adaptor.getSrcIndices());
// Intrinsics takes a global pointer so we need an address space cast.
auto srcPointerGlobalType = LLVM::LLVMPointerType::get(
op->getContext(), NVVM::NVVMMemorySpace::kGlobalMemorySpace);
op->getContext(), static_cast<unsigned>(NVVM::NVVMMemorySpace::Global));
scrPtr = LLVM::AddrSpaceCastOp::create(b, srcPointerGlobalType, scrPtr);
int64_t dstElements = adaptor.getDstElements().getZExtValue();
int64_t sizeInBytes =
Expand Down
8 changes: 3 additions & 5 deletions mlir/lib/Dialect/GPU/TransformOps/GPUTransformOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,14 @@ void transform::ApplyGPUToNVVMConversionPatternsOp::populatePatterns(
llvmTypeConverter, [](AddressSpace space) -> unsigned {
switch (space) {
case AddressSpace::Global:
return static_cast<unsigned>(
NVVM::NVVMMemorySpace::kGlobalMemorySpace);
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Global);
case AddressSpace::Workgroup:
return static_cast<unsigned>(
NVVM::NVVMMemorySpace::kSharedMemorySpace);
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Shared);
case AddressSpace::Private:
return 0;
}
llvm_unreachable("unknown address space enum value");
return 0;
return static_cast<unsigned>(NVVM::NVVMMemorySpace::Generic);
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change modifies the control flow by adding a return statement in the default case. This could affect performance profiling data by changing the execution path from an unreachable code path to a valid return.

Copilot generated this review using guidance from repository custom instructions.

});
// Used in GPUToNVVM/WmmaOpsToNvvm.cpp so attaching here for now.
// TODO: We should have a single to_nvvm_type_converter.
Expand Down
14 changes: 8 additions & 6 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ void LLVMDialect::registerAttributes() {
//===----------------------------------------------------------------------===//

/// Checks whether the given type is an LLVM type that can be loaded or stored.
static bool isValidLoadStoreImpl(Type type, ptr::AtomicOrdering ordering,
std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) {
bool LLVM::detail::isValidLoadStoreImpl(
Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) {
if (!isLoadableType(type)) {
if (emitError)
emitError() << "type must be LLVM type with size, but got " << type;
Expand All @@ -87,14 +87,16 @@ bool AddressSpaceAttr::isValidLoad(
Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) const {
return isValidLoadStoreImpl(type, ordering, alignment, dataLayout, emitError);
return detail::isValidLoadStoreImpl(type, ordering, alignment, dataLayout,
emitError);
}

bool AddressSpaceAttr::isValidStore(
Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) const {
return isValidLoadStoreImpl(type, ordering, alignment, dataLayout, emitError);
return detail::isValidLoadStoreImpl(type, ordering, alignment, dataLayout,
emitError);
}

bool AddressSpaceAttr::isValidAtomicOp(
Expand Down
6 changes: 3 additions & 3 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,14 +703,14 @@ const llvm::fltSemantics &LLVMPPCFP128Type::getFloatSemantics() const {
//===----------------------------------------------------------------------===//

/// Check whether type is a compatible ptr type. These are pointer-like types
/// with no element type, no metadata, and using the LLVM AddressSpaceAttr
/// memory space.
/// with no element type, no metadata, and using the LLVM
/// LLVMAddrSpaceAttrInterface memory space.
static bool isCompatiblePtrType(Type type) {
auto ptrTy = dyn_cast<PtrLikeTypeInterface>(type);
if (!ptrTy)
return false;
return !ptrTy.hasPtrMetadata() && ptrTy.getElementType() == nullptr &&
isa<AddressSpaceAttr>(ptrTy.getMemorySpace());
isa<LLVMAddrSpaceAttrInterface>(ptrTy.getMemorySpace());
}

bool mlir::LLVM::isCompatibleOuterType(Type type) {
Expand Down
Loading
Loading