diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -188,7 +188,9 @@ relax enforcement of some requirements on actual arguments that must otherwise hold true for definable arguments. * Assignment of `LOGICAL` to `INTEGER` and vice versa (but not other types) is - allowed. The values are normalized. + allowed. The values are normalized to canonical `.TRUE.`/`.FALSE.`. + The values are also normalized for assignments of `LOGICAL(KIND=K1)` to + `LOGICAL(KIND=K2)`, when `K1 != K2`. * Static initialization of `LOGICAL` with `INTEGER` is allowed in `DATA` statements and object initializers. The results are *not* normalized to canonical `.TRUE.`/`.FALSE.`. diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -79,10 +79,12 @@ mlir::Region::iterator(insertBefore)); } -/// Extract constant from a value that must be the result of one of the -/// ConstantOp operations. -static int64_t getConstantIntValue(mlir::Value val) { - assert(val && val.dyn_cast() && "must not be null value"); +/// Extract constant from a value if it is a result of one of the +/// ConstantOp operations, otherwise, return std::nullopt. +static std::optional getIfConstantIntValue(mlir::Value val) { + if (!val || !val.dyn_cast()) + return {}; + mlir::Operation *defop = val.getDefiningOp(); if (auto constOp = mlir::dyn_cast(defop)) @@ -90,6 +92,15 @@ if (auto llConstOp = mlir::dyn_cast(defop)) if (auto attr = llConstOp.getValue().dyn_cast()) return attr.getValue().getSExtValue(); + + return {}; +} + +/// Extract constant from a value that must be the result of one of the +/// ConstantOp operations. +static int64_t getConstantIntValue(mlir::Value val) { + if (auto constVal = getIfConstantIntValue(val)) + return *constVal; fir::emitFatalError(val.getLoc(), "must be a constant"); } @@ -858,11 +869,67 @@ auto fromTy = convertType(fromFirTy); auto toTy = convertType(toFirTy); mlir::Value op0 = adaptor.getOperands()[0]; - if (fromTy == toTy) { + + if (fromFirTy == toFirTy) { rewriter.replaceOp(convert, op0); return mlir::success(); } + auto loc = convert.getLoc(); + auto i1Type = mlir::IntegerType::get(convert.getContext(), 1); + + if (fromFirTy.isa() || toFirTy.isa()) { + // By specification fir::LogicalType value may be any number, + // where non-zero value represents .true. and zero value represents + // .false. + // + // integer<->logical conversion requires value normalization. + // Conversion from wide logical to narrow logical must set the result + // to non-zero iff the input is non-zero - the easiest way to implement + // it is to compare the input agains zero and set the result to + // the canonical 0/1. + // Conversion from narrow logical to wide logical may be implemented + // as a zero or sign extension of the input, but it may use value + // normalization as well. + if (!fromTy.isa() || !toTy.isa()) + return mlir::emitError(loc) + << "unsupported types for logical conversion: " << fromTy + << " -> " << toTy; + + // Do folding for constant inputs. + if (auto constVal = getIfConstantIntValue(op0)) { + mlir::Value normVal = + genConstantIndex(loc, toTy, rewriter, *constVal ? 1 : 0); + rewriter.replaceOp(convert, normVal); + return mlir::success(); + } + + // If the input is i1, then we can just zero extend it, and + // the result will be normalized. + if (fromTy == i1Type) { + rewriter.replaceOpWithNewOp(convert, toTy, op0); + return mlir::success(); + } + + // Compare the input with zero. + mlir::Value zero = genConstantIndex(loc, fromTy, rewriter, 0); + auto isTrue = rewriter.create( + loc, mlir::LLVM::ICmpPredicate::ne, op0, zero); + + // Zero extend the i1 isTrue result to the required type (unless it is i1 + // itself). + if (toTy != i1Type) + rewriter.replaceOpWithNewOp(convert, toTy, isTrue); + else + rewriter.replaceOp(convert, isTrue.getResult()); + + return mlir::success(); + } + + if (fromTy == toTy) { + rewriter.replaceOp(convert, op0); + return mlir::success(); + } auto convertFpToFp = [&](mlir::Value val, unsigned fromBits, unsigned toBits, mlir::Type toTy) -> mlir::Value { if (fromBits == toBits) { @@ -896,21 +963,6 @@ return mlir::success(); } - // Follow UNIX F77 convention for logicals: - // 1. underlying integer is not zero => logical is .TRUE. - // 2. logical is .TRUE. => set underlying integer to 1. - auto i1Type = mlir::IntegerType::get(convert.getContext(), 1); - if (fromFirTy.isa() && toFirTy == i1Type) { - mlir::Value zero = genConstantIndex(loc, fromTy, rewriter, 0); - rewriter.replaceOpWithNewOp( - convert, mlir::LLVM::ICmpPredicate::ne, op0, zero); - return mlir::success(); - } - if (fromFirTy == i1Type && toFirTy.isa()) { - rewriter.replaceOpWithNewOp(convert, toTy, op0); - return mlir::success(); - } - // Floating point to floating point conversion. if (isFloatingPointTy(fromTy)) { if (isFloatingPointTy(toTy)) { diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -490,9 +490,8 @@ // CHECK: omp.reduction.declare @[[EQV_REDUCTION:.*]] : i32 init { // CHECK: ^bb0(%{{.*}}: i32): -// CHECK: %[[TRUE:.*]] = llvm.mlir.constant(true) : i1 -// CHECK: %[[TRUE_EXT:.*]] = llvm.zext %[[TRUE]] : i1 to i32 -// CHECK: omp.yield(%[[TRUE_EXT]] : i32) +// CHECK: %[[TRUE:.*]] = llvm.mlir.constant(1 : i64) : i32 +// CHECK: omp.yield(%[[TRUE]] : i32) // CHECK: } combiner { // CHECK: ^bb0(%[[ARG_1:.*]]: i32, %[[ARG_2:.*]]: i32): // CHECK: %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32 diff --git a/flang/test/Fir/global-initialization.fir b/flang/test/Fir/global-initialization.fir --- a/flang/test/Fir/global-initialization.fir +++ b/flang/test/Fir/global-initialization.fir @@ -40,7 +40,7 @@ // CHECK: llvm.mlir.global internal @_QEmasklogical() {addr_space = 0 : i32} : !llvm.array<32768 x i32> { // CHECK: [[VAL0:%.*]] = llvm.mlir.constant(true) : i1 // CHECK: [[VAL1:%.*]] = llvm.mlir.undef : !llvm.array<32768 x i32> -// CHECK: [[VAL2:%.*]] = llvm.zext [[VAL0]] : i1 to i32 +// CHECK: [[VAL2:%.*]] = llvm.mlir.constant(1 : i64) : i32 // CHECK: [[VAL3:%.*]] = llvm.mlir.constant(dense : vector<32768xi1>) : !llvm.array<32768 x i32> // CHECK: llvm.return [[VAL3]] : !llvm.array<32768 x i32> // CHECK: } diff --git a/flang/test/Fir/logical-convert.fir b/flang/test/Fir/logical-convert.fir new file mode 100644 --- /dev/null +++ b/flang/test/Fir/logical-convert.fir @@ -0,0 +1,513 @@ +// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s +// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s +// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s +// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s + +// ----- +// CHECK-LABEL: @test_l1_i1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: llvm.return [[t1]] : i1 +func.func @test_l1_i1(%arg0: !fir.logical<1>) -> i1 { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> i1 + return %0 : i1 +} +// ----- +// CHECK-LABEL: @test_l1_i8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l1_i8(%arg0: !fir.logical<1>) -> i8 { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> i8 + return %0 : i8 +} +// ----- +// CHECK-LABEL: @test_l1_i16 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l1_i16(%arg0: !fir.logical<1>) -> i16 { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> i16 + return %0 : i16 +} +// ----- +// CHECK-LABEL: @test_l1_i32 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l1_i32(%arg0: !fir.logical<1>) -> i32 { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> i32 + return %0 : i32 +} +// ----- +// CHECK-LABEL: @test_l1_i64 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l1_i64(%arg0: !fir.logical<1>) -> i64 { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> i64 + return %0 : i64 +} +// ----- +// CHECK-LABEL: @test_l2_i1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: llvm.return [[t1]] : i1 +func.func @test_l2_i1(%arg0: !fir.logical<2>) -> i1 { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> i1 + return %0 : i1 +} +// ----- +// CHECK-LABEL: @test_l2_i8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l2_i8(%arg0: !fir.logical<2>) -> i8 { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> i8 + return %0 : i8 +} +// ----- +// CHECK-LABEL: @test_l2_i16 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l2_i16(%arg0: !fir.logical<2>) -> i16 { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> i16 + return %0 : i16 +} +// ----- +// CHECK-LABEL: @test_l2_i32 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l2_i32(%arg0: !fir.logical<2>) -> i32 { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> i32 + return %0 : i32 +} +// ----- +// CHECK-LABEL: @test_l2_i64 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l2_i64(%arg0: !fir.logical<2>) -> i64 { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> i64 + return %0 : i64 +} +// ----- +// CHECK-LABEL: @test_l4_i1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: llvm.return [[t1]] : i1 +func.func @test_l4_i1(%arg0: !fir.logical<4>) -> i1 { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> i1 + return %0 : i1 +} +// ----- +// CHECK-LABEL: @test_l4_i8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l4_i8(%arg0: !fir.logical<4>) -> i8 { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> i8 + return %0 : i8 +} +// ----- +// CHECK-LABEL: @test_l4_i16 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l4_i16(%arg0: !fir.logical<4>) -> i16 { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> i16 + return %0 : i16 +} +// ----- +// CHECK-LABEL: @test_l4_i32 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l4_i32(%arg0: !fir.logical<4>) -> i32 { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> i32 + return %0 : i32 +} +// ----- +// CHECK-LABEL: @test_l4_i64 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l4_i64(%arg0: !fir.logical<4>) -> i64 { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> i64 + return %0 : i64 +} +// ----- +// CHECK-LABEL: @test_l8_i1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: llvm.return [[t1]] : i1 +func.func @test_l8_i1(%arg0: !fir.logical<8>) -> i1 { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> i1 + return %0 : i1 +} +// ----- +// CHECK-LABEL: @test_l8_i8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l8_i8(%arg0: !fir.logical<8>) -> i8 { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> i8 + return %0 : i8 +} +// ----- +// CHECK-LABEL: @test_l8_i16 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l8_i16(%arg0: !fir.logical<8>) -> i16 { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> i16 + return %0 : i16 +} +// ----- +// CHECK-LABEL: @test_l8_i32 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l8_i32(%arg0: !fir.logical<8>) -> i32 { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> i32 + return %0 : i32 +} +// ----- +// CHECK-LABEL: @test_l8_i64 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l8_i64(%arg0: !fir.logical<8>) -> i64 { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> i64 + return %0 : i64 +} +// ----- +// CHECK-LABEL: @test_i1_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.zext %arg0 : i1 to i8 +// CHECK: llvm.return [[t0]] : i8 +func.func @test_i1_l1(%arg0: i1) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (i1) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_i1_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.zext %arg0 : i1 to i16 +// CHECK: llvm.return [[t0]] : i16 +func.func @test_i1_l2(%arg0: i1) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (i1) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_i1_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.zext %arg0 : i1 to i32 +// CHECK: llvm.return [[t0]] : i32 +func.func @test_i1_l4(%arg0: i1) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (i1) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_i1_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.zext %arg0 : i1 to i64 +// CHECK: llvm.return [[t0]] : i64 +func.func @test_i1_l8(%arg0: i1) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (i1) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_i8_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_i8_l1(%arg0: i8) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (i8) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_i8_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_i8_l2(%arg0: i8) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (i8) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_i8_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_i8_l4(%arg0: i8) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (i8) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_i8_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_i8_l8(%arg0: i8) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (i8) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_i16_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_i16_l1(%arg0: i16) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (i16) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_i16_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_i16_l2(%arg0: i16) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (i16) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_i16_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_i16_l4(%arg0: i16) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (i16) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_i16_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_i16_l8(%arg0: i16) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (i16) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_i32_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_i32_l1(%arg0: i32) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (i32) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_i32_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_i32_l2(%arg0: i32) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (i32) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_i32_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_i32_l4(%arg0: i32) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (i32) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_i32_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_i32_l8(%arg0: i32) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (i32) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_i64_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_i64_l1(%arg0: i64) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (i64) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_i64_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_i64_l2(%arg0: i64) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (i64) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_i64_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_i64_l4(%arg0: i64) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (i64) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_i64_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_i64_l8(%arg0: i64) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (i64) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_l1_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l1_l2(%arg0: !fir.logical<1>) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_l1_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l1_l4(%arg0: !fir.logical<1>) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_l1_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i8 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i8 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l1_l8(%arg0: !fir.logical<1>) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (!fir.logical<1>) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_l2_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l2_l1(%arg0: !fir.logical<2>) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_l2_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l2_l4(%arg0: !fir.logical<2>) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> !fir.logical<4> + return %0 : !fir.logical<4> +} +// ----- +// CHECK-LABEL: @test_l2_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i16 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i16 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l2_l8(%arg0: !fir.logical<2>) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (!fir.logical<2>) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_l4_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l4_l1(%arg0: !fir.logical<4>) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_l4_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l4_l2(%arg0: !fir.logical<4>) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_l4_l8 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i32 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i32 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i64 +// CHECK: llvm.return [[t2]] : i64 +func.func @test_l4_l8(%arg0: !fir.logical<4>) -> !fir.logical<8> { + %0 = fir.convert %arg0 : (!fir.logical<4>) -> !fir.logical<8> + return %0 : !fir.logical<8> +} +// ----- +// CHECK-LABEL: @test_l8_l1 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i8 +// CHECK: llvm.return [[t2]] : i8 +func.func @test_l8_l1(%arg0: !fir.logical<8>) -> !fir.logical<1> { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> !fir.logical<1> + return %0 : !fir.logical<1> +} +// ----- +// CHECK-LABEL: @test_l8_l2 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i16 +// CHECK: llvm.return [[t2]] : i16 +func.func @test_l8_l2(%arg0: !fir.logical<8>) -> !fir.logical<2> { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> !fir.logical<2> + return %0 : !fir.logical<2> +} +// ----- +// CHECK-LABEL: @test_l8_l4 +// CHECK: [[t0:%[0-9]*]] = llvm.mlir.constant(0 : i64) : i64 +// CHECK: [[t1:%[0-9]*]] = llvm.icmp "ne" %arg0, [[t0]] : i64 +// CHECK: [[t2:%[0-9]*]] = llvm.zext [[t1]] : i1 to i32 +// CHECK: llvm.return [[t2]] : i32 +func.func @test_l8_l4(%arg0: !fir.logical<8>) -> !fir.logical<4> { + %0 = fir.convert %arg0 : (!fir.logical<8>) -> !fir.logical<4> + return %0 : !fir.logical<4> +}