forked from OSchip/llvm-project
[AArch64][GlobalISel] Add support for narrowScalar of G_ZEXT
We do this by merging the source with the high bits set to 0. Differential Revision: https://reviews.llvm.org/D66181 llvm-svn: 369480
This commit is contained in:
parent
d979a29935
commit
56606a4db3
|
@ -615,6 +615,24 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
|
||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
return Legalized;
|
return Legalized;
|
||||||
}
|
}
|
||||||
|
case TargetOpcode::G_ZEXT: {
|
||||||
|
if (TypeIdx != 0)
|
||||||
|
return UnableToLegalize;
|
||||||
|
|
||||||
|
if (SizeOp0 % NarrowTy.getSizeInBits() != 0)
|
||||||
|
return UnableToLegalize;
|
||||||
|
|
||||||
|
// Generate a merge where the bottom bits are taken from the source, and
|
||||||
|
// zero everything else.
|
||||||
|
Register ZeroReg = MIRBuilder.buildConstant(NarrowTy, 0).getReg(0);
|
||||||
|
unsigned NumParts = SizeOp0 / NarrowTy.getSizeInBits();
|
||||||
|
SmallVector<Register, 4> Srcs = {MI.getOperand(1).getReg()};
|
||||||
|
for (unsigned Part = 1; Part < NumParts; ++Part)
|
||||||
|
Srcs.push_back(ZeroReg);
|
||||||
|
MIRBuilder.buildMerge(MI.getOperand(0).getReg(), Srcs);
|
||||||
|
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
|
||||||
|
|
|
@ -341,7 +341,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
|
||||||
unsigned DstSize = Query.Types[0].getSizeInBits();
|
unsigned DstSize = Query.Types[0].getSizeInBits();
|
||||||
|
|
||||||
if (DstSize == 128 && !Query.Types[0].isVector())
|
if (DstSize == 128 && !Query.Types[0].isVector())
|
||||||
return false; // Extending to a scalar s128 is not legal.
|
return false; // Extending to a scalar s128 needs narrowing.
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -363,8 +363,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
getActionDefinitionsBuilder({G_ZEXT, G_ANYEXT}).legalIf(ExtLegalFunc);
|
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
|
||||||
getActionDefinitionsBuilder(G_SEXT)
|
|
||||||
.legalIf(ExtLegalFunc)
|
.legalIf(ExtLegalFunc)
|
||||||
.clampScalar(0, s64, s64); // Just for s128, others are handled above.
|
.clampScalar(0, s64, s64); // Just for s128, others are handled above.
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,9 @@ const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
|
||||||
if (X86::GR8RegClass.hasSubClassEq(&RC) ||
|
if (X86::GR8RegClass.hasSubClassEq(&RC) ||
|
||||||
X86::GR16RegClass.hasSubClassEq(&RC) ||
|
X86::GR16RegClass.hasSubClassEq(&RC) ||
|
||||||
X86::GR32RegClass.hasSubClassEq(&RC) ||
|
X86::GR32RegClass.hasSubClassEq(&RC) ||
|
||||||
X86::GR64RegClass.hasSubClassEq(&RC))
|
X86::GR64RegClass.hasSubClassEq(&RC) ||
|
||||||
|
X86::LOW32_ADDR_ACCESSRegClass.hasSubClassEq(&RC) ||
|
||||||
|
X86::LOW32_ADDR_ACCESS_RBPRegClass.hasSubClassEq(&RC))
|
||||||
return getRegBank(X86::GPRRegBankID);
|
return getRegBank(X86::GPRRegBankID);
|
||||||
|
|
||||||
if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
|
if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
# 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
|
|
||||||
|
|
||||||
...
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
# 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_sext_s128
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.1:
|
||||||
|
liveins: $x0, $x1
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: narrow_sext_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
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: narrow_zext_s128
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.1:
|
||||||
|
liveins: $x0, $x1
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: narrow_zext_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 0
|
||||||
|
; CHECK: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[C]](s64)
|
||||||
|
; CHECK: G_STORE [[MV]](s128), [[COPY1]](p0) :: (store 16)
|
||||||
|
; CHECK: RET_ReallyLR
|
||||||
|
%0:_(s64) = COPY $x0
|
||||||
|
%1:_(p0) = COPY $x1
|
||||||
|
%2:_(s128) = G_ZEXT %0(s64)
|
||||||
|
G_STORE %2(s128), %1(p0) :: (store 16)
|
||||||
|
RET_ReallyLR
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: narrow_zext_s192
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.1:
|
||||||
|
liveins: $x0, $x1
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: narrow_zext_s192
|
||||||
|
; 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 0
|
||||||
|
; CHECK: [[MV:%[0-9]+]]:_(s192) = G_MERGE_VALUES [[COPY]](s64), [[C]](s64), [[C]](s64)
|
||||||
|
; CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64), [[UV2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[MV]](s192)
|
||||||
|
; CHECK: G_STORE [[UV]](s64), [[COPY1]](p0) :: (store 8)
|
||||||
|
; CHECK: RET_ReallyLR
|
||||||
|
%0:_(s64) = COPY $x0
|
||||||
|
%1:_(p0) = COPY $x1
|
||||||
|
%2:_(s192) = G_ZEXT %0(s64)
|
||||||
|
%3:_(s64), %4:_(s64), %5:_(s64) = G_UNMERGE_VALUES %2(s192)
|
||||||
|
G_STORE %3, %1(p0) :: (store 8)
|
||||||
|
RET_ReallyLR
|
||||||
|
|
||||||
|
...
|
|
@ -227,6 +227,7 @@
|
||||||
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
|
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
|
||||||
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
|
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
|
||||||
# DEBUG-NEXT: G_SEXT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
|
# DEBUG-NEXT: G_SEXT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
|
||||||
|
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
|
||||||
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
|
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
|
||||||
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
|
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
|
||||||
# DEBUG-NEXT: G_SEXT_INREG (opcode {{[0-9]+}}): 1 type index, 1 imm index
|
# DEBUG-NEXT: G_SEXT_INREG (opcode {{[0-9]+}}): 1 type index, 1 imm index
|
||||||
|
|
Loading…
Reference in New Issue