[Mlir-commits] [mlir] [mlir] AMDGPUToROCDL: lower `amdgpu.swizzle_bitmode` (PR #136223)
Stanley Winata
llvmlistbot at llvm.org
Thu Apr 17 18:45:17 PDT 2025
================
@@ -381,3 +381,95 @@ LogicalResult LLVM::detail::oneToOneRewrite(
rewriter.replaceOp(op, results);
return success();
}
+
+static unsigned getBitWidth(Type type) {
+ if (type.isIntOrFloat())
+ return type.getIntOrFloatBitWidth();
+
+ auto vec = cast<VectorType>(type);
+ return vec.getNumElements() * getBitWidth(vec.getElementType());
+}
+
+static Value createI32Constant(OpBuilder &builder, Location loc,
+ int32_t value) {
+ Type i32 = builder.getI32Type();
+ return builder.create<LLVM::ConstantOp>(loc, i32, value);
+}
+
+SmallVector<Value> mlir::LLVM::decomposeValue(OpBuilder &builder, Location loc,
+ Value src, Type dstType) {
+ Type srcType = src.getType();
+ if (srcType == dstType)
+ return {src};
+
+ unsigned srcBitWidth = getBitWidth(srcType);
+ unsigned dstBitWidth = getBitWidth(dstType);
+ if (srcBitWidth == dstBitWidth) {
+ Value cast = builder.create<LLVM::BitcastOp>(loc, dstType, src);
+ return {cast};
+ }
+
+ if (dstBitWidth > srcBitWidth) {
+ auto smallerInt = builder.getIntegerType(srcBitWidth);
+ if (srcType != smallerInt)
+ src = builder.create<LLVM::BitcastOp>(loc, smallerInt, src);
+
+ auto largerInt = builder.getIntegerType(dstBitWidth);
+ Value res = builder.create<LLVM::ZExtOp>(loc, largerInt, src);
+ return {res};
+ }
+ assert(srcBitWidth % dstBitWidth == 0 &&
+ "src bit width must be a multiple of dst bit width");
+ int64_t numElements = srcBitWidth / dstBitWidth;
+ auto vecType = VectorType::get(numElements, dstType);
+
+ src = builder.create<LLVM::BitcastOp>(loc, vecType, src);
+
+ SmallVector<Value> res;
+ for (auto i : llvm::seq<int64_t>(0, numElements)) {
+ Value idx = createI32Constant(builder, loc, i);
+ Value elem = builder.create<LLVM::ExtractElementOp>(loc, src, idx);
+ res.emplace_back(elem);
+ }
+
+ return res;
+}
+
+Value mlir::LLVM::composeValue(OpBuilder &builder, Location loc, ValueRange src,
+ Type dstType) {
+ assert(!src.empty() && "src range must not be empty");
+ if (src.size() == 1) {
+ Value res = src.front();
+ if (res.getType() == dstType)
+ return res;
+
+ unsigned srcBitWidth = getBitWidth(res.getType());
+ unsigned dstBitWidth = getBitWidth(dstType);
+ if (dstBitWidth < srcBitWidth) {
+ auto largerInt = builder.getIntegerType(srcBitWidth);
+ if (res.getType() != largerInt)
+ res = builder.create<LLVM::BitcastOp>(loc, largerInt, res);
+
+ auto smallerInt = builder.getIntegerType(dstBitWidth);
+ res = builder.create<LLVM::TruncOp>(loc, smallerInt, res);
+ }
+
+ if (res.getType() != dstType)
+ res = builder.create<LLVM::BitcastOp>(loc, dstType, res);
+
+ return res;
+ }
+
+ int64_t numElements = src.size();
+ auto srcType = VectorType::get(numElements, src.front().getType());
+ Value res = builder.create<LLVM::PoisonOp>(loc, srcType);
----------------
raikonenfnu wrote:
can you explain a little how this poisonOp work for setting up the vector to be bitcasted? any reasons we do not just initialize the vector with the first value?
https://github.com/llvm/llvm-project/pull/136223
More information about the Mlir-commits
mailing list