-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[flang] Added definition of hlfir.cshift operation. #118732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1341,6 +1341,91 @@ void hlfir::MatmulTransposeOp::getEffects( | |
| getIntrinsicEffects(getOperation(), effects); | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // CShiftOp | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| llvm::LogicalResult hlfir::CShiftOp::verify() { | ||
| mlir::Value array = getArray(); | ||
| fir::SequenceType arrayTy = mlir::cast<fir::SequenceType>( | ||
| hlfir::getFortranElementOrSequenceType(array.getType())); | ||
| llvm::ArrayRef<int64_t> inShape = arrayTy.getShape(); | ||
| std::size_t arrayRank = inShape.size(); | ||
| mlir::Type eleTy = arrayTy.getEleTy(); | ||
| hlfir::ExprType resultTy = mlir::cast<hlfir::ExprType>(getResult().getType()); | ||
| llvm::ArrayRef<int64_t> resultShape = resultTy.getShape(); | ||
| std::size_t resultRank = resultShape.size(); | ||
| mlir::Type resultEleTy = resultTy.getEleTy(); | ||
| mlir::Value shift = getShift(); | ||
| mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType(shift.getType()); | ||
|
|
||
| if (eleTy != resultEleTy) | ||
| return emitOpError( | ||
| "input and output arrays should have the same element type"); | ||
|
|
||
| if (arrayRank != resultRank) | ||
| return emitOpError("input and output arrays should have the same rank"); | ||
|
|
||
| constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent(); | ||
| for (auto [inDim, resultDim] : llvm::zip(inShape, resultShape)) | ||
| if (inDim != unknownExtent && resultDim != unknownExtent && | ||
| inDim != resultDim) | ||
| return emitOpError( | ||
| "output array's shape conflicts with the input array's shape"); | ||
|
|
||
| int64_t dimVal = -1; | ||
| if (!getDim()) | ||
| dimVal = 1; | ||
| else if (auto dim = fir::getIntIfConstant(getDim())) | ||
| dimVal = *dim; | ||
|
|
||
| if (dimVal != -1) { | ||
| if (dimVal < 1) | ||
| return emitOpError("DIM must be >= 1"); | ||
| if (dimVal > static_cast<int64_t>(arrayRank)) | ||
| return emitOpError("DIM must be <= input array's rank"); | ||
jeanPerier marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if (auto shiftSeqTy = mlir::dyn_cast<fir::SequenceType>(shiftTy)) { | ||
| // SHIFT is an array. Verify the rank and the shape (if DIM is constant). | ||
| llvm::ArrayRef<int64_t> shiftShape = shiftSeqTy.getShape(); | ||
| std::size_t shiftRank = shiftShape.size(); | ||
| if (shiftRank != arrayRank - 1) | ||
| return emitOpError( | ||
| "SHIFT's rank must be 1 less than the input array's rank"); | ||
|
|
||
| if (dimVal != -1) { | ||
|
||
| // SHIFT's shape must be [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)], | ||
| // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY. | ||
| int64_t arrayDimIdx = 0; | ||
| int64_t shiftDimIdx = 0; | ||
| for (auto shiftDim : shiftShape) { | ||
| if (arrayDimIdx == dimVal - 1) | ||
| ++arrayDimIdx; | ||
|
|
||
| if (inShape[arrayDimIdx] != unknownExtent && | ||
| shiftDim != unknownExtent && inShape[arrayDimIdx] != shiftDim) | ||
| return emitOpError("SHAPE(ARRAY)(" + llvm::Twine(arrayDimIdx + 1) + | ||
| ") must be equal to SHAPE(SHIFT)(" + | ||
| llvm::Twine(shiftDimIdx + 1) + | ||
| "): " + llvm::Twine(inShape[arrayDimIdx]) + | ||
| " != " + llvm::Twine(shiftDim)); | ||
| ++arrayDimIdx; | ||
| ++shiftDimIdx; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return mlir::success(); | ||
| } | ||
|
|
||
| void hlfir::CShiftOp::getEffects( | ||
| llvm::SmallVectorImpl< | ||
| mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> | ||
| &effects) { | ||
| getIntrinsicEffects(getOperation(), effects); | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // AssociateOp | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be relaxed for characters where dynamic length vs constant length should be OK. After transformations, the operand could go from a dynamic length to constant length or vice versa without this technically be incorrect.