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:
parent
b0e99e532a
commit
adb21d1650
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user