[flang-commits] [flang] [Flang][LoongArch] Add sign extension for i32 arguments and returns in function signatures. (PR #116146)
Zhaoxin Yang via flang-commits
flang-commits at lists.llvm.org
Mon Nov 18 00:59:31 PST 2024
https://github.com/ylzsx updated https://github.com/llvm/llvm-project/pull/116146
>From 714af00296a9c4439c6d2d34a3e63fba296fa1d6 Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Mon, 11 Nov 2024 19:39:18 +0800
Subject: [PATCH 1/2] [Flang][LoongArch] Add sign extension for i32 arguments
and returns in function signatures.
In loongarch64 LP64D ABI, `unsigned 32-bit` types, such as unsigned int,
are stored in general-purpose registers as proper sign extensions of their
32-bit values. Therefore, Flang also follows it if a function needs to be
interoperable with C.
Reference:
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_abi_lp64d
---
flang/lib/Optimizer/CodeGen/Target.cpp | 24 +++++++++++++++++
.../target-rewrite-integer-loongarch64.fir | 27 +++++++++++++++++++
2 files changed, 51 insertions(+)
create mode 100644 flang/test/Fir/target-rewrite-integer-loongarch64.fir
diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp
index 5f746bf80e9d5b..9ec055b1aecabb 100644
--- a/flang/lib/Optimizer/CodeGen/Target.cpp
+++ b/flang/lib/Optimizer/CodeGen/Target.cpp
@@ -1127,6 +1127,30 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> {
}
return marshal;
}
+
+ CodeGenSpecifics::Marshalling
+ integerArgumentType(mlir::Location loc,
+ mlir::IntegerType argTy) const override {
+ if (argTy.getWidth() == 32) {
+ // LA64 LP64D ABI requires unsigned 32 bit integers to be sign extended.
+ // Therefore, Flang also follows it if a function needs to be
+ // interoperable with C.
+ //
+ // Currently, it only adds `signext` attribute to the dummy arguments and
+ // return values in the function signatures, but it does not add the
+ // corresponding attribute to the actual arguments and return values in
+ // `fir.call` instruction. Thanks to LLVM's integration of all these
+ // attributes, the modification is still effective.
+ CodeGenSpecifics::Marshalling marshal;
+ AT::IntegerExtension intExt = AT::IntegerExtension::Sign;
+ marshal.emplace_back(argTy, AT{/*alignment=*/0, /*byval=*/false,
+ /*sret=*/false, /*append=*/false,
+ /*intExt=*/intExt});
+ return marshal;
+ }
+
+ return GenericTarget::integerArgumentType(loc, argTy);
+ }
};
} // namespace
diff --git a/flang/test/Fir/target-rewrite-integer-loongarch64.fir b/flang/test/Fir/target-rewrite-integer-loongarch64.fir
new file mode 100644
index 00000000000000..e48673afb2b019
--- /dev/null
+++ b/flang/test/Fir/target-rewrite-integer-loongarch64.fir
@@ -0,0 +1,27 @@
+// Test i32 passing and returning on LoongArch64
+// LoongArch64 LP64D ABI requires unsigned 32 bit integers to be sign extended.
+//
+// REQUIRES: loongarch-registered-target
+// RUN: fir-opt --target-rewrite="target=loongarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=LOONGARCH64
+// RUN: tco -target="loongarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=LOONGARCH64_LLVM
+
+// LOONGARCH64: func.func private @cfunc32(i32 {llvm.signext}) -> (i32 {llvm.signext}) attributes {fir.bindc_name = "cfunc32"}
+
+// LOONGARCH64_LLVM: declare signext i32 @cfunc32(i32 signext)
+func.func private @cfunc32(i32) -> i32 attributes {fir.bindc_name = "cfunc32"}
+
+// LOONGARCH64-LABEL: func.func @foo(
+// LOONGARCH64-SAME: %[[VAL_0:.*]]: i32 {llvm.signext}) -> (i32 {llvm.signext}) attributes {fir.bindc_name = "foo"} {
+// LOONGARCH64: %[[VAL_1:.*]] = fir.call @cfunc32(%[[VAL_0]]) fastmath<contract> : (i32) -> i32
+// LOONGARCH64: return %[[VAL_1]] : i32
+// LOONGARCH64: }
+
+// LOONGARCH64_LLVM-LABEL: define signext i32 @foo(
+// LOONGARCH64_LLVM: i32 signext %[[VAL_0:.*]]) {
+// LOONGARCH64_LLVM: %[[VAL_1:.*]] = call i32 @cfunc32(i32 %[[VAL_0]])
+// LOONGARCH64_LLVM: ret i32 %[[VAL_1]]
+// LOONGARCH64_LLVM: }
+func.func @foo(%0: i32) -> i32 attributes {fir.bindc_name = "foo"} {
+ %1 = fir.call @cfunc32(%0) fastmath<contract> : (i32) -> i32
+ return %1 : i32
+}
>From 56f64ed12967283e3ee0078805d2efd696c1544c Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Mon, 18 Nov 2024 16:53:31 +0800
Subject: [PATCH 2/2] Modify comments. NFC
---
flang/test/Fir/target-rewrite-integer-loongarch64.fir | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/flang/test/Fir/target-rewrite-integer-loongarch64.fir b/flang/test/Fir/target-rewrite-integer-loongarch64.fir
index e48673afb2b019..6fe97ec92fa549 100644
--- a/flang/test/Fir/target-rewrite-integer-loongarch64.fir
+++ b/flang/test/Fir/target-rewrite-integer-loongarch64.fir
@@ -1,6 +1,6 @@
-// Test i32 passing and returning on LoongArch64
-// LoongArch64 LP64D ABI requires unsigned 32 bit integers to be sign extended.
-//
+/// Test i32 passing and returning on LoongArch64
+/// LoongArch64 LP64D ABI requires unsigned 32 bit integers to be sign extended.
+
// REQUIRES: loongarch-registered-target
// RUN: fir-opt --target-rewrite="target=loongarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=LOONGARCH64
// RUN: tco -target="loongarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=LOONGARCH64_LLVM
More information about the flang-commits
mailing list