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 <sepavl...@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 abea0fef5cdc5..7bf44abf3fa8f 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 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" } + >From 01580695a88ee34e8c00f5e45ea076ed42ce27e3 Mon Sep 17 00:00:00 2001 From: Serge Pavlov <sepavl...@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 7bf44abf3fa8f..67187c4b1b3ae 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. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits