23#include "llvm/Support/MathExtras.h"
26#define GEN_PASS_DEF_AMDGPUMASKEDLOADTOLOADPASS
27#include "mlir/Dialect/AMDGPU/Transforms/Passes.h.inc"
36 auto memRefType = dyn_cast<MemRefType>(type);
40 Attribute addrSpace = memRefType.getMemorySpace();
41 if (!isa_and_nonnull<amdgpu::AddressSpaceAttr>(addrSpace))
44 if (dyn_cast<amdgpu::AddressSpaceAttr>(addrSpace).getValue() !=
45 amdgpu::AddressSpace::FatRawBuffer)
52 vector::MaskedLoadOp maskedOp,
54 VectorType vectorType = maskedOp.getVectorType();
56 builder, loc, vectorType, maskedOp.getBase(), maskedOp.getIndices());
58 load = arith::SelectOp::create(builder, loc, vectorType, maskedOp.getMask(),
59 load, maskedOp.getPassThru());
68 if (isa<VectorType>(broadcastOp.getSourceType()))
70 return broadcastOp.getSource();
74 "amdgpu.buffer_maskedload_needs_mask";
81 LogicalResult matchAndRewrite(vector::MaskedLoadOp maskedOp,
88 maskedOp,
"isn't a load from a fat buffer resource");
102 Value src = maskedOp.getBase();
104 VectorType vectorType = maskedOp.getVectorType();
105 int64_t vectorSize = vectorType.getNumElements();
106 int64_t elementBitWidth = vectorType.getElementTypeBitWidth();
109 auto stridedMetadata =
110 memref::ExtractStridedMetadataOp::create(rewriter, loc, src);
112 stridedMetadata.getConstifiedMixedStrides();
114 OpFoldResult offset = stridedMetadata.getConstifiedMixedOffset();
117 std::tie(linearizedInfo, linearizedIndices) =
119 elementBitWidth, offset, sizes,
123 Value vectorSizeOffset =
129 Value delta = arith::SubIOp::create(rewriter, loc, totalSize, linearIndex);
132 Value isOutofBounds = arith::CmpIOp::create(
133 rewriter, loc, arith::CmpIPredicate::ult, delta, vectorSizeOffset);
137 rewriter, loc, llvm::divideCeil(32, elementBitWidth));
138 Value isNotWordAligned = arith::CmpIOp::create(
139 rewriter, loc, arith::CmpIPredicate::ne,
140 arith::RemUIOp::create(rewriter, loc, delta, elementsPerWord),
148 arith::AndIOp::create(rewriter, loc, isOutofBounds, isNotWordAligned);
154 scf::YieldOp::create(builder, loc, readResult);
160 scf::YieldOp::create(rewriter, loc, res);
164 scf::IfOp::create(rewriter, loc, ifCondition, thenBuilder, elseBuilder);
172struct FullMaskedLoadToConditionalLoad
176 LogicalResult matchAndRewrite(vector::MaskedLoadOp loadOp,
180 loadOp,
"buffer loads are handled by a more specialized pattern");
182 FailureOr<Value> maybeCond =
matchFullMask(rewriter, loadOp.getMask());
183 if (failed(maybeCond)) {
185 "isn't loading a broadcasted scalar");
188 Value cond = maybeCond.value();
192 scf::YieldOp::create(rewriter, loc, res);
195 scf::YieldOp::create(rewriter, loc, loadOp.getPassThru());
197 auto ifOp = scf::IfOp::create(rewriter, loadOp.getLoc(), cond, trueBuilder,
204struct FullMaskedStoreToConditionalStore
208 LogicalResult matchAndRewrite(vector::MaskedStoreOp storeOp,
219 FailureOr<Value> maybeCond =
matchFullMask(rewriter, storeOp.getMask());
220 if (failed(maybeCond)) {
223 Value cond = maybeCond.value();
226 vector::StoreOp::create(rewriter, loc, storeOp.getValueToStore(),
227 storeOp.getBase(), storeOp.getIndices());
228 scf::YieldOp::create(rewriter, loc);
231 scf::IfOp::create(rewriter, storeOp.getLoc(), cond, trueBuilder);
241 patterns.
add<MaskedLoadLowering, FullMaskedLoadToConditionalLoad,
242 FullMaskedStoreToConditionalStore>(patterns.
getContext(),
247 : amdgpu::impl::AmdgpuMaskedloadToLoadPassBase<AmdgpuMaskedloadToLoadPass> {
252 return signalPassFailure();
static Value createVectorLoadForMaskedLoad(OpBuilder &builder, Location loc, vector::MaskedLoadOp maskedOp, bool passthru)
static constexpr char kMaskedloadNeedsMask[]
static FailureOr< Value > matchFullMask(OpBuilder &b, Value val)
Check if the given value comes from a broadcasted i1 condition.
static LogicalResult hasBufferAddressSpace(Type type)
This pattern supports lowering of: vector.maskedload to vector.load and arith.select if the memref is...
Attributes are known-constant values of operations.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This class helps build Operations.
Operation * clone(Operation &op, IRMapping &mapper)
Creates a deep copy of the specified operation, remapping any operands that use values outside of the...
This class represents a single result from folding an operation.
Operation is the basic unit of execution within MLIR.
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
static ConstantIndexOp create(OpBuilder &builder, Location location, int64_t value)
void populateAmdgpuMaskedloadToLoadPatterns(RewritePatternSet &patterns, PatternBenefit benefit=1)
std::pair< LinearizedMemRefInfo, OpFoldResult > getLinearizedMemRefOffsetAndSize(OpBuilder &builder, Location loc, int srcBits, int dstBits, OpFoldResult offset, ArrayRef< OpFoldResult > sizes, ArrayRef< OpFoldResult > strides, ArrayRef< OpFoldResult > indices={}, LinearizedDivKind sizeDivKind=LinearizedDivKind::Floor)
Include the generated interface declarations.
LogicalResult applyPatternsGreedily(Region ®ion, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
Value getValueOrCreateConstantIndexOp(OpBuilder &b, Location loc, OpFoldResult ofr)
Converts an OpFoldResult to a Value.
void runOnOperation() override
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})
Patterns must specify the root operation name they match against, and can also specify the benefit of...
For a memref with offset, sizes and strides, returns the offset, size, and potentially the size padde...
OpFoldResult linearizedSize