diff options
author | Quentin Colombet <qcolombet@apple.com> | 2017-10-03 04:53:56 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2017-10-03 04:53:56 +0000 |
commit | c2f3cea608a123fa51ec523d91b9df46edf22df3 (patch) | |
tree | 844f30cd8e3afa1d4eee71fa71474f317d2a9f30 /llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | |
parent | 60ee7e302a043351107def9ae1a59cc23c444dd6 (diff) | |
download | bcm5719-llvm-c2f3cea608a123fa51ec523d91b9df46edf22df3.tar.gz bcm5719-llvm-c2f3cea608a123fa51ec523d91b9df46edf22df3.zip |
[Legalizer] Add support for G_OR NarrowScalar.
Legalize bitwise OR:
A = BinOp<Ty> B, C
into:
B1, ..., BN = G_UNMERGE_VALUES B
C1, ..., CN = G_UNMERGE_VALUES C
A1 = BinOp<Ty/N> B1, C2
...
AN = BinOp<Ty/N> BN, CN
A = G_MERGE_VALUES A1, ..., AN
llvm-svn: 314760
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index a70e46e67df..cd6684fbb4e 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -396,6 +396,50 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, MI.eraseFromParent(); return Legalized; } + case TargetOpcode::G_OR: { + // Legalize bitwise operation: + // A = BinOp<Ty> B, C + // into: + // B1, ..., BN = G_UNMERGE_VALUES B + // C1, ..., CN = G_UNMERGE_VALUES C + // A1 = BinOp<Ty/N> B1, C2 + // ... + // AN = BinOp<Ty/N> BN, CN + // A = G_MERGE_VALUES A1, ..., AN + unsigned NarrowSize = NarrowTy.getSizeInBits(); + int NumParts = + MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowSize; + + // List the registers where the destination will be scattered. + SmallVector<unsigned, 2> DstRegs; + // List the registers where the first argument will be split. + SmallVector<unsigned, 2> SrcsReg1; + // List the registers where the second argument will be split. + SmallVector<unsigned, 2> SrcsReg2; + // Create all the temporary registers. + for (int i = 0; i < NumParts; ++i) { + unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); + unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy); + unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy); + + DstRegs.push_back(DstReg); + SrcsReg1.push_back(SrcReg1); + SrcsReg2.push_back(SrcReg2); + } + // Explode the big arguments into smaller chunks. + MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg()); + MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg()); + + // Do the operation on each small part. + for (int i = 0; i < NumParts; ++i) + MIRBuilder.buildOr(DstRegs[i], SrcsReg1[i], SrcsReg2[i]); + + // Gather the destination registers into the final destination. + unsigned DstReg = MI.getOperand(0).getReg(); + MIRBuilder.buildMerge(DstReg, DstRegs); + MI.eraseFromParent(); + return Legalized; + } } } |