Skip to content

Commit 89227b6

Browse files
committed
[flang][hlfir] relax the strictness of intrinsic verifiers
The verifiers for hlfir.matmul and hlfir.transpose try to ensure that the shape of the result value makes sense given the shapes of the input argument(s). It there are some cases in the gfortran tests where lowering knows a bit more about shape information than (HL)FIR. I think the cases here will be solved when hlfir.shape_meet is implemented. But in the meantime, and to improve robustness, I've relaxed the verifier to allow the return type to have more precise shape information than can be deduced from the argument type(s). Differential Revision: https://reviews.llvm.org/D152254
1 parent 6efb2af commit 89227b6

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -778,9 +778,11 @@ mlir::LogicalResult hlfir::MatmulOp::verify() {
778778
}
779779
if (resultShape.size() != expectedResultShape.size())
780780
return emitOpError("incorrect result shape");
781-
if (resultShape[0] != expectedResultShape[0])
781+
if (resultShape[0] != expectedResultShape[0] &&
782+
expectedResultShape[0] != unknownExtent)
782783
return emitOpError("incorrect result shape");
783-
if (resultShape.size() == 2 && resultShape[1] != expectedResultShape[1])
784+
if (resultShape.size() == 2 && resultShape[1] != expectedResultShape[1] &&
785+
expectedResultShape[1] != unknownExtent)
784786
return emitOpError("incorrect result shape");
785787

786788
return mlir::success();
@@ -852,7 +854,10 @@ mlir::LogicalResult hlfir::TransposeOp::verify() {
852854
if (rank != 2 || resultRank != 2)
853855
return emitOpError("input and output arrays should have rank 2");
854856

855-
if (inShape[0] != resultShape[1] || inShape[1] != resultShape[0])
857+
constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent();
858+
if ((inShape[0] != resultShape[1]) && (inShape[0] != unknownExtent))
859+
return emitOpError("output shape does not match input array");
860+
if ((inShape[1] != resultShape[0]) && (inShape[1] != unknownExtent))
856861
return emitOpError("output shape does not match input array");
857862

858863
if (eleTy != resultEleTy)

flang/test/Lower/HLFIR/matmul.f90

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,41 @@ subroutine matmul1(lhs, rhs, res)
1717
! CHECK-NEXT: hlfir.destroy %[[EXPR]]
1818
! CHECK-NEXT: return
1919
! CHECK-NEXT: }
20+
21+
! regression test for a case where the AST and FIR have different amounts of
22+
! shape inference
23+
subroutine matmul2(c)
24+
integer, parameter :: N = 4
25+
integer, dimension(:,:), allocatable :: a, b, c
26+
integer, dimension(N,N) :: x
27+
28+
allocate(a(3*N, N), b(N, N), c(3*N, N))
29+
30+
call fill(a)
31+
call fill(b)
32+
call fill(x)
33+
34+
c = matmul(a, b - x)
35+
endsubroutine
36+
! CHECK-LABEL: func.func @_QPmatmul2
37+
! CHECK: %[[C_ARG:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>
38+
! CHECK: %[[B_BOX_ALLOC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?xi32>>> {bindc_name = "b"
39+
! CHECK: %[[B_BOX_DECL:.*]]:2 = hlfir.declare %[[B_BOX_ALLOC]] {{.*}} uniq_name = "_QFmatmul2Eb"
40+
41+
42+
! CHECK: fir.call @_QPfill
43+
! CHECK: fir.call @_QPfill
44+
! CHECK: fir.call @_QPfill
45+
! CHECK-NEXT: %[[B_BOX:.*]] = fir.load %[[B_BOX_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>
46+
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : index
47+
! CHECK-NEXT: %[[B_DIMS_0:.*]]:3 = fir.box_dims %[[B_BOX]], %[[C0]]
48+
! CHECK-NEXT: %[[C1:.*]] = arith.constant 1 : index
49+
! CHECK-NEXT: %[[B_DIMS_1:.*]]:3 = fir.box_dims %[[B_BOX]], %[[C1]]
50+
! CHECK-NEXT: %[[B_SHAPE:.*]] = fir.shape %[[B_DIMS_0]]#1, %[[B_DIMS_1]]#1
51+
! CHECK-NEXT: %[[ELEMENTAL:.*]] = hlfir.elemental %[[B_SHAPE]] : (!fir.shape<2>) -> !hlfir.expr<?x?xi32> {
52+
53+
! CHECK: }
54+
! CHECK-NEXT: %[[A_BOX:.*]] = fir.load %{{.*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi32>>>>
55+
56+
! The shapes in these types are what is being tested:
57+
! CHECK-NEXT: %[[MATMUL:.*]] = hlfir.matmul %[[A_BOX]] %[[ELEMENTAL]] {{.*}} : (!fir.box<!fir.heap<!fir.array<?x?xi32>>>, !hlfir.expr<?x?xi32>) -> !hlfir.expr<?x4xi32>

flang/test/Lower/HLFIR/transpose.f90

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,16 @@ subroutine transpose1(m, res)
1515
! CHECK-NEXT: hlfir.destroy %[[EXPR]]
1616
! CHECK-NEXT: return
1717
! CHECK-NEXT: }
18+
19+
! test the case where lowering has more exact information about the output
20+
! shape than is available from the argument
21+
subroutine transpose2(a, out)
22+
real, allocatable, dimension(:) :: a
23+
real, dimension(:,:) :: out
24+
integer, parameter :: N = 3
25+
integer, parameter :: M = 4
26+
27+
allocate(a(N*M))
28+
out = transpose(reshape(a, (/N, M/)))
29+
end subroutine
30+
! CHECK-LABEL: func.func @_QPtranspose2(

0 commit comments

Comments
 (0)