[Mlir-commits] [mlir] [MLIR][Mem2Reg][LLVM] Enhance partial load support (PR #89094)
Théo Degioanni
llvmlistbot at llvm.org
Wed Apr 17 10:34:10 PDT 2024
================
@@ -122,37 +123,119 @@ bool LLVM::StoreOp::storesTo(const MemorySlot &slot) {
return getAddr() == slot.ptr;
}
-/// Checks that two types are the same or can be cast into one another.
-static bool areCastCompatible(const DataLayout &layout, Type lhs, Type rhs) {
- return lhs == rhs || (!isa<LLVM::LLVMStructType, LLVM::LLVMArrayType>(lhs) &&
- !isa<LLVM::LLVMStructType, LLVM::LLVMArrayType>(rhs) &&
- layout.getTypeSize(lhs) == layout.getTypeSize(rhs));
+/// Checks if `type` can be used in any kind of conversion sequences.
+static bool isSupportedTypeForConversion(Type type) {
+ // Aggregate types are not bitcastable.
+ if (isa<LLVM::LLVMStructType, LLVM::LLVMArrayType>(type))
+ return false;
+
+ // LLVM vector types are only used for either pointers or target specific
+ // types. These types cannot be casted in the general case, thus the memory
+ // optimizations do not support them.
+ if (isa<LLVM::LLVMFixedVectorType, LLVM::LLVMScalableVectorType>(type))
+ return false;
+
+ // Scalable types are not supported.
+ if (auto vectorType = dyn_cast<VectorType>(type))
+ return !vectorType.isScalable();
+ return true;
}
+/// Checks that `rhs` can be converted to `lhs` by a sequence of casts and
+/// truncations.
+static bool areConversionCompatible(const DataLayout &layout, Type lhs,
+ Type rhs) {
+ if (lhs == rhs)
+ return true;
+
+ if (!isSupportedTypeForConversion(lhs) || !isSupportedTypeForConversion(rhs))
+ return false;
+
+ // Pointer casts will only be sane when the bitsize of both pointer types is
+ // the same.
+ if (isa<LLVM::LLVMPointerType>(lhs) && isa<LLVM::LLVMPointerType>(rhs))
+ return layout.getTypeSize(lhs) == layout.getTypeSize(rhs);
+
+ return layout.getTypeSize(lhs) <= layout.getTypeSize(rhs);
+}
+
+/// Checks if `dataLayout` describes a little endian layout.
+static bool isLittleEndian(const DataLayout &dataLayout) {
+ auto endiannessStr = dyn_cast_or_null<StringAttr>(dataLayout.getEndianness());
+ return !endiannessStr || endiannessStr == "little";
+}
+
+/// The size of a byte in bits.
+constexpr const static uint64_t kBitsInByte = 8;
+
/// Constructs operations that convert `inputValue` into a new value of type
/// `targetType`. Assumes that this conversion is possible.
static Value createConversionSequence(RewriterBase &rewriter, Location loc,
- Value inputValue, Type targetType) {
- if (inputValue.getType() == targetType)
- return inputValue;
-
- if (!isa<LLVM::LLVMPointerType>(targetType) &&
- !isa<LLVM::LLVMPointerType>(inputValue.getType()))
- return rewriter.createOrFold<LLVM::BitcastOp>(loc, targetType, inputValue);
+ Value srcValue, Type targetType,
+ const DataLayout &dataLayout) {
+ // Get the types of the source and target values.
+ Type srcType = srcValue.getType();
+ assert(areConversionCompatible(dataLayout, targetType, srcType) &&
+ "expected that the compatibility was checked before");
+
+ uint64_t srcTypeSize = dataLayout.getTypeSize(srcType);
+ uint64_t targetTypeSize = dataLayout.getTypeSize(targetType);
+
+ // Nothing has to be done if the types are already the same.
+ if (srcType == targetType)
+ return srcValue;
+
+ // In the special case of casting one pointer to another, we want to generate
+ // an address space cast. Bitcasts of pointers are not allowed and using
+ // pointer to integer conversions are not equivalent due to the loss or
+ // provenance.
----------------
Moxinilian wrote:
I assume you meant
```suggestion
// pointer to integer conversions are not equivalent due to the loss of
// provenance.
```
https://github.com/llvm/llvm-project/pull/89094
More information about the Mlir-commits
mailing list