llvm.org GIT mirror llvm / 9feda17
Try once again to optimize "icmp (srem X, Y), Y" by turning the comparison into true/false or "icmp slt/sge Y, 0". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127063 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 8 years ago
2 changed file(s) with 45 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
23132313 BO0->hasOneUse() && BO1->hasOneUse())
23142314 return new ICmpInst(Pred, D, B);
23152315
2316 BinaryOperator *SRem = NULL;
2317 // icmp Y, (srem X, Y)
2318 if (BO0 && BO0->getOpcode() == Instruction::SRem &&
2319 Op1 == BO0->getOperand(1))
2320 SRem = BO0;
2321 // icmp (srem X, Y), Y
2322 else if (BO1 && BO1->getOpcode() == Instruction::SRem &&
2323 Op0 == BO1->getOperand(1))
2324 SRem = BO1;
2325 if (SRem) {
2326 // We don't check hasOneUse to avoid increasing register pressure because
2327 // the value we use is the same value this instruction was already using.
2328 switch (SRem == BO0 ? ICmpInst::getSwappedPredicate(Pred) : Pred) {
2329 default: break;
2330 case ICmpInst::ICMP_EQ:
2331 return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
2332 case ICmpInst::ICMP_NE:
2333 return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
2334 case ICmpInst::ICMP_SGT:
2335 case ICmpInst::ICMP_SGE:
2336 return new ICmpInst(ICmpInst::ICMP_SGT, SRem->getOperand(1),
2337 Constant::getAllOnesValue(SRem->getType()));
2338 case ICmpInst::ICMP_SLT:
2339 case ICmpInst::ICMP_SLE:
2340 return new ICmpInst(ICmpInst::ICMP_SLT, SRem->getOperand(1),
2341 Constant::getNullValue(SRem->getType()));
2342 }
2343 }
2344
23162345 if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() &&
23172346 BO0->hasOneUse() && BO1->hasOneUse() &&
23182347 BO0->getOperand(1) == BO1->getOperand(1)) {
402402 %B = icmp ugt i32 %Y, %A
403403 ret i1 %B
404404 }
405
406 ; CHECK: @test42
407 ; CHECK: %B = icmp sgt i32 %Y, -1
408 define i1 @test42(i32 %X, i32 %Y) {
409 %A = srem i32 %X, %Y
410 %B = icmp slt i32 %A, %Y
411 ret i1 %B
412 }
413
414 ; CHECK: @test43
415 ; CHECK: %B = icmp slt i32 %Y, 0
416 define i1 @test43(i32 %X, i32 %Y) {
417 %A = srem i32 %X, %Y
418 %B = icmp slt i32 %Y, %A
419 ret i1 %B
420 }