From 3fdbdf6c2b5f88549007eccc45503c52a40827b9 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 11 Jun 2024 09:22:05 +0100 Subject: [PATCH 1/5] mlir/MathExtras: consolidate with llvm/MathExtras This patch is part of a project to move the Presburger library into LLVM. --- llvm/include/llvm/Support/MathExtras.h | 40 ++++++++++++++- llvm/unittests/Support/MathExtrasTest.cpp | 22 ++++++-- .../mlir/Analysis/Presburger/Fraction.h | 1 - mlir/include/mlir/Analysis/Presburger/MPInt.h | 10 ++-- .../mlir/Analysis/Presburger/SlowMPInt.h | 1 - mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h | 4 +- mlir/include/mlir/Support/MathExtras.h | 51 ------------------- .../Analysis/FlatLinearValueConstraints.cpp | 1 - mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 1 - .../Conversion/LLVMCommon/MemRefBuilder.cpp | 10 ++-- .../Conversion/MemRefToLLVM/MemRefToLLVM.cpp | 6 +-- .../Affine/Analysis/AffineStructures.cpp | 1 - .../Dialect/Affine/Analysis/LoopAnalysis.cpp | 5 +- mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 6 ++- mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp | 1 - .../Dialect/ControlFlow/IR/ControlFlowOps.cpp | 1 - mlir/lib/Dialect/Func/IR/FuncOps.cpp | 1 - .../Linalg/TransformOps/GPUHeuristics.cpp | 4 +- .../MemRef/Transforms/EmulateNarrowType.cpp | 4 +- mlir/lib/Dialect/SCF/IR/SCF.cpp | 1 - .../Dialect/SCF/Transforms/LoopPipelining.cpp | 4 +- mlir/lib/Dialect/SCF/Utils/Utils.cpp | 4 +- mlir/lib/Dialect/Tensor/IR/TensorOps.cpp | 6 ++- mlir/lib/Dialect/Utils/StaticValueUtils.cpp | 4 +- .../Vector/Transforms/VectorUnroll.cpp | 1 - mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp | 1 - mlir/lib/IR/AffineExpr.cpp | 10 ++-- mlir/lib/IR/AffineMap.cpp | 6 ++- mlir/unittests/Support/CMakeLists.txt | 1 - mlir/unittests/Support/MathExtrasTest.cpp | 31 ----------- 30 files changed, 108 insertions(+), 131 deletions(-) delete mode 100644 mlir/include/mlir/Support/MathExtras.h delete mode 100644 mlir/unittests/Support/MathExtrasTest.cpp diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index f0e4ee534ece3..c5cac51130b1d 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h @@ -424,11 +424,47 @@ template constexpr inline uint64_t alignTo(uint64_t Value) { return (Value + Align - 1) / Align * Align; } -/// Returns the integer ceil(Numerator / Denominator). -inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { +/// Returns the integer ceil(Numerator / Denominator). Unsigned integer version. +LLVM_ATTRIBUTE_ALWAYS_INLINE uint64_t divideCeil(uint64_t Numerator, + uint64_t Denominator) { return alignTo(Numerator, Denominator) / Denominator; } +/// Returns the integer ceil(Numerator / Denominator). Signed integer version. +LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t ceilDiv(int64_t Numerator, + int64_t Denominator) { + assert(Denominator); + if (!Numerator) + return 0; + // C's integer division rounds towards 0. + int64_t X = (Denominator > 0) ? -1 : 1; + bool SameSign = (Numerator > 0) == (Denominator > 0); + return SameSign ? ((Numerator + X) / Denominator) + 1 + : -(-Numerator / Denominator); +} + +/// Returns the integer floor(Numerator / Denominator). Signed integer version. +LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t floorDiv(int64_t Numerator, + int64_t Denominator) { + assert(Denominator); + if (!Numerator) + return 0; + // C's integer division rounds towards 0. + int64_t X = (Denominator > 0) ? -1 : 1; + bool SameSign = (Numerator > 0) == (Denominator > 0); + return SameSign ? Numerator / Denominator + : -((-Numerator + X) / Denominator) - 1; +} + +/// Returns the remainder of the Euclidean division of LHS by RHS. Result is +/// always non-negative. +LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t mod(int64_t Numerator, + int64_t Denominator) { + assert(Denominator >= 1); + return Numerator % Denominator < 0 ? Numerator % Denominator + Denominator + : Numerator % Denominator; +} + /// Returns the integer nearest(Numerator / Denominator). inline uint64_t divideNearest(uint64_t Numerator, uint64_t Denominator) { return (Numerator + (Denominator / 2)) / Denominator; diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp index 67239a24c47ad..b32094e0acdfe 100644 --- a/llvm/unittests/Support/MathExtrasTest.cpp +++ b/llvm/unittests/Support/MathExtrasTest.cpp @@ -434,8 +434,25 @@ TEST(MathExtras, IsShiftedInt) { EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15))); } -template -class OverflowTest : public ::testing::Test { }; +TEST(MathExtras, CeilDivTest) { + EXPECT_EQ(ceilDiv(14, 3), 5); + EXPECT_EQ(ceilDiv(14, -3), -4); + EXPECT_EQ(ceilDiv(-14, -3), 5); + EXPECT_EQ(ceilDiv(-14, 3), -4); + EXPECT_EQ(ceilDiv(0, 3), 0); + EXPECT_EQ(ceilDiv(0, -3), 0); +} + +TEST(MathExtras, FloorDivTest) { + EXPECT_EQ(floorDiv(14, 3), 4); + EXPECT_EQ(floorDiv(14, -3), -5); + EXPECT_EQ(floorDiv(-14, -3), 4); + EXPECT_EQ(floorDiv(-14, 3), -5); + EXPECT_EQ(floorDiv(0, 3), 0); + EXPECT_EQ(floorDiv(0, -3), 0); +} + +template class OverflowTest : public ::testing::Test {}; using OverflowTestTypes = ::testing::Types; @@ -560,5 +577,4 @@ TYPED_TEST(OverflowTest, MulResultZero) { EXPECT_FALSE(MulOverflow(0, -5, Result)); EXPECT_EQ(Result, TypeParam(0)); } - } // namespace diff --git a/mlir/include/mlir/Analysis/Presburger/Fraction.h b/mlir/include/mlir/Analysis/Presburger/Fraction.h index c07bb767f50bf..f76ba3f006d07 100644 --- a/mlir/include/mlir/Analysis/Presburger/Fraction.h +++ b/mlir/include/mlir/Analysis/Presburger/Fraction.h @@ -15,7 +15,6 @@ #define MLIR_ANALYSIS_PRESBURGER_FRACTION_H #include "mlir/Analysis/Presburger/MPInt.h" -#include "mlir/Support/MathExtras.h" namespace mlir { namespace presburger { diff --git a/mlir/include/mlir/Analysis/Presburger/MPInt.h b/mlir/include/mlir/Analysis/Presburger/MPInt.h index 12ab0598d10d9..343f50251c7dc 100644 --- a/mlir/include/mlir/Analysis/Presburger/MPInt.h +++ b/mlir/include/mlir/Analysis/Presburger/MPInt.h @@ -17,7 +17,8 @@ #define MLIR_ANALYSIS_PRESBURGER_MPINT_H #include "mlir/Analysis/Presburger/SlowMPInt.h" -#include "mlir/Support/MathExtras.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include @@ -31,9 +32,10 @@ namespace presburger { /// from the mlir::presburger namespace. So to access the 64-bit overloads, an /// explict call to mlir::ceilDiv would be required. These using declarations /// allow overload resolution to transparently call the right function. -using ::mlir::ceilDiv; -using ::mlir::floorDiv; -using ::mlir::mod; +using ::llvm::ArrayRef; +using ::llvm::ceilDiv; +using ::llvm::floorDiv; +using ::llvm::mod; namespace detail { /// If builtin intrinsics for overflow-checked arithmetic are available, diff --git a/mlir/include/mlir/Analysis/Presburger/SlowMPInt.h b/mlir/include/mlir/Analysis/Presburger/SlowMPInt.h index c70306761c549..482581c573cea 100644 --- a/mlir/include/mlir/Analysis/Presburger/SlowMPInt.h +++ b/mlir/include/mlir/Analysis/Presburger/SlowMPInt.h @@ -18,7 +18,6 @@ #ifndef MLIR_ANALYSIS_PRESBURGER_SLOWMPINT_H #define MLIR_ANALYSIS_PRESBURGER_SLOWMPINT_H -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/Hashing.h" #include "llvm/Support/raw_ostream.h" diff --git a/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h b/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h index 7a24c201a39a7..0e39928b1d6a9 100644 --- a/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h +++ b/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h @@ -17,7 +17,7 @@ #include "mlir/IR/SymbolTable.h" #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" -#include "mlir/Support/MathExtras.h" +#include "llvm/Support/MathExtras.h" namespace mlir { namespace mesh { @@ -114,7 +114,7 @@ inline int64_t shardDimension(int64_t dimSize, int64_t shardCount) { return ShapedType::kDynamic; assert(dimSize % shardCount == 0); - return ceilDiv(dimSize, shardCount); + return llvm::ceilDiv(dimSize, shardCount); } // Get the size of an unsharded dimension. diff --git a/mlir/include/mlir/Support/MathExtras.h b/mlir/include/mlir/Support/MathExtras.h deleted file mode 100644 index 17a747393d26e..0000000000000 --- a/mlir/include/mlir/Support/MathExtras.h +++ /dev/null @@ -1,51 +0,0 @@ -//===- MathExtras.h - Math functions relevant to MLIR -----------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file contains math functions relevant to MLIR. -// -//===----------------------------------------------------------------------===// - -#ifndef MLIR_SUPPORT_MATHEXTRAS_H_ -#define MLIR_SUPPORT_MATHEXTRAS_H_ - -#include "mlir/Support/LLVM.h" -#include "llvm/ADT/APInt.h" - -namespace mlir { - -/// Returns the result of MLIR's ceildiv operation on constants. The RHS is -/// expected to be non-zero. -inline int64_t ceilDiv(int64_t lhs, int64_t rhs) { - assert(rhs != 0); - // C/C++'s integer division rounds towards 0. - int64_t x = (rhs > 0) ? -1 : 1; - return ((lhs != 0) && (lhs > 0) == (rhs > 0)) ? ((lhs + x) / rhs) + 1 - : -(-lhs / rhs); -} - -/// Returns the result of MLIR's floordiv operation on constants. The RHS is -/// expected to be non-zero. -inline int64_t floorDiv(int64_t lhs, int64_t rhs) { - assert(rhs != 0); - // C/C++'s integer division rounds towards 0. - int64_t x = (rhs < 0) ? 1 : -1; - return ((lhs != 0) && ((lhs < 0) != (rhs < 0))) ? -((-lhs + x) / rhs) - 1 - : lhs / rhs; -} - -/// Returns MLIR's mod operation on constants. MLIR's mod operation yields the -/// remainder of the Euclidean division of 'lhs' by 'rhs', and is therefore not -/// C's % operator. The RHS is always expected to be positive, and the result -/// is always non-negative. -inline int64_t mod(int64_t lhs, int64_t rhs) { - assert(rhs >= 1); - return lhs % rhs < 0 ? lhs % rhs + rhs : lhs % rhs; -} -} // namespace mlir - -#endif // MLIR_SUPPORT_MATHEXTRAS_H_ diff --git a/mlir/lib/Analysis/FlatLinearValueConstraints.cpp b/mlir/lib/Analysis/FlatLinearValueConstraints.cpp index bf7e3121ea32a..5c4f353f310d6 100644 --- a/mlir/lib/Analysis/FlatLinearValueConstraints.cpp +++ b/mlir/lib/Analysis/FlatLinearValueConstraints.cpp @@ -16,7 +16,6 @@ #include "mlir/IR/Builders.h" #include "mlir/IR/IntegerSet.h" #include "mlir/Support/LLVM.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp index 94b7c8d4f2fdf..744236692fbb6 100644 --- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp +++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp @@ -36,7 +36,6 @@ #include "mlir/IR/SymbolTable.h" #include "mlir/IR/TypeUtilities.h" #include "mlir/Support/LogicalResult.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" #include "llvm/ADT/SmallVector.h" diff --git a/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp b/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp index da084b89ceadc..0910a1ea076c0 100644 --- a/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp +++ b/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp @@ -12,7 +12,7 @@ #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/LLVMIR/LLVMTypes.h" #include "mlir/IR/Builders.h" -#include "mlir/Support/MathExtras.h" +#include "llvm/Support/MathExtras.h" using namespace mlir; @@ -363,9 +363,9 @@ void UnrankedMemRefDescriptor::computeSizes( // Initialize shared constants. Value one = createIndexAttrConstant(builder, loc, indexType, 1); Value two = createIndexAttrConstant(builder, loc, indexType, 2); - Value indexSize = - createIndexAttrConstant(builder, loc, indexType, - ceilDiv(typeConverter.getIndexTypeBitwidth(), 8)); + Value indexSize = createIndexAttrConstant( + builder, loc, indexType, + llvm::ceilDiv(typeConverter.getIndexTypeBitwidth(), 8)); sizes.reserve(sizes.size() + values.size()); for (auto [desc, addressSpace] : llvm::zip(values, addressSpaces)) { @@ -378,7 +378,7 @@ void UnrankedMemRefDescriptor::computeSizes( // to data layout) into the unranked descriptor. Value pointerSize = createIndexAttrConstant( builder, loc, indexType, - ceilDiv(typeConverter.getPointerBitwidth(addressSpace), 8)); + llvm::ceilDiv(typeConverter.getPointerBitwidth(addressSpace), 8)); Value doublePointerSize = builder.create(loc, indexType, two, pointerSize); diff --git a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp index 2dc42f0a85e66..d7eab77b97d0c 100644 --- a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp +++ b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp @@ -25,8 +25,8 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/IRMapping.h" #include "mlir/Pass/Pass.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/Support/MathExtras.h" #include namespace mlir { @@ -971,8 +971,8 @@ struct MemorySpaceCastOpLowering resultUnderlyingDesc, resultElemPtrType); int64_t bytesToSkip = - 2 * - ceilDiv(getTypeConverter()->getPointerBitwidth(resultAddrSpace), 8); + 2 * llvm::ceilDiv( + getTypeConverter()->getPointerBitwidth(resultAddrSpace), 8); Value bytesToSkipConst = rewriter.create( loc, getIndexType(), rewriter.getIndexAttr(bytesToSkip)); Value copySize = rewriter.create( diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp index 24427c25d79ff..034484af83b79 100644 --- a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp @@ -21,7 +21,6 @@ #include "mlir/IR/AffineExprVisitor.h" #include "mlir/IR/IntegerSet.h" #include "mlir/Support/LLVM.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" diff --git a/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp b/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp index 1c28d6b00b3c8..11a9f1485514a 100644 --- a/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp @@ -18,7 +18,7 @@ #include "mlir/Dialect/Affine/Analysis/NestedMatcher.h" #include "mlir/Dialect/Affine/IR/AffineOps.h" #include "mlir/Dialect/Affine/IR/AffineValueMap.h" -#include "mlir/Support/MathExtras.h" +#include "llvm/Support/MathExtras.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" @@ -47,7 +47,8 @@ void mlir::affine::getTripCountMapAndOperands( loopSpan = ub - lb; if (loopSpan < 0) loopSpan = 0; - *tripCountMap = AffineMap::getConstantMap(ceilDiv(loopSpan, step), context); + *tripCountMap = + AffineMap::getConstantMap(llvm::ceilDiv(loopSpan, step), context); tripCountOperands->clear(); return; } diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp index 0a58d2fdb02f5..b52bc05e908fc 100644 --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -18,19 +18,23 @@ #include "mlir/IR/PatternMatch.h" #include "mlir/Interfaces/ShapedOpInterfaces.h" #include "mlir/Interfaces/ValueBoundsOpInterface.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/InliningUtils.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallVectorExtras.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include #include using namespace mlir; using namespace mlir::affine; +using llvm::ceilDiv; +using llvm::floorDiv; +using llvm::mod; + #define DEBUG_TYPE "affine-ops" #include "mlir/Dialect/Affine/IR/AffineOpsDialect.cpp.inc" diff --git a/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp b/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp index 268050a30e002..c934f229bb6c4 100644 --- a/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp +++ b/mlir/lib/Dialect/Affine/Utils/LoopUtils.cpp @@ -23,7 +23,6 @@ #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/IR/IRMapping.h" #include "mlir/IR/IntegerSet.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallPtrSet.h" diff --git a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp index 1320db3f9e543..ede158db911ea 100644 --- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp +++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp @@ -23,7 +23,6 @@ #include "mlir/IR/PatternMatch.h" #include "mlir/IR/TypeUtilities.h" #include "mlir/IR/Value.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/InliningUtils.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" diff --git a/mlir/lib/Dialect/Func/IR/FuncOps.cpp b/mlir/lib/Dialect/Func/IR/FuncOps.cpp index 95589e8989e27..c719981769b9e 100644 --- a/mlir/lib/Dialect/Func/IR/FuncOps.cpp +++ b/mlir/lib/Dialect/Func/IR/FuncOps.cpp @@ -19,7 +19,6 @@ #include "mlir/IR/TypeUtilities.h" #include "mlir/IR/Value.h" #include "mlir/Interfaces/FunctionImplementation.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/InliningUtils.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/MapVector.h" diff --git a/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp b/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp index 38abdd122d633..24763c036192f 100644 --- a/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp @@ -9,11 +9,11 @@ #include "mlir/Dialect/Linalg/TransformOps/GPUHeuristics.h" #include "mlir/Dialect/GPU/IR/GPUDialect.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -76,7 +76,7 @@ transform::gpu::CopyMappingInfo::CopyMappingInfo(MLIRContext *ctx, llvm::map_range(llvm::zip(copySizes, this->numThreads), [](auto &&pair) { int64_t size, numThreads; std::tie(size, numThreads) = pair; - return mlir::ceilDiv(size, numThreads); + return llvm::ceilDiv(size, numThreads); })); SmallVector allThreadMappings{linearId2(ctx), linearId1(ctx), linearId0(ctx)}; diff --git a/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp b/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp index 2392e10522dd0..4c49ebb3b4cd7 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp @@ -20,9 +20,9 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/OpDefinition.h" #include "mlir/Support/LogicalResult.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/DialectConversion.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/MathExtras.h" #include #include @@ -74,7 +74,7 @@ convertCastingOp(ConversionPatternRewriter &rewriter, SmallVector size; if (sizes.size()) - size.push_back(ceilDiv(sizes[0], elementsPerByte)); + size.push_back(llvm::ceilDiv(sizes[0], elementsPerByte)); offset = offset / elementsPerByte; rewriter.replaceOpWithNewOp( diff --git a/mlir/lib/Dialect/SCF/IR/SCF.cpp b/mlir/lib/Dialect/SCF/IR/SCF.cpp index 5e94f4dc612a7..524711dbbb6fd 100644 --- a/mlir/lib/Dialect/SCF/IR/SCF.cpp +++ b/mlir/lib/Dialect/SCF/IR/SCF.cpp @@ -21,7 +21,6 @@ #include "mlir/IR/PatternMatch.h" #include "mlir/Interfaces/FunctionInterfaces.h" #include "mlir/Interfaces/ValueBoundsOpInterface.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/InliningUtils.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallPtrSet.h" diff --git a/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp b/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp index 82ec95d31f525..f5b7a6e28a178 100644 --- a/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp @@ -17,10 +17,10 @@ #include "mlir/Dialect/SCF/Utils/Utils.h" #include "mlir/IR/IRMapping.h" #include "mlir/IR/PatternMatch.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/MapVector.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #define DEBUG_TYPE "scf-loop-pipelining" #define DBGS() (llvm::dbgs() << "[" DEBUG_TYPE "]: ") @@ -119,7 +119,7 @@ bool LoopPipelinerInternal::initializeLoopInfo( int64_t ubImm = upperBoundCst.value(); int64_t lbImm = lowerBoundCst.value(); int64_t stepImm = stepCst.value(); - int64_t numIteration = ceilDiv(ubImm - lbImm, stepImm); + int64_t numIteration = llvm::ceilDiv(ubImm - lbImm, stepImm); if (numIteration > maxStage) { dynamicLoop = false; } else if (!options.supportDynamicLoops) { diff --git a/mlir/lib/Dialect/SCF/Utils/Utils.cpp b/mlir/lib/Dialect/SCF/Utils/Utils.cpp index 6658cca03eba7..eacbc736daffe 100644 --- a/mlir/lib/Dialect/SCF/Utils/Utils.cpp +++ b/mlir/lib/Dialect/SCF/Utils/Utils.cpp @@ -20,12 +20,12 @@ #include "mlir/IR/IRMapping.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Interfaces/SideEffectInterfaces.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Transforms/RegionUtils.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/MathExtras.h" using namespace mlir; @@ -382,7 +382,7 @@ LogicalResult mlir::loopUnrollByFactor( int64_t stepCst = stepCstOp.value(); assert(lbCst >= 0 && ubCst >= 0 && stepCst >= 0 && "expected positive loop bounds and step"); - int64_t tripCount = mlir::ceilDiv(ubCst - lbCst, stepCst); + int64_t tripCount = llvm::ceilDiv(ubCst - lbCst, stepCst); if (unrollFactor == 1) { if (tripCount == 1 && failed(forOp.promoteIfSingleIteration(rewriter))) diff --git a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp index 7fc29ec0139c2..b8fd1832180a7 100644 --- a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp +++ b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp @@ -24,17 +24,21 @@ #include "mlir/IR/TypeUtilities.h" #include "mlir/Interfaces/DestinationStyleOpInterface.h" #include "mlir/Interfaces/LoopLikeInterface.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/MathExtras.h" #include #include using namespace mlir; using namespace mlir::tensor; +using llvm::ceilDiv; +using llvm::floorDiv; +using llvm::mod; + /// Materialize a single constant operation from a given attribute value with /// the desired resultant type. Operation *TensorDialect::materializeConstant(OpBuilder &builder, diff --git a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp index 74a53709592dd..7ee7f18759881 100644 --- a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp +++ b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp @@ -9,8 +9,8 @@ #include "mlir/Dialect/Utils/StaticValueUtils.h" #include "mlir/IR/Matchers.h" #include "mlir/Support/LLVM.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/APSInt.h" +#include "llvm/Support/MathExtras.h" namespace mlir { @@ -248,7 +248,7 @@ std::optional constantTripCount(OpFoldResult lb, OpFoldResult ub, if (!stepConstant) return std::nullopt; - return mlir::ceilDiv(*ubConstant - *lbConstant, *stepConstant); + return llvm::ceilDiv(*ubConstant - *lbConstant, *stepConstant); } bool hasValidSizesOffsets(SmallVector sizesOrOffsets) { diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorUnroll.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorUnroll.cpp index c83776422f224..b3f558c3bac12 100644 --- a/mlir/lib/Dialect/Vector/Transforms/VectorUnroll.cpp +++ b/mlir/lib/Dialect/Vector/Transforms/VectorUnroll.cpp @@ -15,7 +15,6 @@ #include "mlir/Dialect/Vector/Transforms/VectorTransforms.h" #include "mlir/IR/ImplicitLocOpBuilder.h" #include "mlir/Interfaces/VectorInterfaces.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" diff --git a/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp b/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp index 6727f3f461722..4ed5a8bac20d1 100644 --- a/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp +++ b/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp @@ -25,7 +25,6 @@ #include "mlir/IR/Operation.h" #include "mlir/IR/TypeUtilities.h" #include "mlir/Support/LLVM.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SetVector.h" diff --git a/mlir/lib/IR/AffineExpr.cpp b/mlir/lib/IR/AffineExpr.cpp index 5f2016470b25f..9ce03e32a40a3 100644 --- a/mlir/lib/IR/AffineExpr.cpp +++ b/mlir/lib/IR/AffineExpr.cpp @@ -13,15 +13,19 @@ #include "mlir/IR/AffineExprVisitor.h" #include "mlir/IR/AffineMap.h" #include "mlir/IR/IntegerSet.h" -#include "mlir/Support/MathExtras.h" #include "mlir/Support/TypeID.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/MathExtras.h" #include #include using namespace mlir; using namespace mlir::detail; +using llvm::ceilDiv; +using llvm::floorDiv; +using llvm::mod; + MLIRContext *AffineExpr::getContext() const { return expr->context; } AffineExprKind AffineExpr::getKind() const { return expr->kind; } @@ -1570,7 +1574,7 @@ std::optional mlir::getBoundForAffineExpr( constLowerBounds, constUpperBounds, isUpper); if (!bound) return std::nullopt; - return mlir::floorDiv(*bound, rhsConst.getValue()); + return floorDiv(*bound, rhsConst.getValue()); } if (binOpExpr.getKind() == AffineExprKind::CeilDiv) { auto rhsConst = dyn_cast(binOpExpr.getRHS()); @@ -1580,7 +1584,7 @@ std::optional mlir::getBoundForAffineExpr( constLowerBounds, constUpperBounds, isUpper); if (!bound) return std::nullopt; - return mlir::ceilDiv(*bound, rhsConst.getValue()); + return ceilDiv(*bound, rhsConst.getValue()); } return std::nullopt; } diff --git a/mlir/lib/IR/AffineMap.cpp b/mlir/lib/IR/AffineMap.cpp index 411ac656e4afb..3402fdf17aeae 100644 --- a/mlir/lib/IR/AffineMap.cpp +++ b/mlir/lib/IR/AffineMap.cpp @@ -13,12 +13,12 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/Support/LogicalResult.h" -#include "mlir/Support/MathExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -27,6 +27,10 @@ using namespace mlir; +using llvm::ceilDiv; +using llvm::floorDiv; +using llvm::mod; + namespace { // AffineExprConstantFolder evaluates an affine expression using constant diff --git a/mlir/unittests/Support/CMakeLists.txt b/mlir/unittests/Support/CMakeLists.txt index 09cc2c5bf1d99..1dbf072bcbbfd 100644 --- a/mlir/unittests/Support/CMakeLists.txt +++ b/mlir/unittests/Support/CMakeLists.txt @@ -1,6 +1,5 @@ add_mlir_unittest(MLIRSupportTests IndentedOstreamTest.cpp - MathExtrasTest.cpp StorageUniquerTest.cpp ) diff --git a/mlir/unittests/Support/MathExtrasTest.cpp b/mlir/unittests/Support/MathExtrasTest.cpp deleted file mode 100644 index 6ece2dc560837..0000000000000 --- a/mlir/unittests/Support/MathExtrasTest.cpp +++ /dev/null @@ -1,31 +0,0 @@ -//===- MathExtrasTest.cpp - MathExtras Tests ------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "mlir/Support/MathExtras.h" -#include "gmock/gmock.h" - -using namespace mlir; -using ::testing::Eq; - -TEST(MathExtrasTest, CeilDivTest) { - EXPECT_THAT(ceilDiv(14, 3), Eq(5)); - EXPECT_THAT(ceilDiv(14, -3), Eq(-4)); - EXPECT_THAT(ceilDiv(-14, -3), Eq(5)); - EXPECT_THAT(ceilDiv(-14, 3), Eq(-4)); - EXPECT_THAT(ceilDiv(0, 3), Eq(0)); - EXPECT_THAT(ceilDiv(0, -3), Eq(0)); -} - -TEST(MathExtrasTest, FloorDivTest) { - EXPECT_THAT(floorDiv(14, 3), Eq(4)); - EXPECT_THAT(floorDiv(14, -3), Eq(-5)); - EXPECT_THAT(floorDiv(-14, -3), Eq(4)); - EXPECT_THAT(floorDiv(-14, 3), Eq(-5)); - EXPECT_THAT(floorDiv(0, 3), Eq(0)); - EXPECT_THAT(floorDiv(0, -3), Eq(0)); -} From 10c979af218f2ec11a7f845082bfc1254285237f Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 11 Jun 2024 10:52:14 +0100 Subject: [PATCH 2/5] llvm/MathExtras: address review --- llvm/include/llvm/Support/MathExtras.h | 12 +++---- llvm/unittests/Support/MathExtrasTest.cpp | 32 +++++++++---------- mlir/include/mlir/Analysis/Presburger/MPInt.h | 8 ++--- mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h | 2 +- .../Conversion/LLVMCommon/MemRefBuilder.cpp | 5 +-- .../Conversion/MemRefToLLVM/MemRefToLLVM.cpp | 2 +- .../Dialect/Affine/Analysis/LoopAnalysis.cpp | 4 +-- mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 20 ++++++------ .../Linalg/TransformOps/GPUHeuristics.cpp | 2 +- .../MemRef/Transforms/EmulateNarrowType.cpp | 2 +- .../Dialect/SCF/Transforms/LoopPipelining.cpp | 2 +- mlir/lib/Dialect/SCF/Utils/Utils.cpp | 2 +- mlir/lib/Dialect/Tensor/IR/TensorOps.cpp | 8 ++--- mlir/lib/Dialect/Utils/StaticValueUtils.cpp | 2 +- mlir/lib/IR/AffineExpr.cpp | 17 ++++++---- mlir/lib/IR/AffineMap.cpp | 8 ++--- 16 files changed, 64 insertions(+), 64 deletions(-) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index c5cac51130b1d..f7a7cfa83704e 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h @@ -425,14 +425,12 @@ template constexpr inline uint64_t alignTo(uint64_t Value) { } /// Returns the integer ceil(Numerator / Denominator). Unsigned integer version. -LLVM_ATTRIBUTE_ALWAYS_INLINE uint64_t divideCeil(uint64_t Numerator, - uint64_t Denominator) { +inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { return alignTo(Numerator, Denominator) / Denominator; } /// Returns the integer ceil(Numerator / Denominator). Signed integer version. -LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t ceilDiv(int64_t Numerator, - int64_t Denominator) { +inline int64_t divideCeilSigned(int64_t Numerator, int64_t Denominator) { assert(Denominator); if (!Numerator) return 0; @@ -444,8 +442,7 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t ceilDiv(int64_t Numerator, } /// Returns the integer floor(Numerator / Denominator). Signed integer version. -LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t floorDiv(int64_t Numerator, - int64_t Denominator) { +inline int64_t divideFloorSigned(int64_t Numerator, int64_t Denominator) { assert(Denominator); if (!Numerator) return 0; @@ -458,8 +455,7 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t floorDiv(int64_t Numerator, /// Returns the remainder of the Euclidean division of LHS by RHS. Result is /// always non-negative. -LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t mod(int64_t Numerator, - int64_t Denominator) { +inline int64_t mod(int64_t Numerator, int64_t Denominator) { assert(Denominator >= 1); return Numerator % Denominator < 0 ? Numerator % Denominator + Denominator : Numerator % Denominator; diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp index b32094e0acdfe..132150ccecad5 100644 --- a/llvm/unittests/Support/MathExtrasTest.cpp +++ b/llvm/unittests/Support/MathExtrasTest.cpp @@ -434,22 +434,22 @@ TEST(MathExtras, IsShiftedInt) { EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15))); } -TEST(MathExtras, CeilDivTest) { - EXPECT_EQ(ceilDiv(14, 3), 5); - EXPECT_EQ(ceilDiv(14, -3), -4); - EXPECT_EQ(ceilDiv(-14, -3), 5); - EXPECT_EQ(ceilDiv(-14, 3), -4); - EXPECT_EQ(ceilDiv(0, 3), 0); - EXPECT_EQ(ceilDiv(0, -3), 0); -} - -TEST(MathExtras, FloorDivTest) { - EXPECT_EQ(floorDiv(14, 3), 4); - EXPECT_EQ(floorDiv(14, -3), -5); - EXPECT_EQ(floorDiv(-14, -3), 4); - EXPECT_EQ(floorDiv(-14, 3), -5); - EXPECT_EQ(floorDiv(0, 3), 0); - EXPECT_EQ(floorDiv(0, -3), 0); +TEST(MathExtras, DivideCeilSigned) { + EXPECT_EQ(divideCeilSigned(14, 3), 5); + EXPECT_EQ(divideCeilSigned(14, -3), -4); + EXPECT_EQ(divideCeilSigned(-14, -3), 5); + EXPECT_EQ(divideCeilSigned(-14, 3), -4); + EXPECT_EQ(divideCeilSigned(0, 3), 0); + EXPECT_EQ(divideCeilSigned(0, -3), 0); +} + +TEST(MathExtras, DivideFloorSigned) { + EXPECT_EQ(divideFloorSigned(14, 3), 4); + EXPECT_EQ(divideFloorSigned(14, -3), -5); + EXPECT_EQ(divideFloorSigned(-14, -3), 4); + EXPECT_EQ(divideFloorSigned(-14, 3), -5); + EXPECT_EQ(divideFloorSigned(0, 3), 0); + EXPECT_EQ(divideFloorSigned(0, -3), 0); } template class OverflowTest : public ::testing::Test {}; diff --git a/mlir/include/mlir/Analysis/Presburger/MPInt.h b/mlir/include/mlir/Analysis/Presburger/MPInt.h index 343f50251c7dc..cf9c666da4f3a 100644 --- a/mlir/include/mlir/Analysis/Presburger/MPInt.h +++ b/mlir/include/mlir/Analysis/Presburger/MPInt.h @@ -33,8 +33,8 @@ namespace presburger { /// explict call to mlir::ceilDiv would be required. These using declarations /// allow overload resolution to transparently call the right function. using ::llvm::ArrayRef; -using ::llvm::ceilDiv; -using ::llvm::floorDiv; +using ::llvm::divideCeilSigned; +using ::llvm::divideFloorSigned; using ::llvm::mod; namespace detail { @@ -377,7 +377,7 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE MPInt ceilDiv(const MPInt &lhs, const MPInt &rhs) { if (LLVM_LIKELY(lhs.isSmall() && rhs.isSmall())) { if (LLVM_UNLIKELY(detail::divWouldOverflow(lhs.getSmall(), rhs.getSmall()))) return -lhs; - return MPInt(ceilDiv(lhs.getSmall(), rhs.getSmall())); + return MPInt(divideCeilSigned(lhs.getSmall(), rhs.getSmall())); } return MPInt(ceilDiv(detail::SlowMPInt(lhs), detail::SlowMPInt(rhs))); } @@ -386,7 +386,7 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE MPInt floorDiv(const MPInt &lhs, if (LLVM_LIKELY(lhs.isSmall() && rhs.isSmall())) { if (LLVM_UNLIKELY(detail::divWouldOverflow(lhs.getSmall(), rhs.getSmall()))) return -lhs; - return MPInt(floorDiv(lhs.getSmall(), rhs.getSmall())); + return MPInt(divideFloorSigned(lhs.getSmall(), rhs.getSmall())); } return MPInt(floorDiv(detail::SlowMPInt(lhs), detail::SlowMPInt(rhs))); } diff --git a/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h b/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h index 0e39928b1d6a9..83157b60c590b 100644 --- a/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h +++ b/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.h @@ -114,7 +114,7 @@ inline int64_t shardDimension(int64_t dimSize, int64_t shardCount) { return ShapedType::kDynamic; assert(dimSize % shardCount == 0); - return llvm::ceilDiv(dimSize, shardCount); + return llvm::divideCeilSigned(dimSize, shardCount); } // Get the size of an unsharded dimension. diff --git a/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp b/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp index 0910a1ea076c0..1b2d0258130cb 100644 --- a/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp +++ b/mlir/lib/Conversion/LLVMCommon/MemRefBuilder.cpp @@ -365,7 +365,7 @@ void UnrankedMemRefDescriptor::computeSizes( Value two = createIndexAttrConstant(builder, loc, indexType, 2); Value indexSize = createIndexAttrConstant( builder, loc, indexType, - llvm::ceilDiv(typeConverter.getIndexTypeBitwidth(), 8)); + llvm::divideCeilSigned(typeConverter.getIndexTypeBitwidth(), 8)); sizes.reserve(sizes.size() + values.size()); for (auto [desc, addressSpace] : llvm::zip(values, addressSpaces)) { @@ -378,7 +378,8 @@ void UnrankedMemRefDescriptor::computeSizes( // to data layout) into the unranked descriptor. Value pointerSize = createIndexAttrConstant( builder, loc, indexType, - llvm::ceilDiv(typeConverter.getPointerBitwidth(addressSpace), 8)); + llvm::divideCeilSigned(typeConverter.getPointerBitwidth(addressSpace), + 8)); Value doublePointerSize = builder.create(loc, indexType, two, pointerSize); diff --git a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp index d7eab77b97d0c..7ef5a77fcb42c 100644 --- a/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp +++ b/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp @@ -971,7 +971,7 @@ struct MemorySpaceCastOpLowering resultUnderlyingDesc, resultElemPtrType); int64_t bytesToSkip = - 2 * llvm::ceilDiv( + 2 * llvm::divideCeilSigned( getTypeConverter()->getPointerBitwidth(resultAddrSpace), 8); Value bytesToSkipConst = rewriter.create( loc, getIndexType(), rewriter.getIndexAttr(bytesToSkip)); diff --git a/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp b/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp index 11a9f1485514a..82ba8fc5ccbc1 100644 --- a/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/LoopAnalysis.cpp @@ -47,8 +47,8 @@ void mlir::affine::getTripCountMapAndOperands( loopSpan = ub - lb; if (loopSpan < 0) loopSpan = 0; - *tripCountMap = - AffineMap::getConstantMap(llvm::ceilDiv(loopSpan, step), context); + *tripCountMap = AffineMap::getConstantMap( + llvm::divideCeilSigned(loopSpan, step), context); tripCountOperands->clear(); return; } diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp index b52bc05e908fc..6baed92d208fb 100644 --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -31,8 +31,8 @@ using namespace mlir; using namespace mlir::affine; -using llvm::ceilDiv; -using llvm::floorDiv; +using llvm::divideCeilSigned; +using llvm::divideFloorSigned; using llvm::mod; #define DEBUG_TYPE "affine-ops" @@ -828,19 +828,19 @@ static void simplifyExprAndOperands(AffineExpr &expr, unsigned numDims, // lhs floordiv c is a single value lhs is bounded in a range `c` that has // the same quotient. if (binExpr.getKind() == AffineExprKind::FloorDiv && - floorDiv(lhsLbConstVal, rhsConstVal) == - floorDiv(lhsUbConstVal, rhsConstVal)) { - expr = - getAffineConstantExpr(floorDiv(lhsLbConstVal, rhsConstVal), context); + divideFloorSigned(lhsLbConstVal, rhsConstVal) == + divideFloorSigned(lhsUbConstVal, rhsConstVal)) { + expr = getAffineConstantExpr( + divideFloorSigned(lhsLbConstVal, rhsConstVal), context); return; } // lhs ceildiv c is a single value if the entire range has the same ceil // quotient. if (binExpr.getKind() == AffineExprKind::CeilDiv && - ceilDiv(lhsLbConstVal, rhsConstVal) == - ceilDiv(lhsUbConstVal, rhsConstVal)) { - expr = - getAffineConstantExpr(ceilDiv(lhsLbConstVal, rhsConstVal), context); + divideCeilSigned(lhsLbConstVal, rhsConstVal) == + divideCeilSigned(lhsUbConstVal, rhsConstVal)) { + expr = getAffineConstantExpr(divideCeilSigned(lhsLbConstVal, rhsConstVal), + context); return; } // lhs mod c is lhs if the entire range has quotient 0 w.r.t the rhs. diff --git a/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp b/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp index 24763c036192f..e6162ad97d784 100644 --- a/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/GPUHeuristics.cpp @@ -76,7 +76,7 @@ transform::gpu::CopyMappingInfo::CopyMappingInfo(MLIRContext *ctx, llvm::map_range(llvm::zip(copySizes, this->numThreads), [](auto &&pair) { int64_t size, numThreads; std::tie(size, numThreads) = pair; - return llvm::ceilDiv(size, numThreads); + return llvm::divideCeilSigned(size, numThreads); })); SmallVector allThreadMappings{linearId2(ctx), linearId1(ctx), linearId0(ctx)}; diff --git a/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp b/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp index 4c49ebb3b4cd7..f140c049f320f 100644 --- a/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp +++ b/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp @@ -74,7 +74,7 @@ convertCastingOp(ConversionPatternRewriter &rewriter, SmallVector size; if (sizes.size()) - size.push_back(llvm::ceilDiv(sizes[0], elementsPerByte)); + size.push_back(llvm::divideCeilSigned(sizes[0], elementsPerByte)); offset = offset / elementsPerByte; rewriter.replaceOpWithNewOp( diff --git a/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp b/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp index f5b7a6e28a178..cc1a22d0d48a1 100644 --- a/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp +++ b/mlir/lib/Dialect/SCF/Transforms/LoopPipelining.cpp @@ -119,7 +119,7 @@ bool LoopPipelinerInternal::initializeLoopInfo( int64_t ubImm = upperBoundCst.value(); int64_t lbImm = lowerBoundCst.value(); int64_t stepImm = stepCst.value(); - int64_t numIteration = llvm::ceilDiv(ubImm - lbImm, stepImm); + int64_t numIteration = llvm::divideCeilSigned(ubImm - lbImm, stepImm); if (numIteration > maxStage) { dynamicLoop = false; } else if (!options.supportDynamicLoops) { diff --git a/mlir/lib/Dialect/SCF/Utils/Utils.cpp b/mlir/lib/Dialect/SCF/Utils/Utils.cpp index eacbc736daffe..8bdbef15521b6 100644 --- a/mlir/lib/Dialect/SCF/Utils/Utils.cpp +++ b/mlir/lib/Dialect/SCF/Utils/Utils.cpp @@ -382,7 +382,7 @@ LogicalResult mlir::loopUnrollByFactor( int64_t stepCst = stepCstOp.value(); assert(lbCst >= 0 && ubCst >= 0 && stepCst >= 0 && "expected positive loop bounds and step"); - int64_t tripCount = llvm::ceilDiv(ubCst - lbCst, stepCst); + int64_t tripCount = llvm::divideCeilSigned(ubCst - lbCst, stepCst); if (unrollFactor == 1) { if (tripCount == 1 && failed(forOp.promoteIfSingleIteration(rewriter))) diff --git a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp index b8fd1832180a7..6d6d7e506e854 100644 --- a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp +++ b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp @@ -35,8 +35,8 @@ using namespace mlir; using namespace mlir::tensor; -using llvm::ceilDiv; -using llvm::floorDiv; +using llvm::divideCeilSigned; +using llvm::divideFloorSigned; using llvm::mod; /// Materialize a single constant operation from a given attribute value with @@ -3977,8 +3977,8 @@ static SmallVector getPackOpResultTypeShape( resultShape[tiledDim.value()] = ShapedType::kDynamic; continue; } - resultShape[tiledDim.value()] = ceilDiv(resultShape[tiledDim.value()], - innerTileSizes[tiledDim.index()]); + resultShape[tiledDim.value()] = divideCeilSigned( + resultShape[tiledDim.value()], innerTileSizes[tiledDim.index()]); } // Swap tile loops if outer_dims_perm is available. diff --git a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp index 7ee7f18759881..b01d3183af135 100644 --- a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp +++ b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp @@ -248,7 +248,7 @@ std::optional constantTripCount(OpFoldResult lb, OpFoldResult ub, if (!stepConstant) return std::nullopt; - return llvm::ceilDiv(*ubConstant - *lbConstant, *stepConstant); + return llvm::divideCeilSigned(*ubConstant - *lbConstant, *stepConstant); } bool hasValidSizesOffsets(SmallVector sizesOrOffsets) { diff --git a/mlir/lib/IR/AffineExpr.cpp b/mlir/lib/IR/AffineExpr.cpp index 9ce03e32a40a3..1fab33327ba76 100644 --- a/mlir/lib/IR/AffineExpr.cpp +++ b/mlir/lib/IR/AffineExpr.cpp @@ -22,8 +22,8 @@ using namespace mlir; using namespace mlir::detail; -using llvm::ceilDiv; -using llvm::floorDiv; +using llvm::divideCeilSigned; +using llvm::divideFloorSigned; using llvm::mod; MLIRContext *AffineExpr::getContext() const { return expr->context; } @@ -851,7 +851,8 @@ static AffineExpr simplifyFloorDiv(AffineExpr lhs, AffineExpr rhs) { if (lhsConst) return getAffineConstantExpr( - floorDiv(lhsConst.getValue(), rhsConst.getValue()), lhs.getContext()); + divideFloorSigned(lhsConst.getValue(), rhsConst.getValue()), + lhs.getContext()); // Fold floordiv of a multiply with a constant that is a multiple of the // divisor. Eg: (i * 128) floordiv 64 = i * 2. @@ -906,7 +907,8 @@ static AffineExpr simplifyCeilDiv(AffineExpr lhs, AffineExpr rhs) { if (lhsConst) return getAffineConstantExpr( - ceilDiv(lhsConst.getValue(), rhsConst.getValue()), lhs.getContext()); + divideCeilSigned(lhsConst.getValue(), rhsConst.getValue()), + lhs.getContext()); // Fold ceildiv of a multiply with a constant that is a multiple of the // divisor. Eg: (i * 128) ceildiv 64 = i * 2. @@ -1574,7 +1576,7 @@ std::optional mlir::getBoundForAffineExpr( constLowerBounds, constUpperBounds, isUpper); if (!bound) return std::nullopt; - return floorDiv(*bound, rhsConst.getValue()); + return divideFloorSigned(*bound, rhsConst.getValue()); } if (binOpExpr.getKind() == AffineExprKind::CeilDiv) { auto rhsConst = dyn_cast(binOpExpr.getRHS()); @@ -1584,7 +1586,7 @@ std::optional mlir::getBoundForAffineExpr( constLowerBounds, constUpperBounds, isUpper); if (!bound) return std::nullopt; - return ceilDiv(*bound, rhsConst.getValue()); + return divideCeilSigned(*bound, rhsConst.getValue()); } return std::nullopt; } @@ -1602,7 +1604,8 @@ std::optional mlir::getBoundForAffineExpr( getBoundForAffineExpr(binOpExpr.getLHS(), numDims, numSymbols, constLowerBounds, constUpperBounds, isUpper); if (ub && lb && - floorDiv(*lb, rhsConstVal) == floorDiv(*ub, rhsConstVal)) + divideFloorSigned(*lb, rhsConstVal) == + divideFloorSigned(*ub, rhsConstVal)) return isUpper ? mod(*ub, rhsConstVal) : mod(*lb, rhsConstVal); return isUpper ? rhsConstVal - 1 : 0; } diff --git a/mlir/lib/IR/AffineMap.cpp b/mlir/lib/IR/AffineMap.cpp index 3402fdf17aeae..ce7b751294cc9 100644 --- a/mlir/lib/IR/AffineMap.cpp +++ b/mlir/lib/IR/AffineMap.cpp @@ -27,8 +27,8 @@ using namespace mlir; -using llvm::ceilDiv; -using llvm::floorDiv; +using llvm::divideCeilSigned; +using llvm::divideFloorSigned; using llvm::mod; namespace { @@ -77,7 +77,7 @@ class AffineExprConstantFolder { hasPoison_ = true; return std::nullopt; } - return floorDiv(lhs, rhs); + return divideFloorSigned(lhs, rhs); }); case AffineExprKind::CeilDiv: return constantFoldBinExpr( @@ -86,7 +86,7 @@ class AffineExprConstantFolder { hasPoison_ = true; return std::nullopt; } - return ceilDiv(lhs, rhs); + return divideCeilSigned(lhs, rhs); }); case AffineExprKind::Constant: return cast(expr).getValue(); From 3006125e965a7a64cc83cd154cb70fc6abe6918e Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 11 Jun 2024 12:41:21 +0100 Subject: [PATCH 3/5] llvm/MathExtras: fix nits, increase test coverage --- llvm/include/llvm/Support/MathExtras.h | 12 ++++++------ llvm/unittests/Support/MathExtrasTest.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index f7a7cfa83704e..8d0fbfb0cd628 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h @@ -431,19 +431,19 @@ inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { /// Returns the integer ceil(Numerator / Denominator). Signed integer version. inline int64_t divideCeilSigned(int64_t Numerator, int64_t Denominator) { - assert(Denominator); + assert(Denominator && "Division by zero"); if (!Numerator) return 0; // C's integer division rounds towards 0. int64_t X = (Denominator > 0) ? -1 : 1; bool SameSign = (Numerator > 0) == (Denominator > 0); return SameSign ? ((Numerator + X) / Denominator) + 1 - : -(-Numerator / Denominator); + : Numerator / Denominator; } /// Returns the integer floor(Numerator / Denominator). Signed integer version. inline int64_t divideFloorSigned(int64_t Numerator, int64_t Denominator) { - assert(Denominator); + assert(Denominator && "Division by zero"); if (!Numerator) return 0; // C's integer division rounds towards 0. @@ -456,9 +456,9 @@ inline int64_t divideFloorSigned(int64_t Numerator, int64_t Denominator) { /// Returns the remainder of the Euclidean division of LHS by RHS. Result is /// always non-negative. inline int64_t mod(int64_t Numerator, int64_t Denominator) { - assert(Denominator >= 1); - return Numerator % Denominator < 0 ? Numerator % Denominator + Denominator - : Numerator % Denominator; + assert(Denominator >= 1 && "Mod by non-positive number"); + int64_t Mod = Numerator % Denominator; + return Mod < 0 ? Mod + Denominator : Mod; } /// Returns the integer nearest(Numerator / Denominator). diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp index 132150ccecad5..e75700df67e69 100644 --- a/llvm/unittests/Support/MathExtrasTest.cpp +++ b/llvm/unittests/Support/MathExtrasTest.cpp @@ -436,22 +436,36 @@ TEST(MathExtras, IsShiftedInt) { TEST(MathExtras, DivideCeilSigned) { EXPECT_EQ(divideCeilSigned(14, 3), 5); + EXPECT_EQ(divideCeilSigned(15, 3), 5); EXPECT_EQ(divideCeilSigned(14, -3), -4); EXPECT_EQ(divideCeilSigned(-14, -3), 5); EXPECT_EQ(divideCeilSigned(-14, 3), -4); + EXPECT_EQ(divideCeilSigned(-15, 3), -5); EXPECT_EQ(divideCeilSigned(0, 3), 0); EXPECT_EQ(divideCeilSigned(0, -3), 0); } TEST(MathExtras, DivideFloorSigned) { EXPECT_EQ(divideFloorSigned(14, 3), 4); + EXPECT_EQ(divideFloorSigned(15, 3), 5); EXPECT_EQ(divideFloorSigned(14, -3), -5); EXPECT_EQ(divideFloorSigned(-14, -3), 4); EXPECT_EQ(divideFloorSigned(-14, 3), -5); + EXPECT_EQ(divideFloorSigned(-15, 3), -5); EXPECT_EQ(divideFloorSigned(0, 3), 0); EXPECT_EQ(divideFloorSigned(0, -3), 0); } +TEST(MathExtras, Mod) { + EXPECT_EQ(mod(1, 14), 1); + EXPECT_EQ(mod(-1, 14), 13); + EXPECT_EQ(mod(14, 3), 2); + EXPECT_EQ(mod(15, 3), 0); + EXPECT_EQ(mod(-14, 3), 1); + EXPECT_EQ(mod(-15, 3), 0); + EXPECT_EQ(mod(0, 3), 0); +} + template class OverflowTest : public ::testing::Test {}; using OverflowTestTypes = ::testing::Types Date: Tue, 11 Jun 2024 12:47:31 +0100 Subject: [PATCH 4/5] MPInt: fix nit in comment --- mlir/include/mlir/Analysis/Presburger/MPInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/include/mlir/Analysis/Presburger/MPInt.h b/mlir/include/mlir/Analysis/Presburger/MPInt.h index cf9c666da4f3a..86be3ffc93d31 100644 --- a/mlir/include/mlir/Analysis/Presburger/MPInt.h +++ b/mlir/include/mlir/Analysis/Presburger/MPInt.h @@ -30,7 +30,7 @@ namespace presburger { /// identically-named functions that operate on MPInts, which would otherwie /// become the only candidates of overload resolution when calling e.g. ceilDiv /// from the mlir::presburger namespace. So to access the 64-bit overloads, an -/// explict call to mlir::ceilDiv would be required. These using declarations +/// explict call to llvm::ceilDiv would be required. These using declarations /// allow overload resolution to transparently call the right function. using ::llvm::ArrayRef; using ::llvm::divideCeilSigned; From a70c51dae4282b7a7fe1eca0e9036482f4c7c8ba Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 11 Jun 2024 16:26:57 +0100 Subject: [PATCH 5/5] MPInt: strip bad comment --- mlir/include/mlir/Analysis/Presburger/MPInt.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mlir/include/mlir/Analysis/Presburger/MPInt.h b/mlir/include/mlir/Analysis/Presburger/MPInt.h index 86be3ffc93d31..f7678967190a0 100644 --- a/mlir/include/mlir/Analysis/Presburger/MPInt.h +++ b/mlir/include/mlir/Analysis/Presburger/MPInt.h @@ -24,14 +24,6 @@ namespace mlir { namespace presburger { - -/// Redefine these functions, which operate on 64-bit ints, to also be part of -/// the mlir::presburger namespace. This is useful because this file defines -/// identically-named functions that operate on MPInts, which would otherwie -/// become the only candidates of overload resolution when calling e.g. ceilDiv -/// from the mlir::presburger namespace. So to access the 64-bit overloads, an -/// explict call to llvm::ceilDiv would be required. These using declarations -/// allow overload resolution to transparently call the right function. using ::llvm::ArrayRef; using ::llvm::divideCeilSigned; using ::llvm::divideFloorSigned;