Skip to content

Commit c19e503

Browse files
committed
[SelectionDAG] Add f16 soft promotion for lrint and lround
On platforms that soft promote `half`, using `lrint` intrinsics crashes with the following: SoftPromoteHalfOperand Op #0: t5: i32 = lrint t4 LLVM ERROR: Do not know how to soft promote this operator's operand! PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. Stack dump: 0. Program arguments: /Users/tmgross/Documents/projects/llvm/llvm-build/bin/llc -mtriple=riscv32 1. Running pass 'Function Pass Manager' on module '<stdin>'. 2. Running pass 'RISC-V DAG->DAG Pattern Instruction Selection' on function '@test_lrint_ixx_f16' Resolve this by adding a soft promotion. `SoftPromoteHalfOp_FP_TO_XINT` is reused here since it provides the correct input and output types. It is renamed `PromoteFloatOp_UnaryOp` to match `PromoteFloatOp_UnaryOp` and similar functions that are used to handle the same sets of intrinsics.
1 parent 8ace6b7 commit c19e503

File tree

9 files changed

+5297
-90
lines changed

9 files changed

+5297
-90
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "LegalizeTypes.h"
2222
#include "llvm/Analysis/TargetLibraryInfo.h"
23+
#include "llvm/CodeGen/ISDOpcodes.h"
2324
#include "llvm/Support/ErrorHandling.h"
2425
#include "llvm/Support/raw_ostream.h"
2526
using namespace llvm;
@@ -3729,10 +3730,20 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
37293730
Res = SoftPromoteHalfOp_FAKE_USE(N, OpNo);
37303731
break;
37313732
case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(N, OpNo); break;
3733+
case ISD::FP_TO_SINT:
3734+
case ISD::FP_TO_UINT:
3735+
case ISD::LLRINT:
3736+
case ISD::LLROUND:
3737+
case ISD::LRINT:
3738+
case ISD::LROUND:
37323739
case ISD::STRICT_FP_TO_SINT:
37333740
case ISD::STRICT_FP_TO_UINT:
3734-
case ISD::FP_TO_SINT:
3735-
case ISD::FP_TO_UINT: Res = SoftPromoteHalfOp_FP_TO_XINT(N); break;
3741+
case ISD::STRICT_LLRINT:
3742+
case ISD::STRICT_LLROUND:
3743+
case ISD::STRICT_LRINT:
3744+
case ISD::STRICT_LROUND:
3745+
Res = SoftPromoteHalfOp_UnaryOp(N);
3746+
break;
37363747
case ISD::FP_TO_SINT_SAT:
37373748
case ISD::FP_TO_UINT_SAT:
37383749
Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
@@ -3811,7 +3822,7 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(SDNode *N) {
38113822
return DAG.getNode(GetPromotionOpcode(SVT, RVT), SDLoc(N), RVT, Op);
38123823
}
38133824

3814-
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
3825+
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_UnaryOp(SDNode *N) {
38153826
EVT RVT = N->getValueType(0);
38163827
bool IsStrict = N->isStrictFPOpcode();
38173828
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
@@ -840,7 +840,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
840840
SDValue SoftPromoteHalfOp_FAKE_USE(SDNode *N, unsigned OpNo);
841841
SDValue SoftPromoteHalfOp_FCOPYSIGN(SDNode *N, unsigned OpNo);
842842
SDValue SoftPromoteHalfOp_FP_EXTEND(SDNode *N);
843-
SDValue SoftPromoteHalfOp_FP_TO_XINT(SDNode *N);
843+
SDValue SoftPromoteHalfOp_UnaryOp(SDNode *N);
844844
SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N);
845845
SDValue SoftPromoteHalfOp_SETCC(SDNode *N);
846846
SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft | FileCheck %s --check-prefix=SOFTFP
22
; RUN: llc < %s -mtriple=arm-eabi -float-abi=hard | FileCheck %s --check-prefix=HARDFP
33

4-
; FIXME: crash
5-
; define i32 @testmswh_builtin(half %x) {
6-
; entry:
7-
; %0 = tail call i32 @llvm.lrint.i32.f16(half %x)
8-
; ret i32 %0
9-
; }
4+
; SOFTFP-LABEL: testmswh_builtin:
5+
; SOFTFP: bl lrintf
6+
; HARDFP-LABEL: testmswh_builtin:
7+
; HARDFP: bl lrintf
8+
define i32 @testmswh_builtin(half %x) {
9+
entry:
10+
%0 = tail call i32 @llvm.lrint.i32.f16(half %x)
11+
ret i32 %0
12+
}
1013

1114
; SOFTFP-LABEL: testmsws_builtin:
1215
; SOFTFP: bl lrintf

0 commit comments

Comments
 (0)