diff options
author | David Majnemer <david.majnemer@gmail.com> | 2017-01-04 02:21:31 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2017-01-04 02:21:31 +0000 |
commit | 022d2a563bf81be5c0629ebc9193bcb51b88d0a4 (patch) | |
tree | 2b8a1f4e902dc5710e64ee52c798aa5132beb317 | |
parent | 6298b44448c9edf852694d2bb9ed35c04325b098 (diff) | |
download | bcm5719-llvm-022d2a563bf81be5c0629ebc9193bcb51b88d0a4.tar.gz bcm5719-llvm-022d2a563bf81be5c0629ebc9193bcb51b88d0a4.zip |
[InstCombine] Combine adds across a zext
We can perform the following:
(add (zext (add nuw X, C1)), C2) -> (zext (add nuw X, C1+C2))
This is only possible if C2 is negative and C2 is greater than or equal to negative C1.
llvm-svn: 290927
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 12 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/add.ll | 12 |
2 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 3bbc70ab21c..55151c13b43 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1057,6 +1057,18 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { // add(zext(xor i16 X, -32768), -32768) --> sext X return CastInst::Create(Instruction::SExt, X, LHS->getType()); } + + if (Val->isNegative() && + match(LHS, m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C)))) && + Val->sge(-C->sext(Val->getBitWidth()))) { + // (add (zext (add nuw X, C)), Val) -> (zext (add nuw X, C+Val)) + return CastInst::Create( + Instruction::ZExt, + Builder->CreateNUWAdd( + X, Constant::getIntegerValue(X->getType(), + *C + Val->trunc(C->getBitWidth()))), + I.getType()); + } } // FIXME: Use the match above instead of dyn_cast to allow these transforms diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index 7c46257273a..39a746ab310 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -507,3 +507,15 @@ define i1 @test40(i32 %a, i32 %b) { %cmp = icmp eq i32 %add, %b ret i1 %cmp } + +define i64 @test41(i32 %a) { +; CHECK-LABEL: @test41( +; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 %a, 15 +; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[ADD]] to i64 +; CHECK-NEXT: ret i64 [[EXT]] +; + %add = add nuw i32 %a, 16 + %zext = zext i32 %add to i64 + %sub = add i64 %zext, -1 + ret i64 %sub +} |