summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-04-22 17:07:44 +0000
committerSanjay Patel <spatel@rotateright.com>2018-04-22 17:07:44 +0000
commit30be665e82989243f5a9b4c71ec1805c59b376ec (patch)
treee1865da5b1e432b58a85d56dd8d296c3dd5f0e1d /llvm/lib/Analysis/InstructionSimplify.cpp
parentc7f9b183c2551dc478ff2b55b287e900dc8719f8 (diff)
downloadbcm5719-llvm-30be665e82989243f5a9b4c71ec1805c59b376ec.tar.gz
bcm5719-llvm-30be665e82989243f5a9b4c71ec1805c59b376ec.zip
[PatternMatch] allow undef elements when matching a vector zero
This is the last step in getting constant pattern matchers to allow undef elements in constant vectors. I'm adding a dedicated m_ZeroInt() function and building m_Zero() from that. In most cases, calling code can be updated to use m_ZeroInt() directly when there's no need to match pointers, but I'm leaving that efficiency optimization as a follow-up step because it's not always clear when that's ok. There are just enough icmp folds in InstSimplify that can be used for integer or pointer types, that we probably still want a generic m_Zero() for those cases. Otherwise, we could eliminate it (and possibly add a m_NullPtr() as an alias for isa<ConstantPointerNull>()). We're conservatively returning a full zero vector (zeroinitializer) in InstSimplify/InstCombine on some of these folds (see diffs in InstSimplify), but I'm not sure if that's actually necessary in all cases. We may be able to propagate an undef lane instead. One test where this happens is marked with 'TODO'. llvm-svn: 330550
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp20
1 files changed, 8 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 73c3c47e909..1e62b9d407e 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -680,14 +680,14 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
if (match(Op0, m_Zero())) {
// 0 - X -> 0 if the sub is NUW.
if (isNUW)
- return Op0;
+ return Constant::getNullValue(Op0->getType());
KnownBits Known = computeKnownBits(Op1, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
if (Known.Zero.isMaxSignedValue()) {
// Op1 is either 0 or the minimum signed value. If the sub is NSW, then
// Op1 must be 0 because negating the minimum signed value is undefined.
if (isNSW)
- return Op0;
+ return Constant::getNullValue(Op0->getType());
// 0 - X -> X if X is 0 or the minimum signed value.
return Op1;
@@ -799,12 +799,9 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
return C;
// X * undef -> 0
- if (match(Op1, m_Undef()))
- return Constant::getNullValue(Op0->getType());
-
// X * 0 -> 0
- if (match(Op1, m_Zero()))
- return Op1;
+ if (match(Op1, m_CombineOr(m_Undef(), m_Zero())))
+ return Constant::getNullValue(Op0->getType());
// X * 1 -> X
if (match(Op1, m_One()))
@@ -888,7 +885,7 @@ static Value *simplifyDivRem(Value *Op0, Value *Op1, bool IsDiv) {
// 0 / X -> 0
// 0 % X -> 0
if (match(Op0, m_Zero()))
- return Op0;
+ return Constant::getNullValue(Op0->getType());
// X / X -> 1
// X % X -> 0
@@ -1147,7 +1144,7 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
// 0 shift by X -> 0
if (match(Op0, m_Zero()))
- return Op0;
+ return Constant::getNullValue(Op0->getType());
// X shift by 0 -> X
if (match(Op1, m_Zero()))
@@ -1689,7 +1686,7 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
// X & 0 = 0
if (match(Op1, m_Zero()))
- return Op1;
+ return Constant::getNullValue(Op0->getType());
// X & -1 = X
if (match(Op1, m_AllOnes()))
@@ -3068,8 +3065,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
Type *ITy = GetCompareTy(LHS); // The return type.
// icmp X, X -> true/false
- // X icmp undef -> true/false. For example, icmp ugt %X, undef -> false
- // because X could be 0.
+ // icmp X, undef -> true/false because undef could be X.
if (LHS == RHS || isa<UndefValue>(RHS))
return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
OpenPOWER on IntegriCloud