diff --git a/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td b/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td index 1dbde5c1c7302..2414de496d45b 100644 --- a/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td +++ b/flang/include/flang/Optimizer/Dialect/CanonicalizationPatterns.td @@ -57,6 +57,9 @@ def StrictSmallerWidthPred : Constraint>; +def PointerCompatiblePred + : Constraint>; + // floats or ints that undergo successive extensions or successive truncations. def ConvertConvertOptPattern : Pat<(fir_ConvertOp:$res (fir_ConvertOp:$irm $arg)), @@ -112,4 +115,18 @@ def ForwardConstantConvertPattern (createConstantOp $res, $attr), [(IndexTypePred $res), (IntegerTypePred $cnt)]>; +// Optimize redundant pointer conversions, e.g.: +// %1 = fir.convert %0 : +// (!fir.heap>) -> !fir.ref> +// %2 = fir.convert %1 : +// (!fir.ref>) -> !fir.heap> +// Will be optimized into: +// %2 = fir.convert %0 : +// (!fir.heap>) -> !fir.heap> +// which is redundant due to RedundantConvertOptPattern. +def ChainedPointerConvertsPattern + : Pat<(fir_ConvertOp:$res(fir_ConvertOp:$irm $arg)), (fir_ConvertOp $arg), + [(PointerCompatiblePred $arg), (PointerCompatiblePred $irm), + (PointerCompatiblePred $res)]>; + #endif // FORTRAN_FIR_REWRITE_PATTERNS diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index cdcf9bda49a62..fa83aa380e489 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1313,7 +1313,8 @@ void fir::ConvertOp::getCanonicalizationPatterns( results.insert(context); + ForwardConstantConvertPattern, ChainedPointerConvertsPattern>( + context); } mlir::OpFoldResult fir::ConvertOp::fold(FoldAdaptor adaptor) { diff --git a/flang/test/Fir/convert-fold.fir b/flang/test/Fir/convert-fold.fir index ebb6c8db7c891..fb30e634ba5e6 100644 --- a/flang/test/Fir/convert-fold.fir +++ b/flang/test/Fir/convert-fold.fir @@ -35,3 +35,12 @@ func.func @ctest() -> index { // CHECK-NEXT: return %{{.*}} : index return %2 : index } + +// CHECK-LABEL: func.func @ptrtest( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.heap>) -> !fir.heap> { +func.func @ptrtest(%0 : !fir.heap>) -> !fir.heap> { + %1 = fir.convert %0 : (!fir.heap>) -> !fir.ref> + %2 = fir.convert %1 : (!fir.ref>) -> !fir.heap> +// CHECK: return %[[VAL_0]] : !fir.heap> + return %2 : !fir.heap> +} diff --git a/flang/test/Lower/array-substring.f90 b/flang/test/Lower/array-substring.f90 index 02101039120e9..7544fbb989627 100644 --- a/flang/test/Lower/array-substring.f90 +++ b/flang/test/Lower/array-substring.f90 @@ -24,9 +24,8 @@ ! CHECK: %[[VAL_16:.*]] = fir.array_coor %[[VAL_7]](%[[VAL_9]]) {{\[}}%[[VAL_10]]] %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref> ! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref>) -> !fir.ref>> ! CHECK: %[[VAL_18:.*]] = fir.coordinate_of %[[VAL_17]], %[[VAL_2]] : (!fir.ref>>, index) -> !fir.ref> -! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref> ! CHECK: %[[VAL_20:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_9]]) %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> -! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_4]] : (index) -> i64 ! CHECK: %[[VAL_24:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_23]]) {{.*}}: (!fir.ref, !fir.ref, i64, i64) -> i32 diff --git a/flang/test/Lower/vector-subscript-io.f90 b/flang/test/Lower/vector-subscript-io.f90 index 372130fd09907..9a041af16c88c 100644 --- a/flang/test/Lower/vector-subscript-io.f90 +++ b/flang/test/Lower/vector-subscript-io.f90 @@ -325,12 +325,11 @@ subroutine substring(x, y, i, j) ! CHECK: %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index ! CHECK: %[[VAL_231:.*]] = fir.convert %[[VAL_228]] : (!fir.ref>) -> !fir.ref>> ! CHECK: %[[VAL_232:.*]] = fir.coordinate_of %[[VAL_231]], %[[VAL_230]] : (!fir.ref>>, index) -> !fir.ref> -! CHECK: %[[VAL_233:.*]] = fir.convert %[[VAL_232]] : (!fir.ref>) -> !fir.ref> ! CHECK: %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index ! CHECK: %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index ! CHECK: %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index ! CHECK: %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index -! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_233]] : (!fir.ref>) -> !fir.ref +! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_232]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64 ! CHECK: %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) {{.*}}: (!fir.ref, !fir.ref, i64) -> i1 ! CHECK: %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] overflow : index