From 6b9b85b79d09b8fd107be1aa6a5fa91d49a36d4e Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Fri, 2 Sep 2022 20:44:44 +0200 Subject: [PATCH] [flang] Use APInt to lower 128 bits integer constants Lowering was truncating 128 bits integer to 64 bits. This patch makes use of APInt to lower 128 bits integer correctly. ``` program bug print *, 170141183460469231731687303715884105727_16 end ! Before patch: 18446744073709551615 ! With patch: 170141183460469231731687303715884105727 ``` Reviewed By: vdonaldson Differential Revision: https://reviews.llvm.org/D133206 --- flang/lib/Lower/ConvertExpr.cpp | 8 ++++++ flang/test/Lower/big-integer-parameter.f90 | 39 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 flang/test/Lower/big-integer-parameter.f90 diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp index 7b3d258..57e8d81 100644 --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -1451,6 +1451,14 @@ public: const Fortran::evaluate::Scalar> &value) { if constexpr (TC == Fortran::common::TypeCategory::Integer) { + if (KIND == 16) { + mlir::Type ty = + converter.genType(Fortran::common::TypeCategory::Integer, KIND); + auto bigInt = + llvm::APInt(ty.getIntOrFloatBitWidth(), value.SignedDecimal(), 10); + return builder.create( + getLoc(), ty, mlir::IntegerAttr::get(ty, bigInt)); + } return genIntegerConstant(builder.getContext(), value.ToInt64()); } else if constexpr (TC == Fortran::common::TypeCategory::Logical) { return genBoolConstant(value.IsTrue()); diff --git a/flang/test/Lower/big-integer-parameter.f90 b/flang/test/Lower/big-integer-parameter.f90 new file mode 100644 index 0000000..85c7808 --- /dev/null +++ b/flang/test/Lower/big-integer-parameter.f90 @@ -0,0 +1,39 @@ +! Test correct lowering of 128 bit integer parameters. +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +program i128 + integer(16), parameter :: maxi64 = 9223372036854775807_16 + integer(16), parameter :: mini64 = -9223372036854775808_16 + integer(16), parameter :: maxi128 = 170141183460469231731687303715884105727_16 + integer(16), parameter :: mini128 = -170141183460469231731687303715884105728_16 + integer(16), parameter :: x = 9223372036854775808_16 + integer(16), parameter :: y = -9223372036854775809_16 + integer(16), parameter :: z = 0_16 + print*,x + print*,y +end + +! CHECK-LABEL: func.func @_QQmain() { +! CHECK-COUNT-2: %{{.*}} = fir.call @_FortranAioOutputInteger128(%{{.*}}, %{{.*}}) : (!fir.ref, i128) -> i1 + + +! CHECK-LABEL: fir.global internal @_QFECmaxi128 constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant 170141183460469231731687303715884105727 : i128 + +! CHECK-LABEL: fir.global internal @_QFECmaxi64 constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant 9223372036854775807 : i128 + +! CHECK-LABEL: fir.global internal @_QFECmini128 constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant -170141183460469231731687303715884105728 : i128 + +! CHECK-LABEL: fir.global internal @_QFECmini64 constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant -9223372036854775808 : i128 + +! CHECK-LABEL: fir.global internal @_QFECx constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant 9223372036854775808 : i128 + +! CHECK-LABEL: fir.global internal @_QFECy constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant -9223372036854775809 : i128 + +! CHECK-LABEL: fir.global internal @_QFECz constant : i128 { +! CHECK-NEXT: %{{.*}} = arith.constant 0 : i128 -- 2.7.4