[llvm] [GlobalISel][ARM] Legalze set_fpenv and get_fpenv (PR #79852)
Serge Pavlov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 29 09:22:30 PST 2024
https://github.com/spavloff updated https://github.com/llvm/llvm-project/pull/79852
>From b0cd3a40ecaac9ca49c7a0e697ecdbe2b6c899e2 Mon Sep 17 00:00:00 2001
From: Serge Pavlov <sepavloff at gmail.com>
Date: Mon, 29 Jan 2024 21:09:40 +0700
Subject: [PATCH 1/2] [GlobalISel][ARM] Legalze set_fpenv and get_fpenv
Implement handling of get/set floating point environment for ARM in
Global Instruction Selector. Lowering of these intrinsics to operations
on FPSCR was previously inplemented in DAG selector, in GlobalISel it
is reused.
---
llvm/lib/Target/ARM/ARMLegalizerInfo.cpp | 8 +++
llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp | 8 +++
llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll | 78 +++++++++++++++++++++
3 files changed, 94 insertions(+)
create mode 100644 llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index abea0fef5cdc5f3..7bf44abf3fa8f12 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -193,6 +193,11 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
.legalForCartesianProduct({s32}, {s32, s64});
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.legalForCartesianProduct({s32, s64}, {s32});
+
+ getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV})
+ .legalFor({s32});
+ getActionDefinitionsBuilder(G_RESET_FPENV)
+ .legalIf([=](const LegalityQuery &Query) { return true; });
} else {
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
.libcallFor({s32, s64});
@@ -219,6 +224,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
.libcallForCartesianProduct({s32}, {s32, s64});
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.libcallForCartesianProduct({s32, s64}, {s32});
+
+ getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV})
+ .libcall();
}
// Just expand whatever loads and stores are left.
diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
index 746a8715df0a652..5d4ae9a7648e694 100644
--- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
@@ -469,6 +469,14 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
OperandsMapping = getOperandsMapping(OperandBanks);
break;
}
+ case G_GET_FPENV:
+ case G_SET_FPENV:
+ OperandsMapping =
+ getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
+ break;
+ case G_RESET_FPENV:
+ OperandsMapping = getOperandsMapping({nullptr});
+ break;
default:
return getInvalidInstructionMapping();
}
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll b/llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll
new file mode 100644
index 000000000000000..3d18a65bd434523
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=arm-eabi -mattr=+vfp2 -global-isel=1 --verify-machineinstrs %s -o - | FileCheck %s
+
+declare i32 @llvm.get.fpenv.i32()
+declare void @llvm.set.fpenv.i32(i32)
+declare void @llvm.reset.fpenv()
+
+define i32 @func_get_fpenv() {
+; CHECK-LABEL: func_get_fpenv:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: vmrs r0, fpscr
+; CHECK-NEXT: mov pc, lr
+entry:
+ %fpenv = call i32 @llvm.get.fpenv.i32()
+ ret i32 %fpenv
+}
+
+define i32 @func_get_fpenv_soft() #0 {
+; CHECK-LABEL: func_get_fpenv_soft:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: .save {r4, lr}
+; CHECK-NEXT: push {r4, lr}
+; CHECK-NEXT: .pad #8
+; CHECK-NEXT: sub sp, sp, #8
+; CHECK-NEXT: add r4, sp, #4
+; CHECK-NEXT: mov r0, r4
+; CHECK-NEXT: bl fegetenv
+; CHECK-NEXT: ldr r0, [r4]
+; CHECK-NEXT: add sp, sp, #8
+; CHECK-NEXT: pop {r4, lr}
+; CHECK-NEXT: mov pc, lr
+entry:
+ %fpenv = call i32 @llvm.get.fpenv.i32()
+ ret i32 %fpenv
+}
+
+define void @func_set_fpenv(i32 %fpenv) {
+; CHECK-LABEL: func_set_fpenv:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: vmsr fpscr, r0
+; CHECK-NEXT: mov pc, lr
+entry:
+ call void @llvm.set.fpenv.i32(i32 %fpenv)
+ ret void
+}
+
+define void @func_set_fpenv_soft(i32 %fpenv) #0 {
+; CHECK-LABEL: func_set_fpenv_soft:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: .save {r11, lr}
+; CHECK-NEXT: push {r11, lr}
+; CHECK-NEXT: .pad #8
+; CHECK-NEXT: sub sp, sp, #8
+; CHECK-NEXT: add r1, sp, #4
+; CHECK-NEXT: str r0, [r1]
+; CHECK-NEXT: mov r0, r1
+; CHECK-NEXT: bl fesetenv
+; CHECK-NEXT: add sp, sp, #8
+; CHECK-NEXT: pop {r11, lr}
+; CHECK-NEXT: mov pc, lr
+entry:
+ call void @llvm.set.fpenv.i32(i32 %fpenv)
+ ret void
+}
+
+define void @func_reset() {
+; CHECK-LABEL: func_reset:
+; CHECK: @ %bb.0: @ %entry
+; CHECK-NEXT: mov r0, #0
+; CHECK-NEXT: vmsr fpscr, r0
+; CHECK-NEXT: mov pc, lr
+entry:
+ call void @llvm.reset.fpenv()
+ ret void
+}
+
+attributes #0 = { nounwind "use-soft-float"="true" }
+
>From 01580695a88ee34e8c00f5e45ea076ed42ce27e3 Mon Sep 17 00:00:00 2001
From: Serge Pavlov <sepavloff at gmail.com>
Date: Tue, 30 Jan 2024 00:19:55 +0700
Subject: [PATCH 2/2] Fix formatting, use alwaysLegal()
---
llvm/lib/Target/ARM/ARMLegalizerInfo.cpp | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index 7bf44abf3fa8f12..67187c4b1b3ae71 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -194,10 +194,8 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.legalForCartesianProduct({s32, s64}, {s32});
- getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV})
- .legalFor({s32});
- getActionDefinitionsBuilder(G_RESET_FPENV)
- .legalIf([=](const LegalityQuery &Query) { return true; });
+ getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV}).legalFor({s32});
+ getActionDefinitionsBuilder(G_RESET_FPENV).alwaysLegal();
} else {
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
.libcallFor({s32, s64});
@@ -225,8 +223,7 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.libcallForCartesianProduct({s32, s64}, {s32});
- getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV})
- .libcall();
+ getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV}).libcall();
}
// Just expand whatever loads and stores are left.
More information about the llvm-commits
mailing list