diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 9930dd69e0c0a..81e09a1ca5bc9 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -26,7 +26,6 @@ #include "flang/Optimizer/Builder/Complex.h" #include "flang/Optimizer/Builder/IntrinsicCall.h" #include "flang/Optimizer/Builder/MutableBox.h" -#include "flang/Optimizer/Builder/Runtime/Character.h" #include "flang/Optimizer/Builder/Runtime/Derived.h" #include "flang/Optimizer/Builder/Runtime/Pointer.h" #include "flang/Optimizer/Builder/Todo.h" @@ -1286,16 +1285,8 @@ struct BinaryOp { } }; +class CmpCharOpConversion : public HlfirIntrinsicConversion { + using HlfirIntrinsicConversion::HlfirIntrinsicConversion; + + llvm::LogicalResult + matchAndRewrite(hlfir::CmpCharOp cmp, + mlir::PatternRewriter &rewriter) const override { + fir::FirOpBuilder builder{rewriter, cmp.getOperation()}; + const mlir::Location &loc = cmp->getLoc(); + hlfir::Entity lhs{cmp.getLchr()}; + hlfir::Entity rhs{cmp.getRchr()}; + + auto [lhsExv, lhsCleanUp] = + hlfir::translateToExtendedValue(loc, builder, lhs); + auto [rhsExv, rhsCleanUp] = + hlfir::translateToExtendedValue(loc, builder, rhs); + + auto resultVal = fir::runtime::genCharCompare( + builder, loc, cmp.getPredicate(), lhsExv, rhsExv); + if (lhsCleanUp || rhsCleanUp) { + mlir::OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPointAfter(cmp); + if (lhsCleanUp) + (*lhsCleanUp)(); + if (rhsCleanUp) + (*rhsCleanUp)(); + } + auto resultEntity = hlfir::EntityWithAttributes{resultVal}; + + processReturnValue(cmp, resultEntity, /*mustBeFreed=*/false, builder, + rewriter); + return mlir::success(); + } +}; + class LowerHLFIRIntrinsics : public hlfir::impl::LowerHLFIRIntrinsicsBase { public: @@ -558,13 +592,14 @@ class LowerHLFIRIntrinsics mlir::ModuleOp module = this->getOperation(); mlir::MLIRContext *context = &getContext(); mlir::RewritePatternSet patterns(context); - patterns.insert< - MatmulOpConversion, MatmulTransposeOpConversion, AllOpConversion, - AnyOpConversion, SumOpConversion, ProductOpConversion, - TransposeOpConversion, CountOpConversion, DotProductOpConversion, - MaxvalOpConversion, MinvalOpConversion, MinlocOpConversion, - MaxlocOpConversion, ArrayShiftOpConversion, - ArrayShiftOpConversion, ReshapeOpConversion>(context); + patterns.insert, + ArrayShiftOpConversion, + ReshapeOpConversion, CmpCharOpConversion>(context); // While conceptually this pass is performing dialect conversion, we use // pattern rewrites here instead of dialect conversion because this pass diff --git a/flang/test/HLFIR/cmpchar-lowering.fir b/flang/test/HLFIR/cmpchar-lowering.fir new file mode 100644 index 0000000000000..7621c968c30ba --- /dev/null +++ b/flang/test/HLFIR/cmpchar-lowering.fir @@ -0,0 +1,242 @@ +// Test hlfir.cmpchar operation lowering to a fir runtime call +// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s + +// HLFIR for the test below has been produced from reduced flang/test/Lower/Intrinsics/lge_lgt_lle_llt.f90 +func.func @_QPlge_test() { +// CHECK-LABEL: func.func @_QPlge_test() { +// CHECK: %[[VAL_0:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_1:.*]] = arith.constant 7 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_4:.*]] = fir.alloca !fir.array<3x!fir.char<1,3>> {bindc_name = "c1", uniq_name = "_QFlge_testEc1"} +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_4]](%[[VAL_5]]) typeparams %[[VAL_2]] {uniq_name = "_QFlge_testEc1"} : (!fir.ref>>, !fir.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) +// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<3x!fir.char<1,7>> {bindc_name = "c2", uniq_name = "_QFlge_testEc2"} +// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) typeparams %[[VAL_1]] {uniq_name = "_QFlge_testEc2"} : (!fir.ref>>, !fir.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) +// CHECK: %[[VAL_10:.*]] = fir.alloca !fir.array<3x!fir.logical<4>> {bindc_name = "l", uniq_name = "_QFlge_testEl"} +// CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]](%[[VAL_11]]) {uniq_name = "_QFlge_testEl"} : (!fir.ref>>, !fir.shape<1>) -> (!fir.ref>>, !fir.ref>>) +// CHECK: %[[VAL_13:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { + %0 = fir.dummy_scope : !fir.dscope + %c3 = arith.constant 3 : index + %c3_0 = arith.constant 3 : index + %1 = fir.alloca !fir.array<3x!fir.char<1,3>> {bindc_name = "c1", uniq_name = "_QFlge_testEc1"} + %2 = fir.shape %c3_0 : (index) -> !fir.shape<1> + %3:2 = hlfir.declare %1(%2) typeparams %c3 {uniq_name = "_QFlge_testEc1"} : (!fir.ref>>, !fir.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) + %c7 = arith.constant 7 : index + %c3_1 = arith.constant 3 : index + %4 = fir.alloca !fir.array<3x!fir.char<1,7>> {bindc_name = "c2", uniq_name = "_QFlge_testEc2"} + %5 = fir.shape %c3_1 : (index) -> !fir.shape<1> + %6:2 = hlfir.declare %4(%5) typeparams %c7 {uniq_name = "_QFlge_testEc2"} : (!fir.ref>>, !fir.shape<1>, index) -> (!fir.ref>>, !fir.ref>>) + %c3_2 = arith.constant 3 : index + %7 = fir.alloca !fir.array<3x!fir.logical<4>> {bindc_name = "l", uniq_name = "_QFlge_testEl"} + %8 = fir.shape %c3_2 : (index) -> !fir.shape<1> + %9:2 = hlfir.declare %7(%8) {uniq_name = "_QFlge_testEl"} : (!fir.ref>>, !fir.shape<1>) -> (!fir.ref>>, !fir.ref>>) + %10 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { + ^bb0(%arg0: index): + %14 = hlfir.designate %3#0 (%arg0) typeparams %c3 : (!fir.ref>>, index, index) -> !fir.ref> + %15 = hlfir.designate %6#0 (%arg0) typeparams %c7 : (!fir.ref>>, index, index) -> !fir.ref> + %16 = hlfir.cmpchar sge %14 %15 : (!fir.ref>, !fir.ref>) -> i1 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + hlfir.assign %10 to %9#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> + hlfir.destroy %10 : !hlfir.expr<3x!fir.logical<4>> +// CHECK: ^bb0(%[[VAL_14:.*]]: index): +// CHECK: %[[VAL_15:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_14]]) typeparams %[[VAL_2]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_14]]) typeparams %[[VAL_1]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_2]] : (index) -> i64 +// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 +// CHECK: %[[VAL_21:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_17]], %[[VAL_18]], %[[VAL_19]], %[[VAL_20]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_22:.*]] = arith.cmpi sge, %[[VAL_21]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.yield_element %[[VAL_23]] : !fir.logical<4> +// CHECK: } +// CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_12]]#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> +// CHECK: hlfir.destroy %[[VAL_13]] : !hlfir.expr<3x!fir.logical<4>> + %11 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { + ^bb0(%arg0: index): + %14 = hlfir.designate %3#0 (%arg0) typeparams %c3 : (!fir.ref>>, index, index) -> !fir.ref> + %15 = hlfir.designate %6#0 (%arg0) typeparams %c7 : (!fir.ref>>, index, index) -> !fir.ref> + %16 = hlfir.cmpchar sgt %14 %15 : (!fir.ref>, !fir.ref>) -> i1 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + hlfir.assign %11 to %9#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> + hlfir.destroy %11 : !hlfir.expr<3x!fir.logical<4>> +// CHECK: %[[VAL_24:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { +// CHECK: ^bb0(%[[VAL_25:.*]]: index): +// CHECK: %[[VAL_26:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_25]]) typeparams %[[VAL_2]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_27:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_25]]) typeparams %[[VAL_1]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_2]] : (index) -> i64 +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 +// CHECK: %[[VAL_32:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_31]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_33:.*]] = arith.cmpi sgt, %[[VAL_32]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.yield_element %[[VAL_34]] : !fir.logical<4> +// CHECK: } +// CHECK: hlfir.assign %[[VAL_24]] to %[[VAL_12]]#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> +// CHECK: hlfir.destroy %[[VAL_24]] : !hlfir.expr<3x!fir.logical<4>> + %12 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { + ^bb0(%arg0: index): + %14 = hlfir.designate %3#0 (%arg0) typeparams %c3 : (!fir.ref>>, index, index) -> !fir.ref> + %15 = hlfir.designate %6#0 (%arg0) typeparams %c7 : (!fir.ref>>, index, index) -> !fir.ref> + %16 = hlfir.cmpchar sle %14 %15 : (!fir.ref>, !fir.ref>) -> i1 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + hlfir.assign %12 to %9#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> + hlfir.destroy %12 : !hlfir.expr<3x!fir.logical<4>> +// CHECK: %[[VAL_35:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { +// CHECK: ^bb0(%[[VAL_36:.*]]: index): +// CHECK: %[[VAL_37:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_36]]) typeparams %[[VAL_2]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_38:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_36]]) typeparams %[[VAL_1]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_2]] : (index) -> i64 +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 +// CHECK: %[[VAL_43:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_39]], %[[VAL_40]], %[[VAL_41]], %[[VAL_42]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_44:.*]] = arith.cmpi sle, %[[VAL_43]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.yield_element %[[VAL_45]] : !fir.logical<4> +// CHECK: } +// CHECK: hlfir.assign %[[VAL_35]] to %[[VAL_12]]#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> +// CHECK: hlfir.destroy %[[VAL_35]] : !hlfir.expr<3x!fir.logical<4>> + %13 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { + ^bb0(%arg0: index): + %14 = hlfir.designate %3#0 (%arg0) typeparams %c3 : (!fir.ref>>, index, index) -> !fir.ref> + %15 = hlfir.designate %6#0 (%arg0) typeparams %c7 : (!fir.ref>>, index, index) -> !fir.ref> + %16 = hlfir.cmpchar slt %14 %15 : (!fir.ref>, !fir.ref>) -> i1 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + hlfir.assign %13 to %9#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> + hlfir.destroy %13 : !hlfir.expr<3x!fir.logical<4>> + return +} +// CHECK: %[[VAL_46:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<3x!fir.logical<4>> { +// CHECK: ^bb0(%[[VAL_47:.*]]: index): +// CHECK: %[[VAL_48:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_47]]) typeparams %[[VAL_2]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_49:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_47]]) typeparams %[[VAL_1]] : (!fir.ref>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_48]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_49]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_2]] : (index) -> i64 +// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_1]] : (index) -> i64 +// CHECK: %[[VAL_54:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_50]], %[[VAL_51]], %[[VAL_52]], %[[VAL_53]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_55:.*]] = arith.cmpi slt, %[[VAL_54]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_55]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.yield_element %[[VAL_56]] : !fir.logical<4> +// CHECK: } +// CHECK: hlfir.assign %[[VAL_46]] to %[[VAL_12]]#0 : !hlfir.expr<3x!fir.logical<4>>, !fir.ref>> +// CHECK: hlfir.destroy %[[VAL_46]] : !hlfir.expr<3x!fir.logical<4>> +// CHECK: return +// CHECK: } + + +// HLFIR for the test below has been produced +// from test case in flang/test/Lower/HLFIR/binary-ops.f90 +// cmp_char2/cmp_char4 are produced from the modified original test to cover other character kinds. +func.func @_QPcmp_char(%arg0: !fir.ref> {fir.bindc_name = "l"}, %arg1: !fir.boxchar<1> {fir.bindc_name = "x"}, %arg2: !fir.boxchar<1> {fir.bindc_name = "y"}) { +// CHECK-LABEL: func.func @_QPcmp_char( +// CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "l"}, +// CHECK-SAME: %[[ARG1:.*]]: !fir.boxchar<1> {fir.bindc_name = "x"}, +// CHECK-SAME: %[[ARG2:.*]]: !fir.boxchar<1> {fir.bindc_name = "y"}) { +// CHECK: %[[VAL_0:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_charEl"} : (!fir.ref>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +// CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[ARG1]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]]#0 typeparams %[[VAL_3]]#1 dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_charEx"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) +// CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[ARG2]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]]#0 typeparams %[[VAL_5]]#1 dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_charEy"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) +// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64 +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_5]]#1 : (index) -> i64 +// CHECK: %[[VAL_11:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_7]], %[[VAL_8]], %[[VAL_9]], %[[VAL_10]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_2]]#0 : !fir.logical<4>, !fir.ref> +// CHECK: return + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFcmp_charEl"} : (!fir.ref>, !fir.dscope) -> (!fir.ref>, !fir.ref>) + %2:2 = fir.unboxchar %arg1 : (!fir.boxchar<1>) -> (!fir.ref>, index) + %3:2 = hlfir.declare %2#0 typeparams %2#1 dummy_scope %0 {uniq_name = "_QFcmp_charEx"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) + %4:2 = fir.unboxchar %arg2 : (!fir.boxchar<1>) -> (!fir.ref>, index) + %5:2 = hlfir.declare %4#0 typeparams %4#1 dummy_scope %0 {uniq_name = "_QFcmp_charEy"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) + %6 = hlfir.cmpchar eq %3#0 %5#0 : (!fir.boxchar<1>, !fir.boxchar<1>) -> i1 + %7 = fir.convert %6 : (i1) -> !fir.logical<4> + hlfir.assign %7 to %1#0 : !fir.logical<4>, !fir.ref> + return +} + +func.func @_QPcmp_char4(%arg0: !fir.ref> {fir.bindc_name = "l"}, %arg1: !fir.boxchar<4> {fir.bindc_name = "x"}, %arg2: !fir.boxchar<4> {fir.bindc_name = "y"}) { +// CHECK-LABEL: func.func @_QPcmp_char4( +// CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "l"}, +// CHECK-SAME: %[[ARG1:.*]]: !fir.boxchar<4> {fir.bindc_name = "x"}, +// CHECK-SAME: %[[ARG2:.*]]: !fir.boxchar<4> {fir.bindc_name = "y"}) { +// CHECK: %[[VAL_0:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_char4El"} : (!fir.ref>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +// CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[ARG1]] : (!fir.boxchar<4>) -> (!fir.ref>, index) +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]]#0 typeparams %[[VAL_3]]#1 dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_char4Ex"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<4>, !fir.ref>) +// CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[ARG2]] : (!fir.boxchar<4>) -> (!fir.ref>, index) +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]]#0 typeparams %[[VAL_5]]#1 dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_char4Ey"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<4>, !fir.ref>) +// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64 +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_5]]#1 : (index) -> i64 +// CHECK: %[[VAL_11:.*]] = fir.call @_FortranACharacterCompareScalar4(%[[VAL_7]], %[[VAL_8]], %[[VAL_9]], %[[VAL_10]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_2]]#0 : !fir.logical<4>, !fir.ref> +// CHECK: return + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFcmp_char4El"} : (!fir.ref>, !fir.dscope) -> (!fir.ref>, !fir.ref>) + %2:2 = fir.unboxchar %arg1 : (!fir.boxchar<4>) -> (!fir.ref>, index) + %3:2 = hlfir.declare %2#0 typeparams %2#1 dummy_scope %0 {uniq_name = "_QFcmp_char4Ex"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<4>, !fir.ref>) + %4:2 = fir.unboxchar %arg2 : (!fir.boxchar<4>) -> (!fir.ref>, index) + %5:2 = hlfir.declare %4#0 typeparams %4#1 dummy_scope %0 {uniq_name = "_QFcmp_char4Ey"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<4>, !fir.ref>) + %6 = hlfir.cmpchar eq %3#0 %5#0 : (!fir.boxchar<4>, !fir.boxchar<4>) -> i1 + %7 = fir.convert %6 : (i1) -> !fir.logical<4> + hlfir.assign %7 to %1#0 : !fir.logical<4>, !fir.ref> + return +} + +func.func @_QPcmp_char2(%arg0: !fir.ref> {fir.bindc_name = "l"}, %arg1: !fir.boxchar<2> {fir.bindc_name = "x"}, %arg2: !fir.boxchar<2> {fir.bindc_name = "y"}) { +// CHECK-LABEL: func.func @_QPcmp_char2( +// CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "l"}, +// CHECK-SAME: %[[ARG1:.*]]: !fir.boxchar<2> {fir.bindc_name = "x"}, +// CHECK-SAME: %[[ARG2:.*]]: !fir.boxchar<2> {fir.bindc_name = "y"}) { +// CHECK: %[[VAL_0:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_char2El"} : (!fir.ref>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +// CHECK: %[[VAL_3:.*]]:2 = fir.unboxchar %[[ARG1]] : (!fir.boxchar<2>) -> (!fir.ref>, index) +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]]#0 typeparams %[[VAL_3]]#1 dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_char2Ex"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<2>, !fir.ref>) +// CHECK: %[[VAL_5:.*]]:2 = fir.unboxchar %[[ARG2]] : (!fir.boxchar<2>) -> (!fir.ref>, index) +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]]#0 typeparams %[[VAL_5]]#1 dummy_scope %[[VAL_1]] {uniq_name = "_QFcmp_char2Ey"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<2>, !fir.ref>) +// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]]#1 : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64 +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_5]]#1 : (index) -> i64 +// CHECK: %[[VAL_11:.*]] = fir.call @_FortranACharacterCompareScalar2(%[[VAL_7]], %[[VAL_8]], %[[VAL_9]], %[[VAL_10]]) : (!fir.ref, !fir.ref, i64, i64) -> i32 +// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_0]] : i32 +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<4> +// CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_2]]#0 : !fir.logical<4>, !fir.ref> +// CHECK: return + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFcmp_char2El"} : (!fir.ref>, !fir.dscope) -> (!fir.ref>, !fir.ref>) + %2:2 = fir.unboxchar %arg1 : (!fir.boxchar<2>) -> (!fir.ref>, index) + %3:2 = hlfir.declare %2#0 typeparams %2#1 dummy_scope %0 {uniq_name = "_QFcmp_char2Ex"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<2>, !fir.ref>) + %4:2 = fir.unboxchar %arg2 : (!fir.boxchar<2>) -> (!fir.ref>, index) + %5:2 = hlfir.declare %4#0 typeparams %4#1 dummy_scope %0 {uniq_name = "_QFcmp_char2Ey"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<2>, !fir.ref>) + %6 = hlfir.cmpchar eq %3#0 %5#0 : (!fir.boxchar<2>, !fir.boxchar<2>) -> i1 + %7 = fir.convert %6 : (i1) -> !fir.logical<4> + hlfir.assign %7 to %1#0 : !fir.logical<4>, !fir.ref> + return +} + diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90 index 5855d5ad00036..72cd048ea3615 100644 --- a/flang/test/Lower/HLFIR/binary-ops.f90 +++ b/flang/test/Lower/HLFIR/binary-ops.f90 @@ -283,13 +283,8 @@ subroutine cmp_char(l, x, y) ! CHECK-LABEL: func.func @_QPcmp_char( ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}} typeparams %[[VAL_4:.*]]#1 dummy_scope %{{[0-9]+}} {uniq_name = "_QFcmp_charEx"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) ! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %{{.*}} typeparams %[[VAL_6:.*]]#1 dummy_scope %{{[0-9]+}} {uniq_name = "_QFcmp_charEy"} : (!fir.ref>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) -! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_5]]#1 : (!fir.ref>) -> !fir.ref -! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_7]]#1 : (!fir.ref>) -> !fir.ref -! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_4]]#1 : (index) -> i64 -! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]]#1 : (index) -> i64 -! CHECK: %[[VAL_12:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_8]], %[[VAL_9]], %[[VAL_10]], %[[VAL_11]]) fastmath : (!fir.ref, !fir.ref, i64, i64) -> i32 -! CHECK: %[[VAL_13:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_14:.*]] = arith.cmpi eq, %[[VAL_12]], %[[VAL_13]] : i32 +! CHECK: %[[VAL_8:.*]] = hlfir.cmpchar eq %[[VAL_5]]#0 %[[VAL_7]]#0 : (!fir.boxchar<1>, !fir.boxchar<1>) -> i1 +! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i1) -> !fir.logical<4> subroutine logical_and(x, y, z) logical :: x, y, z diff --git a/flang/test/Lower/HLFIR/elemental-array-ops.f90 b/flang/test/Lower/HLFIR/elemental-array-ops.f90 index a9494325c6123..b23c8185b3d22 100644 --- a/flang/test/Lower/HLFIR/elemental-array-ops.f90 +++ b/flang/test/Lower/HLFIR/elemental-array-ops.f90 @@ -195,15 +195,7 @@ end subroutine char_return ! CHECK: ^bb0(%[[VAL_33:.*]]: index): ! CHECK: %[[VAL_34:.*]] = hlfir.designate %[[VAL_10]]#0 (%[[VAL_33]]) typeparams %[[VAL_9]] : (!fir.box>>, index, index) -> !fir.ref> ! CHECK: %[[VAL_35:.*]] = hlfir.apply %[[VAL_36:.*]], %[[VAL_33]] typeparams %[[VAL_16]] : (!hlfir.expr>, index, index) -> !hlfir.expr> -! CHECK: %[[VAL_37:.*]]:3 = hlfir.associate %[[VAL_35]] typeparams %[[VAL_16]] {adapt.valuebyref} : (!hlfir.expr>, index) -> (!fir.ref>, !fir.ref>, i1) -! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref -! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]]#0 : (!fir.ref>) -> !fir.ref -! CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_9]] : (index) -> i64 -! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_16]] : (index) -> i64 -! CHECK: %[[VAL_42:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_38]], %[[VAL_39]], %[[VAL_40]], %[[VAL_41]]) fastmath : (!fir.ref, !fir.ref, i64, i64) -> i32 -! CHECK: %[[VAL_43:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_44:.*]] = arith.cmpi eq, %[[VAL_42]], %[[VAL_43]] : i32 -! CHECK: hlfir.end_associate %[[VAL_37]]#1, %[[VAL_37]]#2 : !fir.ref>, i1 +! CHECK: %[[VAL_44:.*]] = hlfir.cmpchar eq %[[VAL_34]] %[[VAL_35]] : (!fir.ref>, !hlfir.expr>) -> i1 ! CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_44]] : (i1) -> !fir.logical<4> ! CHECK: hlfir.yield_element %[[VAL_45]] : !fir.logical<4> ! CHECK: } diff --git a/flang/test/Lower/Intrinsics/lge_lgt_lle_llt.f90 b/flang/test/Lower/Intrinsics/lge_lgt_lle_llt.f90 index c49d193f0c098..71e5c6da64c12 100644 --- a/flang/test/Lower/Intrinsics/lge_lgt_lle_llt.f90 +++ b/flang/test/Lower/Intrinsics/lge_lgt_lle_llt.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -emit-fir %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s subroutine lge_test character*3 :: c1(3) @@ -30,4 +30,4 @@ subroutine lge_test ! CHECK: EndIoStatement print*, llt(c1, c2) end - \ No newline at end of file + diff --git a/flang/test/Lower/character-compare.f90 b/flang/test/Lower/character-compare.f90 index e3587cdf11e02..a7893f18f4a54 100644 --- a/flang/test/Lower/character-compare.f90 +++ b/flang/test/Lower/character-compare.f90 @@ -1,4 +1,4 @@ -! RUN: bbc %s -o - | FileCheck %s +! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s ! CHECK-LABEL: compare subroutine compare(x, c1, c2)