diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -731,9 +731,11 @@ } if (resultShape.size() != expectedResultShape.size()) return emitOpError("incorrect result shape"); - if (resultShape[0] != expectedResultShape[0]) + if (resultShape[0] != expectedResultShape[0] && + expectedResultShape[0] != unknownExtent) return emitOpError("incorrect result shape"); - if (resultShape.size() == 2 && resultShape[1] != expectedResultShape[1]) + if (resultShape.size() == 2 && resultShape[1] != expectedResultShape[1] && + expectedResultShape[1] != unknownExtent) return emitOpError("incorrect result shape"); return mlir::success(); @@ -805,7 +807,10 @@ if (rank != 2 || resultRank != 2) return emitOpError("input and output arrays should have rank 2"); - if (inShape[0] != resultShape[1] || inShape[1] != resultShape[0]) + constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent(); + if ((inShape[0] != resultShape[1]) && (inShape[0] != unknownExtent)) + return emitOpError("output shape does not match input array"); + if ((inShape[1] != resultShape[0]) && (inShape[1] != unknownExtent)) return emitOpError("output shape does not match input array"); if (eleTy != resultEleTy) diff --git a/flang/test/Lower/HLFIR/matmul.f90 b/flang/test/Lower/HLFIR/matmul.f90 --- a/flang/test/Lower/HLFIR/matmul.f90 +++ b/flang/test/Lower/HLFIR/matmul.f90 @@ -17,3 +17,19 @@ ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return ! CHECK-NEXT: } + +! regression test for a case where the AST and FIR have different amounts of +! shape inference +subroutine matmul2(c) + integer, parameter :: N = 4 + integer, dimension(:,:), allocatable :: a, b, c + integer, dimension(N,N) :: x + + allocate(a(3*N, N), b(N, N), c(3*N, N)) + + call fill(a) + call fill(b) + call fill(x) + + c = matmul(a, b - x) +endsubroutine diff --git a/flang/test/Lower/HLFIR/transpose.f90 b/flang/test/Lower/HLFIR/transpose.f90 --- a/flang/test/Lower/HLFIR/transpose.f90 +++ b/flang/test/Lower/HLFIR/transpose.f90 @@ -15,3 +15,15 @@ ! CHECK-NEXT: hlfir.destroy %[[EXPR]] ! CHECK-NEXT: return ! CHECK-NEXT: } + +! test the case where lowering has more exact information about the output +! shape than is available from the argument +subroutine transpose2(a, out) + real, allocatable, dimension(:) :: a + real, dimension(:,:) :: out + integer, parameter :: N = 3 + integer, parameter :: M = 4 + + allocate(a(N*M)) + out = transpose(reshape(a, (/N, M/))) +end subroutine