[llvm] b4eb7a1 - [GlobalISel][ARM] Legalze set_fpenv and get_fpenv (#79852)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 3 21:30:36 PST 2024
Author: Serge Pavlov
Date: 2024-02-04T12:30:33+07:00
New Revision: b4eb7a10c01162b17cb5dc94a97d9d137bb6fe57
URL: https://github.com/llvm/llvm-project/commit/b4eb7a10c01162b17cb5dc94a97d9d137bb6fe57
DIFF: https://github.com/llvm/llvm-project/commit/b4eb7a10c01162b17cb5dc94a97d9d137bb6fe57.diff
LOG: [GlobalISel][ARM] Legalze set_fpenv and get_fpenv (#79852)
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.
Added:
llvm/test/CodeGen/ARM/GlobalISel/fpenv.ll
Modified:
llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index abea0fef5cdc5..67187c4b1b3ae 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -193,6 +193,9 @@ 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).alwaysLegal();
} else {
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
.libcallFor({s32, s64});
@@ -219,6 +222,8 @@ 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 746a8715df0a6..5d4ae9a7648e6 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 0000000000000..3d18a65bd4345
--- /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" }
+
More information about the llvm-commits
mailing list