mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[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
42742afe74
commit
fe45ee47e4
@ -567,6 +567,26 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
|
||||
MI.eraseFromParent();
|
||||
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: {
|
||||
// FIXME: add support for when SizeOp0 isn't an exact multiple of
|
||||
// NarrowSize.
|
||||
|
@ -340,30 +340,36 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
|
||||
.widenScalarToNextPow2(1);
|
||||
|
||||
// Extensions
|
||||
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
|
||||
.legalIf([=](const LegalityQuery &Query) {
|
||||
unsigned DstSize = Query.Types[0].getSizeInBits();
|
||||
auto ExtLegalFunc = [=](const LegalityQuery &Query) {
|
||||
unsigned DstSize = Query.Types[0].getSizeInBits();
|
||||
|
||||
// Make sure that we have something that will fit in a register, and
|
||||
// make sure it's a power of 2.
|
||||
if (DstSize < 8 || DstSize > 128 || !isPowerOf2_32(DstSize))
|
||||
return false;
|
||||
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 it's a power of 2.
|
||||
if (DstSize < 8 || DstSize > 128 || !isPowerOf2_32(DstSize))
|
||||
return false;
|
||||
|
||||
const LLT &SrcTy = Query.Types[1];
|
||||
const LLT &SrcTy = Query.Types[1];
|
||||
|
||||
// Special case for s1.
|
||||
if (SrcTy == s1)
|
||||
return true;
|
||||
// Special case for s1.
|
||||
if (SrcTy == s1)
|
||||
return true;
|
||||
|
||||
// Make sure we fit in a register otherwise. Don't bother checking that
|
||||
// the source type is below 128 bits. We shouldn't be allowing anything
|
||||
// through which is wider than the destination in the first place.
|
||||
unsigned SrcSize = SrcTy.getSizeInBits();
|
||||
if (SrcSize < 8 || !isPowerOf2_32(SrcSize))
|
||||
return false;
|
||||
// Make sure we fit in a register otherwise. Don't bother checking that
|
||||
// the source type is below 128 bits. We shouldn't be allowing anything
|
||||
// through which is wider than the destination in the first place.
|
||||
unsigned SrcSize = SrcTy.getSizeInBits();
|
||||
if (SrcSize < 8 || !isPowerOf2_32(SrcSize))
|
||||
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();
|
||||
|
||||
|
25
test/CodeGen/AArch64/GlobalISel/legalize-sext-128.mir
Normal file
25
test/CodeGen/AArch64/GlobalISel/legalize-sext-128.mir
Normal 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
|
||||
|
||||
...
|
Loading…
Reference in New Issue
Block a user