@@ -319,7 +319,8 @@ def hlfir_ParentComponentOp : hlfir_Op<"parent_comp", [AttrSizedOperandSegments,
319319 let hasVerifier = 1;
320320}
321321
322- def hlfir_ConcatOp : hlfir_Op<"concat", []> {
322+ def hlfir_ConcatOp : hlfir_Op<"concat",
323+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
323324 let summary = "concatenate characters";
324325 let description = [{
325326 Concatenate two or more character strings of a same character kind.
@@ -340,7 +341,7 @@ def hlfir_ConcatOp : hlfir_Op<"concat", []> {
340341 let hasVerifier = 1;
341342}
342343
343- def hlfir_AllOp : hlfir_Op<"all", []> {
344+ def hlfir_AllOp : hlfir_Op<"all", [DeclareOpInterfaceMethods<MemoryEffectsOpInterface> ]> {
344345 let summary = "ALL transformational intrinsic";
345346 let description = [{
346347 Takes a logical array MASK as argument, optionally along a particular dimension,
@@ -361,7 +362,7 @@ def hlfir_AllOp : hlfir_Op<"all", []> {
361362 let hasVerifier = 1;
362363}
363364
364- def hlfir_AnyOp : hlfir_Op<"any", []> {
365+ def hlfir_AnyOp : hlfir_Op<"any", [DeclareOpInterfaceMethods<MemoryEffectsOpInterface> ]> {
365366 let summary = "ANY transformational intrinsic";
366367 let description = [{
367368 Takes a logical array MASK as argument, optionally along a particular dimension,
@@ -382,7 +383,7 @@ def hlfir_AnyOp : hlfir_Op<"any", []> {
382383 let hasVerifier = 1;
383384}
384385
385- def hlfir_CountOp : hlfir_Op<"count", [AttrSizedOperandSegments]> {
386+ def hlfir_CountOp : hlfir_Op<"count", [AttrSizedOperandSegments, DeclareOpInterfaceMethods<MemoryEffectsOpInterface> ]> {
386387 let summary = "COUNT transformational intrinsic";
387388 let description = [{
388389 Takes a logical and counts the number of true values.
@@ -403,9 +404,9 @@ def hlfir_CountOp : hlfir_Op<"count", [AttrSizedOperandSegments]> {
403404 let hasVerifier = 1;
404405}
405406
406-
407407def hlfir_ProductOp : hlfir_Op<"product", [AttrSizedOperandSegments,
408- DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
408+ DeclareOpInterfaceMethods<ArithFastMathInterface>,
409+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
409410 let summary = "PRODUCT transformational intrinsic";
410411 let description = [{
411412 Multiplies the elements of an array, optionally along a particular dimension,
@@ -429,7 +430,8 @@ def hlfir_ProductOp : hlfir_Op<"product", [AttrSizedOperandSegments,
429430 let hasVerifier = 1;
430431}
431432
432- def hlfir_SetLengthOp : hlfir_Op<"set_length", []> {
433+ def hlfir_SetLengthOp : hlfir_Op<"set_length",
434+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
433435 let summary = "change the length of a character entity";
434436 let description = [{
435437 Change the length of character entity. This trims or pads the
@@ -468,7 +470,8 @@ def hlfir_GetLengthOp : hlfir_Op<"get_length", [Pure]> {
468470}
469471
470472def hlfir_SumOp : hlfir_Op<"sum", [AttrSizedOperandSegments,
471- DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
473+ DeclareOpInterfaceMethods<ArithFastMathInterface>,
474+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
472475 let summary = "SUM transformational intrinsic";
473476 let description = [{
474477 Sums the elements of an array, optionally along a particular dimension,
@@ -493,7 +496,8 @@ def hlfir_SumOp : hlfir_Op<"sum", [AttrSizedOperandSegments,
493496}
494497
495498def hlfir_DotProductOp : hlfir_Op<"dot_product",
496- [DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
499+ [DeclareOpInterfaceMethods<ArithFastMathInterface>,
500+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
497501 let summary = "DOT_PRODUCT transformational intrinsic";
498502 let description = [{
499503 Dot product of two vectors
@@ -516,7 +520,8 @@ def hlfir_DotProductOp : hlfir_Op<"dot_product",
516520}
517521
518522def hlfir_MatmulOp : hlfir_Op<"matmul",
519- [DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
523+ [DeclareOpInterfaceMethods<ArithFastMathInterface>,
524+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
520525 let summary = "MATMUL transformational intrinsic";
521526 let description = [{
522527 Matrix multiplication
@@ -541,7 +546,8 @@ def hlfir_MatmulOp : hlfir_Op<"matmul",
541546 let hasVerifier = 1;
542547}
543548
544- def hlfir_TransposeOp : hlfir_Op<"transpose", []> {
549+ def hlfir_TransposeOp : hlfir_Op<"transpose",
550+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
545551 let summary = "TRANSPOSE transformational intrinsic";
546552 let description = [{
547553 Transpose a rank 2 array
@@ -559,7 +565,8 @@ def hlfir_TransposeOp : hlfir_Op<"transpose", []> {
559565}
560566
561567def hlfir_MatmulTransposeOp : hlfir_Op<"matmul_transpose",
562- [DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
568+ [DeclareOpInterfaceMethods<ArithFastMathInterface>,
569+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
563570 let summary = "Optimized MATMUL(TRANSPOSE(...), ...)";
564571 let description = [{
565572 Matrix multiplication where the left hand side is transposed
@@ -581,8 +588,12 @@ def hlfir_MatmulTransposeOp : hlfir_Op<"matmul_transpose",
581588 let hasVerifier = 1;
582589}
583590
591+ // An allocation effect is needed because the value produced by the associate
592+ // is "deallocated" by hlfir.end_associate (the end_associate must not be
593+ // removed, and there must be only one hlfir.end_associate).
584594def hlfir_AssociateOp : hlfir_Op<"associate", [AttrSizedOperandSegments,
585- DeclareOpInterfaceMethods<fir_FortranVariableOpInterface>]> {
595+ DeclareOpInterfaceMethods<fir_FortranVariableOpInterface>,
596+ MemoryEffects<[MemAlloc]>]> {
586597 let summary = "Create a variable from an expression value";
587598 let description = [{
588599 Create a variable from an expression value.
@@ -635,7 +646,7 @@ def hlfir_AssociateOp : hlfir_Op<"associate", [AttrSizedOperandSegments,
635646 }];
636647}
637648
638- def hlfir_EndAssociateOp : hlfir_Op<"end_associate", []> {
649+ def hlfir_EndAssociateOp : hlfir_Op<"end_associate", [MemoryEffects<[MemFree]> ]> {
639650 let summary = "Mark the end of life of a variable associated to an expression";
640651
641652 let description = [{
@@ -652,7 +663,8 @@ def hlfir_EndAssociateOp : hlfir_Op<"end_associate", []> {
652663 let builders = [OpBuilder<(ins "hlfir::AssociateOp":$associate)>];
653664}
654665
655- def hlfir_AsExprOp : hlfir_Op<"as_expr", []> {
666+ def hlfir_AsExprOp : hlfir_Op<"as_expr",
667+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
656668 let summary = "Take the value of an array, character or derived variable";
657669
658670 let description = [{
@@ -934,7 +946,7 @@ def hlfir_DestroyOp : hlfir_Op<"destroy", [MemoryEffects<[MemFree]>]> {
934946 let assemblyFormat = "$expr attr-dict `:` qualified(type($expr))";
935947}
936948
937- def hlfir_CopyInOp : hlfir_Op<"copy_in", []> {
949+ def hlfir_CopyInOp : hlfir_Op<"copy_in", [MemoryEffects<[MemAlloc]> ]> {
938950 let summary = "copy a variable into a contiguous temporary if it is not contiguous";
939951 let description = [{
940952 Copy a variable into a contiguous temporary if the variable is not
@@ -954,7 +966,7 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", []> {
954966 is true and, when it is false, the original value will be returned instead.
955967 }];
956968
957- let arguments = (ins fir_BaseBoxType:$var,
969+ let arguments = (ins Arg< fir_BaseBoxType, "", [MemRead]> :$var,
958970 Optional<I1>:$var_is_present);
959971
960972 let results = (outs fir_BaseBoxType, I1);
@@ -981,7 +993,7 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", []> {
981993 }];
982994}
983995
984- def hlfir_CopyOutOp : hlfir_Op<"copy_out", []> {
996+ def hlfir_CopyOutOp : hlfir_Op<"copy_out", [MemoryEffects<[MemFree]> ]> {
985997 let summary = "copy out a variable after a copy in";
986998 let description = [{
987999 If the variable was copied in a temporary in the related hlfir.copy_in,
@@ -992,9 +1004,9 @@ def hlfir_CopyOutOp : hlfir_Op<"copy_out", []> {
9921004 The deallocation of $temp is done if $was_copied is true.
9931005 }];
9941006
995- let arguments = (ins fir_BaseBoxType:$temp,
1007+ let arguments = (ins Arg< fir_BaseBoxType, "", [MemRead]> :$temp,
9961008 I1:$was_copied,
997- Optional<fir_BaseBoxType>:$var);
1009+ Arg< Optional<fir_BaseBoxType>, "", [MemWrite] >:$var);
9981010
9991011 let assemblyFormat = [{
10001012 $temp `,` $was_copied (`to` $var^)?
@@ -1546,7 +1558,8 @@ def hlfir_ForallIndexOp : hlfir_Op<"forall_index", [fir_FortranVariableOpInterfa
15461558 let hasCanonicalizeMethod = 1;
15471559}
15481560
1549- def hlfir_CharExtremumOp : hlfir_Op<"char_extremum", []> {
1561+ def hlfir_CharExtremumOp : hlfir_Op<"char_extremum",
1562+ [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
15501563 let summary = "Find max/min from given character strings";
15511564 let description = [{
15521565 Find the lexicographical minimum or maximum of two or more character
0 commit comments