From 47089c91aea7bdd8b2fa81223dfdd3484a20fd12 Mon Sep 17 00:00:00 2001 From: Jyotsna Verma Date: Tue, 23 Apr 2013 19:15:55 +0000 Subject: [PATCH] Hexagon: Remove assembler mapped instruction definitions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180133 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonHardwareLoops.cpp | 6 -- lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 11 +++ lib/Target/Hexagon/HexagonInstrInfo.cpp | 8 -- lib/Target/Hexagon/HexagonInstrInfo.td | 100 +++++++++++--------- lib/Target/Hexagon/HexagonNewValueJump.cpp | 63 ++++-------- test/CodeGen/Hexagon/cmp_pred2.ll | 87 +++++++++++++++++ 6 files changed, 167 insertions(+), 108 deletions(-) create mode 100644 test/CodeGen/Hexagon/cmp_pred2.ll diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 178662447a7..0c78ebbfc3e 100644 --- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -541,12 +541,6 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, case Hexagon::CMPEQrr: Cmp = !Negated ? Comparison::EQ : Comparison::NE; break; - case Hexagon::CMPLTrr: - Cmp = !Negated ? Comparison::LTs : Comparison::GEs; - break; - case Hexagon::CMPLTUrr: - Cmp = !Negated ? Comparison::LTu : Comparison::GEu; - break; case Hexagon::CMPGTUri: case Hexagon::CMPGTUrr: Cmp = !Negated ? Comparison::GTu : Comparison::LEu; diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 2aecb413a6d..ba6c10035fb 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -160,6 +160,17 @@ inline SDValue XformU7ToU7M1Imm(signed Imm) { return CurDAG->getTargetConstant(Imm - 1, MVT::i8); } +// XformS8ToS8M1Imm - Return a target constant decremented by 1. +inline SDValue XformSToSM1Imm(signed Imm) { + return CurDAG->getTargetConstant(Imm - 1, MVT::i32); +} + +// XformU8ToU8M1Imm - Return a target constant decremented by 1. +inline SDValue XformUToUM1Imm(unsigned Imm) { + assert((Imm >= 1) && "Cannot decrement unsigned int less than 1"); + return CurDAG->getTargetConstant(Imm - 1, MVT::i32); +} + // Include the pieces autogenerated from the target description. #include "HexagonGenDAGISel.inc" }; diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index a753da53032..725fc8a5bd0 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -325,8 +325,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI, case Hexagon::CMPGTUrr: case Hexagon::CMPGTri: case Hexagon::CMPGTrr: - case Hexagon::CMPLTUrr: - case Hexagon::CMPLTrr: SrcReg = MI->getOperand(1).getReg(); Mask = ~0; break; @@ -366,8 +364,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI, case Hexagon::CMPhEQrr_xor_V4: case Hexagon::CMPhGTUrr_V4: case Hexagon::CMPhGTrr_shl_V4: - case Hexagon::CMPLTUrr: - case Hexagon::CMPLTrr: SrcReg2 = MI->getOperand(2).getReg(); return true; @@ -2114,14 +2110,10 @@ bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const { default: return false; case Hexagon::CMPEQrr: case Hexagon::CMPEQri: - case Hexagon::CMPLTrr: case Hexagon::CMPGTrr: case Hexagon::CMPGTri: - case Hexagon::CMPLTUrr: case Hexagon::CMPGTUrr: case Hexagon::CMPGTUri: - case Hexagon::CMPGEri: - case Hexagon::CMPGEUri: return true; } } diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index f671fd32892..6e2637b508b 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -14,6 +14,8 @@ include "HexagonInstrFormats.td" include "HexagonOperands.td" +//===----------------------------------------------------------------------===// + // Multi-class for logical operators. multiclass ALU32_rr_ri { def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), @@ -34,12 +36,6 @@ multiclass CMP64_rr { [(set (i1 PredRegs:$dst), (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>; } -multiclass CMP32_rr { - def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), - !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), - [(set (i1 PredRegs:$dst), - (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; -} multiclass CMP32_rr_ri_s10 { let CextOpcode = CextOp in { @@ -75,14 +71,6 @@ multiclass CMP32_rr_ri_u9 { } } -multiclass CMP32_ri_u8 { -let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in - def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Ext:$c), - !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b), - u8ExtPred:$c))]>; -} - multiclass CMP32_ri_s8 { let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c), @@ -188,11 +176,6 @@ def OR_ri : ALU32_ri<(outs IntRegs:$dst), [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), s10ExtPred:$src2))]>, ImmRegRel; -def NOT_rr : ALU32_rr<(outs IntRegs:$dst), - (ins IntRegs:$src1), - "$dst = not($src1)", - [(set (i32 IntRegs:$dst), (not (i32 IntRegs:$src1)))]>; - let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10, InputType = "imm", CextOpcode = "AND" in def AND_ri : ALU32_ri<(outs IntRegs:$dst), @@ -200,10 +183,7 @@ def AND_ri : ALU32_ri<(outs IntRegs:$dst), "$dst = and($src1, #$src2)", [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), s10ExtPred:$src2))]>, ImmRegRel; -// Negate. -def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), - "$dst = neg($src1)", - [(set (i32 IntRegs:$dst), (ineg (i32 IntRegs:$src1)))]>; + // Nop. let neverHasSideEffects = 1 in def NOP : ALU32_rr<(outs), (ins), @@ -219,6 +199,12 @@ def SUB_ri : ALU32_ri<(outs IntRegs:$dst), [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>, ImmRegRel; +// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs). +def : Pat<(not (i32 IntRegs:$src1)), + (SUB_ri -1, (i32 IntRegs:$src1))>; + +// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs). +// Pattern definition for 'neg' was not necessary. multiclass TFR_Pred { let isPredicatedFalse = PredNot in { @@ -535,11 +521,21 @@ def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst), // Compare. defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel; defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel; -defm CMPLT : CMP32_rr<"cmp.lt", setlt>; -defm CMPLTU : CMP32_rr<"cmp.ltu", setult>; defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel; -defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>; -defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>; + +// SDNode for converting immediate C to C-1. +def DEC_CONST_SIGNED : SDNodeXFormgetSExtValue(); + return XformSToSM1Imm(imm); +}]>; + +// SDNode for converting immediate C to C-1. +def DEC_CONST_UNSIGNED : SDNodeXFormgetZExtValue(); + return XformUToUM1Imm(imm); +}]>; def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), "$dst = cl0($src1)", @@ -2132,10 +2128,11 @@ def : Pat <(add (i1 PredRegs:$src1), -1), // Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) => // p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1). +// cmp.lt(r0, r1) -> cmp.gt(r1, r0) def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), (i32 IntRegs:$src3), (i32 IntRegs:$src4)), - (i32 (TFR_condset_rr (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), + (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), (i32 IntRegs:$src4), (i32 IntRegs:$src3)))>, Requires<[HasV2TOnly]>; @@ -2153,16 +2150,16 @@ def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2, // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i) // => r0 = TFR_condset_ir(p0, #i, r1) -def : Pat <(select (not PredRegs:$src1), IntRegs:$src2, s12ImmPred:$src3), +def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3), (i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3, (i32 IntRegs:$src2)))>; // Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump. -def : Pat <(brcond (not PredRegs:$src1), bb:$offset), +def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset), (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>; // Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2). -def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)), +def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))), (i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>; // Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned. @@ -2201,13 +2198,16 @@ def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset), def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset), (JMP_c (i1 PredRegs:$src1), bb:$offset)>; +// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1) def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)), bb:$offset), - (JMP_cNot (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2), bb:$offset)>; + (JMP_cNot (CMPGTri (i32 IntRegs:$src1), + (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>; +// cmp.lt(r0, r1) -> cmp.gt(r1, r0) def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), bb:$offset), - (JMP_c (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), bb:$offset)>; + (JMP_c (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>; def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), bb:$offset), @@ -2299,8 +2299,8 @@ def : Pat<(i64 (anyext (i32 IntRegs:$src1))), // Map cmple -> cmpgt. // rs <= rt -> !(rs > rt). -def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ImmPred:$src2)), - (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ImmPred:$src2)))>; +def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)), + (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>; // rs <= rt -> !(rs > rt). def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))), @@ -2313,8 +2313,8 @@ def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), // Map cmpne -> cmpeq. // Hexagon_TODO: We should improve on this. // rs != rt -> !(rs == rt). -def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)), - (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2))))>; +def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)), + (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>; // Map cmpne(Rs) -> !cmpeqe(Rs). // rs != rt -> !(rs == rt). @@ -2336,8 +2336,9 @@ def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))), (i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>; -def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ImmPred:$src2)), - (i1 (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2))>; +// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1) +def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)), + (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>; // Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss). // rss >= rtt -> !(rtt > rss). @@ -2346,9 +2347,10 @@ def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), (i64 DoubleRegs:$src1)))))>; // Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm). +// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1). // rs < rt -> !(rs >= rt). -def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)), - (i1 (NOT_p (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2)))>; +def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)), + (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>; // Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs). // rs < rt -> rt > rs. @@ -2372,13 +2374,17 @@ def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))), def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), (i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>; -// Generate cmpgeu(Rs, #u8) -def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ImmPred:$src2)), - (i1 (CMPGEUri (i32 IntRegs:$src1), u8ImmPred:$src2))>; +// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs) +def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)), + (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>; + +// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1) +def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)), + (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>; // Generate cmpgtu(Rs, #u9) -def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)), - (i1 (CMPGTUri (i32 IntRegs:$src1), u9ImmPred:$src2))>; +def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)), + (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>; // Map from Rs >= Rt -> !(Rt > Rs). // rs >= rt -> !(rt > rs). @@ -2390,7 +2396,7 @@ def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))), def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>; -// Map from cmpleu(Rs, Rs) -> !cmpgtu(Rs, Rs). +// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt). // Map from (Rs <= Rt) -> !(Rs > Rt). def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))), (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>; diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp index 5e80e48b01d..11608898457 100644 --- a/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp @@ -208,14 +208,10 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, // range specified by the arch. if (!secondReg) { int64_t v = MI->getOperand(2).getImm(); - if (MI->getOpcode() == Hexagon::CMPGEri || - (MI->getOpcode() == Hexagon::CMPGEUri && v > 0)) - --v; if (!(isUInt<5>(v) || ((MI->getOpcode() == Hexagon::CMPEQri || - MI->getOpcode() == Hexagon::CMPGTri || - MI->getOpcode() == Hexagon::CMPGEri) && + MI->getOpcode() == Hexagon::CMPGTri) && (v == -1)))) return false; } @@ -284,7 +280,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg, return Hexagon::JMP_EQriPtneg_nv_V4; } - case Hexagon::CMPLTrr: case Hexagon::CMPGTrr: { if (secondRegNewified) return Hexagon::JMP_GTrrdnPt_nv_V4; @@ -292,13 +287,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg, return Hexagon::JMP_GTrrPt_nv_V4; } - case Hexagon::CMPGEri: { - if (reg >= 1) - return Hexagon::JMP_GTriPt_nv_V4; - else - return Hexagon::JMP_GTriPtneg_nv_V4; - } - case Hexagon::CMPGTri: { if (reg >= 0) return Hexagon::JMP_GTriPt_nv_V4; @@ -306,7 +294,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg, return Hexagon::JMP_GTriPtneg_nv_V4; } - case Hexagon::CMPLTUrr: case Hexagon::CMPGTUrr: { if (secondRegNewified) return Hexagon::JMP_GTUrrdnPt_nv_V4; @@ -317,13 +304,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg, case Hexagon::CMPGTUri: return Hexagon::JMP_GTUriPt_nv_V4; - case Hexagon::CMPGEUri: { - if (reg == 0) - return Hexagon::JMP_EQrrPt_nv_V4; - else - return Hexagon::JMP_GTUriPt_nv_V4; - } - default: llvm_unreachable("Could not find matching New Value Jump instruction."); } @@ -525,10 +505,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { if (isSecondOpReg) { // In case of CMPLT, or CMPLTU, or EQ with the second register // to newify, swap the operands. - if (cmpInstr->getOpcode() == Hexagon::CMPLTrr || - cmpInstr->getOpcode() == Hexagon::CMPLTUrr || - (cmpInstr->getOpcode() == Hexagon::CMPEQrr && - feederReg == (unsigned) cmpOp2)) { + if (cmpInstr->getOpcode() == Hexagon::CMPEQrr && + feederReg == (unsigned) cmpOp2) { unsigned tmp = cmpReg1; bool tmpIsKill = MO1IsKill; cmpReg1 = cmpOp2; @@ -586,38 +564,29 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { if (invertPredicate) opc = QII->getInvertedPredicatedOpcode(opc); - // Manage the conversions from CMPGEUri to either CMPEQrr - // or CMPGTUri properly. See Arch spec for CMPGEUri instructions. - // This has to be after the getNewValueJumpOpcode function call as - // second operand of the compare could be modified in this logic. - if (cmpInstr->getOpcode() == Hexagon::CMPGEUri) { - if (cmpOp2 == 0) { - cmpOp2 = cmpReg1; - MO2IsKill = MO1IsKill; - isSecondOpReg = true; - } else - --cmpOp2; - } - - // Manage the conversions from CMPGEri to CMPGTUri properly. - // See Arch spec for CMPGEri instructions. - if (cmpInstr->getOpcode() == Hexagon::CMPGEri) - --cmpOp2; - - if (isSecondOpReg) { + if (isSecondOpReg) NewMI = BuildMI(*MBB, jmpPos, dl, QII->get(opc)) .addReg(cmpReg1, getKillRegState(MO1IsKill)) .addReg(cmpOp2, getKillRegState(MO2IsKill)) .addMBB(jmpTarget); - } - else { + + else if ((cmpInstr->getOpcode() == Hexagon::CMPEQri || + cmpInstr->getOpcode() == Hexagon::CMPGTri) && + cmpOp2 == -1 ) + // Corresponding new-value compare jump instructions don't have the + // operand for -1 immediate value. + NewMI = BuildMI(*MBB, jmpPos, dl, + QII->get(opc)) + .addReg(cmpReg1, getKillRegState(MO1IsKill)) + .addMBB(jmpTarget); + + else NewMI = BuildMI(*MBB, jmpPos, dl, QII->get(opc)) .addReg(cmpReg1, getKillRegState(MO1IsKill)) .addImm(cmpOp2) .addMBB(jmpTarget); - } assert(NewMI && "New Value Jump Instruction Not created!"); if (cmpInstr->getOperand(0).isReg() && diff --git a/test/CodeGen/Hexagon/cmp_pred2.ll b/test/CodeGen/Hexagon/cmp_pred2.ll new file mode 100644 index 00000000000..a20b9f09b6e --- /dev/null +++ b/test/CodeGen/Hexagon/cmp_pred2.ll @@ -0,0 +1,87 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s | FileCheck %s +; Make sure that the assembler mapped compare instructions are correctly generated. + +@c = common global i32 0, align 4 + +define i32 @test1(i32 %a, i32 %b) nounwind { +; CHECK-NOT: cmp.ge +; CHECK: cmp.gt +entry: + %cmp = icmp slt i32 %a, 100 + br i1 %cmp, label %if.then, label %entry.if.end_crit_edge + +entry.if.end_crit_edge: + %.pre = load i32* @c, align 4 + br label %if.end + +if.then: + %sub = add nsw i32 %a, -10 + store i32 %sub, i32* @c, align 4 + br label %if.end + +if.end: + %0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ] + ret i32 %0 +} + +define i32 @test2(i32 %a, i32 %b) nounwind { +; CHECK-NOT: cmp.lt +; CHECK: cmp.gt +entry: + %cmp = icmp sge i32 %a, %b + br i1 %cmp, label %entry.if.end_crit_edge, label %if.then + +entry.if.end_crit_edge: + %.pre = load i32* @c, align 4 + br label %if.end + +if.then: + %sub = add nsw i32 %a, -10 + store i32 %sub, i32* @c, align 4 + br label %if.end + +if.end: + %0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ] + ret i32 %0 +} + +define i32 @test4(i32 %a, i32 %b) nounwind { +; CHECK-NOT: cmp.ltu +; CHECK: cmp.gtu +entry: + %cmp = icmp uge i32 %a, %b + br i1 %cmp, label %entry.if.end_crit_edge, label %if.then + +entry.if.end_crit_edge: + %.pre = load i32* @c, align 4 + br label %if.end + +if.then: + %sub = add i32 %a, -10 + store i32 %sub, i32* @c, align 4 + br label %if.end + +if.end: + %0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ] + ret i32 %0 +} + +define i32 @test5(i32 %a, i32 %b) nounwind { +; CHECK: cmp.gtu +entry: + %cmp = icmp uge i32 %a, 29999 + br i1 %cmp, label %if.then, label %entry.if.end_crit_edge + +entry.if.end_crit_edge: + %.pre = load i32* @c, align 4 + br label %if.end + +if.then: + %sub = add i32 %a, -10 + store i32 %sub, i32* @c, align 4 + br label %if.end + +if.end: + %0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ] + ret i32 %0 +} -- 2.34.1