[flang-commits] [flang] [flang] Added definition of hlfir.cshift operation. (PR #118732)

via flang-commits flang-commits at lists.llvm.org
Thu Dec 5 01:48:19 PST 2024


================
@@ -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 wrote:

While these checks make sense and it is very tempting to enforce Fortran intrinsic requirements in MLIR verifiers, I think it may be best to stick to checks for invariants that are required for the compiler to generate code without crashing.

This is because enforcing Fortran semantics after optimization could lead to raising errors in unreachable code, which I do not think we should. Take for instance a case where the CSHIFT DIM can be folded after inlining, if the CSHIFT call is a block that cannot be reached given the program state (which the compiler may or may not be able to know), I think the user would be unhappy for the compilation to stop and report an error:
 


```
subroutine foo(dim)
 real, dimension(2) :: res, array
 if (is_dim_acceptable(dim, array))
   res = cshift(array, shift, dim)
 end if
end subroutine
call foo(3)
end
```

https://github.com/llvm/llvm-project/pull/118732


More information about the flang-commits mailing list