Skip to content

Commit 125f0ac

Browse files
authored
[ARM][SDAG] Half promote llvm.lrint nodes. (#161088)
As shown in #137101, fp16 lrint are not handled correctly on Arm. This adds soft-half promotion for them, reusing the function that promotes a value with operands (and can handle strict fp once that is added).
1 parent 5f7dc8a commit 125f0ac

File tree

6 files changed

+1335
-38
lines changed

6 files changed

+1335
-38
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,7 +3740,11 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
37403740
case ISD::STRICT_FP_TO_SINT:
37413741
case ISD::STRICT_FP_TO_UINT:
37423742
case ISD::FP_TO_SINT:
3743-
case ISD::FP_TO_UINT: Res = SoftPromoteHalfOp_FP_TO_XINT(N); break;
3743+
case ISD::FP_TO_UINT:
3744+
case ISD::LRINT:
3745+
case ISD::LLRINT:
3746+
Res = SoftPromoteHalfOp_Op0WithStrict(N);
3747+
break;
37443748
case ISD::FP_TO_SINT_SAT:
37453749
case ISD::FP_TO_UINT_SAT:
37463750
Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
@@ -3819,7 +3823,7 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(SDNode *N) {
38193823
return DAG.getNode(GetPromotionOpcode(SVT, RVT), SDLoc(N), RVT, Op);
38203824
}
38213825

3822-
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
3826+
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(SDNode *N) {
38233827
EVT RVT = N->getValueType(0);
38243828
bool IsStrict = N->isStrictFPOpcode();
38253829
SDValue Op = N->getOperand(IsStrict ? 1 : 0);

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
843843
SDValue SoftPromoteHalfOp_FAKE_USE(SDNode *N, unsigned OpNo);
844844
SDValue SoftPromoteHalfOp_FCOPYSIGN(SDNode *N, unsigned OpNo);
845845
SDValue SoftPromoteHalfOp_FP_EXTEND(SDNode *N);
846-
SDValue SoftPromoteHalfOp_FP_TO_XINT(SDNode *N);
846+
SDValue SoftPromoteHalfOp_Op0WithStrict(SDNode *N);
847847
SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N);
848848
SDValue SoftPromoteHalfOp_SETCC(SDNode *N);
849849
SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
13531353
setOperationAction(ISD::FLOG, MVT::f16, Promote);
13541354
setOperationAction(ISD::FLOG10, MVT::f16, Promote);
13551355
setOperationAction(ISD::FLOG2, MVT::f16, Promote);
1356+
setOperationAction(ISD::LRINT, MVT::f16, Expand);
13561357

13571358
setOperationAction(ISD::FROUND, MVT::f16, Legal);
13581359
setOperationAction(ISD::FROUNDEVEN, MVT::f16, Legal);

llvm/test/CodeGen/ARM/llrint-conv.ll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
22
; RUN: llc < %s -mtriple=armv7-none-eabi -float-abi=soft | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT
33
; RUN: llc < %s -mtriple=armv7-none-eabihf -mattr=+vfp2 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-NOFP16
4-
; RUN: llc < %s -mtriple=armv7-none-eabihf -mattr=+vfp2,+fullfp16 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
4+
; RUN: llc < %s -mtriple=armv8-none-eabihf -mattr=+fp-armv8 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FPv8
5+
; RUN: llc < %s -mtriple=armv8-none-eabihf -mattr=+fp-armv8,+fullfp16 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
56

67
define i64 @testmsxh_builtin(half %x) {
78
; CHECK-SOFT-LABEL: testmsxh_builtin:
@@ -22,6 +23,14 @@ define i64 @testmsxh_builtin(half %x) {
2223
; CHECK-NOFP16-NEXT: bl llrintf
2324
; CHECK-NOFP16-NEXT: pop {r11, pc}
2425
;
26+
; CHECK-FPv8-LABEL: testmsxh_builtin:
27+
; CHECK-FPv8: @ %bb.0: @ %entry
28+
; CHECK-FPv8-NEXT: .save {r11, lr}
29+
; CHECK-FPv8-NEXT: push {r11, lr}
30+
; CHECK-FPv8-NEXT: vcvtb.f32.f16 s0, s0
31+
; CHECK-FPv8-NEXT: bl llrintf
32+
; CHECK-FPv8-NEXT: pop {r11, pc}
33+
;
2534
; CHECK-FP16-LABEL: testmsxh_builtin:
2635
; CHECK-FP16: @ %bb.0: @ %entry
2736
; CHECK-FP16-NEXT: .save {r11, lr}

llvm/test/CodeGen/ARM/lrint-conv.ll

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
22
; RUN: llc < %s -mtriple=armv7-none-eabi -float-abi=soft | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT
33
; RUN: llc < %s -mtriple=armv7-none-eabihf -mattr=+vfp2 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-NOFP16
4-
; RUN: llc < %s -mtriple=armv7-none-eabihf -mattr=+vfp2,+fullfp16 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
4+
; RUN: llc < %s -mtriple=armv8-none-eabihf -mattr=+fp-armv8 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FPv8
5+
; RUN: llc < %s -mtriple=armv8-none-eabihf -mattr=+fp-armv8,+fullfp16 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
56

6-
; FIXME: crash
7-
; define i32 @testmswh_builtin(half %x) {
8-
; entry:
9-
; %0 = tail call i32 @llvm.lrint.i32.f16(half %x)
10-
; ret i32 %0
11-
; }
7+
define i32 @testmswh_builtin(half %x) {
8+
; CHECK-SOFT-LABEL: testmswh_builtin:
9+
; CHECK-SOFT: @ %bb.0: @ %entry
10+
; CHECK-SOFT-NEXT: .save {r11, lr}
11+
; CHECK-SOFT-NEXT: push {r11, lr}
12+
; CHECK-SOFT-NEXT: bl __aeabi_h2f
13+
; CHECK-SOFT-NEXT: pop {r11, lr}
14+
; CHECK-SOFT-NEXT: b lrintf
15+
;
16+
; CHECK-NOFP16-LABEL: testmswh_builtin:
17+
; CHECK-NOFP16: @ %bb.0: @ %entry
18+
; CHECK-NOFP16-NEXT: .save {r11, lr}
19+
; CHECK-NOFP16-NEXT: push {r11, lr}
20+
; CHECK-NOFP16-NEXT: vmov r0, s0
21+
; CHECK-NOFP16-NEXT: bl __aeabi_h2f
22+
; CHECK-NOFP16-NEXT: vmov s0, r0
23+
; CHECK-NOFP16-NEXT: pop {r11, lr}
24+
; CHECK-NOFP16-NEXT: b lrintf
25+
;
26+
; CHECK-FPv8-LABEL: testmswh_builtin:
27+
; CHECK-FPv8: @ %bb.0: @ %entry
28+
; CHECK-FPv8-NEXT: vcvtb.f32.f16 s0, s0
29+
; CHECK-FPv8-NEXT: b lrintf
30+
;
31+
; CHECK-FP16-LABEL: testmswh_builtin:
32+
; CHECK-FP16: @ %bb.0: @ %entry
33+
; CHECK-FP16-NEXT: vrintx.f16 s0, s0
34+
; CHECK-FP16-NEXT: vcvt.s32.f16 s0, s0
35+
; CHECK-FP16-NEXT: vmov r0, s0
36+
; CHECK-FP16-NEXT: bx lr
37+
entry:
38+
%0 = tail call i32 @llvm.lrint.i32.f16(half %x)
39+
ret i32 %0
40+
}
1241

1342
define i32 @testmsws_builtin(float %x) {
1443
; CHECK-LABEL: testmsws_builtin:
@@ -39,8 +68,3 @@ entry:
3968
%0 = tail call i32 @llvm.lrint.i32.f128(fp128 %x)
4069
ret i32 %0
4170
}
42-
43-
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
44-
; CHECK-FP16: {{.*}}
45-
; CHECK-NOFP16: {{.*}}
46-
; CHECK-SOFT: {{.*}}

0 commit comments

Comments
 (0)