Skip to content

Commit

Permalink
[AArch64][GISel] Add fp128 and i128 sitofp/uitofp handling (#97691)
Browse files Browse the repository at this point in the history
Legalize sitofp/uitofp involving fp128/i128 types into a libcall. 
Vector with i128/fp128 types are scalarized.
  • Loading branch information
Him188 authored Jul 15, 2024
1 parent 4e338dc commit 365f5b4
Show file tree
Hide file tree
Showing 4 changed files with 1,519 additions and 992 deletions.
11 changes: 4 additions & 7 deletions llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1154,16 +1154,13 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
}
case TargetOpcode::G_SITOFP:
case TargetOpcode::G_UITOFP: {
// FIXME: Support other types
unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
if ((FromSize != 32 && FromSize != 64) || (ToSize != 32 && ToSize != 64))
Type *ToTy =
getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg()));
if ((FromSize != 32 && FromSize != 64 && FromSize != 128) || !ToTy)
return UnableToLegalize;
LegalizeResult Status = conversionLibcall(
MI, MIRBuilder,
ToSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx),
FromSize == 32 ? Type::getInt32Ty(Ctx) : Type::getInt64Ty(Ctx),
LocObserver);
MI, MIRBuilder, ToTy, Type::getIntNTy(Ctx, FromSize), LocObserver);
if (Status != Legalized)
return Status;
break;
Expand Down
37 changes: 26 additions & 11 deletions llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,34 +711,49 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
{{s32, s128}, {s64, s128}, {s128, s128}, {s128, s32}, {s128, s64}});

getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.legalForCartesianProduct({s32, s64, v2s64, v4s32, v2s32})
.legalFor({{s32, s32},
{s64, s32},
{s32, s64},
{s64, s64},
{v2s64, v2s64},
{v4s32, v4s32},
{v2s32, v2s32}})
.legalIf([=](const LegalityQuery &Query) {
return HasFP16 &&
(Query.Types[0] == s16 || Query.Types[0] == v4s16 ||
Query.Types[0] == v8s16) &&
(Query.Types[1] == s32 || Query.Types[1] == s64 ||
Query.Types[1] == v4s16 || Query.Types[1] == v8s16);
})
.widenScalarToNextPow2(1)
.clampScalar(1, s32, s64)
.widenScalarToNextPow2(0)
.clampScalarOrElt(0, MinFPScalar, s64)
.moreElementsToNextPow2(0)
.scalarizeIf(scalarOrEltWiderThan(1, 64), 1)
.scalarizeIf(scalarOrEltWiderThan(0, 64), 0)
.moreElementsToNextPow2(1)
.widenScalarOrEltToNextPow2OrMinSize(1)
.minScalar(1, s32)
.widenScalarOrEltToNextPow2OrMinSize(0, /*MinSize=*/HasFP16 ? 16 : 32)
.widenScalarIf(
[=](const LegalityQuery &Query) {
return Query.Types[0].getScalarSizeInBits() <
Query.Types[1].getScalarSizeInBits();
return Query.Types[1].getScalarSizeInBits() <= 64 &&
Query.Types[0].getScalarSizeInBits() <
Query.Types[1].getScalarSizeInBits();
},
LegalizeMutations::changeElementSizeTo(0, 1))
.widenScalarIf(
[=](const LegalityQuery &Query) {
return Query.Types[0].getScalarSizeInBits() >
Query.Types[1].getScalarSizeInBits();
return Query.Types[0].getScalarSizeInBits() <= 64 &&
Query.Types[0].getScalarSizeInBits() >
Query.Types[1].getScalarSizeInBits();
},
LegalizeMutations::changeElementSizeTo(1, 0))
.clampNumElements(0, v4s16, v8s16)
.clampNumElements(0, v2s32, v4s32)
.clampMaxNumElements(0, s64, 2);
.clampMaxNumElements(0, s64, 2)
.libcallFor({{s16, s128},
{s32, s128},
{s64, s128},
{s128, s128},
{s128, s32},
{s128, s64}});

// Control-flow
getActionDefinitionsBuilder(G_BRCOND)
Expand Down
76 changes: 0 additions & 76 deletions llvm/test/CodeGen/AArch64/GlobalISel/select-fp-casts.mir
Original file line number Diff line number Diff line change
Expand Up @@ -635,79 +635,3 @@ body: |
%1(s64) = G_FPTOUI %0
$x0 = COPY %1(s64)
...

---
name: sitofp_v2s64_v2s32
legalized: true
regBankSelected: true

body: |
bb.0:
liveins: $d0
; CHECK-LABEL: name: sitofp_v2s64_v2s32
; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
; CHECK: [[SSHLLv2i32_shift:%[0-9]+]]:fpr128 = SSHLLv2i32_shift [[COPY]], 0
; CHECK: [[SCVTFv2f64_:%[0-9]+]]:fpr128 = nofpexcept SCVTFv2f64 [[SSHLLv2i32_shift]]
; CHECK: $q0 = COPY [[SCVTFv2f64_]]
%0:fpr(<2 x s32>) = COPY $d0
%1:fpr(<2 x s64>) = G_SITOFP %0
$q0 = COPY %1(<2 x s64>)
...

---
name: uitofp_v2s64_v2s32
legalized: true
regBankSelected: true

body: |
bb.0:
liveins: $d0
; CHECK-LABEL: name: uitofp_v2s64_v2s32
; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
; CHECK: [[USHLLv2i32_shift:%[0-9]+]]:fpr128 = USHLLv2i32_shift [[COPY]], 0
; CHECK: [[UCVTFv2f64_:%[0-9]+]]:fpr128 = nofpexcept UCVTFv2f64 [[USHLLv2i32_shift]]
; CHECK: $q0 = COPY [[UCVTFv2f64_]]
%0:fpr(<2 x s32>) = COPY $d0
%1:fpr(<2 x s64>) = G_UITOFP %0
$q0 = COPY %1(<2 x s64>)
...

---
name: sitofp_v2s32_v2s64
legalized: true
regBankSelected: true

body: |
bb.0:
liveins: $q0
; CHECK-LABEL: name: sitofp_v2s32_v2s64
; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
; CHECK: [[SCVTFv2f64_:%[0-9]+]]:fpr128 = nofpexcept SCVTFv2f64 [[COPY]]
; CHECK: [[FCVTNv2i32_:%[0-9]+]]:fpr64 = nofpexcept FCVTNv2i32 [[SCVTFv2f64_]]
; CHECK: $d0 = COPY [[FCVTNv2i32_]]
%0:fpr(<2 x s64>) = COPY $q0
%1:fpr(<2 x s32>) = G_SITOFP %0
$d0 = COPY %1(<2 x s32>)
...

---
name: uitofp_v2s32_v2s64
legalized: true
regBankSelected: true

body: |
bb.0:
liveins: $q0
; CHECK-LABEL: name: uitofp_v2s32_v2s64
; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
; CHECK: [[UCVTFv2f64_:%[0-9]+]]:fpr128 = nofpexcept UCVTFv2f64 [[COPY]]
; CHECK: [[FCVTNv2i32_:%[0-9]+]]:fpr64 = nofpexcept FCVTNv2i32 [[UCVTFv2f64_]]
; CHECK: $d0 = COPY [[FCVTNv2i32_]]
%0:fpr(<2 x s64>) = COPY $q0
%1:fpr(<2 x s32>) = G_UITOFP %0
$d0 = COPY %1(<2 x s32>)
...
Loading

0 comments on commit 365f5b4

Please sign in to comment.