Skip to content

Commit 5550e9c

Browse files
authored
[GlobalISel][AArch64] Add libcall lowering for fpowi. (#67114)
This adds legalization, notably libcall lowering for fpowi. It is a little different to other methods as the function takes both a float and integer register. Otherwise all vectors get scalarized and fp16 is promoted to fp32.
1 parent 55395f5 commit 5550e9c

File tree

4 files changed

+1455
-2
lines changed

4 files changed

+1455
-2
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
532532
RTLIBCASE(REM_F);
533533
case TargetOpcode::G_FPOW:
534534
RTLIBCASE(POW_F);
535+
case TargetOpcode::G_FPOWI:
536+
RTLIBCASE(POWI_F);
535537
case TargetOpcode::G_FMA:
536538
RTLIBCASE(FMA_F);
537539
case TargetOpcode::G_FSIN:
@@ -1014,6 +1016,27 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
10141016
return Status;
10151017
break;
10161018
}
1019+
case TargetOpcode::G_FPOWI: {
1020+
LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
1021+
unsigned Size = LLTy.getSizeInBits();
1022+
Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
1023+
Type *ITy = IntegerType::get(
1024+
Ctx, MRI.getType(MI.getOperand(2).getReg()).getSizeInBits());
1025+
if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
1026+
LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
1027+
return UnableToLegalize;
1028+
}
1029+
auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
1030+
std::initializer_list<CallLowering::ArgInfo> Args = {
1031+
{MI.getOperand(1).getReg(), HLTy, 0},
1032+
{MI.getOperand(2).getReg(), ITy, 1}};
1033+
LegalizeResult Status =
1034+
createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), HLTy, 0},
1035+
Args, LocObserver, &MI);
1036+
if (Status != Legalized)
1037+
return Status;
1038+
break;
1039+
}
10171040
case TargetOpcode::G_FPEXT:
10181041
case TargetOpcode::G_FPTRUNC: {
10191042
Type *FromTy = getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(1).getReg()));
@@ -4557,6 +4580,8 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
45574580
return fewerElementsVectorReductions(MI, TypeIdx, NarrowTy);
45584581
case G_SHUFFLE_VECTOR:
45594582
return fewerElementsVectorShuffle(MI, TypeIdx, NarrowTy);
4583+
case G_FPOWI:
4584+
return fewerElementsVectorMultiEltType(GMI, NumElts, {2 /*pow*/});
45604585
default:
45614586
return UnableToLegalize;
45624587
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
282282
// Regardless of FP16 support, widen 16-bit elements to 32-bits.
283283
.minScalar(0, s32)
284284
.libcallFor({s32, s64});
285+
getActionDefinitionsBuilder(G_FPOWI)
286+
.scalarize(0)
287+
.minScalar(0, s32)
288+
.libcallFor({{s32, s32}, {s64, s32}});
285289

286290
getActionDefinitionsBuilder(G_INSERT)
287291
.legalIf(all(typeInSet(0, {s32, s64, p0}),

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,8 @@
463463
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
464464
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
465465
# DEBUG-NEXT: G_FPOWI (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
466-
# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
467-
# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
466+
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
467+
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
468468
# DEBUG-NEXT: G_FEXP (opcode {{[0-9]+}}): 1 type index, 0 imm indices
469469
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
470470
# DEBUG-NEXT: .. the first uncovered type index: 1, OK

0 commit comments

Comments
 (0)