@@ -839,34 +839,28 @@ void LoadOp::getEffects(
839
839
}
840
840
841
841
// / 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))
850
847
if (!isCompatibleFloatingPointType (type))
851
848
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 ())
858
852
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 ;
861
855
}
862
856
863
857
// / Verifies the attributes and the type of atomic memory access operations.
864
858
template <typename OpTy>
865
859
LogicalResult verifyAtomicMemOp (OpTy memOp, Type valueType,
866
860
ArrayRef<AtomicOrdering> unsupportedOrderings) {
867
861
if (memOp.getOrdering () != AtomicOrdering::not_atomic) {
868
- if (! isTypeCompatibleWithAtomicOp (valueType,
869
- /* isPointerTypeAllowed= */ true ))
862
+ DataLayout dataLayout = DataLayout::closest (memOp);
863
+ if (! isTypeCompatibleWithAtomicOp (valueType, dataLayout ))
870
864
return memOp.emitOpError (" unsupported type " )
871
865
<< valueType << " for atomic access" ;
872
866
if (llvm::is_contained (unsupportedOrderings, memOp.getOrdering ()))
@@ -2694,7 +2688,8 @@ LogicalResult AtomicRMWOp::verify() {
2694
2688
if (!mlir::LLVM::isCompatibleFloatingPointType (valType))
2695
2689
return emitOpError (" expected LLVM IR floating point type" );
2696
2690
} else if (getBinOp () == AtomicBinOp::xchg) {
2697
- if (!isTypeCompatibleWithAtomicOp (valType, /* isPointerTypeAllowed=*/ true ))
2691
+ DataLayout dataLayout = DataLayout::closest (*this );
2692
+ if (!isTypeCompatibleWithAtomicOp (valType, dataLayout))
2698
2693
return emitOpError (" unexpected LLVM IR type for 'xchg' bin_op" );
2699
2694
} else {
2700
2695
auto intType = llvm::dyn_cast<IntegerType>(valType);
@@ -2741,8 +2736,8 @@ LogicalResult AtomicCmpXchgOp::verify() {
2741
2736
if (!ptrType)
2742
2737
return emitOpError (" expected LLVM IR pointer type for operand #0" );
2743
2738
auto valType = getVal ().getType ();
2744
- if (! isTypeCompatibleWithAtomicOp (valType,
2745
- /* isPointerTypeAllowed= */ true ))
2739
+ DataLayout dataLayout = DataLayout::closest (* this );
2740
+ if (! isTypeCompatibleWithAtomicOp (valType, dataLayout ))
2746
2741
return emitOpError (" unexpected LLVM IR type" );
2747
2742
if (getSuccessOrdering () < AtomicOrdering::monotonic ||
2748
2743
getFailureOrdering () < AtomicOrdering::monotonic)
0 commit comments