Skip to content

Commit b4eb7a1

Browse files
authored
[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.
1 parent b0f0bab commit b4eb7a1

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

llvm/lib/Target/ARM/ARMLegalizerInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
193193
.legalForCartesianProduct({s32}, {s32, s64});
194194
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
195195
.legalForCartesianProduct({s32, s64}, {s32});
196+
197+
getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV}).legalFor({s32});
198+
getActionDefinitionsBuilder(G_RESET_FPENV).alwaysLegal();
196199
} else {
197200
getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
198201
.libcallFor({s32, s64});
@@ -219,6 +222,8 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
219222
.libcallForCartesianProduct({s32}, {s32, s64});
220223
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
221224
.libcallForCartesianProduct({s32, s64}, {s32});
225+
226+
getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV}).libcall();
222227
}
223228

224229
// Just expand whatever loads and stores are left.

llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,14 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
469469
OperandsMapping = getOperandsMapping(OperandBanks);
470470
break;
471471
}
472+
case G_GET_FPENV:
473+
case G_SET_FPENV:
474+
OperandsMapping =
475+
getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
476+
break;
477+
case G_RESET_FPENV:
478+
OperandsMapping = getOperandsMapping({nullptr});
479+
break;
472480
default:
473481
return getInvalidInstructionMapping();
474482
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=arm-eabi -mattr=+vfp2 -global-isel=1 --verify-machineinstrs %s -o - | FileCheck %s
3+
4+
declare i32 @llvm.get.fpenv.i32()
5+
declare void @llvm.set.fpenv.i32(i32)
6+
declare void @llvm.reset.fpenv()
7+
8+
define i32 @func_get_fpenv() {
9+
; CHECK-LABEL: func_get_fpenv:
10+
; CHECK: @ %bb.0: @ %entry
11+
; CHECK-NEXT: vmrs r0, fpscr
12+
; CHECK-NEXT: mov pc, lr
13+
entry:
14+
%fpenv = call i32 @llvm.get.fpenv.i32()
15+
ret i32 %fpenv
16+
}
17+
18+
define i32 @func_get_fpenv_soft() #0 {
19+
; CHECK-LABEL: func_get_fpenv_soft:
20+
; CHECK: @ %bb.0: @ %entry
21+
; CHECK-NEXT: .save {r4, lr}
22+
; CHECK-NEXT: push {r4, lr}
23+
; CHECK-NEXT: .pad #8
24+
; CHECK-NEXT: sub sp, sp, #8
25+
; CHECK-NEXT: add r4, sp, #4
26+
; CHECK-NEXT: mov r0, r4
27+
; CHECK-NEXT: bl fegetenv
28+
; CHECK-NEXT: ldr r0, [r4]
29+
; CHECK-NEXT: add sp, sp, #8
30+
; CHECK-NEXT: pop {r4, lr}
31+
; CHECK-NEXT: mov pc, lr
32+
entry:
33+
%fpenv = call i32 @llvm.get.fpenv.i32()
34+
ret i32 %fpenv
35+
}
36+
37+
define void @func_set_fpenv(i32 %fpenv) {
38+
; CHECK-LABEL: func_set_fpenv:
39+
; CHECK: @ %bb.0: @ %entry
40+
; CHECK-NEXT: vmsr fpscr, r0
41+
; CHECK-NEXT: mov pc, lr
42+
entry:
43+
call void @llvm.set.fpenv.i32(i32 %fpenv)
44+
ret void
45+
}
46+
47+
define void @func_set_fpenv_soft(i32 %fpenv) #0 {
48+
; CHECK-LABEL: func_set_fpenv_soft:
49+
; CHECK: @ %bb.0: @ %entry
50+
; CHECK-NEXT: .save {r11, lr}
51+
; CHECK-NEXT: push {r11, lr}
52+
; CHECK-NEXT: .pad #8
53+
; CHECK-NEXT: sub sp, sp, #8
54+
; CHECK-NEXT: add r1, sp, #4
55+
; CHECK-NEXT: str r0, [r1]
56+
; CHECK-NEXT: mov r0, r1
57+
; CHECK-NEXT: bl fesetenv
58+
; CHECK-NEXT: add sp, sp, #8
59+
; CHECK-NEXT: pop {r11, lr}
60+
; CHECK-NEXT: mov pc, lr
61+
entry:
62+
call void @llvm.set.fpenv.i32(i32 %fpenv)
63+
ret void
64+
}
65+
66+
define void @func_reset() {
67+
; CHECK-LABEL: func_reset:
68+
; CHECK: @ %bb.0: @ %entry
69+
; CHECK-NEXT: mov r0, #0
70+
; CHECK-NEXT: vmsr fpscr, r0
71+
; CHECK-NEXT: mov pc, lr
72+
entry:
73+
call void @llvm.reset.fpenv()
74+
ret void
75+
}
76+
77+
attributes #0 = { nounwind "use-soft-float"="true" }
78+

0 commit comments

Comments
 (0)