MLIR 24.0.0git
PromoteShuffleToAMDGPU.cpp
Go to the documentation of this file.
1//===- PromoteShuffleToAMDGPU.cpp - Promote shuffle to AMDGPU -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains patterns to try to promote `gpu.shuffle`s to specialized
10// AMDGPU intrinsics.
11//
12//===----------------------------------------------------------------------===//
13
16
21#include <optional>
22
23using namespace mlir;
24
25namespace {
26/// Try to promote `gpu.shuffle` to `amdgpu.swizzle_bitmode`, width must be 64
27/// and offset must be a constant integer in the range [0, 31].
28struct PromoteShuffleToSwizzlePattern
29 : public OpRewritePattern<gpu::ShuffleOp> {
30 using Base::Base;
31
32 LogicalResult matchAndRewrite(gpu::ShuffleOp op,
33 PatternRewriter &rewriter) const override {
34 if (op.getMode() != gpu::ShuffleMode::XOR)
35 return rewriter.notifyMatchFailure(op,
36 "only xor shuffle mode is supported");
37
38 if (!isConstantIntValue(op.getWidth(), 64))
39 return rewriter.notifyMatchFailure(op,
40 "only 64 width shuffle is supported");
41
42 std::optional<int64_t> offset = getConstantIntValue(op.getOffset());
43 if (!offset)
44 return rewriter.notifyMatchFailure(op,
45 "offset must be a constant integer");
46
47 int64_t offsetValue = *offset;
48 if (offsetValue < 0 || offsetValue >= 32)
49 return rewriter.notifyMatchFailure(op,
50 "offset must be in the range [0, 31]");
51
52 Location loc = op.getLoc();
53 Value res = amdgpu::SwizzleBitModeOp::create(
54 rewriter, loc, op.getResult(0).getType(), op.getValue(),
55 /*and_mask=*/31,
56 /*orMask=*/0, /*xorMask=*/offsetValue);
57 Value valid = arith::ConstantIntOp::create(rewriter, loc, 1, /*width*/ 1);
58 rewriter.replaceOp(op, {res, valid});
59 return success();
60 }
61};
62
63/// Try to promote `gpu.shuffle` to `amdgpu.permlane_swap`, width must be 64
64/// and offset must be a constant integer in the set {16, 32}.
65struct PromoteShuffleToPermlanePattern
66 : public OpRewritePattern<gpu::ShuffleOp> {
67 using Base::Base;
68
69 LogicalResult matchAndRewrite(gpu::ShuffleOp op,
70 PatternRewriter &rewriter) const override {
71 if (op.getMode() != gpu::ShuffleMode::XOR)
72 return rewriter.notifyMatchFailure(op,
73 "only xor shuffle mode is supported");
74
75 if (!isConstantIntValue(op.getWidth(), 64))
76 return rewriter.notifyMatchFailure(op,
77 "only 64 width shuffle is supported");
78
79 std::optional<int64_t> offset = getConstantIntValue(op.getOffset());
80 if (!offset)
81 return rewriter.notifyMatchFailure(op,
82 "offset must be a constant integer");
83
84 int64_t offsetValue = *offset;
85 if (offsetValue != 16 && offsetValue != 32)
86 return rewriter.notifyMatchFailure(op, "offset must be either 15 or 31");
87
88 Location loc = op.getLoc();
89 Value res = amdgpu::PermlaneSwapOp::create(
90 rewriter, loc, op.getResult(0).getType(), op.getValue(), offsetValue);
91 Value valid = arith::ConstantIntOp::create(rewriter, loc, 1, /*width*/ 1);
92 rewriter.replaceOp(op, {res, valid});
93 return success();
94 }
95};
96} // namespace
97
99 RewritePatternSet &patterns, std::optional<ROCDL::TargetInfo> target) {
100 patterns.add<PromoteShuffleToSwizzlePattern>(patterns.getContext(),
101 /*benefit*/ 1);
102 if (target && target->has(llvm::AMDGPU::FEAT_PERMLANE32_SWAP))
103 patterns.add<PromoteShuffleToPermlanePattern>(patterns.getContext(),
104 /*benefit*/ 2);
105}
return success()
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,...
static ConstantIntOp create(OpBuilder &builder, Location location, int64_t value, unsigned width)
Definition ArithOps.cpp:333
Include the generated interface declarations.
bool isConstantIntValue(OpFoldResult ofr, int64_t value)
Return true if ofr is constant integer equal to value.
void populateGpuPromoteShuffleToAMDGPUPatterns(RewritePatternSet &patterns, std::optional< ROCDL::TargetInfo > target)
Tries to promote gpu.shuffles to specialized AMDGPU intrinsics.
std::optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...