llvm.org GIT mirror llvm / 012f854
The expression icmp eq (select (icmp eq x, 0), 1, x), 0 folds to false. Spotted by my super-optimizer in 186.crafty and 450.soplex. We really need a proper infrastructure for handling generalizations of this kind of thing (which occur a lot), however this case is so simple that I decided to go ahead and implement it directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143214 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 7 years ago
2 changed file(s) with 55 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
415415 }
416416 assert(isa(LHS) && "Not comparing with a select instruction!");
417417 SelectInst *SI = cast(LHS);
418 Value *Cond = SI->getCondition();
419 Value *TV = SI->getTrueValue();
420 Value *FV = SI->getFalseValue();
418421
419422 // Now that we have "cmp select(Cond, TV, FV), RHS", analyse it.
420423 // Does "cmp TV, RHS" simplify?
421 if (Value *TCmp = SimplifyCmpInst(Pred, SI->getTrueValue(), RHS, TD, DT,
422 MaxRecurse)) {
423 // It does! Does "cmp FV, RHS" simplify?
424 if (Value *FCmp = SimplifyCmpInst(Pred, SI->getFalseValue(), RHS, TD, DT,
425 MaxRecurse)) {
426 // It does! If they simplified to the same value, then use it as the
427 // result of the original comparison.
428 if (TCmp == FCmp)
429 return TCmp;
430 Value *Cond = SI->getCondition();
431 // If the false value simplified to false, then the result of the compare
432 // is equal to "Cond && TCmp". This also catches the case when the false
433 // value simplified to false and the true value to true, returning "Cond".
434 if (match(FCmp, m_Zero()))
435 if (Value *V = SimplifyAndInst(Cond, TCmp, TD, DT, MaxRecurse))
436 return V;
437 // If the true value simplified to true, then the result of the compare
438 // is equal to "Cond || FCmp".
439 if (match(TCmp, m_One()))
440 if (Value *V = SimplifyOrInst(Cond, FCmp, TD, DT, MaxRecurse))
441 return V;
442 // Finally, if the false value simplified to true and the true value to
443 // false, then the result of the compare is equal to "!Cond".
444 if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
445 if (Value *V =
446 SimplifyXorInst(Cond, Constant::getAllOnesValue(Cond->getType()),
447 TD, DT, MaxRecurse))
448 return V;
449 }
450 }
424 Value *TCmp = SimplifyCmpInst(Pred, TV, RHS, TD, DT, MaxRecurse);
425 if (!TCmp) {
426 // It didn't simplify. However if "cmp TV, RHS" is equal to the select
427 // condition itself then we can replace it with 'true'.
428 if (match(Cond, m_ICmp(Pred, m_Specific(TV), m_Specific(RHS))))
429 TCmp = getTrue(Cond->getType());
430 }
431 if (!TCmp)
432 return 0;
433
434 // Does "cmp FV, RHS" simplify?
435 Value *FCmp = SimplifyCmpInst(Pred, FV, RHS, TD, DT, MaxRecurse);
436 if (!FCmp) {
437 // It didn't simplify. However if "cmp FV, RHS" is equal to the select
438 // condition itself then we can replace it with 'false'.
439 if (match(Cond, m_ICmp(Pred, m_Specific(FV), m_Specific(RHS))))
440 FCmp = getFalse(Cond->getType());
441 }
442 if (!FCmp)
443 return 0;
444
445 // If both sides simplified to the same value, then use it as the result of
446 // the original comparison.
447 if (TCmp == FCmp)
448 return TCmp;
449 // If the false value simplified to false, then the result of the compare
450 // is equal to "Cond && TCmp". This also catches the case when the false
451 // value simplified to false and the true value to true, returning "Cond".
452 if (match(FCmp, m_Zero()))
453 if (Value *V = SimplifyAndInst(Cond, TCmp, TD, DT, MaxRecurse))
454 return V;
455 // If the true value simplified to true, then the result of the compare
456 // is equal to "Cond || FCmp".
457 if (match(TCmp, m_One()))
458 if (Value *V = SimplifyOrInst(Cond, FCmp, TD, DT, MaxRecurse))
459 return V;
460 // Finally, if the false value simplified to true and the true value to
461 // false, then the result of the compare is equal to "!Cond".
462 if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
463 if (Value *V =
464 SimplifyXorInst(Cond, Constant::getAllOnesValue(Cond->getType()),
465 TD, DT, MaxRecurse))
466 return V;
451467
452468 return 0;
453469 }
201201 %c = icmp ne i32 %s, 0
202202 ret i1 %c
203203 ; CHECK: ret i1 %cond
204 }
205
206 define i1 @select5(i32 %x) {
207 ; CHECK: @select5
208 %c = icmp eq i32 %x, 0
209 %s = select i1 %c, i32 1, i32 %x
210 %c2 = icmp eq i32 %s, 0
211 ret i1 %c2
212 ; CHECK: ret i1 false
204213 }
205214
206215 define i1 @urem1(i32 %X, i32 %Y) {