[Flang] Lower achar intrinsic
authorKiran Chandramohan <kiran.chandramohan@arm.com>
Fri, 25 Mar 2022 14:22:49 +0000 (14:22 +0000)
committerKiran Chandramohan <kiran.chandramohan@arm.com>
Fri, 25 Mar 2022 14:23:32 +0000 (14:23 +0000)
The intrinsic returns the character located at the position requested
in the ASCII sequence. The intrinsic is lowered to inline FIR code.

This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project

Reviewed By: clementval

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

Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
flang/lib/Lower/IntrinsicCall.cpp
flang/test/Lower/Intrinsics/achar.f90 [new file with mode: 0644]

index bc67c8d..2b92e52 100644 (file)
@@ -648,6 +648,7 @@ static constexpr bool handleDynamicOptional = true;
 /// should be provided for all the intrinsic arguments for completeness.
 static constexpr IntrinsicHandler handlers[]{
     {"abs", &I::genAbs},
+    {"achar", &I::genChar},
     {"adjustl",
      &I::genAdjustRtCall<fir::runtime::genAdjustL>,
      {{{"string", asAddr}}},
diff --git a/flang/test/Lower/Intrinsics/achar.f90 b/flang/test/Lower/Intrinsics/achar.f90
new file mode 100644 (file)
index 0000000..9cf3948
--- /dev/null
@@ -0,0 +1,23 @@
+! RUN: bbc -emit-fir %s -o - | fir-opt --canonicalize | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | fir-opt --canonicalize | FileCheck %s
+
+! CHECK-LABEL: test1
+! CHECK-SAME: (%[[XREF:.*]]: !fir.ref<i32> {{.*}}, %[[CBOX:.*]]: !fir.boxchar<1> {{.*}})
+! CHECK: %[[C1:.*]] = arith.constant 1 : index
+! CHECK: %[[FALSE:.*]] = arith.constant false
+! CHECK: %[[TEMP:.*]] = fir.alloca !fir.char<1> {adapt.valuebyref}
+! CHECK: %[[C:.*]]:2 = fir.unboxchar %[[CBOX]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK: %[[X:.*]] = fir.load %[[XREF]] : !fir.ref<i32>
+! CHECK: %[[X_I8:.*]] = fir.convert %[[X]] : (i32) -> i8
+! CHECK: %[[UNDEF:.*]] = fir.undefined !fir.char<1>
+! CHECK: %[[XCHAR:.*]] = fir.insert_value %[[UNDEF]], %[[X_I8]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1>
+! CHECK: fir.store %[[XCHAR]] to %[[TEMP]] : !fir.ref<!fir.char<1>>
+! CHECK: %[[C1_I64:.*]] = fir.convert %[[C1]] : (index) -> i64
+! CHECK: %[[C_CVT:.*]] = fir.convert %[[C]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
+! CHECK: %[[TEMP_WITH_XCHAR:.*]] = fir.convert %[[TEMP]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
+! CHECK: fir.call @llvm.memmove.p0i8.p0i8.i64(%[[C_CVT]], %[[TEMP_WITH_XCHAR]], %[[C1_I64]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
+subroutine test1(x, c)
+  integer :: x
+  character :: c
+  c = achar(x)
+end subroutine