Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AArch64] Add LRINT/LLRINT/LROUND/LLROUND FP16 lowering without fullfp16 #66174

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,

// Round-to-integer need custom lowering for fp16, as Promote doesn't work
// because the result type is integer.
for (auto Op : {ISD::STRICT_LROUND, ISD::STRICT_LLROUND, ISD::STRICT_LRINT,
for (auto Op : {ISD::LROUND, ISD::LLROUND, ISD::LRINT, ISD::LLRINT,
ISD::STRICT_LROUND, ISD::STRICT_LLROUND, ISD::STRICT_LRINT,
ISD::STRICT_LLRINT})
setOperationAction(Op, MVT::f16, Custom);

Expand Down Expand Up @@ -6183,6 +6184,16 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
return LowerVECTOR_DEINTERLEAVE(Op, DAG);
case ISD::VECTOR_INTERLEAVE:
return LowerVECTOR_INTERLEAVE(Op, DAG);
case ISD::LROUND:
case ISD::LLROUND:
case ISD::LRINT:
case ISD::LLRINT: {
assert(Op.getOperand(0).getValueType() == MVT::f16 &&
"Expected custom lowering of rounding operations only for f16");
SDLoc DL(Op);
SDValue Ext = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, Op.getOperand(0));
return DAG.getNode(Op.getOpcode(), DL, Op.getValueType(), Ext);
}
case ISD::STRICT_LROUND:
case ISD::STRICT_LLROUND:
case ISD::STRICT_LRINT:
Expand Down
56 changes: 43 additions & 13 deletions llvm/test/CodeGen/AArch64/llrint-conv-fp16.ll
Original file line number Diff line number Diff line change
@@ -1,32 +1,62 @@
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK-NOFP16
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK-FP16

; CHECK-LABEL: testmhhs:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs x0, h0
; CHECK: ret
define i16 @testmhhs(half %x) {
; CHECK-NOFP16-LABEL: testmhhs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: frintx s0, s0
; CHECK-NOFP16-NEXT: fcvtzs x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhhs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: frintx h0, h0
; CHECK-FP16-NEXT: fcvtzs x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.llrint.i64.f16(half %x)
%conv = trunc i64 %0 to i16
ret i16 %conv
}

; CHECK-LABEL: testmhws:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs x0, h0
; CHECK: ret
define i32 @testmhws(half %x) {
; CHECK-NOFP16-LABEL: testmhws:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: frintx s0, s0
; CHECK-NOFP16-NEXT: fcvtzs x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhws:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: frintx h0, h0
; CHECK-FP16-NEXT: fcvtzs x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.llrint.i64.f16(half %x)
%conv = trunc i64 %0 to i32
ret i32 %conv
}

; CHECK-LABEL: testmhxs:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs x0, h0
; CHECK: ret
define i64 @testmhxs(half %x) {
; CHECK-NOFP16-LABEL: testmhxs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: frintx s0, s0
; CHECK-NOFP16-NEXT: fcvtzs x0, s0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhxs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: frintx h0, h0
; CHECK-FP16-NEXT: fcvtzs x0, h0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.llrint.i64.f16(half %x)
ret i64 %0
Expand Down
47 changes: 37 additions & 10 deletions llvm/test/CodeGen/AArch64/llround-conv-fp16.ll
Original file line number Diff line number Diff line change
@@ -1,29 +1,56 @@
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK-NOFP16
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK-FP16

; CHECK-LABEL: testmhhs:
; CHECK: fcvtas x0, h0
; CHECK: ret
define i16 @testmhhs(half %x) {
; CHECK-NOFP16-LABEL: testmhhs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: fcvtas x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhhs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: fcvtas x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.llround.i64.f16(half %x)
%conv = trunc i64 %0 to i16
ret i16 %conv
}

; CHECK-LABEL: testmhws:
; CHECK: fcvtas x0, h0
; CHECK: ret
define i32 @testmhws(half %x) {
; CHECK-NOFP16-LABEL: testmhws:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: fcvtas x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhws:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: fcvtas x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.llround.i64.f16(half %x)
%conv = trunc i64 %0 to i32
ret i32 %conv
}

; CHECK-LABEL: testmhxs:
; CHECK: fcvtas x0, h0
; CHECK-NEXT: ret
define i64 @testmhxs(half %x) {
; CHECK-NOFP16-LABEL: testmhxs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: fcvtas x0, s0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhxs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: fcvtas x0, h0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.llround.i64.f16(half %x)
ret i64 %0
Expand Down
56 changes: 43 additions & 13 deletions llvm/test/CodeGen/AArch64/lrint-conv-fp16.ll
Original file line number Diff line number Diff line change
@@ -1,32 +1,62 @@
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK-NOFP16
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK-FP16

; CHECK-LABEL: testmhhs:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs x0, h0
; CHECK: ret
define i16 @testmhhs(half %x) {
; CHECK-NOFP16-LABEL: testmhhs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: frintx s0, s0
; CHECK-NOFP16-NEXT: fcvtzs x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhhs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: frintx h0, h0
; CHECK-FP16-NEXT: fcvtzs x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.lrint.i64.f16(half %x)
%conv = trunc i64 %0 to i16
ret i16 %conv
}

; CHECK-LABEL: testmhws:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs x0, h0
; CHECK: ret
define i32 @testmhws(half %x) {
; CHECK-NOFP16-LABEL: testmhws:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: frintx s0, s0
; CHECK-NOFP16-NEXT: fcvtzs x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhws:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: frintx h0, h0
; CHECK-FP16-NEXT: fcvtzs x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.lrint.i64.f16(half %x)
%conv = trunc i64 %0 to i32
ret i32 %conv
}

; CHECK-LABEL: testmhxs:
; CHECK: frintx h0, h0
; CHECK-NEXT: fcvtzs x0, h0
; CHECK: ret
define i64 @testmhxs(half %x) {
; CHECK-NOFP16-LABEL: testmhxs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: frintx s0, s0
; CHECK-NOFP16-NEXT: fcvtzs x0, s0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhxs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: frintx h0, h0
; CHECK-FP16-NEXT: fcvtzs x0, h0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.lrint.i64.f16(half %x)
ret i64 %0
Expand Down
47 changes: 37 additions & 10 deletions llvm/test/CodeGen/AArch64/lround-conv-fp16.ll
Original file line number Diff line number Diff line change
@@ -1,29 +1,56 @@
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK-NOFP16
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK-FP16

; CHECK-LABEL: testmhhs:
; CHECK: fcvtas x0, h0
; CHECK: ret
define i16 @testmhhs(half %x) {
; CHECK-NOFP16-LABEL: testmhhs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: fcvtas x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhhs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: fcvtas x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.lround.i64.f16(half %x)
%conv = trunc i64 %0 to i16
ret i16 %conv
}

; CHECK-LABEL: testmhws:
; CHECK: fcvtas x0, h0
; CHECK: ret
define i32 @testmhws(half %x) {
; CHECK-NOFP16-LABEL: testmhws:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: fcvtas x0, s0
; CHECK-NOFP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhws:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: fcvtas x0, h0
; CHECK-FP16-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.lround.i64.f16(half %x)
%conv = trunc i64 %0 to i32
ret i32 %conv
}

; CHECK-LABEL: testmhxs:
; CHECK: fcvtas x0, h0
; CHECK-NEXT: ret
define i64 @testmhxs(half %x) {
; CHECK-NOFP16-LABEL: testmhxs:
; CHECK-NOFP16: // %bb.0: // %entry
; CHECK-NOFP16-NEXT: fcvt s0, h0
; CHECK-NOFP16-NEXT: fcvtas x0, s0
; CHECK-NOFP16-NEXT: ret
;
; CHECK-FP16-LABEL: testmhxs:
; CHECK-FP16: // %bb.0: // %entry
; CHECK-FP16-NEXT: fcvtas x0, h0
; CHECK-FP16-NEXT: ret
entry:
%0 = tail call i64 @llvm.lround.i64.f16(half %x)
ret i64 %0
Expand Down