[AArch64][GlobalISel] Implement narrowing of G_SEXT.
We need this to narrow a sext to s128. Differential Revision: https://reviews.llvm.org/D65357 llvm-svn: 367164
This commit is contained in:
parent
aa8b9993c2
commit
7bc4fad0fb
|
@ -567,6 +567,26 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
|
||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
return Legalized;
|
return Legalized;
|
||||||
}
|
}
|
||||||
|
case TargetOpcode::G_SEXT: {
|
||||||
|
if (TypeIdx != 0)
|
||||||
|
return UnableToLegalize;
|
||||||
|
|
||||||
|
if (NarrowTy.getSizeInBits() != SizeOp0 / 2) {
|
||||||
|
LLVM_DEBUG(dbgs() << "Can't narrow sext to type " << NarrowTy << "\n");
|
||||||
|
return UnableToLegalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register SrcReg = MI.getOperand(1).getReg();
|
||||||
|
|
||||||
|
// Shift the sign bit of the low register through the high register.
|
||||||
|
auto ShiftAmt =
|
||||||
|
MIRBuilder.buildConstant(LLT::scalar(64), NarrowTy.getSizeInBits() - 1);
|
||||||
|
auto Shift = MIRBuilder.buildAShr(NarrowTy, SrcReg, ShiftAmt);
|
||||||
|
MIRBuilder.buildMerge(MI.getOperand(0).getReg(), {SrcReg, Shift.getReg(0)});
|
||||||
|
MI.eraseFromParent();
|
||||||
|
return Legalized;
|
||||||
|
}
|
||||||
|
|
||||||
case TargetOpcode::G_ADD: {
|
case TargetOpcode::G_ADD: {
|
||||||
// FIXME: add support for when SizeOp0 isn't an exact multiple of
|
// FIXME: add support for when SizeOp0 isn't an exact multiple of
|
||||||
// NarrowSize.
|
// NarrowSize.
|
||||||
|
|
|
@ -340,10 +340,12 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
|
||||||
.widenScalarToNextPow2(1);
|
.widenScalarToNextPow2(1);
|
||||||
|
|
||||||
// Extensions
|
// Extensions
|
||||||
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
|
auto ExtLegalFunc = [=](const LegalityQuery &Query) {
|
||||||
.legalIf([=](const LegalityQuery &Query) {
|
|
||||||
unsigned DstSize = Query.Types[0].getSizeInBits();
|
unsigned DstSize = Query.Types[0].getSizeInBits();
|
||||||
|
|
||||||
|
if (DstSize == 128 && !Query.Types[0].isVector())
|
||||||
|
return false; // Extending to a scalar s128 is not legal.
|
||||||
|
|
||||||
// Make sure that we have something that will fit in a register, and
|
// Make sure that we have something that will fit in a register, and
|
||||||
// make sure it's a power of 2.
|
// make sure it's a power of 2.
|
||||||
if (DstSize < 8 || DstSize > 128 || !isPowerOf2_32(DstSize))
|
if (DstSize < 8 || DstSize > 128 || !isPowerOf2_32(DstSize))
|
||||||
|
@ -363,7 +365,11 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
};
|
||||||
|
getActionDefinitionsBuilder({G_ZEXT, G_ANYEXT}).legalIf(ExtLegalFunc);
|
||||||
|
getActionDefinitionsBuilder(G_SEXT)
|
||||||
|
.legalIf(ExtLegalFunc)
|
||||||
|
.clampScalar(0, s64, s64); // Just for s128, others are handled above.
|
||||||
|
|
||||||
getActionDefinitionsBuilder(G_TRUNC).alwaysLegal();
|
getActionDefinitionsBuilder(G_TRUNC).alwaysLegal();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -march=aarch64 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
---
|
||||||
|
name: narrow_s128
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.1:
|
||||||
|
liveins: $x0, $x1
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: narrow_s128
|
||||||
|
; CHECK: liveins: $x0, $x1
|
||||||
|
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
|
||||||
|
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
|
||||||
|
; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
|
||||||
|
; CHECK: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[COPY]], [[C]](s64)
|
||||||
|
; CHECK: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[ASHR]](s64)
|
||||||
|
; CHECK: G_STORE [[MV]](s128), [[COPY1]](p0) :: (store 16)
|
||||||
|
; CHECK: RET_ReallyLR
|
||||||
|
%0:_(s64) = COPY $x0
|
||||||
|
%1:_(p0) = COPY $x1
|
||||||
|
%2:_(s128) = G_SEXT %0(s64)
|
||||||
|
G_STORE %2(s128), %1(p0) :: (store 16)
|
||||||
|
RET_ReallyLR
|
||||||
|
|
||||||
|
...
|
Loading…
Reference in New Issue