1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

[GlobalISel] support widen unmerge if WideTy > SrcTy

Summary:
Widening G_UNMERGE_VALUES to a type which is larger than the
original source type is the same as widening it to the same
type as the source type: in both cases, G_UNMERGE_VALUES has
to be replaced with bit arithmetic which. Although the arithmetic
itself is independent of whether the source type is smaller
or equal to the widen type, widening the source type to the
widen type should result in less artifacts being emitted,
since this is the type that the user explicitly requested.

Reviewers: arsenm, dsanders, aemerson, aditya_nandakumar

Reviewed By: arsenm, dsanders

Subscribers: jvesely, wdng, nhaehnle, rovka, hiraditya, volkan, kerbowa, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D76494
This commit is contained in:
Dominik Montada 2020-03-20 14:46:01 +01:00
parent b0e99e532a
commit adb21d1650
3 changed files with 121 additions and 33 deletions

View File

@ -1390,11 +1390,12 @@ LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
if (!DstTy.isScalar())
return UnableToLegalize;
if (WideTy.getSizeInBits() == SrcTy.getSizeInBits()) {
if (WideTy.getSizeInBits() >= SrcTy.getSizeInBits()) {
if (SrcTy.isPointer()) {
const DataLayout &DL = MIRBuilder.getDataLayout();
if (DL.isNonIntegralAddressSpace(SrcTy.getAddressSpace())) {
LLVM_DEBUG(dbgs() << "Not casting non-integral address space integer\n");
LLVM_DEBUG(
dbgs() << "Not casting non-integral address space integer\n");
return UnableToLegalize;
}
@ -1402,6 +1403,14 @@ LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
SrcReg = MIRBuilder.buildPtrToInt(SrcTy, SrcReg).getReg(0);
}
// Widen SrcTy to WideTy. This does not affect the result, but since the
// user requested this size, it is probably better handled than SrcTy and
// should reduce the total number of legalization artifacts
if (WideTy.getSizeInBits() > SrcTy.getSizeInBits()) {
SrcTy = WideTy;
SrcReg = MIRBuilder.buildAnyExt(WideTy, SrcReg).getReg(0);
}
// Theres no unmerge type to target. Directly extract the bits from the
// source type
unsigned DstSize = DstTy.getSizeInBits();
@ -1417,10 +1426,6 @@ LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
return Legalized;
}
// TODO
if (WideTy.getSizeInBits() > SrcTy.getSizeInBits())
return UnableToLegalize;
// Extend the source to a wider type.
LLT LCMTy = getLCMType(SrcTy, WideTy);

View File

@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=amdgcn-- -O0 -run-pass=legalizer -global-isel-abort=0 -o - %s | FileCheck %s
# RUN: llc -mtriple=amdgcn-- -O0 -run-pass=legalizer -o - %s | FileCheck %s
---
name: test_unmerge_s32_s64
@ -694,14 +694,21 @@ body: |
liveins: $vgpr0
; CHECK-LABEL: name: test_unmerge_s1_s3
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0
; CHECK: [[TRUNC:%[0-9]+]]:_(s3) = G_TRUNC [[COPY]](s32)
; CHECK: [[UV:%[0-9]+]]:_(s1), [[UV1:%[0-9]+]]:_(s1), [[UV2:%[0-9]+]]:_(s1) = G_UNMERGE_VALUES [[TRUNC]](s3)
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s1)
; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s1)
; CHECK: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s1)
; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
; CHECK: $vgpr1 = COPY [[ANYEXT1]](s32)
; CHECK: $vgpr2 = COPY [[ANYEXT2]](s32)
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
; CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
; CHECK: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[C2]](s32)
; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY [[LSHR]](s32)
; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[LSHR1]](s32)
; CHECK: $vgpr0 = COPY [[COPY3]](s32)
; CHECK: $vgpr1 = COPY [[COPY4]](s32)
; CHECK: $vgpr2 = COPY [[COPY5]](s32)
%0:_(s32) = COPY $vgpr0
%1:_(s3) = G_TRUNC %0
%2:_(s1), %3:_(s1), %4:_(s1) = G_UNMERGE_VALUES %1
@ -720,24 +727,51 @@ body: |
liveins: $vgpr0
; CHECK-LABEL: name: test_unmerge_s1_s8
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0
; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; CHECK: [[UV:%[0-9]+]]:_(s1), [[UV1:%[0-9]+]]:_(s1), [[UV2:%[0-9]+]]:_(s1), [[UV3:%[0-9]+]]:_(s1), [[UV4:%[0-9]+]]:_(s1), [[UV5:%[0-9]+]]:_(s1), [[UV6:%[0-9]+]]:_(s1), [[UV7:%[0-9]+]]:_(s1) = G_UNMERGE_VALUES [[TRUNC]](s8)
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s1)
; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[UV1]](s1)
; CHECK: [[ANYEXT2:%[0-9]+]]:_(s32) = G_ANYEXT [[UV2]](s1)
; CHECK: [[ANYEXT3:%[0-9]+]]:_(s32) = G_ANYEXT [[UV3]](s1)
; CHECK: [[ANYEXT4:%[0-9]+]]:_(s32) = G_ANYEXT [[UV4]](s1)
; CHECK: [[ANYEXT5:%[0-9]+]]:_(s32) = G_ANYEXT [[UV5]](s1)
; CHECK: [[ANYEXT6:%[0-9]+]]:_(s32) = G_ANYEXT [[UV6]](s1)
; CHECK: [[ANYEXT7:%[0-9]+]]:_(s32) = G_ANYEXT [[UV7]](s1)
; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
; CHECK: $vgpr1 = COPY [[ANYEXT1]](s32)
; CHECK: $vgpr2 = COPY [[ANYEXT2]](s32)
; CHECK: $vgpr3 = COPY [[ANYEXT3]](s32)
; CHECK: $vgpr4 = COPY [[ANYEXT4]](s32)
; CHECK: $vgpr5 = COPY [[ANYEXT5]](s32)
; CHECK: $vgpr6 = COPY [[ANYEXT6]](s32)
; CHECK: $vgpr7 = COPY [[ANYEXT7]](s32)
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C1]]
; CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[AND]], [[C]](s32)
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C1]]
; CHECK: [[LSHR1:%[0-9]+]]:_(s32) = G_LSHR [[AND1]], [[C2]](s32)
; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C1]]
; CHECK: [[LSHR2:%[0-9]+]]:_(s32) = G_LSHR [[AND2]], [[C3]](s32)
; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND3:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C1]]
; CHECK: [[LSHR3:%[0-9]+]]:_(s32) = G_LSHR [[AND3]], [[C4]](s32)
; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND4:%[0-9]+]]:_(s32) = G_AND [[COPY5]], [[C1]]
; CHECK: [[LSHR4:%[0-9]+]]:_(s32) = G_LSHR [[AND4]], [[C5]](s32)
; CHECK: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND5:%[0-9]+]]:_(s32) = G_AND [[COPY6]], [[C1]]
; CHECK: [[LSHR5:%[0-9]+]]:_(s32) = G_LSHR [[AND5]], [[C6]](s32)
; CHECK: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
; CHECK: [[COPY7:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[AND6:%[0-9]+]]:_(s32) = G_AND [[COPY7]], [[C1]]
; CHECK: [[LSHR6:%[0-9]+]]:_(s32) = G_LSHR [[AND6]], [[C7]](s32)
; CHECK: [[COPY8:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
; CHECK: [[COPY9:%[0-9]+]]:_(s32) = COPY [[LSHR]](s32)
; CHECK: [[COPY10:%[0-9]+]]:_(s32) = COPY [[LSHR1]](s32)
; CHECK: [[COPY11:%[0-9]+]]:_(s32) = COPY [[LSHR2]](s32)
; CHECK: [[COPY12:%[0-9]+]]:_(s32) = COPY [[LSHR3]](s32)
; CHECK: [[COPY13:%[0-9]+]]:_(s32) = COPY [[LSHR4]](s32)
; CHECK: [[COPY14:%[0-9]+]]:_(s32) = COPY [[LSHR5]](s32)
; CHECK: [[COPY15:%[0-9]+]]:_(s32) = COPY [[LSHR6]](s32)
; CHECK: $vgpr0 = COPY [[COPY8]](s32)
; CHECK: $vgpr1 = COPY [[COPY9]](s32)
; CHECK: $vgpr2 = COPY [[COPY10]](s32)
; CHECK: $vgpr3 = COPY [[COPY11]](s32)
; CHECK: $vgpr4 = COPY [[COPY12]](s32)
; CHECK: $vgpr5 = COPY [[COPY13]](s32)
; CHECK: $vgpr6 = COPY [[COPY14]](s32)
; CHECK: $vgpr7 = COPY [[COPY15]](s32)
%0:_(s32) = COPY $vgpr0
%1:_(s8) = G_TRUNC %0
%2:_(s1), %3:_(s1), %4:_(s1), %5:_(s1), %6:_(s1), %7:_(s1), %8:_(s1), %9:_(s1) = G_UNMERGE_VALUES %1

View File

@ -2516,4 +2516,53 @@ TEST_F(GISelMITest, LowerBSWAP) {
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// Test widening of G_UNMERGE_VALUES
TEST_F(GISelMITest, WidenUnmerge) {
setUp();
if (!TM)
return;
DefineLegalizerInfo(A, {});
// Check that widening G_UNMERGE_VALUES to a larger type than the source type
// works as expected
LLT P0{LLT::pointer(0, 64)};
LLT S32{LLT::scalar(32)};
LLT S96{LLT::scalar(96)};
auto IntToPtr = B.buildIntToPtr(P0, Copies[0]);
auto UnmergePtr = B.buildUnmerge(S32, IntToPtr);
auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]);
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
// Perform Legalization
EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
Helper.widenScalar(*UnmergePtr, 0, S96));
EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
Helper.widenScalar(*UnmergeScalar, 0, S96));
const auto *CheckStr = R"(
CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY
CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]
CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]
CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]
CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]
CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]
CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 32
CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]
CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]
)";
// Check
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
} // namespace