diff --git a/llvm/lib/Target/ARM/ARMFeatures.h b/llvm/lib/Target/ARM/ARMFeatures.h index 99e0ef05b5e21..eeb67abe27512 100644 --- a/llvm/lib/Target/ARM/ARMFeatures.h +++ b/llvm/lib/Target/ARM/ARMFeatures.h @@ -51,7 +51,7 @@ inline bool isV8EligibleForIT(const InstrType *Instr) { // Outside of an IT block, these set CPSR. return IsCPSRDead(Instr); case ARM::tADDrSPi: - case ARM::tCMNz: + case ARM::tCMN: case ARM::tCMPi8: case ARM::tCMPr: case ARM::tLDRBi: diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index cd8d7a0bee5e3..d9bcdde688941 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -4525,6 +4525,29 @@ static bool isFloatingPointZero(SDValue Op) { return false; } +static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG) { + // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe. + if (Op->getFlags().hasNoSignedWrap()) + return true; + + // We can still figure out if the second operand is safe to use + // in a CMN instruction by checking if it is known to be not the minimum + // signed value. If it is not, then we can safely use CMN. + // Note: We can eventually remove this check and simply rely on + // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering + // consistently sets them appropriately when making said nodes. + + KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1)); + return !KnownSrc.getSignedMinValue().isMinSignedValue(); +} + +static bool isCMN(SDValue Op, ISD::CondCode CC, SelectionDAG &DAG) { + return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) && + (isIntEqualitySetCC(CC) || + (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) || + (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG))); +} + /// Returns appropriate ARM CMP (cmp) and corresponding condition code for /// the given operands. SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, @@ -4658,6 +4681,21 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, CompareType = ARMISD::CMPZ; break; } + + // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from + // the codebase. + + // TODO: When we have a solution to the vselect predicate not allowing pl/mi + // all the time, allow those cases to be cmn too no matter what. + if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) { + CompareType = ARMISD::CMN; + RHS = RHS.getOperand(1); + } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) { + CompareType = ARMISD::CMN; + LHS = LHS.getOperand(1); + CondCode = IntCCToARMCC(ISD::getSetCCSwappedOperands(CC)); + } + ARMcc = DAG.getConstant(CondCode, dl, MVT::i32); return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS); } @@ -10307,34 +10345,12 @@ SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const { // Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC unsigned Opcode = ARMISD::SUBC; - // Check if RHS is a subtraction against 0: (0 - X) - if (RHS.getOpcode() == ISD::SUB) { - SDValue SubLHS = RHS.getOperand(0); - SDValue SubRHS = RHS.getOperand(1); - - // Check if it's 0 - X - if (isNullConstant(SubLHS)) { - bool CanUseAdd = false; - if (IsSigned) { - // For SCMP: only if X is known to never be INT_MIN (to avoid overflow) - if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS) - .getSignedMinValue() - .isMinSignedValue()) { - CanUseAdd = true; - } - } else { - // For UCMP: only if X is known to never be zero - if (DAG.isKnownNeverZero(SubRHS)) { - CanUseAdd = true; - } - } - - if (CanUseAdd) { - Opcode = ARMISD::ADDC; - RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of - // LHS - (0 - X) - } - } + // Doesn't matter as it's a 3-way but let's just send in a signed comparison + // if signed or an unsigned comparison if unsigned. + ISD::CondCode CC = IsSigned ? ISD::SETGT : ISD::SETUGT; + if (isCMN(RHS, CC, DAG)) { + Opcode = ARMISD::ADDC; + RHS = RHS.getOperand(1); } // Generate the operation with flags diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index ddc89415cfb20..ce04cfeb84bb8 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -250,7 +250,7 @@ def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64, def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp>; // ARM CMN instructions. -def ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp>; +def ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp, [SDNPCommutative]>; // ARM compare that sets only Z flag. def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, [SDNPCommutative]>; @@ -5074,10 +5074,10 @@ def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, IIC_iCMPi, } // CMN register-register/shift -def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, +def CMNrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, "cmn", "\t$Rn, $Rm", - [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> - GPR:$Rn, GPR:$Rm))]>, Sched<[WriteCMP, ReadALU, ReadALU]> { + [(set CPSR, (ARMcmn GPR:$Rn, GPR:$Rm))]>, + Sched<[WriteCMP, ReadALU, ReadALU]> { bits<4> Rn; bits<4> Rm; let isCommutable = 1; @@ -5091,12 +5091,11 @@ def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr, let Unpredictable{15-12} = 0b1111; } -def CMNzrsi : AI1<0b1011, (outs), +def CMNrsi : AI1<0b1011, (outs), (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr, "cmn", "\t$Rn, $shift", - [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> - GPR:$Rn, so_reg_imm:$shift))]>, - Sched<[WriteCMPsi, ReadALU]> { + [(set CPSR, (ARMcmn GPR:$Rn, so_reg_imm:$shift))]>, + Sched<[WriteCMPsi, ReadALU]> { bits<4> Rn; bits<12> shift; let Inst{25} = 0; @@ -5110,12 +5109,11 @@ def CMNzrsi : AI1<0b1011, (outs), let Unpredictable{15-12} = 0b1111; } -def CMNzrsr : AI1<0b1011, (outs), +def CMNrsr : AI1<0b1011, (outs), (ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr, "cmn", "\t$Rn, $shift", - [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> - GPRnopc:$Rn, so_reg_reg:$shift))]>, - Sched<[WriteCMPsr, ReadALU]> { + [(set CPSR, (ARMcmn GPRnopc:$Rn, so_reg_reg:$shift))]>, + Sched<[WriteCMPsr, ReadALU]> { bits<4> Rn; bits<12> shift; let Inst{25} = 0; @@ -5133,11 +5131,17 @@ def CMNzrsr : AI1<0b1011, (outs), } +// ARMcmpZ patterns for CMN (compare-to-zero with negated operands) def : ARMPat<(ARMcmp GPR:$src, mod_imm_neg:$imm), (CMNri GPR:$src, mod_imm_neg:$imm)>; - def : ARMPat<(ARMcmpZ GPR:$src, mod_imm_neg:$imm), (CMNri GPR:$src, mod_imm_neg:$imm)>; +def : ARMPat<(ARMcmpZ GPR:$src, (ineg GPR:$rhs)), + (CMNrr GPR:$src, GPR:$rhs)>; +def : ARMPat<(ARMcmpZ GPR:$src, (ineg so_reg_imm:$rhs)), + (CMNrsi GPR:$src, so_reg_imm:$rhs)>; +def : ARMPat<(ARMcmpZ GPRnopc:$src, (ineg so_reg_reg:$rhs)), + (CMNrsr GPRnopc:$src, so_reg_reg:$rhs)>; // Note that TST/TEQ don't set all the same flags that CMP does! defm TST : AI1_cmp_irs<0b1000, "tst", diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index 55b0d9e1c01fc..58ee70db28dcb 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -986,8 +986,7 @@ let isAdd = 1 in { T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn), (ins tGPR:$Rn, imm0_255_expr:$imm8), IIC_iALUi, "add", "\t$Rdn, $imm8", - [(set tGPR:$Rdn, (add tGPR:$Rn, imm0_255_expr:$imm8))]>, - Sched<[WriteALU]>; + [(set tGPR:$Rdn, (add tGPR:$Rn, imm0_255_expr:$imm8))]>, Sched<[WriteALU]>; // Add register let isCommutable = 1 in @@ -1090,7 +1089,8 @@ def tASRrr : // A8.6.15 T1sItDPEncode<0b0100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iMOVsr, "asr", "\t$Rdn, $Rm", - [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; + [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>, + Sched<[WriteALU]>; // BIC register def tBIC : // A8.6.20 @@ -1102,21 +1102,12 @@ def tBIC : // A8.6.20 // CMN register let isCompare = 1, Defs = [CPSR] in { -//FIXME: Disable CMN, as CCodes are backwards from compare expectations -// Compare-to-zero still works out, just not the relationals -//def tCMN : // A8.6.33 -// T1pIDPEncode<0b1011, (outs), (ins tGPR:$lhs, tGPR:$rhs), -// IIC_iCMPr, -// "cmn", "\t$lhs, $rhs", -// [(set CPSR, (ARMcmp tGPR:$lhs, (ineg tGPR:$rhs)))]>; - -def tCMNz : // A8.6.33 +def tCMN : // A8.6.33 T1pIDPEncode<0b1011, (outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iCMPr, "cmn", "\t$Rn, $Rm", - [(set CPSR, (ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm)))]>, - Sched<[WriteCMP]>; - + [(set CPSR, (ARMcmn tGPR:$Rn, tGPR:$Rm))]>, + Sched<[WriteCMP]>; } // isCompare = 1, Defs = [CPSR] // CMP immediate @@ -1570,6 +1561,9 @@ def tInt_WIN_eh_sjlj_longjmp // Comparisons def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8), (tCMPi8 tGPR:$Rn, imm0_255:$imm8)>; +// Fold compare-to-zero of a negated register into CMN register form. +def : T1Pat<(ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm)), + (tCMN tGPR:$Rn, tGPR:$Rm)>; def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm), (tCMPr tGPR:$Rn, tGPR:$Rm)>; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 317959c0342f7..48d59cfda9dad 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -3495,12 +3495,11 @@ let isCompare = 1, Defs = [CPSR] in { let Inst{11-8} = 0b1111; // Rd } // register - def t2CMNzrr : T2TwoRegCmp< + def t2CMNrr : T2TwoRegCmp< (outs), (ins GPRnopc:$Rn, rGPR:$Rm), IIC_iCMPr, "cmn", ".w\t$Rn, $Rm", - [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> - GPRnopc:$Rn, rGPR:$Rm))]>, - Sched<[WriteCMP, ReadALU, ReadALU]> { + [(set CPSR, (ARMcmn GPRnopc:$Rn, rGPR:$Rm))]>, + Sched<[WriteCMP, ReadALU, ReadALU]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = 0b1000; @@ -3511,12 +3510,11 @@ let isCompare = 1, Defs = [CPSR] in { let Inst{5-4} = 0b00; // type } // shifted register - def t2CMNzrs : T2OneRegCmpShiftedReg< + def t2CMNrs : T2OneRegCmpShiftedReg< (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), IIC_iCMPsi, "cmn", ".w\t$Rn, $ShiftedRm", - [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> - GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>, - Sched<[WriteCMPsi, ReadALU, ReadALU]> { + [(set CPSR, (ARMcmn GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>, + Sched<[WriteCMPsi, ReadALU, ReadALU]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = 0b1000; @@ -3531,7 +3529,7 @@ let isCompare = 1, Defs = [CPSR] in { def : t2InstAlias<"cmn${p} $Rn, $imm", (t2CMNri GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>; def : t2InstAlias<"cmn${p} $Rn, $shift", - (t2CMNzrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>; + (t2CMNrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>; def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; @@ -3539,6 +3537,12 @@ def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), def : T2Pat<(ARMcmpZ GPRnopc:$src, t2_so_imm_neg:$imm), (t2CMNri GPRnopc:$src, t2_so_imm_neg:$imm)>; +// Fold compare-to-zero of a negated register into CMN register forms. +def : T2Pat<(ARMcmpZ GPRnopc:$Rn, (ineg rGPR:$Rm)), + (t2CMNrr GPRnopc:$Rn, rGPR:$Rm)>; +def : T2Pat<(ARMcmpZ GPRnopc:$Rn, (ineg t2_so_reg:$ShiftedRm)), + (t2CMNrs GPRnopc:$Rn, t2_so_reg:$ShiftedRm)>; + defm t2TST : T2I_cmp_irs<0b0000, "tst", rGPR, IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>; @@ -5096,7 +5100,7 @@ def : t2InstAlias<"subw${p} $Rdn, $imm", // Alias for compares without the ".w" optional width specifier. def : t2InstAlias<"cmn${p} $Rn, $Rm", - (t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; + (t2CMNrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; def : t2InstAlias<"teq${p} $Rn, $Rm", (t2TEQrr rGPR:$Rn, rGPR:$Rm, pred:$p)>; def : t2InstAlias<"tst${p} $Rn, $Rm", diff --git a/llvm/lib/Target/ARM/ARMLatencyMutations.cpp b/llvm/lib/Target/ARM/ARMLatencyMutations.cpp index 85bad4f1925a4..bd497f4172406 100644 --- a/llvm/lib/Target/ARM/ARMLatencyMutations.cpp +++ b/llvm/lib/Target/ARM/ARMLatencyMutations.cpp @@ -114,7 +114,7 @@ InstructionInformation::InstructionInformation(const ARMBaseInstrInfo *TII) { std::initializer_list isInlineShiftALUList = { t2ADCrs, t2ADDSrs, t2ADDrs, t2BICrs, t2EORrs, t2ORNrs, t2RSBSrs, t2RSBrs, t2SBCrs, t2SUBrs, - t2SUBSrs, t2CMPrs, t2CMNzrs, t2TEQrs, t2TSTrs, + t2SUBSrs, t2CMPrs, t2CMNrs, t2TEQrs, t2TSTrs, }; for (auto op : isInlineShiftALUList) { Info[op].IsInlineShiftALU = true; diff --git a/llvm/lib/Target/ARM/ARMScheduleM55.td b/llvm/lib/Target/ARM/ARMScheduleM55.td index ff05936e8ba45..de55eafb039d6 100644 --- a/llvm/lib/Target/ARM/ARMScheduleM55.td +++ b/llvm/lib/Target/ARM/ARMScheduleM55.td @@ -152,7 +152,7 @@ def : InstRW<[M55WriteDX_SI], (instregex "t2CS(EL|INC|INV|NEG)")>; // Thumb 2 instructions that could be reduced to a thumb 1 instruction and can // be dual issued with one of the above. This list is optimistic. def : InstRW<[M55WriteDX_DI], (instregex "t2ADDC?rr$", "t2ADDrr$", - "t2ADDSrr$", "t2ANDrr$", "t2ASRr[ir]$", "t2BICrr$", "t2CMNzrr$", + "t2ADDSrr$", "t2ANDrr$", "t2ASRr[ir]$", "t2BICrr$", "t2CMNrr$", "t2CMPr[ir]$", "t2EORrr$", "t2LSLr[ir]$", "t2LSRr[ir]$", "t2MVNr$", "t2ORRrr$", "t2REV(16|SH)?$", "t2RORrr$", "t2RSBr[ir]$", "t2RSBSri$", "t2SBCrr$", "t2SUBS?rr$", "t2TEQrr$", "t2TSTrr$", "t2STRi12$", @@ -161,7 +161,7 @@ def : InstRW<[M55WriteDX_DI], (instregex "t2ADDC?rr$", "t2ADDrr$", def : InstRW<[M55WriteDX_DI], (instregex "t2SETPAN$", "tADC$", "tADDhirr$", "tADDrSP$", "tADDrSPi$", "tADDrr$", "tADDspi$", "tADDspr$", "tADR$", "tAND$", "tASRri$", "tASRrr$", "tBIC$", "tBKPT$", "tCBNZ$", "tCBZ$", - "tCMNz$", "tCMPhir$", "tCMPi8$", "tCMPr$", "tCPS$", "tEOR$", "tHINT$", + "tCMN","tCMPhir$", "tCMPi8$", "tCMPr$", "tCPS$", "tEOR$", "tHINT$", "tHLT$", "tLSLri$", "tLSLrr$", "tLSRri$", "tLSRrr$", "tMOVSr$", "tMUL$", "tMVN$", "tORR$", "tPICADD$", "tPOP$", "tPUSH$", "tREV$", "tREV16$", "tREVSH$", "tROR$", "tRSB$", "tSBC$", "tSETEND$", diff --git a/llvm/lib/Target/ARM/ARMScheduleM7.td b/llvm/lib/Target/ARM/ARMScheduleM7.td index 99d2e4a832220..482e417220d3e 100644 --- a/llvm/lib/Target/ARM/ARMScheduleM7.td +++ b/llvm/lib/Target/ARM/ARMScheduleM7.td @@ -324,7 +324,7 @@ def M7Ex1ReadNoFastBypass : SchedReadAdvance<-1, [WriteLd, M7LoadLatency1]>; def : InstRW<[WriteALUsi, M7Ex1ReadNoFastBypass, M7Read_ISS], (instregex "t2(ADC|ADDS|ADD|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|SUBS)rs$", - "t2(SUB|CMP|CMNz|TEQ|TST)rs$", + "t2(SUB|CMP|CMN|TEQ|TST)rs$", "t2(A|L)SRs1$")>; def : InstRW<[WriteALUsi, M7Read_ISS], (instregex "t2MVNs")>; diff --git a/llvm/lib/Target/ARM/ARMScheduleM85.td b/llvm/lib/Target/ARM/ARMScheduleM85.td index e9938d857e6af..beeda468397ec 100644 --- a/llvm/lib/Target/ARM/ARMScheduleM85.td +++ b/llvm/lib/Target/ARM/ARMScheduleM85.td @@ -410,7 +410,7 @@ def M85ReadALUsi : SchedReadVariant<[ def : InstRW<[M85WriteALUsi, M85Read_EX1, M85ReadALUsi], (instregex "t2(ADC|ADDS|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|" - "SUBS|CMP|CMNz|TEQ|TST)rs$")>; + "SUBS|CMP|CMN|TEQ|TST)rs$")>; def : InstRW<[M85WriteALUsi, M85ReadALUsi], (instregex "t2MVNs")>; @@ -419,7 +419,7 @@ def : InstRW<[M85WriteALUsi, M85ReadALUsi], // shift resource. def : InstRW<[M85WriteALUsi, M85Read_EX1, M85ReadALUsi], (instregex "t2(ADC|ADDS|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|" - "SUBS|CMP|CMNz|TEQ|TST)rr$")>; + "SUBS|CMP|CMN|TEQ|TST)rr$")>; def : InstRW<[M85WriteALUsi, M85ReadALUsi], (instregex "t2MVNr")>; diff --git a/llvm/lib/Target/ARM/ARMScheduleR52.td b/llvm/lib/Target/ARM/ARMScheduleR52.td index c350180baa250..8781ece621ba2 100644 --- a/llvm/lib/Target/ARM/ARMScheduleR52.td +++ b/llvm/lib/Target/ARM/ARMScheduleR52.td @@ -330,9 +330,9 @@ def : InstRW<[R52WriteALU_EX1, R52Read_ISS, R52Read_ISS], (instregex "ASRr", "RORS?r", "LSR", "LSL")>; def : InstRW<[R52WriteCC, R52Read_EX1], (instregex "CMPri", "CMNri")>; -def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_EX1], (instregex "CMPrr", "CMNzrr")>; -def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS], (instregex "CMPrsi", "CMNzrsi")>; -def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS, R52Read_ISS], (instregex "CMPrsr", "CMNzrsr")>; +def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_EX1], (instregex "CMPrr", "CMNrr")>; +def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS], (instregex "CMPrsi", "CMNrsi")>; +def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS, R52Read_ISS], (instregex "CMPrsr", "CMNrsr")>; def : InstRW<[R52WriteALU_EX2, R52Read_ISS], (instregex "t2LDC", "RBIT", "REV", "REV16", "REVSH", "RRX")>; diff --git a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp index 18e41297b1734..de1a46ef3682f 100644 --- a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -88,9 +88,7 @@ namespace { { ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 1,0,1 }, { ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 1,0,1 }, { ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 1,0,0 }, - //FIXME: Disable CMN, as CCodes are backwards from compare expectations - //{ ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0,0,0 }, - { ARM::t2CMNzrr, ARM::tCMNz, 0, 0, 0, 1, 0, 2,0, 0,0,0 }, + { ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0,0,0 }, { ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0,0,0 }, { ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0,1,0 }, { ARM::t2EORrr, 0, ARM::tEOR, 0, 0, 0, 1, 0,0, 1,0,0 }, diff --git a/llvm/test/CodeGen/ARM/cmp-to-cmn.ll b/llvm/test/CodeGen/ARM/cmp-to-cmn.ll new file mode 100644 index 0000000000000..fbf707ccb7838 --- /dev/null +++ b/llvm/test/CodeGen/ARM/cmp-to-cmn.ll @@ -0,0 +1,2194 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=armv7 %s -o - | FileCheck %s --check-prefixes=CHECK-ARM +; RUN: llc -mtriple=thumb-eabi -mcpu=arm7tdmi %s -o - | FileCheck %s --check-prefix=CHECK-T1 +; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s --check-prefix=CHECK-T2 + +define i1 @test_EQ_IllEbT(i64 %a, i64 %b) { +; CHECK-ARM-LABEL: test_EQ_IllEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r2, r2, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r1, r2, r1 +; CHECK-ARM-NEXT: orr r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IllEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r4, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r4, r3 +; CHECK-T1-NEXT: eors r4, r1 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r4 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: test_EQ_IllEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: mov.w r12, #0 +; CHECK-T2-NEXT: sbc.w r3, r12, r3 +; CHECK-T2-NEXT: eors r1, r3 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %add = sub i64 0, %b + %cmp = icmp eq i64 %add, %a + ret i1 %cmp +} + +define i1 @test_EQ_IliEbT(i64 %a, i32 %b) { +; CHECK-ARM-LABEL: test_EQ_IliEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r0, r0, #0 +; CHECK-ARM-NEXT: rsc r1, r1, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31 +; CHECK-ARM-NEXT: orr r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IliEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r3, #0 +; CHECK-T1-NEXT: rsbs r4, r0, #0 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: asrs r0, r2, #31 +; CHECK-T1-NEXT: eors r0, r3 +; CHECK-T1-NEXT: eors r4, r2 +; CHECK-T1-NEXT: orrs r4, r0 +; CHECK-T1-NEXT: rsbs r0, r4, #0 +; CHECK-T1-NEXT: adcs r0, r4 +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: test_EQ_IliEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: mov.w r3, #0 +; CHECK-T2-NEXT: sbc.w r1, r3, r1 +; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i32 %b to i64 + %add = sub i64 0, %a + %cmp = icmp eq i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IlsEbT(i64 %a, i16 %b) { +; CHECK-ARM-LABEL: test_EQ_IlsEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r0, r0, #0 +; CHECK-ARM-NEXT: sxth r2, r2 +; CHECK-ARM-NEXT: rsc r1, r1, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31 +; CHECK-ARM-NEXT: orr r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IlsEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r3, #0 +; CHECK-T1-NEXT: rsbs r0, r0, #0 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: lsls r1, r2, #16 +; CHECK-T1-NEXT: asrs r2, r1, #31 +; CHECK-T1-NEXT: eors r2, r3 +; CHECK-T1-NEXT: asrs r1, r1, #16 +; CHECK-T1-NEXT: eors r1, r0 +; CHECK-T1-NEXT: orrs r1, r2 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IlsEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r3, #0 +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: sxth r2, r2 +; CHECK-T2-NEXT: sbc.w r1, r3, r1 +; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %b to i64 + %add = sub i64 0, %a + %cmp = icmp eq i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IlcEbT(i64 %a, i8 %b) { +; CHECK-ARM-LABEL: test_EQ_IlcEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r0, r0, #0 +; CHECK-ARM-NEXT: uxtb r2, r2 +; CHECK-ARM-NEXT: rsc r1, r1, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: orr r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IlcEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r3, #0 +; CHECK-T1-NEXT: rsbs r0, r0, #0 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: movs r1, #255 +; CHECK-T1-NEXT: ands r1, r2 +; CHECK-T1-NEXT: eors r1, r0 +; CHECK-T1-NEXT: orrs r1, r3 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IlcEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r3, #0 +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: uxtb r2, r2 +; CHECK-T2-NEXT: sbc.w r1, r3, r1 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %b to i64 + %add = sub i64 0, %a + %cmp = icmp eq i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IilEbT(i32 %a, i64 %b) { +; CHECK-ARM-LABEL: test_EQ_IilEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r1, r2, #0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r1, r0, r1 +; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31 +; CHECK-ARM-NEXT: orr r0, r1, r0 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IilEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r1, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r1, r3 +; CHECK-T1-NEXT: asrs r3, r0, #31 +; CHECK-T1-NEXT: eors r3, r1 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r3 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IilEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: sbcs r1, r3 +; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i32 %a to i64 + %add = sub i64 0, %b + %cmp = icmp eq i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IiiEbT(i32 %a, i32 %b) { +; CHECK-ARM-LABEL: test_EQ_IiiEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: add r0, r1, r0 +; CHECK-ARM-NEXT: rsb r0, r0, #0 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IiiEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: adds r0, r1, r0 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IiiEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: add r0, r1 +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %add = sub i32 0, %b + %cmp = icmp eq i32 %add, %a + ret i1 %cmp +} + +define i1 @test_EQ_IisEbT(i32 %a, i16 %b) { +; CHECK-ARM-LABEL: test_EQ_IisEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxtah r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IisEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: lsls r1, r1, #16 +; CHECK-T1-NEXT: asrs r1, r1, #16 +; CHECK-T1-NEXT: adds r0, r0, r1 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IisEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxtah r0, r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %b to i32 + %add = sub i32 0, %a + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IicEbT(i32 %a, i8 %b) { +; CHECK-ARM-LABEL: test_EQ_IicEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: uxtab r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IicEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r1 +; CHECK-T1-NEXT: adds r1, r2, r0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IicEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: uxtab r0, r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %b to i32 + %add = sub i32 0, %a + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IslEbT(i16 %a, i64 %b) { +; CHECK-ARM-LABEL: test_EQ_IslEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r1, r2, #0 +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r1, r0, r1 +; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31 +; CHECK-ARM-NEXT: orr r0, r1, r0 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IslEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r1, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r1, r3 +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r3, r0, #31 +; CHECK-T1-NEXT: eors r3, r1 +; CHECK-T1-NEXT: asrs r1, r0, #16 +; CHECK-T1-NEXT: eors r1, r2 +; CHECK-T1-NEXT: orrs r1, r3 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IslEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: sbcs r1, r3 +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i64 + %add = sub i64 0, %b + %cmp = icmp eq i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IsiEbT(i16 %a, i32 %b) { +; CHECK-ARM-LABEL: test_EQ_IsiEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxtah r0, r1, r0 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IsiEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: adds r0, r1, r0 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IsiEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxtah r0, r1, r0 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i32 + %add = sub i32 0, %b + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IssEbT(i16 %a, i16 %b) { +; CHECK-ARM-LABEL: test_EQ_IssEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: sxtah r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IssEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: lsls r1, r1, #16 +; CHECK-T1-NEXT: asrs r1, r1, #16 +; CHECK-T1-NEXT: adds r0, r1, r0 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IssEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: sxtah r0, r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i32 + %conv1 = sext i16 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IscEbT(i16 %a, i8 %b) { +; CHECK-ARM-LABEL: test_EQ_IscEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: uxtab r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IscEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r1 +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: adds r0, r2, r0 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IscEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: uxtab r0, r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i32 + %conv1 = zext i8 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IclEbT(i8 %a, i64 %b) { +; CHECK-ARM-LABEL: test_EQ_IclEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r1, r2, #0 +; CHECK-ARM-NEXT: uxtb r0, r0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r0, r0, r1 +; CHECK-ARM-NEXT: orr r0, r0, r2 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IclEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r1, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r1, r3 +; CHECK-T1-NEXT: movs r3, #255 +; CHECK-T1-NEXT: ands r0, r3 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r1 +; CHECK-T1-NEXT: rsbs r1, r0, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IclEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: uxtb r0, r0 +; CHECK-T2-NEXT: sbcs r1, r3 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i64 + %add = sub i64 0, %b + %cmp = icmp eq i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IciEbT(i8 %a, i32 %b) { +; CHECK-ARM-LABEL: test_EQ_IciEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: uxtab r0, r1, r0 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IciEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r0 +; CHECK-T1-NEXT: adds r1, r2, r1 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IciEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: uxtab r0, r1, r0 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i32 + %add = sub i32 0, %b + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IcsEbT(i8 %a, i16 %b) { +; CHECK-ARM-LABEL: test_EQ_IcsEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxth r1, r1 +; CHECK-ARM-NEXT: uxtab r0, r1, r0 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IcsEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r0 +; CHECK-T1-NEXT: lsls r0, r1, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: adds r1, r2, r0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IcsEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxth r1, r1 +; CHECK-T2-NEXT: uxtab r0, r1, r0 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i32 + %conv1 = sext i16 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_EQ_IccEbT(i8 %a, i8 %b) { +; CHECK-ARM-LABEL: test_EQ_IccEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: uxtb r0, r0 +; CHECK-ARM-NEXT: uxtab r0, r0, r1 +; CHECK-ARM-NEXT: clz r0, r0 +; CHECK-ARM-NEXT: lsr r0, r0, #5 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_EQ_IccEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r1, r2 +; CHECK-T1-NEXT: ands r0, r2 +; CHECK-T1-NEXT: adds r1, r0, r1 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: adcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_EQ_IccEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: uxtb r0, r0 +; CHECK-T2-NEXT: uxtab r0, r0, r1 +; CHECK-T2-NEXT: clz r0, r0 +; CHECK-T2-NEXT: lsrs r0, r0, #5 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i32 + %conv1 = zext i8 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp eq i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IllEbT(i64 %a, i64 %b) { +; CHECK-ARM-LABEL: test_NE_IllEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r2, r2, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r1, r2, r1 +; CHECK-ARM-NEXT: orrs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IllEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r4, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r4, r3 +; CHECK-T1-NEXT: eors r4, r1 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r4 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: test_NE_IllEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: mov.w r12, #0 +; CHECK-T2-NEXT: sbc.w r3, r12, r3 +; CHECK-T2-NEXT: eors r1, r3 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %add = sub i64 0, %b + %cmp = icmp ne i64 %add, %a + ret i1 %cmp +} + +define i1 @test_NE_IliEbT(i64 %a, i32 %b) { +; CHECK-ARM-LABEL: test_NE_IliEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r0, r0, #0 +; CHECK-ARM-NEXT: rsc r1, r1, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31 +; CHECK-ARM-NEXT: orrs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IliEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r3, #0 +; CHECK-T1-NEXT: rsbs r0, r0, #0 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: asrs r1, r2, #31 +; CHECK-T1-NEXT: eors r1, r3 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r1 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IliEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: mov.w r3, #0 +; CHECK-T2-NEXT: sbc.w r1, r3, r1 +; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i32 %b to i64 + %add = sub i64 0, %a + %cmp = icmp ne i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IlsEbT(i64 %a, i16 %b) { +; CHECK-ARM-LABEL: test_NE_IlsEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r0, r0, #0 +; CHECK-ARM-NEXT: sxth r2, r2 +; CHECK-ARM-NEXT: rsc r1, r1, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31 +; CHECK-ARM-NEXT: orrs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IlsEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r3, #0 +; CHECK-T1-NEXT: rsbs r4, r0, #0 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: lsls r0, r2, #16 +; CHECK-T1-NEXT: asrs r1, r0, #31 +; CHECK-T1-NEXT: eors r1, r3 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: eors r0, r4 +; CHECK-T1-NEXT: orrs r0, r1 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: test_NE_IlsEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r3, #0 +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: sxth r2, r2 +; CHECK-T2-NEXT: sbc.w r1, r3, r1 +; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %b to i64 + %add = sub i64 0, %a + %cmp = icmp ne i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IlcEbT(i64 %a, i8 %b) { +; CHECK-ARM-LABEL: test_NE_IlcEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r0, r0, #0 +; CHECK-ARM-NEXT: uxtb r2, r2 +; CHECK-ARM-NEXT: rsc r1, r1, #0 +; CHECK-ARM-NEXT: eor r0, r2, r0 +; CHECK-ARM-NEXT: orrs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IlcEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r3, #0 +; CHECK-T1-NEXT: rsbs r4, r0, #0 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: movs r0, #255 +; CHECK-T1-NEXT: ands r0, r2 +; CHECK-T1-NEXT: eors r0, r4 +; CHECK-T1-NEXT: orrs r0, r3 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: test_NE_IlcEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r3, #0 +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: uxtb r2, r2 +; CHECK-T2-NEXT: sbc.w r1, r3, r1 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %b to i64 + %add = sub i64 0, %a + %cmp = icmp ne i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IilEbT(i32 %a, i64 %b) { +; CHECK-ARM-LABEL: test_NE_IilEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r1, r2, #0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r1, r0, r1 +; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31 +; CHECK-ARM-NEXT: orrs r0, r1, r0 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IilEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r1, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r1, r3 +; CHECK-T1-NEXT: asrs r3, r0, #31 +; CHECK-T1-NEXT: eors r3, r1 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r3 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IilEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: sbcs r1, r3 +; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i32 %a to i64 + %add = sub i64 0, %b + %cmp = icmp ne i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IiiEbT(i32 %a, i32 %b) { +; CHECK-ARM-LABEL: test_NE_IiiEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: subs r0, r1, r0 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IiiEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: rsbs r1, r1, #0 +; CHECK-T1-NEXT: subs r0, r1, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IiiEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: subs r0, r1, r0 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %add = sub i32 0, %b + %cmp = icmp ne i32 %add, %a + ret i1 %cmp +} + +define i1 @test_NE_IisEbT(i32 %a, i16 %b) { +; CHECK-ARM-LABEL: test_NE_IisEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsb r0, r0, #0 +; CHECK-ARM-NEXT: sxth r1, r1 +; CHECK-ARM-NEXT: subs r0, r1, r0 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IisEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: rsbs r0, r0, #0 +; CHECK-T1-NEXT: lsls r1, r1, #16 +; CHECK-T1-NEXT: asrs r1, r1, #16 +; CHECK-T1-NEXT: subs r0, r0, r1 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IisEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: sxth r1, r1 +; CHECK-T2-NEXT: subs r0, r1, r0 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %b to i32 + %add = sub i32 0, %a + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IicEbT(i32 %a, i8 %b) { +; CHECK-ARM-LABEL: test_NE_IicEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsb r0, r0, #0 +; CHECK-ARM-NEXT: uxtb r1, r1 +; CHECK-ARM-NEXT: subs r0, r1, r0 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IicEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r1 +; CHECK-T1-NEXT: rsbs r0, r0, #0 +; CHECK-T1-NEXT: subs r0, r2, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IicEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r0, r0, #0 +; CHECK-T2-NEXT: uxtb r1, r1 +; CHECK-T2-NEXT: subs r0, r1, r0 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %b to i32 + %add = sub i32 0, %a + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IslEbT(i16 %a, i64 %b) { +; CHECK-ARM-LABEL: test_NE_IslEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r1, r2, #0 +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r1, r0, r1 +; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31 +; CHECK-ARM-NEXT: orrs r0, r1, r0 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IslEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r1, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r1, r3 +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r3, r0, #31 +; CHECK-T1-NEXT: eors r3, r1 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r3 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IslEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: sbcs r1, r3 +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i64 + %add = sub i64 0, %b + %cmp = icmp ne i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IsiEbT(i16 %a, i32 %b) { +; CHECK-ARM-LABEL: test_NE_IsiEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: subs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IsiEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: rsbs r1, r1, #0 +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: subs r0, r1, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IsiEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: subs r0, r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i32 + %add = sub i32 0, %b + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IssEbT(i16 %a, i16 %b) { +; CHECK-ARM-LABEL: test_NE_IssEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxth r1, r1 +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: subs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IssEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: lsls r1, r1, #16 +; CHECK-T1-NEXT: asrs r1, r1, #16 +; CHECK-T1-NEXT: rsbs r1, r1, #0 +; CHECK-T1-NEXT: subs r0, r1, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IssEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxth r1, r1 +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: subs r0, r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i32 + %conv1 = sext i16 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IscEbT(i16 %a, i8 %b) { +; CHECK-ARM-LABEL: test_NE_IscEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: uxtb r1, r1 +; CHECK-ARM-NEXT: sxth r0, r0 +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: subs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IscEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r1 +; CHECK-T1-NEXT: rsbs r1, r2, #0 +; CHECK-T1-NEXT: lsls r0, r0, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: subs r0, r1, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IscEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: uxtb r1, r1 +; CHECK-T2-NEXT: sxth r0, r0 +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: subs r0, r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = sext i16 %a to i32 + %conv1 = zext i8 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IclEbT(i8 %a, i64 %b) { +; CHECK-ARM-LABEL: test_NE_IclEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsbs r1, r2, #0 +; CHECK-ARM-NEXT: uxtb r0, r0 +; CHECK-ARM-NEXT: rsc r2, r3, #0 +; CHECK-ARM-NEXT: eor r0, r0, r1 +; CHECK-ARM-NEXT: orrs r0, r0, r2 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IclEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r1, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: sbcs r1, r3 +; CHECK-T1-NEXT: movs r3, #255 +; CHECK-T1-NEXT: ands r0, r3 +; CHECK-T1-NEXT: eors r0, r2 +; CHECK-T1-NEXT: orrs r0, r1 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IclEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: uxtb r0, r0 +; CHECK-T2-NEXT: sbcs r1, r3 +; CHECK-T2-NEXT: eors r0, r2 +; CHECK-T2-NEXT: orrs r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i64 + %add = sub i64 0, %b + %cmp = icmp ne i64 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IciEbT(i8 %a, i32 %b) { +; CHECK-ARM-LABEL: test_NE_IciEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: uxtb r0, r0 +; CHECK-ARM-NEXT: subs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IciEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r0 +; CHECK-T1-NEXT: rsbs r0, r1, #0 +; CHECK-T1-NEXT: subs r0, r2, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IciEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: uxtb r0, r0 +; CHECK-T2-NEXT: subs r0, r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i32 + %add = sub i32 0, %b + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IcsEbT(i8 %a, i16 %b) { +; CHECK-ARM-LABEL: test_NE_IcsEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: sxth r1, r1 +; CHECK-ARM-NEXT: uxtb r0, r0 +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: subs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IcsEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r2, r0 +; CHECK-T1-NEXT: lsls r0, r1, #16 +; CHECK-T1-NEXT: asrs r0, r0, #16 +; CHECK-T1-NEXT: rsbs r0, r0, #0 +; CHECK-T1-NEXT: subs r0, r2, r0 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IcsEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: sxth r1, r1 +; CHECK-T2-NEXT: uxtb r0, r0 +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: subs r0, r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i32 + %conv1 = sext i16 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @test_NE_IccEbT(i8 %a, i8 %b) { +; CHECK-ARM-LABEL: test_NE_IccEbT: +; CHECK-ARM: @ %bb.0: @ %entry +; CHECK-ARM-NEXT: uxtb r1, r1 +; CHECK-ARM-NEXT: uxtb r0, r0 +; CHECK-ARM-NEXT: rsb r1, r1, #0 +; CHECK-ARM-NEXT: subs r0, r0, r1 +; CHECK-ARM-NEXT: movwne r0, #1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: test_NE_IccEbT: +; CHECK-T1: @ %bb.0: @ %entry +; CHECK-T1-NEXT: movs r2, #255 +; CHECK-T1-NEXT: ands r0, r2 +; CHECK-T1-NEXT: ands r1, r2 +; CHECK-T1-NEXT: rsbs r1, r1, #0 +; CHECK-T1-NEXT: subs r0, r0, r1 +; CHECK-T1-NEXT: subs r1, r0, #1 +; CHECK-T1-NEXT: sbcs r0, r1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: test_NE_IccEbT: +; CHECK-T2: @ %bb.0: @ %entry +; CHECK-T2-NEXT: uxtb r1, r1 +; CHECK-T2-NEXT: uxtb r0, r0 +; CHECK-T2-NEXT: rsbs r1, r1, #0 +; CHECK-T2-NEXT: subs r0, r0, r1 +; CHECK-T2-NEXT: it ne +; CHECK-T2-NEXT: movne r0, #1 +; CHECK-T2-NEXT: bx lr +entry: + %conv = zext i8 %a to i32 + %conv1 = zext i8 %b to i32 + %add = sub nsw i32 0, %conv1 + %cmp = icmp ne i32 %conv, %add + ret i1 %cmp +} + +define i1 @cmn_large_imm(i32 %a) { +; CHECK-ARM-LABEL: cmn_large_imm: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #64765 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #64764 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwgt r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: cmn_large_imm: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI32_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: bgt .LBB32_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB32_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI32_0: +; CHECK-T1-NEXT: .long 4244438269 @ 0xfcfcfcfd +; +; CHECK-T2-LABEL: cmn_large_imm: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmn.w r0, #50529027 +; CHECK-T2-NEXT: it gt +; CHECK-T2-NEXT: movgt r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sgt i32 %a, -50529027 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_slt(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_slt: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4097 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65281 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwlt r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_slt: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI33_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: blt .LBB33_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB33_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI33_0: +; CHECK-T1-NEXT: .long 4278259713 @ 0xff011001 +; +; CHECK-T2-LABEL: almost_immediate_neg_slt: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4097 +; CHECK-T2-NEXT: movt r2, #65281 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp slt i32 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_slt_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_slt_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4097 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65281 +; CHECK-ARM-NEXT: subs r0, r0, r3 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r1, r12 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_slt_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: ldr r3, .LCPI34_0 +; CHECK-T1-NEXT: adds r2, r2, r3 +; CHECK-T1-NEXT: adcs r1, r0 +; CHECK-T1-NEXT: bge .LBB34_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB34_2: +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI34_0: +; CHECK-T1-NEXT: .long 16707583 @ 0xfeefff +; +; CHECK-T2-LABEL: almost_immediate_neg_slt_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4097 +; CHECK-T2-NEXT: movt r3, #65281 +; CHECK-T2-NEXT: subs r0, r0, r3 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs r0, r1, #-1 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp slt i64 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_sge(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_sge: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4096 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65281 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwgt r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_sge: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI35_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: bgt .LBB35_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB35_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI35_0: +; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000 +; +; CHECK-T2-LABEL: almost_immediate_neg_sge: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4096 +; CHECK-T2-NEXT: movt r2, #65281 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it gt +; CHECK-T2-NEXT: movgt r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sge i32 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_sge_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_sge_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4096 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65281 +; CHECK-ARM-NEXT: subs r0, r3, r0 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r12, r1 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_sge_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: mvns r3, r0 +; CHECK-T1-NEXT: ldr r4, .LCPI36_0 +; CHECK-T1-NEXT: subs r2, r4, r2 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: bge .LBB36_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB36_2: +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI36_0: +; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000 +; +; CHECK-T2-LABEL: almost_immediate_neg_sge_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4096 +; CHECK-T2-NEXT: movt r3, #65281 +; CHECK-T2-NEXT: mov.w r12, #-1 +; CHECK-T2-NEXT: subs r0, r3, r0 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs.w r0, r12, r1 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sge i64 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_uge(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_uge: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4096 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65281 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwhi r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_uge: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI37_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: bhi .LBB37_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB37_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI37_0: +; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000 +; +; CHECK-T2-LABEL: almost_immediate_neg_uge: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4096 +; CHECK-T2-NEXT: movt r2, #65281 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it hi +; CHECK-T2-NEXT: movhi r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp uge i32 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_uge_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_uge_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4096 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65281 +; CHECK-ARM-NEXT: subs r0, r3, r0 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r12, r1 +; CHECK-ARM-NEXT: movwlo r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_uge_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: mvns r3, r0 +; CHECK-T1-NEXT: ldr r4, .LCPI38_0 +; CHECK-T1-NEXT: subs r2, r4, r2 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: bhs .LBB38_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB38_2: +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI38_0: +; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000 +; +; CHECK-T2-LABEL: almost_immediate_neg_uge_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4096 +; CHECK-T2-NEXT: movt r3, #65281 +; CHECK-T2-NEXT: mov.w r12, #-1 +; CHECK-T2-NEXT: subs r0, r3, r0 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs.w r0, r12, r1 +; CHECK-T2-NEXT: it lo +; CHECK-T2-NEXT: movlo r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp uge i64 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_ult(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_ult: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4097 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65281 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwlo r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_ult: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI39_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: blo .LBB39_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB39_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI39_0: +; CHECK-T1-NEXT: .long 4278259713 @ 0xff011001 +; +; CHECK-T2-LABEL: almost_immediate_neg_ult: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4097 +; CHECK-T2-NEXT: movt r2, #65281 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it lo +; CHECK-T2-NEXT: movlo r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp ult i32 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_ult_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_ult_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4097 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65281 +; CHECK-ARM-NEXT: subs r0, r0, r3 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r1, r12 +; CHECK-ARM-NEXT: movwlo r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_ult_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: ldr r3, .LCPI40_0 +; CHECK-T1-NEXT: adds r2, r2, r3 +; CHECK-T1-NEXT: adcs r1, r0 +; CHECK-T1-NEXT: bhs .LBB40_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB40_2: +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI40_0: +; CHECK-T1-NEXT: .long 16707583 @ 0xfeefff +; +; CHECK-T2-LABEL: almost_immediate_neg_ult_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4097 +; CHECK-T2-NEXT: movt r3, #65281 +; CHECK-T2-NEXT: subs r0, r0, r3 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs r0, r1, #-1 +; CHECK-T2-NEXT: it lo +; CHECK-T2-NEXT: movlo r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp ult i64 %x, -16707583 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_sle(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_sle: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4096 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65280 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwlt r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_sle: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI41_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: blt .LBB41_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB41_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI41_0: +; CHECK-T1-NEXT: .long 4278194176 @ 0xff001000 +; +; CHECK-T2-LABEL: almost_immediate_neg_sle: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4096 +; CHECK-T2-NEXT: movt r2, #65280 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sle i32 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_sle_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_sle_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4096 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65280 +; CHECK-ARM-NEXT: subs r0, r0, r3 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r1, r12 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_sle_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: ldr r3, .LCPI42_0 +; CHECK-T1-NEXT: adds r2, r2, r3 +; CHECK-T1-NEXT: adcs r1, r0 +; CHECK-T1-NEXT: bge .LBB42_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB42_2: +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI42_0: +; CHECK-T1-NEXT: .long 16773120 @ 0xfff000 +; +; CHECK-T2-LABEL: almost_immediate_neg_sle_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4096 +; CHECK-T2-NEXT: movt r3, #65280 +; CHECK-T2-NEXT: subs r0, r0, r3 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs r0, r1, #-1 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sle i64 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_sgt(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_sgt: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4095 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65280 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwgt r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_sgt: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI43_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: bgt .LBB43_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB43_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI43_0: +; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff +; +; CHECK-T2-LABEL: almost_immediate_neg_sgt: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4095 +; CHECK-T2-NEXT: movt r2, #65280 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it gt +; CHECK-T2-NEXT: movgt r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sgt i32 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_sgt_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_sgt_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4095 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65280 +; CHECK-ARM-NEXT: subs r0, r3, r0 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r12, r1 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_sgt_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: mvns r3, r0 +; CHECK-T1-NEXT: ldr r4, .LCPI44_0 +; CHECK-T1-NEXT: subs r2, r4, r2 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: bge .LBB44_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB44_2: +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI44_0: +; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff +; +; CHECK-T2-LABEL: almost_immediate_neg_sgt_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4095 +; CHECK-T2-NEXT: movt r3, #65280 +; CHECK-T2-NEXT: mov.w r12, #-1 +; CHECK-T2-NEXT: subs r0, r3, r0 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs.w r0, r12, r1 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp sgt i64 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_ule(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_ule: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4096 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65280 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwlo r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_ule: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI45_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: blo .LBB45_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB45_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI45_0: +; CHECK-T1-NEXT: .long 4278194176 @ 0xff001000 +; +; CHECK-T2-LABEL: almost_immediate_neg_ule: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4096 +; CHECK-T2-NEXT: movt r2, #65280 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it lo +; CHECK-T2-NEXT: movlo r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp ule i32 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_ule_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_ule_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4096 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65280 +; CHECK-ARM-NEXT: subs r0, r0, r3 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r1, r12 +; CHECK-ARM-NEXT: movwlo r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_ule_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: ldr r3, .LCPI46_0 +; CHECK-T1-NEXT: adds r2, r2, r3 +; CHECK-T1-NEXT: adcs r1, r0 +; CHECK-T1-NEXT: bhs .LBB46_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB46_2: +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI46_0: +; CHECK-T1-NEXT: .long 16773120 @ 0xfff000 +; +; CHECK-T2-LABEL: almost_immediate_neg_ule_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4096 +; CHECK-T2-NEXT: movt r3, #65280 +; CHECK-T2-NEXT: subs r0, r0, r3 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs r0, r1, #-1 +; CHECK-T2-NEXT: it lo +; CHECK-T2-NEXT: movlo r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp ule i64 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_ugt(i32 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_ugt: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r2, #4095 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: movt r2, #65280 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwhi r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_ugt: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: ldr r1, .LCPI47_0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: bhi .LBB47_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB47_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI47_0: +; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff +; +; CHECK-T2-LABEL: almost_immediate_neg_ugt: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r2, #4095 +; CHECK-T2-NEXT: movt r2, #65280 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it hi +; CHECK-T2-NEXT: movhi r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %cmp = icmp ugt i32 %x, -16773121 + ret i1 %cmp +} + +define i1 @almost_immediate_neg_ugt_64(i64 %x) { +; CHECK-ARM-LABEL: almost_immediate_neg_ugt_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: movw r3, #4095 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: movt r3, #65280 +; CHECK-ARM-NEXT: subs r0, r3, r0 +; CHECK-ARM-NEXT: mvn r12, #0 +; CHECK-ARM-NEXT: sbcs r0, r12, r1 +; CHECK-ARM-NEXT: movwlo r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: almost_immediate_neg_ugt_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: .save {r4, lr} +; CHECK-T1-NEXT: push {r4, lr} +; CHECK-T1-NEXT: movs r2, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: mvns r3, r0 +; CHECK-T1-NEXT: ldr r4, .LCPI48_0 +; CHECK-T1-NEXT: subs r2, r4, r2 +; CHECK-T1-NEXT: sbcs r3, r1 +; CHECK-T1-NEXT: bhs .LBB48_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB48_2: +; CHECK-T1-NEXT: pop {r4} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; CHECK-T1-NEXT: .p2align 2 +; CHECK-T1-NEXT: @ %bb.3: +; CHECK-T1-NEXT: .LCPI48_0: +; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff +; +; CHECK-T2-LABEL: almost_immediate_neg_ugt_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movw r3, #4095 +; CHECK-T2-NEXT: movt r3, #65280 +; CHECK-T2-NEXT: mov.w r12, #-1 +; CHECK-T2-NEXT: subs r0, r3, r0 +; CHECK-T2-NEXT: mov.w r2, #0 +; CHECK-T2-NEXT: sbcs.w r0, r12, r1 +; CHECK-T2-NEXT: it lo +; CHECK-T2-NEXT: movlo r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %cmp = icmp ugt i64 %x, -16773121 + ret i1 %cmp +} + +define i1 @cmn_nsw(i32 %a, i32 %b) { +; CHECK-ARM-LABEL: cmn_nsw: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: cmn r0, r1 +; CHECK-ARM-NEXT: movwgt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: cmn_nsw: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: cmn r0, r1 +; CHECK-T1-NEXT: bgt .LBB49_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB49_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: cmn_nsw: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movs r2, #0 +; CHECK-T2-NEXT: cmn r0, r1 +; CHECK-T2-NEXT: it gt +; CHECK-T2-NEXT: movgt r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %sub = sub nsw i32 0, %b + %cmp = icmp sgt i32 %a, %sub + ret i1 %cmp +} + +define i1 @cmn_nsw_64(i64 %a, i64 %b) { +; CHECK-ARM-LABEL: cmn_nsw_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: rsbs r12, r2, #0 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: rsc r3, r3, #0 +; CHECK-ARM-NEXT: subs r0, r12, r0 +; CHECK-ARM-NEXT: sbcs r0, r3, r1 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: cmn_nsw_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: .save {r4, r5, r7, lr} +; CHECK-T1-NEXT: push {r4, r5, r7, lr} +; CHECK-T1-NEXT: movs r4, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: mov r12, r0 +; CHECK-T1-NEXT: mov r5, r12 +; CHECK-T1-NEXT: sbcs r5, r3 +; CHECK-T1-NEXT: subs r2, r2, r4 +; CHECK-T1-NEXT: sbcs r5, r1 +; CHECK-T1-NEXT: bge .LBB50_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB50_2: +; CHECK-T1-NEXT: pop {r4, r5, r7} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: cmn_nsw_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: mov.w r12, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: sbc.w r3, r12, r3 +; CHECK-T2-NEXT: subs r0, r2, r0 +; CHECK-T2-NEXT: sbcs.w r0, r3, r1 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt.w r12, #1 +; CHECK-T2-NEXT: mov r0, r12 +; CHECK-T2-NEXT: bx lr + %sub = sub nsw i64 0, %b + %cmp = icmp sgt i64 %a, %sub + ret i1 %cmp +} + +define i1 @cmn_nsw_neg(i32 %a, i32 %b) { +; CHECK-ARM-LABEL: cmn_nsw_neg: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: rsb r2, r1, #0 +; CHECK-ARM-NEXT: mov r1, #0 +; CHECK-ARM-NEXT: cmp r0, r2 +; CHECK-ARM-NEXT: movwgt r1, #1 +; CHECK-ARM-NEXT: mov r0, r1 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: cmn_nsw_neg: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: rsbs r1, r1, #0 +; CHECK-T1-NEXT: cmp r0, r1 +; CHECK-T1-NEXT: bgt .LBB51_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB51_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: cmn_nsw_neg: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: rsbs r2, r1, #0 +; CHECK-T2-NEXT: movs r1, #0 +; CHECK-T2-NEXT: cmp r0, r2 +; CHECK-T2-NEXT: it gt +; CHECK-T2-NEXT: movgt r1, #1 +; CHECK-T2-NEXT: mov r0, r1 +; CHECK-T2-NEXT: bx lr + %sub = sub i32 0, %b + %cmp = icmp sgt i32 %a, %sub + ret i1 %cmp +} + +define i1 @cmn_swap(i32 %a, i32 %b) { +; CHECK-ARM-LABEL: cmn_swap: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: cmn r1, r0 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: cmn_swap: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: cmn r1, r0 +; CHECK-T1-NEXT: blt .LBB52_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: bx lr +; CHECK-T1-NEXT: .LBB52_2: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: bx lr +; +; CHECK-T2-LABEL: cmn_swap: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: movs r2, #0 +; CHECK-T2-NEXT: cmn r1, r0 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt r2, #1 +; CHECK-T2-NEXT: mov r0, r2 +; CHECK-T2-NEXT: bx lr + %sub = sub nsw i32 0, %b + %cmp = icmp sgt i32 %sub, %a + ret i1 %cmp +} + + +define i1 @cmn_nsw_neg_64(i64 %a, i64 %b) { +; CHECK-ARM-LABEL: cmn_nsw_neg_64: +; CHECK-ARM: @ %bb.0: +; CHECK-ARM-NEXT: rsbs r12, r2, #0 +; CHECK-ARM-NEXT: mov r2, #0 +; CHECK-ARM-NEXT: rsc r3, r3, #0 +; CHECK-ARM-NEXT: subs r0, r12, r0 +; CHECK-ARM-NEXT: sbcs r0, r3, r1 +; CHECK-ARM-NEXT: movwlt r2, #1 +; CHECK-ARM-NEXT: mov r0, r2 +; CHECK-ARM-NEXT: bx lr +; +; CHECK-T1-LABEL: cmn_nsw_neg_64: +; CHECK-T1: @ %bb.0: +; CHECK-T1-NEXT: .save {r4, r5, r7, lr} +; CHECK-T1-NEXT: push {r4, r5, r7, lr} +; CHECK-T1-NEXT: movs r4, r0 +; CHECK-T1-NEXT: movs r0, #0 +; CHECK-T1-NEXT: rsbs r2, r2, #0 +; CHECK-T1-NEXT: mov r12, r0 +; CHECK-T1-NEXT: mov r5, r12 +; CHECK-T1-NEXT: sbcs r5, r3 +; CHECK-T1-NEXT: subs r2, r2, r4 +; CHECK-T1-NEXT: sbcs r5, r1 +; CHECK-T1-NEXT: bge .LBB53_2 +; CHECK-T1-NEXT: @ %bb.1: +; CHECK-T1-NEXT: movs r0, #1 +; CHECK-T1-NEXT: .LBB53_2: +; CHECK-T1-NEXT: pop {r4, r5, r7} +; CHECK-T1-NEXT: pop {r1} +; CHECK-T1-NEXT: bx r1 +; +; CHECK-T2-LABEL: cmn_nsw_neg_64: +; CHECK-T2: @ %bb.0: +; CHECK-T2-NEXT: mov.w r12, #0 +; CHECK-T2-NEXT: rsbs r2, r2, #0 +; CHECK-T2-NEXT: sbc.w r3, r12, r3 +; CHECK-T2-NEXT: subs r0, r2, r0 +; CHECK-T2-NEXT: sbcs.w r0, r3, r1 +; CHECK-T2-NEXT: it lt +; CHECK-T2-NEXT: movlt.w r12, #1 +; CHECK-T2-NEXT: mov r0, r12 +; CHECK-T2-NEXT: bx lr + %sub = sub i64 0, %b + %cmp = icmp sgt i64 %a, %sub + ret i1 %cmp +} diff --git a/llvm/test/MC/ARM/arm-shift-encoding.s b/llvm/test/MC/ARM/arm-shift-encoding.s index 3c57b67f6e3ba..52a6f42942986 100644 --- a/llvm/test/MC/ARM/arm-shift-encoding.s +++ b/llvm/test/MC/ARM/arm-shift-encoding.s @@ -76,7 +76,7 @@ @ CHECK: str r9, [r10], r11 @ encoding: [0x0b,0x90,0x8a,0xe6] @ Uses printSORegImmOperand(), used by ADCrsi ADDrsi ANDrsi BICrsi EORrsi -@ ORRrsi RSBrsi RSCrsi SBCrsi SUBrsi CMNzrsi CMPrsi MOVsi MVNsi TEQrsi TSTrsi +@ ORRrsi RSBrsi RSCrsi SBCrsi SUBrsi CMNrsi CMPrsi MOVsi MVNsi TEQrsi TSTrsi adc sp, lr, pc adc r1, r8, r9, lsr #32 diff --git a/llvm/test/MC/ARM/thumb-shift-encoding.s b/llvm/test/MC/ARM/thumb-shift-encoding.s index ad35aff450556..6226e0204757c 100644 --- a/llvm/test/MC/ARM/thumb-shift-encoding.s +++ b/llvm/test/MC/ARM/thumb-shift-encoding.s @@ -1,7 +1,7 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple thumbv7 -show-encoding < %s | FileCheck %s @ Uses printT2SOOperand(), used by t2ADCrs t2ADDrs t2ANDrs t2BICrs t2EORrs -@ t2ORNrs t2ORRrs t2RSBrs t2SBCrs t2SUBrs t2CMNzrs t2CMPrs t2MOVSsi t2MOVsi +@ t2ORNrs t2ORRrs t2RSBrs t2SBCrs t2SUBrs t2CMNrs t2CMPrs t2MOVSsi t2MOVsi @ t2MVNs t2TEQrs t2TSTrs sbc.w r12, lr, r0