llvm.org GIT mirror llvm / 620e876
InstSimplify: Optimize away useless unsigned comparisons Code like X < Y && Y == 0 should always be folded away to false. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223583 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 4 years ago
3 changed file(s) with 98 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
14421442 RecursionLimit);
14431443 }
14441444
1445 static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
1446 ICmpInst *UnsignedICmp, bool IsAnd) {
1447 Value *X, *Y;
1448
1449 ICmpInst::Predicate EqPred;
1450 if (!match(ZeroICmp, m_ICmp(EqPred, m_Value(Y), m_Zero())) &&
1451 ICmpInst::isEquality(EqPred))
1452 return nullptr;
1453
1454 ICmpInst::Predicate UnsignedPred;
1455 if (match(UnsignedICmp, m_ICmp(UnsignedPred, m_Value(X), m_Specific(Y))) &&
1456 ICmpInst::isUnsigned(UnsignedPred))
1457 ;
1458 else if (match(UnsignedICmp,
1459 m_ICmp(UnsignedPred, m_Value(Y), m_Specific(X))) &&
1460 ICmpInst::isUnsigned(UnsignedPred))
1461 UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
1462 else
1463 return nullptr;
1464
1465 // X < Y && Y != 0 --> X < Y
1466 // X < Y || Y != 0 --> Y != 0
1467 if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_NE)
1468 return IsAnd ? UnsignedICmp : ZeroICmp;
1469
1470 // X >= Y || Y != 0 --> true
1471 // X >= Y || Y == 0 --> X >= Y
1472 if (UnsignedPred == ICmpInst::ICMP_UGE && !IsAnd) {
1473 if (EqPred == ICmpInst::ICMP_NE)
1474 return getTrue(UnsignedICmp->getType());
1475 return UnsignedICmp;
1476 }
1477
1478 // X < Y && Y == 0 --> false
1479 if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_EQ &&
1480 IsAnd)
1481 return getFalse(UnsignedICmp->getType());
1482
1483 return nullptr;
1484 }
1485
14451486 // Simplify (and (icmp ...) (icmp ...)) to true when we can tell that the range
14461487 // of possible values cannot be satisfied.
14471488 static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
14481489 ICmpInst::Predicate Pred0, Pred1;
14491490 ConstantInt *CI1, *CI2;
14501491 Value *V;
1492
1493 if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/true))
1494 return X;
1495
14511496 if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_ConstantInt(CI1)),
14521497 m_ConstantInt(CI2))))
14531498 return nullptr;
16011646 ICmpInst::Predicate Pred0, Pred1;
16021647 ConstantInt *CI1, *CI2;
16031648 Value *V;
1649
1650 if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/false))
1651 return X;
1652
16041653 if (!match(Op0, m_ICmp(Pred0, m_Add(m_Value(V), m_ConstantInt(CI1)),
16051654 m_ConstantInt(CI2))))
16061655 return nullptr;
13491349 const GlobalValue *GV2) {
13501350 // Don't try to decide equality of aliases.
13511351 if (!isa(GV1) && !isa(GV2))
1352 if (!GV1->hasExternalWeakLinkage() || !GV2->hasExternalWeakLinkage())
1352 if (!GV1->hasExternalWeakLinkage() && !GV2->hasExternalWeakLinkage())
13531353 return ICmpInst::ICMP_NE;
13541354 return ICmpInst::BAD_ICMP_PREDICATE;
13551355 }
154154 ret i32 %neg
155155 ; CHECK: ret i32 0
156156 }
157
158 define i1 @and_icmp1(i32 %x, i32 %y) {
159 %1 = icmp ult i32 %x, %y
160 %2 = icmp ne i32 %y, 0
161 %3 = and i1 %1, %2
162 ret i1 %3
163 }
164 ; CHECK-LABEL: @and_icmp1(
165 ; CHECK: %[[cmp:.*]] = icmp ult i32 %x, %y
166 ; CHECK: ret i1 %[[cmp]]
167
168 define i1 @and_icmp2(i32 %x, i32 %y) {
169 %1 = icmp ult i32 %x, %y
170 %2 = icmp eq i32 %y, 0
171 %3 = and i1 %1, %2
172 ret i1 %3
173 }
174 ; CHECK-LABEL: @and_icmp2(
175 ; CHECK: ret i1 false
176
177 define i1 @or_icmp1(i32 %x, i32 %y) {
178 %1 = icmp ult i32 %x, %y
179 %2 = icmp ne i32 %y, 0
180 %3 = or i1 %1, %2
181 ret i1 %3
182 }
183 ; CHECK-LABEL: @or_icmp1(
184 ; CHECK: %[[cmp:.*]] = icmp ne i32 %y, 0
185 ; CHECK: ret i1 %[[cmp]]
186
187 define i1 @or_icmp2(i32 %x, i32 %y) {
188 %1 = icmp uge i32 %x, %y
189 %2 = icmp ne i32 %y, 0
190 %3 = or i1 %1, %2
191 ret i1 %3
192 }
193 ; CHECK-LABEL: @or_icmp2(
194 ; CHECK: ret i1 true
195
196 define i1 @or_icmp3(i32 %x, i32 %y) {
197 %1 = icmp uge i32 %x, %y
198 %2 = icmp eq i32 %y, 0
199 %3 = or i1 %1, %2
200 ret i1 %3
201 }
202 ; CHECK-LABEL: @or_icmp3(
203 ; CHECK: %[[cmp:.*]] = icmp uge i32 %x, %y
204 ; CHECK: ret i1 %[[cmp]]