[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