llvm.org GIT mirror llvm / 360cd34
[Thumb] Add support for tMUL in the compare instruction peephole optimizer. We also want to optimise tests like this: return a*b == 0. The MULS instruction is flag setting, so we don't need the CMP instruction but can instead branch on the result of the MULS. The generated instructions sequence for this example was: MULS, MOVS, MOVS, CMP. The MOVS instruction load the boolean values resulting from the select instruction, but these MOVS instructions are flag setting and were thus preventing this optimisation. Now we first reorder and move the MULS to before the CMP and generate sequence MOVS, MOVS, MULS, CMP so that the optimisation could trigger. Reordering of the MULS and MOVS is safe to do because the subsequent MOVS instructions just set the CPSR register and don't use it, i.e. the CPSR is dead. Differential Revision: https://reviews.llvm.org/D27990 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292608 91177308-0d34-0410-b5e6-96231b3b80d8 Sjoerd Meijer 3 years ago
3 changed file(s) with 442 addition(s) and 219 deletion(s). Raw diff Collapse all Expand all
24342434 return false;
24352435 }
24362436
2437 /// optimizeCompareInstr - Convert the instruction supplying the argument to the
2438 /// comparison into one that sets the zero bit in the flags register;
2439 /// Remove a redundant Compare instruction if an earlier instruction can set the
2440 /// flags in the same way as Compare.
2441 /// E.g. SUBrr(r1,r2) and CMPrr(r1,r2). We also handle the case where two
2442 /// operands are swapped: SUBrr(r1,r2) and CMPrr(r2,r1), by updating the
2443 /// condition code of instructions which use the flags.
2444 bool ARMBaseInstrInfo::optimizeCompareInstr(
2445 MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
2446 int CmpValue, const MachineRegisterInfo *MRI) const {
2447 // Get the unique definition of SrcReg.
2448 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
2449 if (!MI) return false;
2450
2451 // Masked compares sometimes use the same register as the corresponding 'and'.
2452 if (CmpMask != ~0) {
2453 if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(*MI)) {
2454 MI = nullptr;
2455 for (MachineRegisterInfo::use_instr_iterator
2456 UI = MRI->use_instr_begin(SrcReg), UE = MRI->use_instr_end();
2457 UI != UE; ++UI) {
2458 if (UI->getParent() != CmpInstr.getParent())
2459 continue;
2460 MachineInstr *PotentialAND = &*UI;
2461 if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) ||
2462 isPredicated(*PotentialAND))
2463 continue;
2464 MI = PotentialAND;
2465 break;
2466 }
2467 if (!MI) return false;
2468 }
2469 }
2470
2471 // Get ready to iterate backward from CmpInstr.
2472 MachineBasicBlock::iterator I = CmpInstr, E = MI,
2473 B = CmpInstr.getParent()->begin();
2474
2475 // Early exit if CmpInstr is at the beginning of the BB.
2476 if (I == B) return false;
2477
2478 // There are two possible candidates which can be changed to set CPSR:
2479 // One is MI, the other is a SUB instruction.
2480 // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
2481 // For CMPri(r1, CmpValue), we are looking for SUBri(r1, CmpValue).
2482 MachineInstr *Sub = nullptr;
2483 if (SrcReg2 != 0)
2484 // MI is not a candidate for CMPrr.
2485 MI = nullptr;
2486 else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
2487 // Conservatively refuse to convert an instruction which isn't in the same
2488 // BB as the comparison.
2489 // For CMPri w/ CmpValue != 0, a Sub may still be a candidate.
2490 // Thus we cannot return here.
2491 if (CmpInstr.getOpcode() == ARM::CMPri ||
2492 CmpInstr.getOpcode() == ARM::t2CMPri)
2493 MI = nullptr;
2494 else
2495 return false;
2496 }
2497
2498 // Check that CPSR isn't set between the comparison instruction and the one we
2499 // want to change. At the same time, search for Sub.
2500 const TargetRegisterInfo *TRI = &getRegisterInfo();
2501 --I;
2502 for (; I != E; --I) {
2503 const MachineInstr &Instr = *I;
2504
2505 if (Instr.modifiesRegister(ARM::CPSR, TRI) ||
2506 Instr.readsRegister(ARM::CPSR, TRI))
2507 // This instruction modifies or uses CPSR after the one we want to
2508 // change. We can't do this transformation.
2509 return false;
2510
2511 // Check whether CmpInstr can be made redundant by the current instruction.
2512 if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
2513 Sub = &*I;
2514 break;
2515 }
2516
2517 if (I == B)
2518 // The 'and' is below the comparison instruction.
2519 return false;
2520 }
2521
2522 // Return false if no candidates exist.
2523 if (!MI && !Sub)
2524 return false;
2525
2526 // The single candidate is called MI.
2527 if (!MI) MI = Sub;
2528
2529 // We can't use a predicated instruction - it doesn't always write the flags.
2530 if (isPredicated(*MI))
2531 return false;
2532
2533 bool IsThumb1 = false;
2437 static bool isOptimizeCompareCandidate(MachineInstr *MI, bool &IsThumb1) {
25342438 switch (MI->getOpcode()) {
2535 default: break;
2439 default: return false;
25362440 case ARM::tLSLri:
25372441 case ARM::tLSRri:
25382442 case ARM::tLSLrr:
25432447 case ARM::tADDi8:
25442448 case ARM::tSUBi3:
25452449 case ARM::tSUBi8:
2450 case ARM::tMUL:
25462451 IsThumb1 = true;
25472452 LLVM_FALLTHROUGH;
25482453 case ARM::RSBrr:
25812486 case ARM::t2LSRri:
25822487 case ARM::t2LSRrr:
25832488 case ARM::t2LSLri:
2584 case ARM::t2LSLrr: {
2585 // Scan forward for the use of CPSR
2586 // When checking against MI: if it's a conditional code that requires
2587 // checking of the V bit or C bit, then this is not safe to do.
2588 // It is safe to remove CmpInstr if CPSR is redefined or killed.
2589 // If we are done with the basic block, we need to check whether CPSR is
2590 // live-out.
2591 SmallVector, 4>
2592 OperandsToUpdate;
2593 bool isSafe = false;
2489 case ARM::t2LSLrr:
2490 return true;
2491 }
2492 }
2493
2494 /// optimizeCompareInstr - Convert the instruction supplying the argument to the
2495 /// comparison into one that sets the zero bit in the flags register;
2496 /// Remove a redundant Compare instruction if an earlier instruction can set the
2497 /// flags in the same way as Compare.
2498 /// E.g. SUBrr(r1,r2) and CMPrr(r1,r2). We also handle the case where two
2499 /// operands are swapped: SUBrr(r1,r2) and CMPrr(r2,r1), by updating the
2500 /// condition code of instructions which use the flags.
2501 bool ARMBaseInstrInfo::optimizeCompareInstr(
2502 MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
2503 int CmpValue, const MachineRegisterInfo *MRI) const {
2504 // Get the unique definition of SrcReg.
2505 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
2506 if (!MI) return false;
2507
2508 // Masked compares sometimes use the same register as the corresponding 'and'.
2509 if (CmpMask != ~0) {
2510 if (!isSuitableForMask(MI, SrcReg, CmpMask, false) || isPredicated(*MI)) {
2511 MI = nullptr;
2512 for (MachineRegisterInfo::use_instr_iterator
2513 UI = MRI->use_instr_begin(SrcReg), UE = MRI->use_instr_end();
2514 UI != UE; ++UI) {
2515 if (UI->getParent() != CmpInstr.getParent())
2516 continue;
2517 MachineInstr *PotentialAND = &*UI;
2518 if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true) ||
2519 isPredicated(*PotentialAND))
2520 continue;
2521 MI = PotentialAND;
2522 break;
2523 }
2524 if (!MI) return false;
2525 }
2526 }
2527
2528 // Get ready to iterate backward from CmpInstr.
2529 MachineBasicBlock::iterator I = CmpInstr, E = MI,
2530 B = CmpInstr.getParent()->begin();
2531
2532 // Early exit if CmpInstr is at the beginning of the BB.
2533 if (I == B) return false;
2534
2535 // There are two possible candidates which can be changed to set CPSR:
2536 // One is MI, the other is a SUB instruction.
2537 // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
2538 // For CMPri(r1, CmpValue), we are looking for SUBri(r1, CmpValue).
2539 MachineInstr *Sub = nullptr;
2540 if (SrcReg2 != 0)
2541 // MI is not a candidate for CMPrr.
2542 MI = nullptr;
2543 else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
2544 // Conservatively refuse to convert an instruction which isn't in the same
2545 // BB as the comparison.
2546 // For CMPri w/ CmpValue != 0, a Sub may still be a candidate.
2547 // Thus we cannot return here.
2548 if (CmpInstr.getOpcode() == ARM::CMPri ||
2549 CmpInstr.getOpcode() == ARM::t2CMPri)
2550 MI = nullptr;
2551 else
2552 return false;
2553 }
2554
2555 bool IsThumb1 = false;
2556 if (MI && !isOptimizeCompareCandidate(MI, IsThumb1))
2557 return false;
2558
2559 // We also want to do this peephole for cases like this: if (a*b == 0),
2560 // and optimise away the CMP instruction from the generated code sequence:
2561 // MULS, MOVS, MOVS, CMP. Here the MOVS instructions load the boolean values
2562 // resulting from the select instruction, but these MOVS instructions for
2563 // Thumb1 (V6M) are flag setting and are thus preventing this optimisation.
2564 // However, if we only have MOVS instructions in between the CMP and the
2565 // other instruction (the MULS in this example), then the CPSR is dead so we
2566 // can safely reorder the sequence into: MOVS, MOVS, MULS, CMP. We do this
2567 // reordering and then continue the analysis hoping we can eliminate the
2568 // CMP. This peephole works on the vregs, so is still in SSA form. As a
2569 // consequence, the movs won't redefine/kill the MUL operands which would
2570 // make this reordering illegal.
2571 if (MI && IsThumb1) {
2572 --I;
2573 bool CanReorder = true;
2574 const bool HasStmts = I != E;
2575 for (; I != E; --I) {
2576 if (I->getOpcode() != ARM::tMOVi8) {
2577 CanReorder = false;
2578 break;
2579 }
2580 }
2581 if (HasStmts && CanReorder) {
2582 MI = MI->removeFromParent();
2583 E = CmpInstr;
2584 CmpInstr.getParent()->insert(E, MI);
2585 }
25942586 I = CmpInstr;
2595 E = CmpInstr.getParent()->end();
2596 while (!isSafe && ++I != E) {
2597 const MachineInstr &Instr = *I;
2598 for (unsigned IO = 0, EO = Instr.getNumOperands();
2599 !isSafe && IO != EO; ++IO) {
2600 const MachineOperand &MO = Instr.getOperand(IO);
2601 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) {
2602 isSafe = true;
2587 E = MI;
2588 }
2589
2590 // Check that CPSR isn't set between the comparison instruction and the one we
2591 // want to change. At the same time, search for Sub.
2592 const TargetRegisterInfo *TRI = &getRegisterInfo();
2593 --I;
2594 for (; I != E; --I) {
2595 const MachineInstr &Instr = *I;
2596
2597 if (Instr.modifiesRegister(ARM::CPSR, TRI) ||
2598 Instr.readsRegister(ARM::CPSR, TRI))
2599 // This instruction modifies or uses CPSR after the one we want to
2600 // change. We can't do this transformation.
2601 return false;
2602
2603 // Check whether CmpInstr can be made redundant by the current instruction.
2604 if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
2605 Sub = &*I;
2606 break;
2607 }
2608
2609 if (I == B)
2610 // The 'and' is below the comparison instruction.
2611 return false;
2612 }
2613
2614 // Return false if no candidates exist.
2615 if (!MI && !Sub)
2616 return false;
2617
2618 // The single candidate is called MI.
2619 if (!MI) MI = Sub;
2620
2621 // We can't use a predicated instruction - it doesn't always write the flags.
2622 if (isPredicated(*MI))
2623 return false;
2624
2625 // Scan forward for the use of CPSR
2626 // When checking against MI: if it's a conditional code that requires
2627 // checking of the V bit or C bit, then this is not safe to do.
2628 // It is safe to remove CmpInstr if CPSR is redefined or killed.
2629 // If we are done with the basic block, we need to check whether CPSR is
2630 // live-out.
2631 SmallVector, 4>
2632 OperandsToUpdate;
2633 bool isSafe = false;
2634 I = CmpInstr;
2635 E = CmpInstr.getParent()->end();
2636 while (!isSafe && ++I != E) {
2637 const MachineInstr &Instr = *I;
2638 for (unsigned IO = 0, EO = Instr.getNumOperands();
2639 !isSafe && IO != EO; ++IO) {
2640 const MachineOperand &MO = Instr.getOperand(IO);
2641 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) {
2642 isSafe = true;
2643 break;
2644 }
2645 if (!MO.isReg() || MO.getReg() != ARM::CPSR)
2646 continue;
2647 if (MO.isDef()) {
2648 isSafe = true;
2649 break;
2650 }
2651 // Condition code is after the operand before CPSR except for VSELs.
2652 ARMCC::CondCodes CC;
2653 bool IsInstrVSel = true;
2654 switch (Instr.getOpcode()) {
2655 default:
2656 IsInstrVSel = false;
2657 CC = (ARMCC::CondCodes)Instr.getOperand(IO - 1).getImm();
2658 break;
2659 case ARM::VSELEQD:
2660 case ARM::VSELEQS:
2661 CC = ARMCC::EQ;
2662 break;
2663 case ARM::VSELGTD:
2664 case ARM::VSELGTS:
2665 CC = ARMCC::GT;
2666 break;
2667 case ARM::VSELGED:
2668 case ARM::VSELGES:
2669 CC = ARMCC::GE;
2670 break;
2671 case ARM::VSELVSS:
2672 case ARM::VSELVSD:
2673 CC = ARMCC::VS;
2674 break;
2675 }
2676
2677 if (Sub) {
2678 ARMCC::CondCodes NewCC = getSwappedCondition(CC);
2679 if (NewCC == ARMCC::AL)
2680 return false;
2681 // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based
2682 // on CMP needs to be updated to be based on SUB.
2683 // Push the condition code operands to OperandsToUpdate.
2684 // If it is safe to remove CmpInstr, the condition code of these
2685 // operands will be modified.
2686 if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
2687 Sub->getOperand(2).getReg() == SrcReg) {
2688 // VSel doesn't support condition code update.
2689 if (IsInstrVSel)
2690 return false;
2691 OperandsToUpdate.push_back(
2692 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
2693 }
2694 } else {
2695 // No Sub, so this is x = y, z; cmp x, 0.
2696 switch (CC) {
2697 case ARMCC::EQ: // Z
2698 case ARMCC::NE: // Z
2699 case ARMCC::MI: // N
2700 case ARMCC::PL: // N
2701 case ARMCC::AL: // none
2702 // CPSR can be used multiple times, we should continue.
26032703 break;
2604 }
2605 if (!MO.isReg() || MO.getReg() != ARM::CPSR)
2606 continue;
2607 if (MO.isDef()) {
2608 isSafe = true;
2609 break;
2610 }
2611 // Condition code is after the operand before CPSR except for VSELs.
2612 ARMCC::CondCodes CC;
2613 bool IsInstrVSel = true;
2614 switch (Instr.getOpcode()) {
2615 default:
2616 IsInstrVSel = false;
2617 CC = (ARMCC::CondCodes)Instr.getOperand(IO - 1).getImm();
2618 break;
2619 case ARM::VSELEQD:
2620 case ARM::VSELEQS:
2621 CC = ARMCC::EQ;
2622 break;
2623 case ARM::VSELGTD:
2624 case ARM::VSELGTS:
2625 CC = ARMCC::GT;
2626 break;
2627 case ARM::VSELGED:
2628 case ARM::VSELGES:
2629 CC = ARMCC::GE;
2630 break;
2631 case ARM::VSELVSS:
2632 case ARM::VSELVSD:
2633 CC = ARMCC::VS;
2634 break;
2635 }
2636
2637 if (Sub) {
2638 ARMCC::CondCodes NewCC = getSwappedCondition(CC);
2639 if (NewCC == ARMCC::AL)
2640 return false;
2641 // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based
2642 // on CMP needs to be updated to be based on SUB.
2643 // Push the condition code operands to OperandsToUpdate.
2644 // If it is safe to remove CmpInstr, the condition code of these
2645 // operands will be modified.
2646 if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
2647 Sub->getOperand(2).getReg() == SrcReg) {
2648 // VSel doesn't support condition code update.
2649 if (IsInstrVSel)
2650 return false;
2651 OperandsToUpdate.push_back(
2652 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
2653 }
2654 } else {
2655 // No Sub, so this is x = y, z; cmp x, 0.
2656 switch (CC) {
2657 case ARMCC::EQ: // Z
2658 case ARMCC::NE: // Z
2659 case ARMCC::MI: // N
2660 case ARMCC::PL: // N
2661 case ARMCC::AL: // none
2662 // CPSR can be used multiple times, we should continue.
2663 break;
2664 case ARMCC::HS: // C
2665 case ARMCC::LO: // C
2666 case ARMCC::VS: // V
2667 case ARMCC::VC: // V
2668 case ARMCC::HI: // C Z
2669 case ARMCC::LS: // C Z
2670 case ARMCC::GE: // N V
2671 case ARMCC::LT: // N V
2672 case ARMCC::GT: // Z N V
2673 case ARMCC::LE: // Z N V
2674 // The instruction uses the V bit or C bit which is not safe.
2675 return false;
2676 }
2704 case ARMCC::HS: // C
2705 case ARMCC::LO: // C
2706 case ARMCC::VS: // V
2707 case ARMCC::VC: // V
2708 case ARMCC::HI: // C Z
2709 case ARMCC::LS: // C Z
2710 case ARMCC::GE: // N V
2711 case ARMCC::LT: // N V
2712 case ARMCC::GT: // Z N V
2713 case ARMCC::LE: // Z N V
2714 // The instruction uses the V bit or C bit which is not safe.
2715 return false;
26772716 }
26782717 }
26792718 }
2680
2681 // If CPSR is not killed nor re-defined, we should check whether it is
2682 // live-out. If it is live-out, do not optimize.
2683 if (!isSafe) {
2684 MachineBasicBlock *MBB = CmpInstr.getParent();
2685 for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
2686 SE = MBB->succ_end(); SI != SE; ++SI)
2687 if ((*SI)->isLiveIn(ARM::CPSR))
2688 return false;
2689 }
2690
2691 // Toggle the optional operand to CPSR (if it exists - in Thumb1 we always
2692 // set CPSR so this is represented as an explicit output)
2693 if (!IsThumb1) {
2694 MI->getOperand(5).setReg(ARM::CPSR);
2695 MI->getOperand(5).setIsDef(true);
2696 }
2697 assert(!isPredicated(*MI) && "Can't use flags from predicated instruction");
2698 CmpInstr.eraseFromParent();
2699
2700 // Modify the condition code of operands in OperandsToUpdate.
2701 // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
2702 // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
2703 for (unsigned i = 0, e = OperandsToUpdate.size(); i < e; i++)
2704 OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
2705 return true;
2706 }
2707 }
2708
2709 return false;
2719 }
2720
2721 // If CPSR is not killed nor re-defined, we should check whether it is
2722 // live-out. If it is live-out, do not optimize.
2723 if (!isSafe) {
2724 MachineBasicBlock *MBB = CmpInstr.getParent();
2725 for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
2726 SE = MBB->succ_end(); SI != SE; ++SI)
2727 if ((*SI)->isLiveIn(ARM::CPSR))
2728 return false;
2729 }
2730
2731 // Toggle the optional operand to CPSR (if it exists - in Thumb1 we always
2732 // set CPSR so this is represented as an explicit output)
2733 if (!IsThumb1) {
2734 MI->getOperand(5).setReg(ARM::CPSR);
2735 MI->getOperand(5).setIsDef(true);
2736 }
2737 assert(!isPredicated(*MI) && "Can't use flags from predicated instruction");
2738 CmpInstr.eraseFromParent();
2739
2740 // Modify the condition code of operands in OperandsToUpdate.
2741 // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
2742 // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
2743 for (unsigned i = 0, e = OperandsToUpdate.size(); i < e; i++)
2744 OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
2745
2746 return true;
27102747 }
27112748
27122749 bool ARMBaseInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
0 # RUN: llc -run-pass=peephole-opt %s -o - | FileCheck %s
1
2 --- |
3 ; ModuleID = ''
4 source_filename = ""
5 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
6 target triple = "thumb-none--eabi"
7
8 define i32 @f(i32 %a, i32 %b) {
9 entry:
10 %mul = mul nsw i32 %b, %a
11 %cmp = icmp eq i32 %mul, 0
12 %conv = zext i1 %cmp to i32
13 ret i32 %conv
14 }
15
16 ...
17 ---
18 name: f
19 # CHECK-LABEL: name: f
20 alignment: 1
21 exposesReturnsTwice: false
22 legalized: false
23 regBankSelected: false
24 selected: false
25 tracksRegLiveness: true
26 registers:
27 - { id: 0, class: tgpr }
28 - { id: 1, class: tgpr }
29 - { id: 2, class: tgpr }
30 - { id: 3, class: tgpr }
31 - { id: 4, class: tgpr }
32 - { id: 5, class: tgpr }
33 liveins:
34 - { reg: '%r0', virtual-reg: '%0' }
35 - { reg: '%r1', virtual-reg: '%1' }
36 frameInfo:
37 isFrameAddressTaken: false
38 isReturnAddressTaken: false
39 hasStackMap: false
40 hasPatchPoint: false
41 stackSize: 0
42 offsetAdjustment: 0
43 maxAlignment: 0
44 adjustsStack: false
45 hasCalls: false
46 maxCallFrameSize: 0
47 hasOpaqueSPAdjustment: false
48 hasVAStart: false
49 hasMustTailInVarArgFunc: false
50
51 # CHECK: tMOVi8 1, 14, _
52 # CHECK: tMOVi8 0, 14, _
53 # CHECK: tMUL %1, %0, 14, _
54 # CHECK-NOT: tCMPi8
55 body: |
56 bb.0.entry:
57 successors: %bb.1.entry(0x40000000), %bb.2.entry(0x40000000)
58 liveins: %r0, %r1
59
60 %1 = COPY %r1
61 %0 = COPY %r0
62 %2, %cpsr = tMUL %1, %0, 14, _
63 %3, %cpsr = tMOVi8 1, 14, _
64 %4, %cpsr = tMOVi8 0, 14, _
65 tCMPi8 killed %2, 0, 14, _, implicit-def %cpsr
66 tBcc %bb.2.entry, 0, %cpsr
67
68 bb.1.entry:
69 successors: %bb.2.entry(0x80000000)
70
71
72 bb.2.entry:
73 %5 = PHI %4, %bb.1.entry, %3, %bb.0.entry
74 %r0 = COPY %5
75 tBX_RET 14, _, implicit %r0
76
77 ...
0 # RUN: llc -run-pass=peephole-opt %s -o - | FileCheck %s
1
2 # Here we check that the peephole cmp rewrite is not triggered, because
3 # there is store instruction between the tMUL and tCMP, i.e. there are
4 # no constants to reorder.
5
6 --- |
7 ; ModuleID = 'cmp2-peephole-thumb.ll'
8 source_filename = ""
9 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
10 target triple = "thumb-none--eabi"
11
12 define i32 @g(i32 %a, i32 %b) {
13 entry:
14 %retval = alloca i32, align 4
15 %mul = alloca i32, align 4
16 %mul1 = mul nsw i32 %a, %b
17 store i32 %mul1, i32* %mul, align 4
18 %0 = load i32, i32* %mul, align 4
19 %cmp = icmp sle i32 %0, 0
20 br i1 %cmp, label %if.then, label %if.end
21
22 if.then: ; preds = %entry
23 store i32 42, i32* %retval, align 4
24 br label %return
25
26 if.end: ; preds = %entry
27 store i32 1, i32* %retval, align 4
28 br label %return
29
30 return: ; preds = %if.end, %if.then
31 %1 = load i32, i32* %retval, align 4
32 ret i32 %1
33 }
34
35 ...
36 ---
37 name: g
38 # CHECK-LABEL: name: g
39 alignment: 1
40 exposesReturnsTwice: false
41 legalized: false
42 regBankSelected: false
43 selected: false
44 tracksRegLiveness: true
45 registers:
46 - { id: 0, class: tgpr }
47 - { id: 1, class: tgpr }
48 - { id: 2, class: tgpr }
49 - { id: 3, class: tgpr }
50 - { id: 4, class: tgpr }
51 - { id: 5, class: tgpr }
52 liveins:
53 - { reg: '%r0', virtual-reg: '%0' }
54 - { reg: '%r1', virtual-reg: '%1' }
55 frameInfo:
56 isFrameAddressTaken: false
57 isReturnAddressTaken: false
58 hasStackMap: false
59 hasPatchPoint: false
60 stackSize: 0
61 offsetAdjustment: 0
62 maxAlignment: 4
63 adjustsStack: false
64 hasCalls: false
65 maxCallFrameSize: 0
66 hasOpaqueSPAdjustment: false
67 hasVAStart: false
68 hasMustTailInVarArgFunc: false
69 stack:
70 - { id: 0, name: retval, offset: 0, size: 4, alignment: 4, local-offset: -4 }
71 - { id: 1, name: mul, offset: 0, size: 4, alignment: 4, local-offset: -8 }
72
73 # CHECK: tMUL
74 # CHECK-NEXT: tSTRspi
75 # CHECK-NEXT: tCMPi8
76 body: |
77 bb.0.entry:
78 successors: %bb.1.if.then(0x40000000), %bb.2.if.end(0x40000000)
79 liveins: %r0, %r1
80
81 %1 = COPY %r1
82 %0 = COPY %r0
83 %2, %cpsr = tMUL %0, %1, 14, _
84 tSTRspi %2, %stack.1.mul, 0, 14, _ :: (store 4 into %ir.mul)
85 tCMPi8 %2, 0, 14, _, implicit-def %cpsr
86 tBcc %bb.2.if.end, 12, %cpsr
87 tB %bb.1.if.then, 14, _
88
89 bb.1.if.then:
90 successors: %bb.3.return(0x80000000)
91
92 %4, %cpsr = tMOVi8 42, 14, _
93 tSTRspi killed %4, %stack.0.retval, 0, 14, _ :: (store 4 into %ir.retval)
94 tB %bb.3.return, 14, _
95
96 bb.2.if.end:
97 successors: %bb.3.return(0x80000000)
98
99 %3, %cpsr = tMOVi8 1, 14, _
100 tSTRspi killed %3, %stack.0.retval, 0, 14, _ :: (store 4 into %ir.retval)
101
102 bb.3.return:
103 %5 = tLDRspi %stack.0.retval, 0, 14, _ :: (dereferenceable load 4 from %ir.retval)
104 %r0 = COPY %5
105 tBX_RET 14, _, implicit %r0
106
107 ...