llvm.org GIT mirror llvm / 559fb26
[PowerPC] Reverting sequence of patches for elimination of comparison instructions In the past while, I've committed a number of patches in the PowerPC back end aimed at eliminating comparison instructions. However, this causes some failures in proprietary source and these issues are not observed in SPEC or any open source packages I've been able to run. As a result, I'm pulling the entire series and will refactor it to: - Have a single entry point for easy control - Have fine-grained control over which patterns we transform A side-effect of this is that test cases for these patches (and modified by them) are XFAIL-ed. This is a temporary measure as it is counter-productive to remove/modify these test cases and then have to modify them again when the refactored patch is recommitted. The failure will be investigated in parallel to the refactoring effort and the recommit will either have a fix for it or will leave this transformation off by default until the problem is resolved. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314244 91177308-0d34-0410-b5e6-96231b3b80d8 Nemanja Ivanovic 2 years ago
89 changed file(s) with 88 addition(s) and 1061 deletion(s). Raw diff Collapse all Expand all
6868
6969 #define DEBUG_TYPE "ppc-codegen"
7070
71 STATISTIC(NumSextSetcc,
72 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
73 STATISTIC(NumZextSetcc,
74 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
75 STATISTIC(SignExtensionsAdded,
76 "Number of sign extensions for compare inputs added.");
77 STATISTIC(ZeroExtensionsAdded,
78 "Number of zero extensions for compare inputs added.");
79 STATISTIC(NumLogicOpsOnComparison,
80 "Number of logical ops on i1 values calculated in GPR.");
81 STATISTIC(OmittedForNonExtendUses,
82 "Number of compares not eliminated as they have non-extending uses.");
83
8471 // FIXME: Remove this once the bug has been fixed!
8572 cl::opt ANDIGlueBug("expose-ppc-andi-glue-bug",
8673 cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden);
275262 #include "PPCGenDAGISel.inc"
276263
277264 private:
278 // Conversion type for interpreting results of a 32-bit instruction as
279 // a 64-bit value or vice versa.
280 enum ExtOrTruncConversion { Ext, Trunc };
281
282 // Modifiers to guide how an ISD::SETCC node's result is to be computed
283 // in a GPR.
284 // ZExtOrig - use the original condition code, zero-extend value
285 // ZExtInvert - invert the condition code, zero-extend value
286 // SExtOrig - use the original condition code, sign-extend value
287 // SExtInvert - invert the condition code, sign-extend value
288 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
289
290 // Comparisons against zero to emit GPR code sequences for. Each of these
291 // sequences may need to be emitted for two or more equivalent patterns.
292 // For example (a >= 0) == (a > -1). The direction of the comparison ()
293 // matters as well as the extension type: sext (-1/0), zext (1/0).
294 // GEZExt - (zext (LHS >= 0))
295 // GESExt - (sext (LHS >= 0))
296 // LEZExt - (zext (LHS <= 0))
297 // LESExt - (sext (LHS <= 0))
298 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
299
300265 bool trySETCC(SDNode *N);
301 bool tryEXTEND(SDNode *N);
302 bool tryLogicOpOfCompares(SDNode *N);
303 SDValue computeLogicOpInGPR(SDValue LogicOp);
304 SDValue signExtendInputIfNeeded(SDValue Input);
305 SDValue zeroExtendInputIfNeeded(SDValue Input);
306 SDValue addExtOrTrunc(SDValue NatWidthRes, ExtOrTruncConversion Conv);
307 SDValue getCompoundZeroComparisonInGPR(SDValue LHS, SDLoc dl,
308 ZeroCompare CmpTy);
309 SDValue get32BitZExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
310 int64_t RHSValue, SDLoc dl);
311 SDValue get32BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
312 int64_t RHSValue, SDLoc dl);
313 SDValue get64BitZExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
314 int64_t RHSValue, SDLoc dl);
315 SDValue get64BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC,
316 int64_t RHSValue, SDLoc dl);
317 SDValue getSETCCInGPR(SDValue Compare, SetccInGPROpts ConvOpts);
318266
319267 void PeepholePPC64();
320268 void PeepholePPC64ZExt();
25282476 return true;
25292477 }
25302478
2531 // Is this opcode a bitwise logical operation?
2532 static bool isLogicOp(unsigned Opc) {
2533 return Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR;
2534 }
2535
2536 /// If this node is a sign/zero extension of an integer comparison,
2537 /// it can usually be computed in GPR's rather than using comparison
2538 /// instructions and ISEL. We only do this on 64-bit targets for now
2539 /// as the code is specialized for 64-bit (it uses 64-bit instructions
2540 /// and assumes 64-bit registers).
2541 bool PPCDAGToDAGISel::tryEXTEND(SDNode *N) {
2542 if (TM.getOptLevel() == CodeGenOpt::None || !TM.isPPC64())
2543 return false;
2544 assert((N->getOpcode() == ISD::ZERO_EXTEND ||
2545 N->getOpcode() == ISD::SIGN_EXTEND) &&
2546 "Expecting a zero/sign extend node!");
2547
2548 SDValue WideRes;
2549 // If we are zero-extending the result of a logical operation on i1
2550 // values, we can keep the values in GPRs.
2551 if (isLogicOp(N->getOperand(0).getOpcode()) &&
2552 N->getOperand(0).getValueType() == MVT::i1 &&
2553 N->getOpcode() == ISD::ZERO_EXTEND)
2554 WideRes = computeLogicOpInGPR(N->getOperand(0));
2555 else if (N->getOperand(0).getOpcode() != ISD::SETCC)
2556 return false;
2557 else
2558 WideRes =
2559 getSETCCInGPR(N->getOperand(0),
2560 N->getOpcode() == ISD::SIGN_EXTEND ?
2561 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2562
2563 if (!WideRes)
2564 return false;
2565
2566 SDLoc dl(N);
2567 bool Input32Bit = WideRes.getValueType() == MVT::i32;
2568 bool Output32Bit = N->getValueType(0) == MVT::i32;
2569
2570 NumSextSetcc += N->getOpcode() == ISD::SIGN_EXTEND ? 1 : 0;
2571 NumZextSetcc += N->getOpcode() == ISD::SIGN_EXTEND ? 0 : 1;
2572
2573 SDValue ConvOp = WideRes;
2574 if (Input32Bit != Output32Bit)
2575 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2576 ExtOrTruncConversion::Trunc);
2577 ReplaceNode(N, ConvOp.getNode());
2578
2579 return true;
2580 }
2581
2582 // Lower a logical operation on i1 values into a GPR sequence if possible.
2583 // The result can be kept in a GPR if requested.
2584 // Three types of inputs can be handled:
2585 // - SETCC
2586 // - TRUNCATE
2587 // - Logical operation (AND/OR/XOR)
2588 // There is also a special case that is handled (namely a complement operation
2589 // achieved with xor %a, -1).
2590 SDValue PPCDAGToDAGISel::computeLogicOpInGPR(SDValue LogicOp) {
2591 assert(isLogicOp(LogicOp.getOpcode()) &&
2592 "Can only handle logic operations here.");
2593 assert(LogicOp.getValueType() == MVT::i1 &&
2594 "Can only handle logic operations on i1 values here.");
2595 SDLoc dl(LogicOp);
2596 SDValue LHS, RHS;
2597
2598 // Special case: xor %a, -1
2599 bool IsBitwiseNegation = isBitwiseNot(LogicOp);
2600
2601 // Produces a GPR sequence for each operand of the binary logic operation.
2602 // For SETCC, it produces the respective comparison, for TRUNCATE it truncates
2603 // the value in a GPR and for logic operations, it will recursively produce
2604 // a GPR sequence for the operation.
2605 auto getLogicOperand = [&] (SDValue Operand) -> SDValue {
2606 unsigned OperandOpcode = Operand.getOpcode();
2607 if (OperandOpcode == ISD::SETCC)
2608 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
2609 else if (OperandOpcode == ISD::TRUNCATE) {
2610 SDValue InputOp = Operand.getOperand(0);
2611 EVT InVT = InputOp.getValueType();
2612 return
2613 SDValue(CurDAG->getMachineNode(InVT == MVT::i32 ? PPC::RLDICL_32 :
2614 PPC::RLDICL, dl, InVT, InputOp,
2615 getI64Imm(0, dl), getI64Imm(63, dl)), 0);
2616 } else if (isLogicOp(OperandOpcode))
2617 return computeLogicOpInGPR(Operand);
2618 return SDValue();
2619 };
2620 LHS = getLogicOperand(LogicOp.getOperand(0));
2621 RHS = getLogicOperand(LogicOp.getOperand(1));
2622
2623 // If a GPR sequence can't be produced for the LHS we can't proceed.
2624 // Not producing a GPR sequence for the RHS is only a problem if this isn't
2625 // a bitwise negation operation.
2626 if (!LHS || (!RHS && !IsBitwiseNegation))
2627 return SDValue();
2628
2629 NumLogicOpsOnComparison++;
2630
2631 // We will use the inputs as 64-bit values.
2632 if (LHS.getValueType() == MVT::i32)
2633 LHS = addExtOrTrunc(LHS, ExtOrTruncConversion::Ext);
2634 if (!IsBitwiseNegation && RHS.getValueType() == MVT::i32)
2635 RHS = addExtOrTrunc(RHS, ExtOrTruncConversion::Ext);
2636
2637 unsigned NewOpc;
2638 switch (LogicOp.getOpcode()) {
2639 default: llvm_unreachable("Unknown logic operation.");
2640 case ISD::AND: NewOpc = PPC::AND8; break;
2641 case ISD::OR: NewOpc = PPC::OR8; break;
2642 case ISD::XOR: NewOpc = PPC::XOR8; break;
2643 }
2644
2645 if (IsBitwiseNegation) {
2646 RHS = getI64Imm(1, dl);
2647 NewOpc = PPC::XORI8;
2648 }
2649
2650 return SDValue(CurDAG->getMachineNode(NewOpc, dl, MVT::i64, LHS, RHS), 0);
2651
2652 }
2653
2654 /// Try performing logical operations on results of comparisons in GPRs.
2655 /// It is typically preferred from a performance perspective over performing
2656 /// the operations on individual bits in the CR. We only do this on 64-bit
2657 /// targets for now as the code is specialized for 64-bit (it uses 64-bit
2658 /// instructions and assumes 64-bit registers).
2659 bool PPCDAGToDAGISel::tryLogicOpOfCompares(SDNode *N) {
2660 if (TM.getOptLevel() == CodeGenOpt::None || !TM.isPPC64())
2661 return false;
2662 if (N->getValueType(0) != MVT::i1)
2663 return false;
2664 assert(isLogicOp(N->getOpcode()) &&
2665 "Expected a logic operation on setcc results.");
2666 SDValue LoweredLogical = computeLogicOpInGPR(SDValue(N, 0));
2667 if (!LoweredLogical)
2668 return false;
2669
2670 SDLoc dl(N);
2671 bool IsBitwiseNegate = LoweredLogical.getMachineOpcode() == PPC::XORI8;
2672 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
2673 SDValue CR0Reg = CurDAG->getRegister(PPC::CR0, MVT::i32);
2674 SDValue LHS = LoweredLogical.getOperand(0);
2675 SDValue RHS = LoweredLogical.getOperand(1);
2676 SDValue WideOp;
2677 SDValue OpToConvToRecForm;
2678
2679 // Look through any 32-bit to 64-bit implicit extend nodes to find the opcode
2680 // that is input to the XORI.
2681 if (IsBitwiseNegate &&
2682 LoweredLogical.getOperand(0).getMachineOpcode() == PPC::INSERT_SUBREG)
2683 OpToConvToRecForm = LoweredLogical.getOperand(0).getOperand(1);
2684 else if (IsBitwiseNegate)
2685 // If the input to the XORI isn't an extension, that's what we're after.
2686 OpToConvToRecForm = LoweredLogical.getOperand(0);
2687 else
2688 // If this is not an XORI, it is a reg-reg logical op and we can convert it
2689 // to record-form.
2690 OpToConvToRecForm = LoweredLogical;
2691
2692 // Get the record-form version of the node we're looking to use to get the
2693 // CR result from.
2694 uint16_t NonRecOpc = OpToConvToRecForm.getMachineOpcode();
2695 int NewOpc = PPCInstrInfo::getRecordFormOpcode(NonRecOpc);
2696
2697 // Convert the right node to record-form. This is either the logical we're
2698 // looking at or it is the input node to the negation (if we're looking at
2699 // a bitwise negation).
2700 if (NewOpc != -1 && IsBitwiseNegate) {
2701 // The input to the XORI has a record-form. Use it.
2702 assert(LoweredLogical.getConstantOperandVal(1) == 1 &&
2703 "Expected a PPC::XORI8 only for bitwise negation.");
2704 // Emit the record-form instruction.
2705 std::vector Ops;
2706 for (int i = 0, e = OpToConvToRecForm.getNumOperands(); i < e; i++)
2707 Ops.push_back(OpToConvToRecForm.getOperand(i));
2708
2709 WideOp =
2710 SDValue(CurDAG->getMachineNode(NewOpc, dl,
2711 OpToConvToRecForm.getValueType(),
2712 MVT::Glue, Ops), 0);
2713 } else {
2714 assert((NewOpc != -1 || !IsBitwiseNegate) &&
2715 "No record form available for AND8/OR8/XOR8?");
2716 WideOp =
2717 SDValue(CurDAG->getMachineNode(NewOpc == -1 ? PPC::ANDIo8 : NewOpc, dl,
2718 MVT::i64, MVT::Glue, LHS, RHS), 0);
2719 }
2720
2721 // Select this node to a single bit from CR0 set by the record-form node
2722 // just created. For bitwise negation, use the EQ bit which is the equivalent
2723 // of negating the result (i.e. it is a bit set when the result of the
2724 // operation is zero).
2725 SDValue SRIdxVal =
2726 CurDAG->getTargetConstant(SubRegToExtract, dl, MVT::i32);
2727 SDValue CRBit =
2728 SDValue(CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl,
2729 MVT::i1, CR0Reg, SRIdxVal,
2730 WideOp.getValue(1)), 0);
2731 ReplaceNode(N, CRBit.getNode());
2732 return true;
2733 }
2734
2735 /// If the value isn't guaranteed to be sign-extended to 64-bits, extend it.
2736 /// Otherwise just reinterpret it as a 64-bit value.
2737 /// Useful when emitting comparison code for 32-bit values without using
2738 /// the compare instruction (which only considers the lower 32-bits).
2739 SDValue PPCDAGToDAGISel::signExtendInputIfNeeded(SDValue Input) {
2740 assert(Input.getValueType() == MVT::i32 &&
2741 "Can only sign-extend 32-bit values here.");
2742 unsigned Opc = Input.getOpcode();
2743
2744 // The value was sign extended and then truncated to 32-bits. No need to
2745 // sign extend it again.
2746 if (Opc == ISD::TRUNCATE &&
2747 (Input.getOperand(0).getOpcode() == ISD::AssertSext ||
2748 Input.getOperand(0).getOpcode() == ISD::SIGN_EXTEND))
2749 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
2750
2751 LoadSDNode *InputLoad = dyn_cast(Input);
2752 // The input is a sign-extending load. No reason to sign-extend.
2753 if (InputLoad && InputLoad->getExtensionType() == ISD::SEXTLOAD)
2754 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
2755
2756 ConstantSDNode *InputConst = dyn_cast(Input);
2757 // We don't sign-extend constants and already sign-extended values.
2758 if (InputConst || Opc == ISD::AssertSext || Opc == ISD::SIGN_EXTEND_INREG ||
2759 Opc == ISD::SIGN_EXTEND)
2760 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
2761
2762 SDLoc dl(Input);
2763 SignExtensionsAdded++;
2764 return SDValue(CurDAG->getMachineNode(PPC::EXTSW_32_64, dl,
2765 MVT::i64, Input), 0);
2766 }
2767
2768 /// If the value isn't guaranteed to be zero-extended to 64-bits, extend it.
2769 /// Otherwise just reinterpret it as a 64-bit value.
2770 /// Useful when emitting comparison code for 32-bit values without using
2771 /// the compare instruction (which only considers the lower 32-bits).
2772 SDValue PPCDAGToDAGISel::zeroExtendInputIfNeeded(SDValue Input) {
2773 assert(Input.getValueType() == MVT::i32 &&
2774 "Can only zero-extend 32-bit values here.");
2775 unsigned Opc = Input.getOpcode();
2776
2777 // The only condition under which we can omit the actual extend instruction:
2778 // - The value has already been zero-extended
2779 // - The value is a positive constant
2780 // - The value comes from a load that isn't a sign-extending load
2781 // An ISD::TRUNCATE needs to be zero-extended unless it is fed by a zext.
2782 bool IsTruncateOfZExt = Opc == ISD::TRUNCATE &&
2783 (Input.getOperand(0).getOpcode() == ISD::AssertZext ||
2784 Input.getOperand(0).getOpcode() == ISD::ZERO_EXTEND);
2785 if (Opc == ISD::AssertZext || Opc == ISD::ZERO_EXTEND || IsTruncateOfZExt)
2786 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
2787
2788 ConstantSDNode *InputConst = dyn_cast(Input);
2789 if (InputConst && InputConst->getSExtValue() >= 0)
2790 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
2791
2792 LoadSDNode *InputLoad = dyn_cast(Input);
2793 // The input is a load that doesn't sign-extend (it will be zero-extended).
2794 if (InputLoad && InputLoad->getExtensionType() != ISD::SEXTLOAD)
2795 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
2796
2797 // None of the above, need to zero-extend.
2798 SDLoc dl(Input);
2799 ZeroExtensionsAdded++;
2800 return SDValue(CurDAG->getMachineNode(PPC::RLDICL_32_64, dl, MVT::i64, Input,
2801 getI64Imm(0, dl), getI64Imm(32, dl)),
2802 0);
2803 }
2804
2805 // Handle a 32-bit value in a 64-bit register and vice-versa. These are of
2806 // course not actual zero/sign extensions that will generate machine code,
2807 // they're just a way to reinterpret a 32 bit value in a register as a
2808 // 64 bit value and vice-versa.
2809 SDValue PPCDAGToDAGISel::addExtOrTrunc(SDValue NatWidthRes,
2810 ExtOrTruncConversion Conv) {
2811 SDLoc dl(NatWidthRes);
2812
2813 // For reinterpreting 32-bit values as 64 bit values, we generate
2814 // INSERT_SUBREG IMPLICIT_DEF:i64, , TargetConstant:i32<1>
2815 if (Conv == ExtOrTruncConversion::Ext) {
2816 SDValue ImDef(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl, MVT::i64), 0);
2817 SDValue SubRegIdx =
2818 CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2819 return SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl, MVT::i64,
2820 ImDef, NatWidthRes, SubRegIdx), 0);
2821 }
2822
2823 assert(Conv == ExtOrTruncConversion::Trunc &&
2824 "Unknown convertion between 32 and 64 bit values.");
2825 // For reinterpreting 64-bit values as 32-bit values, we just need to
2826 // EXTRACT_SUBREG (i.e. extract the low word).
2827 SDValue SubRegIdx =
2828 CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2829 return SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl, MVT::i32,
2830 NatWidthRes, SubRegIdx), 0);
2831 }
2832
2833 // Produce a GPR sequence for compound comparisons (<=, >=) against zero.
2834 // Handle both zero-extensions and sign-extensions.
2835 SDValue PPCDAGToDAGISel::getCompoundZeroComparisonInGPR(SDValue LHS, SDLoc dl,
2836 ZeroCompare CmpTy) {
2837 EVT InVT = LHS.getValueType();
2838 bool Is32Bit = InVT == MVT::i32;
2839 SDValue ToExtend;
2840
2841 // Produce the value that needs to be either zero or sign extended.
2842 switch (CmpTy) {
2843 case ZeroCompare::GEZExt:
2844 case ZeroCompare::GESExt:
2845 ToExtend = SDValue(CurDAG->getMachineNode(Is32Bit ? PPC::NOR : PPC::NOR8,
2846 dl, InVT, LHS, LHS), 0);
2847 break;
2848 case ZeroCompare::LEZExt:
2849 case ZeroCompare::LESExt: {
2850 if (Is32Bit) {
2851 // Upper 32 bits cannot be undefined for this sequence.
2852 LHS = signExtendInputIfNeeded(LHS);
2853 SDValue Neg =
2854 SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0);
2855 ToExtend =
2856 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
2857 Neg, getI64Imm(1, dl),
2858 getI64Imm(63, dl)), 0);
2859 } else {
2860 SDValue Addi =
2861 SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS,
2862 getI64Imm(~0ULL, dl)), 0);
2863 ToExtend = SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2864 Addi, LHS), 0);
2865 }
2866 break;
2867 }
2868 }
2869
2870 // For 64-bit sequences, the extensions are the same for the GE/LE cases.
2871 if (!Is32Bit &&
2872 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
2873 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
2874 ToExtend, getI64Imm(1, dl),
2875 getI64Imm(63, dl)), 0);
2876 if (!Is32Bit &&
2877 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
2878 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, ToExtend,
2879 getI64Imm(63, dl)), 0);
2880
2881 assert(Is32Bit && "Should have handled the 32-bit sequences above.");
2882 // For 32-bit sequences, the extensions differ between GE/LE cases.
2883 switch (CmpTy) {
2884 case ZeroCompare::GEZExt: {
2885 SDValue ShiftOps[] =
2886 { ToExtend, getI32Imm(1, dl), getI32Imm(31, dl), getI32Imm(31, dl) };
2887 return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2888 ShiftOps), 0);
2889 }
2890 case ZeroCompare::GESExt:
2891 return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, ToExtend,
2892 getI32Imm(31, dl)), 0);
2893 case ZeroCompare::LEZExt:
2894 return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, ToExtend,
2895 getI32Imm(1, dl)), 0);
2896 case ZeroCompare::LESExt:
2897 return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, ToExtend,
2898 getI32Imm(-1, dl)), 0);
2899 }
2900
2901 // The above case covers all the enumerators so it can't have a default clause
2902 // to avoid compiler warnings.
2903 llvm_unreachable("Unknown zero-comparison type.");
2904 }
2905
2906 /// Produces a zero-extended result of comparing two 32-bit values according to
2907 /// the passed condition code.
2908 SDValue PPCDAGToDAGISel::get32BitZExtCompare(SDValue LHS, SDValue RHS,
2909 ISD::CondCode CC,
2910 int64_t RHSValue, SDLoc dl) {
2911 bool IsRHSZero = RHSValue == 0;
2912 bool IsRHSOne = RHSValue == 1;
2913 bool IsRHSNegOne = RHSValue == -1LL;
2914 switch (CC) {
2915 default: return SDValue();
2916 case ISD::SETEQ: {
2917 // (zext (setcc %a, %b, seteq)) -> (lshr (cntlzw (xor %a, %b)), 5)
2918 // (zext (setcc %a, 0, seteq)) -> (lshr (cntlzw %a), 5)
2919 SDValue Xor = IsRHSZero ? LHS :
2920 SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0);
2921 SDValue Clz =
2922 SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Xor), 0);
2923 SDValue ShiftOps[] = { Clz, getI32Imm(27, dl), getI32Imm(5, dl),
2924 getI32Imm(31, dl) };
2925 return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2926 ShiftOps), 0);
2927 }
2928 case ISD::SETNE: {
2929 // (zext (setcc %a, %b, setne)) -> (xor (lshr (cntlzw (xor %a, %b)), 5), 1)
2930 // (zext (setcc %a, 0, setne)) -> (xor (lshr (cntlzw %a), 5), 1)
2931 SDValue Xor = IsRHSZero ? LHS :
2932 SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0);
2933 SDValue Clz =
2934 SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Xor), 0);
2935 SDValue ShiftOps[] = { Clz, getI32Imm(27, dl), getI32Imm(5, dl),
2936 getI32Imm(31, dl) };
2937 SDValue Shift =
2938 SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, ShiftOps), 0);
2939 return SDValue(CurDAG->getMachineNode(PPC::XORI, dl, MVT::i32, Shift,
2940 getI32Imm(1, dl)), 0);
2941 }
2942 case ISD::SETGE: {
2943 // (zext (setcc %a, %b, setge)) -> (xor (lshr (sub %a, %b), 63), 1)
2944 // (zext (setcc %a, 0, setge)) -> (lshr (~ %a), 31)
2945 if(IsRHSZero)
2946 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
2947
2948 // Not a special case (i.e. RHS == 0). Handle (%a >= %b) as (%b <= %a)
2949 // by swapping inputs and falling through.
2950 std::swap(LHS, RHS);
2951 ConstantSDNode *RHSConst = dyn_cast(RHS);
2952 IsRHSZero = RHSConst && RHSConst->isNullValue();
2953 LLVM_FALLTHROUGH;
2954 }
2955 case ISD::SETLE: {
2956 // (zext (setcc %a, %b, setle)) -> (xor (lshr (sub %b, %a), 63), 1)
2957 // (zext (setcc %a, 0, setle)) -> (xor (lshr (- %a), 63), 1)
2958 if(IsRHSZero)
2959 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
2960
2961 // The upper 32-bits of the register can't be undefined for this sequence.
2962 LHS = signExtendInputIfNeeded(LHS);
2963 RHS = signExtendInputIfNeeded(RHS);
2964 SDValue Sub =
2965 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, LHS, RHS), 0);
2966 SDValue Shift =
2967 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Sub,
2968 getI64Imm(1, dl), getI64Imm(63, dl)), 0);
2969 return
2970 SDValue(CurDAG->getMachineNode(PPC::XORI8, dl,
2971 MVT::i64, Shift, getI32Imm(1, dl)), 0);
2972 }
2973 case ISD::SETGT: {
2974 // (zext (setcc %a, %b, setgt)) -> (lshr (sub %b, %a), 63)
2975 // (zext (setcc %a, -1, setgt)) -> (lshr (~ %a), 31)
2976 // (zext (setcc %a, 0, setgt)) -> (lshr (- %a), 63)
2977 // Handle SETLT -1 (which is equivalent to SETGE 0).
2978 if (IsRHSNegOne)
2979 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
2980
2981 if (IsRHSZero) {
2982 // The upper 32-bits of the register can't be undefined for this sequence.
2983 LHS = signExtendInputIfNeeded(LHS);
2984 RHS = signExtendInputIfNeeded(RHS);
2985 SDValue Neg =
2986 SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0);
2987 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
2988 Neg, getI32Imm(1, dl), getI32Imm(63, dl)), 0);
2989 }
2990 // Not a special case (i.e. RHS == 0 or RHS == -1). Handle (%a > %b) as
2991 // (%b < %a) by swapping inputs and falling through.
2992 std::swap(LHS, RHS);
2993 ConstantSDNode *RHSConst = dyn_cast(RHS);
2994 IsRHSZero = RHSConst && RHSConst->isNullValue();
2995 IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1;
2996 LLVM_FALLTHROUGH;
2997 }
2998 case ISD::SETLT: {
2999 // (zext (setcc %a, %b, setlt)) -> (lshr (sub %a, %b), 63)
3000 // (zext (setcc %a, 1, setlt)) -> (xor (lshr (- %a), 63), 1)
3001 // (zext (setcc %a, 0, setlt)) -> (lshr %a, 31)
3002 // Handle SETLT 1 (which is equivalent to SETLE 0).
3003 if (IsRHSOne)
3004 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3005
3006 if (IsRHSZero) {
3007 SDValue ShiftOps[] = { LHS, getI32Imm(1, dl), getI32Imm(31, dl),
3008 getI32Imm(31, dl) };
3009 return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
3010 ShiftOps), 0);
3011 }
3012
3013 // The upper 32-bits of the register can't be undefined for this sequence.
3014 LHS = signExtendInputIfNeeded(LHS);
3015 RHS = signExtendInputIfNeeded(RHS);
3016 SDValue SUBFNode =
3017 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0);
3018 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
3019 SUBFNode, getI64Imm(1, dl),
3020 getI64Imm(63, dl)), 0);
3021 }
3022 case ISD::SETUGE:
3023 // (zext (setcc %a, %b, setuge)) -> (xor (lshr (sub %b, %a), 63), 1)
3024 // (zext (setcc %a, %b, setule)) -> (xor (lshr (sub %a, %b), 63), 1)
3025 std::swap(LHS, RHS);
3026 LLVM_FALLTHROUGH;
3027 case ISD::SETULE: {
3028 // The upper 32-bits of the register can't be undefined for this sequence.
3029 LHS = zeroExtendInputIfNeeded(LHS);
3030 RHS = zeroExtendInputIfNeeded(RHS);
3031 SDValue Subtract =
3032 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, LHS, RHS), 0);
3033 SDValue SrdiNode =
3034 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
3035 Subtract, getI64Imm(1, dl),
3036 getI64Imm(63, dl)), 0);
3037 return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, SrdiNode,
3038 getI32Imm(1, dl)), 0);
3039 }
3040 case ISD::SETUGT:
3041 // (zext (setcc %a, %b, setugt)) -> (lshr (sub %b, %a), 63)
3042 // (zext (setcc %a, %b, setult)) -> (lshr (sub %a, %b), 63)
3043 std::swap(LHS, RHS);
3044 LLVM_FALLTHROUGH;
3045 case ISD::SETULT: {
3046 // The upper 32-bits of the register can't be undefined for this sequence.
3047 LHS = zeroExtendInputIfNeeded(LHS);
3048 RHS = zeroExtendInputIfNeeded(RHS);
3049 SDValue Subtract =
3050 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0);
3051 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
3052 Subtract, getI64Imm(1, dl),
3053 getI64Imm(63, dl)), 0);
3054 }
3055 }
3056 }
3057
3058 /// Produces a sign-extended result of comparing two 32-bit values according to
3059 /// the passed condition code.
3060 SDValue PPCDAGToDAGISel::get32BitSExtCompare(SDValue LHS, SDValue RHS,
3061 ISD::CondCode CC,
3062 int64_t RHSValue, SDLoc dl) {
3063 bool IsRHSZero = RHSValue == 0;
3064 bool IsRHSOne = RHSValue == 1;
3065 bool IsRHSNegOne = RHSValue == -1LL;
3066
3067 switch (CC) {
3068 default: return SDValue();
3069 case ISD::SETEQ: {
3070 // (sext (setcc %a, %b, seteq)) ->
3071 // (ashr (shl (ctlz (xor %a, %b)), 58), 63)
3072 // (sext (setcc %a, 0, seteq)) ->
3073 // (ashr (shl (ctlz %a), 58), 63)
3074 SDValue CountInput = IsRHSZero ? LHS :
3075 SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0);
3076 SDValue Cntlzw =
3077 SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, CountInput), 0);
3078 SDValue SHLOps[] = { Cntlzw, getI32Imm(27, dl),
3079 getI32Imm(5, dl), getI32Imm(31, dl) };
3080 SDValue Slwi =
3081 SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, SHLOps), 0);
3082 return SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, Slwi), 0);
3083 }
3084 case ISD::SETNE: {
3085 // Bitwise xor the operands, count leading zeros, shift right by 5 bits and
3086 // flip the bit, finally take 2's complement.
3087 // (sext (setcc %a, %b, setne)) ->
3088 // (neg (xor (lshr (ctlz (xor %a, %b)), 5), 1))
3089 // Same as above, but the first xor is not needed.
3090 // (sext (setcc %a, 0, setne)) ->
3091 // (neg (xor (lshr (ctlz %a), 5), 1))
3092 SDValue Xor = IsRHSZero ? LHS :
3093 SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0);
3094 SDValue Clz =
3095 SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Xor), 0);
3096 SDValue ShiftOps[] =
3097 { Clz, getI32Imm(27, dl), getI32Imm(5, dl), getI32Imm(31, dl) };
3098 SDValue Shift =
3099 SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, ShiftOps), 0);
3100 SDValue Xori =
3101 SDValue(CurDAG->getMachineNode(PPC::XORI, dl, MVT::i32, Shift,
3102 getI32Imm(1, dl)), 0);
3103 return SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, Xori), 0);
3104 }
3105 case ISD::SETGE: {
3106 // (sext (setcc %a, %b, setge)) -> (add (lshr (sub %a, %b), 63), -1)
3107 // (sext (setcc %a, 0, setge)) -> (ashr (~ %a), 31)
3108 if (IsRHSZero)
3109 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3110
3111 // Not a special case (i.e. RHS == 0). Handle (%a >= %b) as (%b <= %a)
3112 // by swapping inputs and falling through.
3113 std::swap(LHS, RHS);
3114 ConstantSDNode *RHSConst = dyn_cast(RHS);
3115 IsRHSZero = RHSConst && RHSConst->isNullValue();
3116 LLVM_FALLTHROUGH;
3117 }
3118 case ISD::SETLE: {
3119 // (sext (setcc %a, %b, setge)) -> (add (lshr (sub %b, %a), 63), -1)
3120 // (sext (setcc %a, 0, setle)) -> (add (lshr (- %a), 63), -1)
3121 if (IsRHSZero)
3122 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3123
3124 // The upper 32-bits of the register can't be undefined for this sequence.
3125 LHS = signExtendInputIfNeeded(LHS);
3126 RHS = signExtendInputIfNeeded(RHS);
3127 SDValue SUBFNode =
3128 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, MVT::Glue,
3129 LHS, RHS), 0);
3130 SDValue Srdi =
3131 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
3132 SUBFNode, getI64Imm(1, dl),
3133 getI64Imm(63, dl)), 0);
3134 return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, Srdi,
3135 getI32Imm(-1, dl)), 0);
3136 }
3137 case ISD::SETGT: {
3138 // (sext (setcc %a, %b, setgt)) -> (ashr (sub %b, %a), 63)
3139 // (sext (setcc %a, -1, setgt)) -> (ashr (~ %a), 31)
3140 // (sext (setcc %a, 0, setgt)) -> (ashr (- %a), 63)
3141 if (IsRHSNegOne)
3142 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3143 if (IsRHSZero) {
3144 // The upper 32-bits of the register can't be undefined for this sequence.
3145 LHS = signExtendInputIfNeeded(LHS);
3146 RHS = signExtendInputIfNeeded(RHS);
3147 SDValue Neg =
3148 SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0);
3149 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Neg,
3150 getI64Imm(63, dl)), 0);
3151 }
3152 // Not a special case (i.e. RHS == 0 or RHS == -1). Handle (%a > %b) as
3153 // (%b < %a) by swapping inputs and falling through.
3154 std::swap(LHS, RHS);
3155 ConstantSDNode *RHSConst = dyn_cast(RHS);
3156 IsRHSZero = RHSConst && RHSConst->isNullValue();
3157 IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1;
3158 LLVM_FALLTHROUGH;
3159 }
3160 case ISD::SETLT: {
3161 // (sext (setcc %a, %b, setgt)) -> (ashr (sub %a, %b), 63)
3162 // (sext (setcc %a, 1, setgt)) -> (add (lshr (- %a), 63), -1)
3163 // (sext (setcc %a, 0, setgt)) -> (ashr %a, 31)
3164 if (IsRHSOne)
3165 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3166 if (IsRHSZero)
3167 return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, LHS,
3168 getI32Imm(31, dl)), 0);
3169
3170 // The upper 32-bits of the register can't be undefined for this sequence.
3171 LHS = signExtendInputIfNeeded(LHS);
3172 RHS = signExtendInputIfNeeded(RHS);
3173 SDValue SUBFNode =
3174 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0);
3175 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64,
3176 SUBFNode, getI64Imm(63, dl)), 0);
3177 }
3178 case ISD::SETUGE:
3179 // (sext (setcc %a, %b, setuge)) -> (add (lshr (sub %a, %b), 63), -1)
3180 // (sext (setcc %a, %b, setule)) -> (add (lshr (sub %b, %a), 63), -1)
3181 std::swap(LHS, RHS);
3182 LLVM_FALLTHROUGH;
3183 case ISD::SETULE: {
3184 // The upper 32-bits of the register can't be undefined for this sequence.
3185 LHS = zeroExtendInputIfNeeded(LHS);
3186 RHS = zeroExtendInputIfNeeded(RHS);
3187 SDValue Subtract =
3188 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, LHS, RHS), 0);
3189 SDValue Shift =
3190 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Subtract,
3191 getI32Imm(1, dl), getI32Imm(63,dl)), 0);
3192 return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, Shift,
3193 getI32Imm(-1, dl)), 0);
3194 }
3195 case ISD::SETUGT:
3196 // (sext (setcc %a, %b, setugt)) -> (ashr (sub %b, %a), 63)
3197 // (sext (setcc %a, %b, setugt)) -> (ashr (sub %a, %b), 63)
3198 std::swap(LHS, RHS);
3199 LLVM_FALLTHROUGH;
3200 case ISD::SETULT: {
3201 // The upper 32-bits of the register can't be undefined for this sequence.
3202 LHS = zeroExtendInputIfNeeded(LHS);
3203 RHS = zeroExtendInputIfNeeded(RHS);
3204 SDValue Subtract =
3205 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0);
3206 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64,
3207 Subtract, getI64Imm(63, dl)), 0);
3208 }
3209 }
3210 }
3211
3212 /// Produces a zero-extended result of comparing two 64-bit values according to
3213 /// the passed condition code.
3214 SDValue PPCDAGToDAGISel::get64BitZExtCompare(SDValue LHS, SDValue RHS,
3215 ISD::CondCode CC,
3216 int64_t RHSValue, SDLoc dl) {
3217 bool IsRHSZero = RHSValue == 0;
3218 bool IsRHSOne = RHSValue == 1;
3219 bool IsRHSNegOne = RHSValue == -1LL;
3220 switch (CC) {
3221 default: return SDValue();
3222 case ISD::SETEQ: {
3223 // (zext (setcc %a, %b, seteq)) -> (lshr (ctlz (xor %a, %b)), 6)
3224 // (zext (setcc %a, 0, seteq)) -> (lshr (ctlz %a), 6)
3225 SDValue Xor = IsRHSZero ? LHS :
3226 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0);
3227 SDValue Clz =
3228 SDValue(CurDAG->getMachineNode(PPC::CNTLZD, dl, MVT::i64, Xor), 0);
3229 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Clz,
3230 getI64Imm(58, dl), getI64Imm(63, dl)),
3231 0);
3232 }
3233 case ISD::SETNE: {
3234 // {addc.reg, addc.CA} = (addcarry (xor %a, %b), -1)
3235 // (zext (setcc %a, %b, setne)) -> (sube addc.reg, addc.reg, addc.CA)
3236 // {addcz.reg, addcz.CA} = (addcarry %a, -1)
3237 // (zext (setcc %a, 0, setne)) -> (sube addcz.reg, addcz.reg, addcz.CA)
3238 SDValue Xor = IsRHSZero ? LHS :
3239 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0);
3240 SDValue AC =
3241 SDValue(CurDAG->getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue,
3242 Xor, getI32Imm(~0U, dl)), 0);
3243 return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, AC,
3244 Xor, AC.getValue(1)), 0);
3245 }
3246 case ISD::SETGE: {
3247 // {subc.reg, subc.CA} = (subcarry %a, %b)
3248 // (zext (setcc %a, %b, setge)) ->
3249 // (adde (lshr %b, 63), (ashr %a, 63), subc.CA)
3250 // (zext (setcc %a, 0, setge)) -> (lshr (~ %a), 63)
3251 if (IsRHSZero)
3252 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3253 std::swap(LHS, RHS);
3254 ConstantSDNode *RHSConst = dyn_cast(RHS);
3255 IsRHSZero = RHSConst && RHSConst->isNullValue();
3256 LLVM_FALLTHROUGH;
3257 }
3258 case ISD::SETLE: {
3259 // {subc.reg, subc.CA} = (subcarry %b, %a)
3260 // (zext (setcc %a, %b, setge)) ->
3261 // (adde (lshr %a, 63), (ashr %b, 63), subc.CA)
3262 // (zext (setcc %a, 0, setge)) -> (lshr (or %a, (add %a, -1)), 63)
3263 if (IsRHSZero)
3264 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3265 SDValue ShiftL =
3266 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, LHS,
3267 getI64Imm(1, dl), getI64Imm(63, dl)), 0);
3268 SDValue ShiftR =
3269 SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, RHS,
3270 getI64Imm(63, dl)), 0);
3271 SDValue SubtractCarry =
3272 SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3273 LHS, RHS), 1);
3274 return SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue,
3275 ShiftR, ShiftL, SubtractCarry), 0);
3276 }
3277 case ISD::SETGT: {
3278 // {subc.reg, subc.CA} = (subcarry %b, %a)
3279 // (zext (setcc %a, %b, setgt)) ->
3280 // (xor (adde (lshr %a, 63), (ashr %b, 63), subc.CA), 1)
3281 // (zext (setcc %a, 0, setgt)) -> (lshr (nor (add %a, -1), %a), 63)
3282 if (IsRHSNegOne)
3283 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3284 if (IsRHSZero) {
3285 SDValue Addi =
3286 SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS,
3287 getI64Imm(~0ULL, dl)), 0);
3288 SDValue Nor =
3289 SDValue(CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, Addi, LHS), 0);
3290 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Nor,
3291 getI64Imm(1, dl),
3292 getI64Imm(63, dl)), 0);
3293 }
3294 std::swap(LHS, RHS);
3295 ConstantSDNode *RHSConst = dyn_cast(RHS);
3296 IsRHSZero = RHSConst && RHSConst->isNullValue();
3297 IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1;
3298 LLVM_FALLTHROUGH;
3299 }
3300 case ISD::SETLT: {
3301 // {subc.reg, subc.CA} = (subcarry %a, %b)
3302 // (zext (setcc %a, %b, setlt)) ->
3303 // (xor (adde (lshr %b, 63), (ashr %a, 63), subc.CA), 1)
3304 // (zext (setcc %a, 0, setlt)) -> (lshr %a, 63)
3305 if (IsRHSOne)
3306 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3307 if (IsRHSZero)
3308 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, LHS,
3309 getI64Imm(1, dl),
3310 getI64Imm(63, dl)), 0);
3311 SDValue SRADINode =
3312 SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64,
3313 LHS, getI64Imm(63, dl)), 0);
3314 SDValue SRDINode =
3315 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
3316 RHS, getI64Imm(1, dl),
3317 getI64Imm(63, dl)), 0);
3318 SDValue SUBFC8Carry =
3319 SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3320 RHS, LHS), 1);
3321 SDValue ADDE8Node =
3322 SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue,
3323 SRDINode, SRADINode, SUBFC8Carry), 0);
3324 return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64,
3325 ADDE8Node, getI64Imm(1, dl)), 0);
3326 }
3327 }
3328 }
3329
3330 /// Produces a sign-extended result of comparing two 64-bit values according to
3331 /// the passed condition code.
3332 SDValue PPCDAGToDAGISel::get64BitSExtCompare(SDValue LHS, SDValue RHS,
3333 ISD::CondCode CC,
3334 int64_t RHSValue, SDLoc dl) {
3335 bool IsRHSZero = RHSValue == 0;
3336 bool IsRHSOne = RHSValue == 1;
3337 bool IsRHSNegOne = RHSValue == -1LL;
3338 switch (CC) {
3339 default: return SDValue();
3340 case ISD::SETEQ: {
3341 // {addc.reg, addc.CA} = (addcarry (xor %a, %b), -1)
3342 // (sext (setcc %a, %b, seteq)) -> (sube addc.reg, addc.reg, addc.CA)
3343 // {addcz.reg, addcz.CA} = (addcarry %a, -1)
3344 // (sext (setcc %a, 0, seteq)) -> (sube addcz.reg, addcz.reg, addcz.CA)
3345 SDValue AddInput = IsRHSZero ? LHS :
3346 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0);
3347 SDValue Addic =
3348 SDValue(CurDAG->getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue,
3349 AddInput, getI32Imm(~0U, dl)), 0);
3350 return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, Addic,
3351 Addic, Addic.getValue(1)), 0);
3352 }
3353 case ISD::SETNE: {
3354 // {subfc.reg, subfc.CA} = (subcarry 0, (xor %a, %b))
3355 // (sext (setcc %a, %b, setne)) -> (sube subfc.reg, subfc.reg, subfc.CA)
3356 // {subfcz.reg, subfcz.CA} = (subcarry 0, %a)
3357 // (sext (setcc %a, 0, setne)) -> (sube subfcz.reg, subfcz.reg, subfcz.CA)
3358 SDValue Xor = IsRHSZero ? LHS :
3359 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0);
3360 SDValue SC =
3361 SDValue(CurDAG->getMachineNode(PPC::SUBFIC8, dl, MVT::i64, MVT::Glue,
3362 Xor, getI32Imm(0, dl)), 0);
3363 return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, SC,
3364 SC, SC.getValue(1)), 0);
3365 }
3366 case ISD::SETGE: {
3367 // {subc.reg, subc.CA} = (subcarry %a, %b)
3368 // (zext (setcc %a, %b, setge)) ->
3369 // (- (adde (lshr %b, 63), (ashr %a, 63), subc.CA))
3370 // (zext (setcc %a, 0, setge)) -> (~ (ashr %a, 63))
3371 if (IsRHSZero)
3372 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3373 std::swap(LHS, RHS);
3374 ConstantSDNode *RHSConst = dyn_cast(RHS);
3375 IsRHSZero = RHSConst && RHSConst->isNullValue();
3376 LLVM_FALLTHROUGH;
3377 }
3378 case ISD::SETLE: {
3379 // {subc.reg, subc.CA} = (subcarry %b, %a)
3380 // (zext (setcc %a, %b, setge)) ->
3381 // (- (adde (lshr %a, 63), (ashr %b, 63), subc.CA))
3382 // (zext (setcc %a, 0, setge)) -> (ashr (or %a, (add %a, -1)), 63)
3383 if (IsRHSZero)
3384 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3385 SDValue ShiftR =
3386 SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, RHS,
3387 getI64Imm(63, dl)), 0);
3388 SDValue ShiftL =
3389 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, LHS,
3390 getI64Imm(1, dl), getI64Imm(63, dl)), 0);
3391 SDValue SubtractCarry =
3392 SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3393 LHS, RHS), 1);
3394 SDValue Adde =
3395 SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue,
3396 ShiftR, ShiftL, SubtractCarry), 0);
3397 return SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, Adde), 0);
3398 }
3399 case ISD::SETGT: {
3400 // {subc.reg, subc.CA} = (subcarry %b, %a)
3401 // (zext (setcc %a, %b, setgt)) ->
3402 // -(xor (adde (lshr %a, 63), (ashr %b, 63), subc.CA), 1)
3403 // (zext (setcc %a, 0, setgt)) -> (ashr (nor (add %a, -1), %a), 63)
3404 if (IsRHSNegOne)
3405 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3406 if (IsRHSZero) {
3407 SDValue Add =
3408 SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS,
3409 getI64Imm(-1, dl)), 0);
3410 SDValue Nor =
3411 SDValue(CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, Add, LHS), 0);
3412 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Nor,
3413 getI64Imm(63, dl)), 0);
3414 }
3415 std::swap(LHS, RHS);
3416 ConstantSDNode *RHSConst = dyn_cast(RHS);
3417 IsRHSZero = RHSConst && RHSConst->isNullValue();
3418 IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1;
3419 LLVM_FALLTHROUGH;
3420 }
3421 case ISD::SETLT: {
3422 // {subc.reg, subc.CA} = (subcarry %a, %b)
3423 // (zext (setcc %a, %b, setlt)) ->
3424 // -(xor (adde (lshr %b, 63), (ashr %a, 63), subc.CA), 1)
3425 // (zext (setcc %a, 0, setlt)) -> (ashr %a, 63)
3426 if (IsRHSOne)
3427 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3428 if (IsRHSZero) {
3429 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, LHS,
3430 getI64Imm(63, dl)), 0);
3431 }
3432 SDValue SRADINode =
3433 SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64,
3434 LHS, getI64Imm(63, dl)), 0);
3435 SDValue SRDINode =
3436 SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
3437 RHS, getI64Imm(1, dl),
3438 getI64Imm(63, dl)), 0);
3439 SDValue SUBFC8Carry =
3440 SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3441 RHS, LHS), 1);
3442 SDValue ADDE8Node =
3443 SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64,
3444 SRDINode, SRADINode, SUBFC8Carry), 0);
3445 SDValue XORI8Node =
3446 SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64,
3447 ADDE8Node, getI64Imm(1, dl)), 0);
3448 return SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64,
3449 XORI8Node), 0);
3450 }
3451 }
3452 }
3453
3454 /// Does this SDValue have any uses for which keeping the value in a GPR is
3455 /// appropriate. This is meant to be used on values that have type i1 since
3456 /// it is somewhat meaningless to ask if values of other types can be kept in
3457 /// GPR's.
3458 static bool allUsesExtend(SDValue Compare, SelectionDAG *CurDAG) {
3459 assert(Compare.getOpcode() == ISD::SETCC &&
3460 "An ISD::SETCC node required here.");
3461
3462 // For values that have a single use, the caller should obviously already have
3463 // checked if that use is an extending use. We check the other uses here.
3464 if (Compare.hasOneUse())
3465 return true;
3466 // We want the value in a GPR if it is being extended, used for a select, or
3467 // used in logical operations.
3468 for (auto CompareUse : Compare.getNode()->uses())
3469 if (CompareUse->getOpcode() != ISD::SIGN_EXTEND &&
3470 CompareUse->getOpcode() != ISD::ZERO_EXTEND &&
3471 CompareUse->getOpcode() != ISD::SELECT &&
3472 !isLogicOp(CompareUse->getOpcode())) {
3473 OmittedForNonExtendUses++;
3474 return false;
3475 }
3476 return true;
3477 }
3478
3479 /// Returns an equivalent of a SETCC node but with the result the same width as
3480 /// the inputs. This can nalso be used for SELECT_CC if either the true or false
3481 /// values is a power of two while the other is zero.
3482 SDValue PPCDAGToDAGISel::getSETCCInGPR(SDValue Compare,
3483 SetccInGPROpts ConvOpts) {
3484 assert((Compare.getOpcode() == ISD::SETCC ||
3485 Compare.getOpcode() == ISD::SELECT_CC) &&
3486 "An ISD::SETCC node required here.");
3487
3488 // Don't convert this comparison to a GPR sequence because there are uses
3489 // of the i1 result (i.e. uses that require the result in the CR).
3490 if ((Compare.getOpcode() == ISD::SETCC) && !allUsesExtend(Compare, CurDAG))
3491 return SDValue();
3492
3493 SDValue LHS = Compare.getOperand(0);
3494 SDValue RHS = Compare.getOperand(1);
3495
3496 // The condition code is operand 2 for SETCC and operand 4 for SELECT_CC.
3497 int CCOpNum = Compare.getOpcode() == ISD::SELECT_CC ? 4 : 2;
3498 ISD::CondCode CC =
3499 cast(Compare.getOperand(CCOpNum))->get();
3500 EVT InputVT = LHS.getValueType();
3501 if (InputVT != MVT::i32 && InputVT != MVT::i64)
3502 return SDValue();
3503
3504 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
3505 ConvOpts == SetccInGPROpts::SExtInvert)
3506 CC = ISD::getSetCCInverse(CC, true);
3507
3508 bool Inputs32Bit = InputVT == MVT::i32;
3509
3510 SDLoc dl(Compare);
3511 ConstantSDNode *RHSConst = dyn_cast(RHS);
3512 int64_t RHSValue = RHSConst ? RHSConst->getSExtValue() : INT64_MAX;
3513 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
3514 ConvOpts == SetccInGPROpts::SExtInvert;
3515
3516 if (IsSext && Inputs32Bit)
3517 return get32BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
3518 else if (Inputs32Bit)
3519 return get32BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
3520 else if (IsSext)
3521 return get64BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
3522 return get64BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
3523 }
3524
35252479 /// Does this node represent a load/store node whose address can be represented
35262480 /// with a register plus an immediate that's a multiple of \p Val:
35272481 bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *N, unsigned Val) const {
35862540 ReplaceNode(N, selectI64Imm(CurDAG, N));
35872541 return;
35882542 }
3589 break;
3590
3591 case ISD::ZERO_EXTEND:
3592 case ISD::SIGN_EXTEND:
3593 if (tryEXTEND(N))
3594 return;
35952543 break;
35962544
35972545 case ISD::SETCC:
37372685 }
37382686
37392687 case ISD::AND: {
3740 if (tryLogicOpOfCompares(N))
3741 return;
3742
37432688 unsigned Imm, Imm2, SH, MB, ME;
37442689 uint64_t Imm64;
37452690
38592804 if (tryBitfieldInsert(N))
38602805 return;
38612806
3862 if (tryLogicOpOfCompares(N))
3863 return;
3864
38652807 int16_t Imm;
38662808 if (N->getOperand(0)->getOpcode() == ISD::FrameIndex &&
38672809 isIntS16Immediate(N->getOperand(1), Imm)) {
38992841 break;
39002842 }
39012843 case ISD::XOR: {
3902 if (tryLogicOpOfCompares(N))
3903 return;
3904
39052844 // XOR with a 32-bit immediate can be handled by xori + xoris
39062845 // without creating an immediate in a GPR.
39072846 uint64_t Imm64 = 0;
0 ; XFAIL: *
1 ; The purpose of the test case is to ensure that a spill that happens during
12 ; intermediate calculations for a comparison performed in a GPR spills the
23 ; full register. Some i32 comparisons performed in GPRs use code that uses
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s
12 ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s
23 target datalayout = "E-m:e-i64:64-n32:64"
0 ; XFAIL: *
1 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
12 target triple = "powerpc64-unknown-linux-gnu"
23 ; RUN: llc -verify-machineinstrs -O2 -ppc-asm-full-reg-names -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck %s --implicit-check-not isel
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mcpu=pwr8 < %s | FileCheck %s
23 target datalayout = "e-m:e-i64:64-n32:64"
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s
12 target datalayout = "E-m:e-i64:64-n32:64"
23 target triple = "powerpc64-unknown-linux-gnu"
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 -mattr=-crbits -disable-ppc-cmp-opt=0 | FileCheck %s
12 ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 -mattr=-crbits -disable-ppc-cmp-opt=0 -ppc-gen-isel=false | FileCheck --check-prefix=CHECK-NO-ISEL %s
23 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mcpu=pwr7 < %s | FileCheck %s
12 ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-gen-isel=false < %s | FileCheck --check-prefix=CHECK-NO-ISEL %s
23 target datalayout = "E-m:e-i64:64-n32:64"
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc < %s -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown | FileCheck %s
23
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
12 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
23 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl
0 ; XFAIL: *
1 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \
12 ; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \
23 ; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl