Skip to content

Commit 28d28d5

Browse files
authored
[AArch64][GlobalISel] Extend scalar lrint legalization. (llvm#88360)
This extends the legalization of lrint, adding libcall support for fp128. The old vector legal types were removed as they were not being properly handled (vector lrint is a fairly new concept as far as I understand). They can be re-added properly in a followup.
1 parent 5fe1466 commit 28d28d5

File tree

7 files changed

+32
-25
lines changed

7 files changed

+32
-25
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
472472
RTLIBCASE(NEARBYINT_F);
473473
case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
474474
RTLIBCASE(ROUNDEVEN_F);
475+
case TargetOpcode::G_INTRINSIC_LRINT:
476+
RTLIBCASE(LRINT_F);
475477
}
476478
llvm_unreachable("Unknown libcall function");
477479
}
@@ -1059,6 +1061,25 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
10591061
return Status;
10601062
break;
10611063
}
1064+
case TargetOpcode::G_INTRINSIC_LRINT: {
1065+
LLT LLTy = MRI.getType(MI.getOperand(1).getReg());
1066+
unsigned Size = LLTy.getSizeInBits();
1067+
Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
1068+
Type *ITy = IntegerType::get(
1069+
Ctx, MRI.getType(MI.getOperand(0).getReg()).getSizeInBits());
1070+
if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
1071+
LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
1072+
return UnableToLegalize;
1073+
}
1074+
auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
1075+
LegalizeResult Status =
1076+
createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ITy, 0},
1077+
{{MI.getOperand(1).getReg(), HLTy, 0}}, LocObserver, &MI);
1078+
if (Status != Legalized)
1079+
return Status;
1080+
MI.eraseFromParent();
1081+
return Legalized;
1082+
}
10621083
case TargetOpcode::G_FPOWI: {
10631084
LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
10641085
unsigned Size = LLTy.getSizeInBits();
@@ -2639,6 +2660,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
26392660

26402661
case TargetOpcode::G_FPTOSI:
26412662
case TargetOpcode::G_FPTOUI:
2663+
case TargetOpcode::G_INTRINSIC_LRINT:
26422664
case TargetOpcode::G_IS_FPCLASS:
26432665
Observer.changingInstr(MI);
26442666

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -263,23 +263,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
263263
.scalarize(0);
264264

265265
getActionDefinitionsBuilder(G_INTRINSIC_LRINT)
266-
// If we don't have full FP16 support, then scalarize the elements of
267-
// vectors containing fp16 types.
268-
.fewerElementsIf(
269-
[=, &ST](const LegalityQuery &Query) {
270-
const auto &Ty = Query.Types[0];
271-
return Ty.isVector() && Ty.getElementType() == s16 &&
272-
!ST.hasFullFP16();
273-
},
274-
[=](const LegalityQuery &Query) { return std::make_pair(0, s16); })
275-
// If we don't have full FP16 support, then widen s16 to s32 if we
276-
// encounter it.
277-
.widenScalarIf(
278-
[=, &ST](const LegalityQuery &Query) {
279-
return Query.Types[0] == s16 && !ST.hasFullFP16();
280-
},
281-
[=](const LegalityQuery &Query) { return std::make_pair(0, s32); })
282-
.legalFor({s16, s32, s64, v2s32, v4s32, v2s64, v2s16, v4s16, v8s16});
266+
.legalFor({{s64, MinFPScalar}, {s64, s32}, {s64, s64}})
267+
.libcallFor({{s64, s128}})
268+
.minScalarOrElt(1, MinFPScalar);
283269

284270
getActionDefinitionsBuilder(
285271
{G_FCOS, G_FSIN, G_FPOW, G_FLOG, G_FLOG2, G_FLOG10,

llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
829829
}
830830
case TargetOpcode::G_FPTOSI:
831831
case TargetOpcode::G_FPTOUI:
832+
case TargetOpcode::G_INTRINSIC_LRINT:
832833
if (MRI.getType(MI.getOperand(0).getReg()).isVector())
833834
break;
834835
OpRegBankIdx = {PMI_FirstGPR, PMI_FirstFPR};

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@
154154
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
155155
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
156156
# DEBUG-NEXT: G_INTRINSIC_LRINT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
157-
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
158-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
157+
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
158+
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
159159
# DEBUG-NEXT: G_INTRINSIC_ROUNDEVEN (opcode {{[0-9]+}}): 1 type index, 0 imm indices
160160
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
161161
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected

llvm/test/CodeGen/AArch64/lrint-conv-fp16.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
22
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK-NOFP16
33
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK-FP16
4+
; RUN: llc < %s -mtriple=aarch64 -global-isel | FileCheck %s --check-prefixes=CHECK-NOFP16
5+
; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 -global-isel | FileCheck %s --check-prefixes=CHECK-FP16
46

57
define i16 @testmhhs(half %x) {
68
; CHECK-NOFP16-LABEL: testmhhs:

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
22
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s
3-
; RUN: llc < %s -mtriple=aarch64 -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4-
5-
; CHECK-GI: warning: Instruction selection used fallback path for testmswl
6-
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for testmsll
3+
; RUN: llc < %s -mtriple=aarch64 -global-isel | FileCheck %s
74

85
define i32 @testmsws(float %x) {
96
; CHECK-LABEL: testmsws:

llvm/test/CodeGen/AArch64/vector-lrint.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
33
; RUN: llc < %s -mtriple=aarch64 -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
44

5-
; CHECK-GI: warning: Instruction selection used fallback path for lrint_v1f16
6-
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_v2f16
5+
; CHECK-GI: warning: Instruction selection used fallback path for lrint_v2f16
76
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_v4f16
87
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_v8f16
98
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for lrint_v16i64_v16f16

0 commit comments

Comments
 (0)