diff --git a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 39d4452cef7d..484835767a4b 100644 --- a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -540,15 +540,15 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, return nullptr; switch (CondOpc) { - case Hexagon::CMPEQri: + case Hexagon::C2_cmpeqi: case Hexagon::C2_cmpeq: Cmp = !Negated ? Comparison::EQ : Comparison::NE; break; - case Hexagon::CMPGTUri: + case Hexagon::C2_cmpgtui: case Hexagon::C2_cmpgtu: Cmp = !Negated ? Comparison::GTu : Comparison::LEu; break; - case Hexagon::CMPGTri: + case Hexagon::C2_cmpgti: case Hexagon::C2_cmpgt: Cmp = !Negated ? Comparison::GTs : Comparison::LEs; break; diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 8d3916e12488..d483b2830cda 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -347,13 +347,13 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI, // Set mask and the first source register. switch (Opc) { case Hexagon::CMPEHexagon4rr: - case Hexagon::CMPEQri: + case Hexagon::C2_cmpeqi: case Hexagon::C2_cmpeq: case Hexagon::CMPGT64rr: case Hexagon::CMPGTU64rr: - case Hexagon::CMPGTUri: + case Hexagon::C2_cmpgtui: case Hexagon::C2_cmpgtu: - case Hexagon::CMPGTri: + case Hexagon::C2_cmpgti: case Hexagon::C2_cmpgt: SrcReg = MI->getOperand(1).getReg(); Mask = ~0; @@ -397,9 +397,9 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI, SrcReg2 = MI->getOperand(2).getReg(); return true; - case Hexagon::CMPEQri: - case Hexagon::CMPGTUri: - case Hexagon::CMPGTri: + case Hexagon::C2_cmpeqi: + case Hexagon::C2_cmpgtui: + case Hexagon::C2_cmpgti: case Hexagon::CMPbEQri_V4: case Hexagon::CMPbGTUri_V4: case Hexagon::CMPhEQri_V4: @@ -1265,11 +1265,11 @@ bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const { switch (MI->getOpcode()) { default: return false; case Hexagon::C2_cmpeq: - case Hexagon::CMPEQri: + case Hexagon::C2_cmpeqi: case Hexagon::C2_cmpgt: - case Hexagon::CMPGTri: + case Hexagon::C2_cmpgti: case Hexagon::C2_cmpgtu: - case Hexagon::CMPGTUri: + case Hexagon::C2_cmpgtui: return true; } } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 5dfb13c629c7..9bcb07e90c03 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -27,6 +27,47 @@ def F64 : PatLeaf<(f64 DoubleRegs:$R)>; //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// Compare +//===----------------------------------------------------------------------===// +let hasSideEffects = 0, isCompare = 1, InputType = "imm", isExtendable = 1, + opExtendable = 2 in +class T_CMP MajOp, bit isNot, Operand ImmOp> + : ALU32Inst <(outs PredRegs:$dst), + (ins IntRegs:$src1, ImmOp:$src2), + "$dst = "#!if(isNot, "!","")#mnemonic#"($src1, #$src2)", + [], "",ALU32_2op_tc_2early_SLOT0123 >, ImmRegRel { + bits<2> dst; + bits<5> src1; + bits<10> src2; + let CextOpcode = mnemonic; + let opExtentBits = !if(!eq(mnemonic, "cmp.gtu"), 9, 10); + let isExtentSigned = !if(!eq(mnemonic, "cmp.gtu"), 0, 1); + + let IClass = 0b0111; + + let Inst{27-24} = 0b0101; + let Inst{23-22} = MajOp; + let Inst{21} = !if(!eq(mnemonic, "cmp.gtu"), 0, src2{9}); + let Inst{20-16} = src1; + let Inst{13-5} = src2{8-0}; + let Inst{4} = isNot; + let Inst{3-2} = 0b00; + let Inst{1-0} = dst; + } + +def C2_cmpeqi : T_CMP <"cmp.eq", 0b00, 0, s10Ext>; +def C2_cmpgti : T_CMP <"cmp.gt", 0b01, 0, s10Ext>; +def C2_cmpgtui : T_CMP <"cmp.gtu", 0b10, 0, u9Ext>; + +class T_CMP_pat + : Pat<(i1 (OpNode (i32 IntRegs:$src1), ImmPred:$src2)), + (MI IntRegs:$src1, ImmPred:$src2)>; + +def : T_CMP_pat ; +def : T_CMP_pat ; +def : T_CMP_pat ; + // Multi-class for logical operators. multiclass ALU32_rr_ri { def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), @@ -47,36 +88,6 @@ multiclass CMP64_rr { [(set (i1 PredRegs:$dst), (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>; } - -multiclass CMP32_rr_ri_s10 { - let CextOpcode = CextOp in { - let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, - opExtentBits = 10, InputType = "imm" in - def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c), - !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set (i1 PredRegs:$dst), - (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>; - } -} - -multiclass CMP32_rr_ri_u9 { - let CextOpcode = CextOp in { - let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, - opExtentBits = 9, InputType = "imm" in - def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c), - !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set (i1 PredRegs:$dst), - (OpNode (i32 IntRegs:$b), u9ExtPred:$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), - !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), - [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b), - s8ExtPred:$c))]>; -} } //===----------------------------------------------------------------------===// @@ -731,11 +742,6 @@ def: T_cmp32_rr_pat; def: T_cmp32_rr_pat, i1>; def: T_cmp32_rr_pat, i1>; -// Compare. -defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel; -defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel; -defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel; - // SDNode for converting immediate C to C-1. def DEC_CONST_SIGNED : SDNodeXForm; + (JMP_f (C2_cmpeqi (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>; def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset), (JMP_f (i1 PredRegs:$src1), bb:$offset)>; @@ -2464,7 +2470,7 @@ def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), 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_f (CMPGTri (i32 IntRegs:$src1), + (JMP_f (C2_cmpgti (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>; // cmp.lt(r0, r1) -> cmp.gt(r1, r0) @@ -2563,7 +2569,7 @@ def : Pat<(i64 (anyext (i32 IntRegs:$src1))), // Map cmple -> cmpgt. // rs <= rt -> !(rs > rt). def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)), - (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>; + (i1 (NOT_p (C2_cmpgti (i32 IntRegs:$src1), s10ExtPred:$src2)))>; // rs <= rt -> !(rs > rt). def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))), @@ -2577,7 +2583,7 @@ def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), // Hexagon_TODO: We should improve on this. // rs != rt -> !(rs == rt). def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)), - (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>; + (i1 (NOT_p(i1 (C2_cmpeqi (i32 IntRegs:$src1), s10ExtPred:$src2))))>; // Map cmpne(Rs) -> !cmpeqe(Rs). // rs != rt -> !(rs == rt). @@ -2601,7 +2607,7 @@ def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$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)))>; + (i1 (C2_cmpgti (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>; // Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss). // rss >= rtt -> !(rtt > rss). @@ -2613,7 +2619,7 @@ def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), // !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1). // rs < rt -> !(rs >= rt). def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)), - (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>; + (i1 (NOT_p (C2_cmpgti (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>; // Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs). // rs < rt -> rt > rs. @@ -2643,11 +2649,11 @@ def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)), // 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)))>; + (i1 (C2_cmpgtui (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>; // Generate cmpgtu(Rs, #u9) def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)), - (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>; + (i1 (C2_cmpgtui (i32 IntRegs:$src1), u9ExtPred:$src2))>; // Map from Rs >= Rt -> !(Rt > Rs). // rs >= rt -> !(rt > rs). diff --git a/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp b/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp index 8f7be60b70ba..9870024dd43f 100644 --- a/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp @@ -227,8 +227,8 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, int64_t v = MI->getOperand(2).getImm(); if (!(isUInt<5>(v) || - ((MI->getOpcode() == Hexagon::CMPEQri || - MI->getOpcode() == Hexagon::CMPGTri) && + ((MI->getOpcode() == Hexagon::C2_cmpeqi || + MI->getOpcode() == Hexagon::C2_cmpgti) && (v == -1)))) return false; } @@ -302,7 +302,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, return taken ? Hexagon::CMPEQrr_t_Jumpnv_t_V4 : Hexagon::CMPEQrr_t_Jumpnv_nt_V4; - case Hexagon::CMPEQri: { + case Hexagon::C2_cmpeqi: { if (reg >= 0) return taken ? Hexagon::CMPEQri_t_Jumpnv_t_V4 : Hexagon::CMPEQri_t_Jumpnv_nt_V4; @@ -320,7 +320,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, : Hexagon::CMPGTrr_t_Jumpnv_nt_V4; } - case Hexagon::CMPGTri: { + case Hexagon::C2_cmpgti: { if (reg >= 0) return taken ? Hexagon::CMPGTri_t_Jumpnv_t_V4 : Hexagon::CMPGTri_t_Jumpnv_nt_V4; @@ -338,7 +338,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, : Hexagon::CMPGTUrr_t_Jumpnv_nt_V4; } - case Hexagon::CMPGTUri: + case Hexagon::C2_cmpgtui: return taken ? Hexagon::CMPGTUri_t_Jumpnv_t_V4 : Hexagon::CMPGTUri_t_Jumpnv_nt_V4; @@ -611,8 +611,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { .addReg(cmpOp2, getKillRegState(MO2IsKill)) .addMBB(jmpTarget); - else if ((cmpInstr->getOpcode() == Hexagon::CMPEQri || - cmpInstr->getOpcode() == Hexagon::CMPGTri) && + else if ((cmpInstr->getOpcode() == Hexagon::C2_cmpeqi || + cmpInstr->getOpcode() == Hexagon::C2_cmpgti) && cmpOp2 == -1 ) // Corresponding new-value compare jump instructions don't have the // operand for -1 immediate value. diff --git a/llvm/test/MC/Hexagon/inst_cmp_eqi.ll b/llvm/test/MC/Hexagon/inst_cmp_eqi.ll new file mode 100644 index 000000000000..78c929023503 --- /dev/null +++ b/llvm/test/MC/Hexagon/inst_cmp_eqi.ll @@ -0,0 +1,10 @@ +;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \ +;; RUN: | llvm-objdump -s - | FileCheck %s + +define i1 @foo (i32 %a) +{ + %1 = icmp eq i32 %a, 42 + ret i1 %1 +} + +; CHECK: 0000 40450075 00400000 00c09f52 diff --git a/llvm/test/MC/Hexagon/inst_cmp_gti.ll b/llvm/test/MC/Hexagon/inst_cmp_gti.ll new file mode 100644 index 000000000000..36828cc4209b --- /dev/null +++ b/llvm/test/MC/Hexagon/inst_cmp_gti.ll @@ -0,0 +1,10 @@ +;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \ +;; RUN: | llvm-objdump -s - | FileCheck %s + +define i1 @foo (i32 %a) +{ + %1 = icmp sgt i32 %a, 42 + ret i1 %1 +} + +; CHECK: 0000 40454075 00400000 00c09f52 diff --git a/llvm/test/MC/Hexagon/inst_cmp_ugti.ll b/llvm/test/MC/Hexagon/inst_cmp_ugti.ll new file mode 100644 index 000000000000..459b5bf77d31 --- /dev/null +++ b/llvm/test/MC/Hexagon/inst_cmp_ugti.ll @@ -0,0 +1,10 @@ +;; RUN: llc -mtriple=hexagon-unknown-elf -filetype=obj %s -o - \ +;; RUN: | llvm-objdump -s - | FileCheck %s + +define i1 @foo (i32 %a) +{ + %1 = icmp ugt i32 %a, 42 + ret i1 %1 +} + +; CHECK: 0000 40458075 00400000 00c09f52