summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2017-10-03 04:53:56 +0000
committerQuentin Colombet <qcolombet@apple.com>2017-10-03 04:53:56 +0000
commitc2f3cea608a123fa51ec523d91b9df46edf22df3 (patch)
tree844f30cd8e3afa1d4eee71fa71474f317d2a9f30 /llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
parent60ee7e302a043351107def9ae1a59cc23c444dd6 (diff)
downloadbcm5719-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.cpp44
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;
+ }
}
}
OpenPOWER on IntegriCloud