[flang-commits] [flang] f9e995b - [flang] Normalize logical values during type conversions.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Tue Mar 28 10:12:15 PDT 2023


Author: Slava Zakharin
Date: 2023-03-28T10:11:47-07:00
New Revision: f9e995b4bdce7e3afbda0997b606fdc80112f803

URL: https://github.com/llvm/llvm-project/commit/f9e995b4bdce7e3afbda0997b606fdc80112f803
DIFF: https://github.com/llvm/llvm-project/commit/f9e995b4bdce7e3afbda0997b606fdc80112f803.diff

LOG: [flang] Normalize logical values during type conversions.

Flang was missing value normalization for logical<->integer conversions
which is required by Flang specification. The shrinking logical<->logical
conversions were also incorrectly truncating the input.
This change performs value normalization for all logical<->integer
conversions and logical<->logical conversions between different kinds.

Note that value normalization is not strictly required for
logical(kind=k1)->logical(kind=k2) conversions when k1 < k2.

Differential Revision: https://reviews.llvm.org/D147019

Added: 
    flang/test/Fir/logical-convert.fir

Modified: 
    flang/docs/Extensions.md
    flang/lib/Optimizer/CodeGen/CodeGen.cpp
    flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
    flang/test/Fir/global-initialization.fir

Removed: 
    


################################################################################
diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index d1b759178ac93..1e79ec4374f81 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -188,7 +188,9 @@ end
   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
index 8ea8fa7290372..ef08a6cb1171e 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -79,10 +79,12 @@ static mlir::Block *createBlock(mlir::ConversionPatternRewriter &rewriter,
                               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<mlir::OpResult>() && "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<int64_t> getIfConstantIntValue(mlir::Value val) {
+  if (!val || !val.dyn_cast<mlir::OpResult>())
+    return {};
+
   mlir::Operation *defop = val.getDefiningOp();
 
   if (auto constOp = mlir::dyn_cast<mlir::arith::ConstantIntOp>(defop))
@@ -90,6 +92,15 @@ static int64_t getConstantIntValue(mlir::Value val) {
   if (auto llConstOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(defop))
     if (auto attr = llConstOp.getValue().dyn_cast<mlir::IntegerAttr>())
       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 @@ struct ConvertOpConversion : public FIROpConversion<fir::ConvertOp> {
     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<fir::LogicalType>() || toFirTy.isa<fir::LogicalType>()) {
+      // 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<mlir::IntegerType>() || !toTy.isa<mlir::IntegerType>())
+        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<mlir::LLVM::ZExtOp>(convert, toTy, op0);
+        return mlir::success();
+      }
+
+      // Compare the input with zero.
+      mlir::Value zero = genConstantIndex(loc, fromTy, rewriter, 0);
+      auto isTrue = rewriter.create<mlir::LLVM::ICmpOp>(
+          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<mlir::LLVM::ZExtOp>(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 @@ struct ConvertOpConversion : public FIROpConversion<fir::ConvertOp> {
       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<fir::LogicalType>() && toFirTy == i1Type) {
-      mlir::Value zero = genConstantIndex(loc, fromTy, rewriter, 0);
-      rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
-          convert, mlir::LLVM::ICmpPredicate::ne, op0, zero);
-      return mlir::success();
-    }
-    if (fromFirTy == i1Type && toFirTy.isa<fir::LogicalType>()) {
-      rewriter.replaceOpWithNewOp<mlir::LLVM::ZExtOp>(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
index ee94ac19accd7..4845580592cd5 100644
--- 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 @@ func.func @_QPsb() {
 
 // 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
index 28361a9438adc..b628acd66713b 100644
--- a/flang/test/Fir/global-initialization.fir
+++ b/flang/test/Fir/global-initialization.fir
@@ -40,7 +40,7 @@ fir.global internal @_QEmasklogical : !fir.array<32768x!fir.logical<4>> {
 // 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<true> : 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
index 0000000000000..4cc081934db43
--- /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>
+}


        


More information about the flang-commits mailing list