Skip to content

Commit 9c966f7

Browse files
committed
[ARM][SDAG] Half promote llvm.lrint nodes.
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 8f2466b commit 9c966f7

File tree

5 files changed

+1317
-36
lines changed

5 files changed

+1317
-36
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,7 +3740,10 @@ 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+
Res = SoftPromoteHalfOp_Op0WithStrict(N);
3746+
break;
37443747
case ISD::FP_TO_SINT_SAT:
37453748
case ISD::FP_TO_UINT_SAT:
37463749
Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
@@ -3819,7 +3822,7 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(SDNode *N) {
38193822
return DAG.getNode(GetPromotionOpcode(SVT, RVT), SDLoc(N), RVT, Op);
38203823
}
38213824

3822-
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
3825+
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(SDNode *N) {
38233826
EVT RVT = N->getValueType(0);
38243827
bool IsStrict = N->isStrictFPOpcode();
38253828
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/lrint-conv.ll

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,35 @@
33
; RUN: llc < %s -mtriple=armv7-none-eabihf -mattr=+vfp2 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-NOFP16
44
; RUN: llc < %s -mtriple=armv7-none-eabihf -mattr=+vfp2,+fullfp16 -float-abi=hard | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
55

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

1336
define i32 @testmsws_builtin(float %x) {
1437
; CHECK-LABEL: testmsws_builtin:
@@ -39,8 +62,3 @@ entry:
3962
%0 = tail call i32 @llvm.lrint.i32.f128(fp128 %x)
4063
ret i32 %0
4164
}
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)