@@ -839,34 +839,28 @@ void LoadOp::getEffects(
839839}
840840
841841// / Returns true if the given type is supported by atomic operations. All
842- // / integer and float types with limited bit width are supported. Additionally,
843- // / depending on the operation pointers may be supported as well.
844- static bool isTypeCompatibleWithAtomicOp (Type type, bool isPointerTypeAllowed) {
845- if (llvm::isa<LLVMPointerType>(type))
846- return isPointerTypeAllowed;
847-
848- std::optional<unsigned > bitWidth;
849- if (auto floatType = llvm::dyn_cast<FloatType>(type)) {
842+ // / integer, float, and pointer types with a power-of-two bitsize and a minimal
843+ // / size of 8 bits are supported.
844+ static bool isTypeCompatibleWithAtomicOp (Type type,
845+ const DataLayout &dataLayout) {
846+ if (!isa<IntegerType, LLVMPointerType>(type))
850847 if (!isCompatibleFloatingPointType (type))
851848 return false ;
852- bitWidth = floatType.getWidth ();
853- }
854- if (auto integerType = llvm::dyn_cast<IntegerType>(type))
855- bitWidth = integerType.getWidth ();
856- // The type is neither an integer, float, or pointer type.
857- if (!bitWidth)
849+
850+ llvm::TypeSize bitWidth = dataLayout.getTypeSizeInBits (type);
851+ if (bitWidth.isScalable ())
858852 return false ;
859- return *bitWidth == 8 || *bitWidth == 16 || *bitWidth == 32 ||
860- * bitWidth == 64 ;
853+ // Needs to be at least 8 bits and a power of two.
854+ return bitWidth >= 8 && (bitWidth & ( bitWidth - 1 )) == 0 ;
861855}
862856
863857// / Verifies the attributes and the type of atomic memory access operations.
864858template <typename OpTy>
865859LogicalResult verifyAtomicMemOp (OpTy memOp, Type valueType,
866860 ArrayRef<AtomicOrdering> unsupportedOrderings) {
867861 if (memOp.getOrdering () != AtomicOrdering::not_atomic) {
868- if (! isTypeCompatibleWithAtomicOp (valueType,
869- /* isPointerTypeAllowed= */ true ))
862+ DataLayout dataLayout = DataLayout::closest (memOp);
863+ if (! isTypeCompatibleWithAtomicOp (valueType, dataLayout ))
870864 return memOp.emitOpError (" unsupported type " )
871865 << valueType << " for atomic access" ;
872866 if (llvm::is_contained (unsupportedOrderings, memOp.getOrdering ()))
@@ -2694,7 +2688,8 @@ LogicalResult AtomicRMWOp::verify() {
26942688 if (!mlir::LLVM::isCompatibleFloatingPointType (valType))
26952689 return emitOpError (" expected LLVM IR floating point type" );
26962690 } else if (getBinOp () == AtomicBinOp::xchg) {
2697- if (!isTypeCompatibleWithAtomicOp (valType, /* isPointerTypeAllowed=*/ true ))
2691+ DataLayout dataLayout = DataLayout::closest (*this );
2692+ if (!isTypeCompatibleWithAtomicOp (valType, dataLayout))
26982693 return emitOpError (" unexpected LLVM IR type for 'xchg' bin_op" );
26992694 } else {
27002695 auto intType = llvm::dyn_cast<IntegerType>(valType);
@@ -2741,8 +2736,8 @@ LogicalResult AtomicCmpXchgOp::verify() {
27412736 if (!ptrType)
27422737 return emitOpError (" expected LLVM IR pointer type for operand #0" );
27432738 auto valType = getVal ().getType ();
2744- if (! isTypeCompatibleWithAtomicOp (valType,
2745- /* isPointerTypeAllowed= */ true ))
2739+ DataLayout dataLayout = DataLayout::closest (* this );
2740+ if (! isTypeCompatibleWithAtomicOp (valType, dataLayout ))
27462741 return emitOpError (" unexpected LLVM IR type" );
27472742 if (getSuccessOrdering () < AtomicOrdering::monotonic ||
27482743 getFailureOrdering () < AtomicOrdering::monotonic)
0 commit comments