summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2017-01-04 02:21:31 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2017-01-04 02:21:31 +0000
commit022d2a563bf81be5c0629ebc9193bcb51b88d0a4 (patch)
tree2b8a1f4e902dc5710e64ee52c798aa5132beb317
parent6298b44448c9edf852694d2bb9ed35c04325b098 (diff)
downloadbcm5719-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.cpp12
-rw-r--r--llvm/test/Transforms/InstCombine/add.ll12
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
+}
OpenPOWER on IntegriCloud