summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
diff options
context:
space:
mode:
authorAditya Nandakumar <aditya_nandakumar@apple.com>2018-08-29 03:17:08 +0000
committerAditya Nandakumar <aditya_nandakumar@apple.com>2018-08-29 03:17:08 +0000
commit6d47a415204a066a0a6b52525240d57f9cb339bf (patch)
tree7de080b80380ded702c5d8ef6a3e16ad383e149c /llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
parent9f42726cc79d4fa5f069bb2242a97ed1426ae20a (diff)
downloadbcm5719-llvm-6d47a415204a066a0a6b52525240d57f9cb339bf.tar.gz
bcm5719-llvm-6d47a415204a066a0a6b52525240d57f9cb339bf.zip
[GISel]: Add legalization support for Widening UADDO/USUBO
https://reviews.llvm.org/D51384 Added code in LegalizerHelper to widen UADDO/USUBO along with unit tests. Reviewed by volkan. llvm-svn: 340892
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 499067364b0..ff2e61c03b4 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -619,6 +619,32 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
switch (MI.getOpcode()) {
default:
return UnableToLegalize;
+ case TargetOpcode::G_UADDO:
+ case TargetOpcode::G_USUBO: {
+ if (TypeIdx == 1)
+ return UnableToLegalize; // TODO
+ auto LHSZext = MIRBuilder.buildInstr(TargetOpcode::G_ZEXT, WideTy,
+ MI.getOperand(2).getReg());
+ auto RHSZext = MIRBuilder.buildInstr(TargetOpcode::G_ZEXT, WideTy,
+ MI.getOperand(3).getReg());
+ unsigned Opcode = MI.getOpcode() == TargetOpcode::G_UADDO
+ ? TargetOpcode::G_ADD
+ : TargetOpcode::G_SUB;
+ // Do the arithmetic in the larger type.
+ auto NewOp = MIRBuilder.buildInstr(Opcode, WideTy, LHSZext, RHSZext);
+ LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
+ APInt Mask = APInt::getAllOnesValue(OrigTy.getSizeInBits());
+ auto AndOp = MIRBuilder.buildInstr(
+ TargetOpcode::G_AND, WideTy, NewOp,
+ MIRBuilder.buildConstant(WideTy, Mask.getZExtValue()));
+ // There is no overflow if the AndOp is the same as NewOp.
+ MIRBuilder.buildICmp(CmpInst::ICMP_NE, MI.getOperand(1).getReg(), NewOp,
+ AndOp);
+ // Now trunc the NewOp to the original result.
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), NewOp);
+ MI.eraseFromParent();
+ return Legalized;
+ }
case TargetOpcode::G_CTTZ:
case TargetOpcode::G_CTTZ_ZERO_UNDEF:
case TargetOpcode::G_CTLZ:
OpenPOWER on IntegriCloud