[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:
Amara Emerson 2019-07-26 23:46:38 +00:00
parent aa8b9993c2
commit 7bc4fad0fb
3 changed files with 70 additions and 19 deletions

View File

@ -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.

View File

@ -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();

View File

@ -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
...