case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG";
case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD";
case ARMISD::CMP: return "ARMISD::CMP";
- case ARMISD::CMPNZ: return "ARMISD::CMPNZ";
+ case ARMISD::CMPZ: return "ARMISD::CMPZ";
case ARMISD::CMPFP: return "ARMISD::CMPFP";
case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0";
case ARMISD::FMSTAT: return "ARMISD::FMSTAT";
break;
case ARMCC::EQ:
case ARMCC::NE:
- case ARMCC::MI:
- case ARMCC::PL:
- // Uses only N and Z Flags
- CompareType = ARMISD::CMPNZ;
+ // Uses only Z Flag
+ CompareType = ARMISD::CMPZ;
break;
}
ARMCC = DAG.getConstant(CondCode, MVT::i32);
PIC_ADD, // Add with a PC operand and a PIC label.
CMP, // ARM compare instructions.
- CMPNZ, // ARM compare that uses only N or Z flags.
+ CMPZ, // ARM compare that sets only Z flag.
CMPFP, // ARM VFP compare instruction, sets FPSCR.
CMPFPw0, // ARM VFP compare against zero instruction, sets FPSCR.
FMSTAT, // ARM fmstat instruction.
def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
[SDNPOutFlag]>;
-def ARMcmpNZ : SDNode<"ARMISD::CMPNZ", SDT_ARMCmp,
- [SDNPOutFlag]>;
+def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
+ [SDNPOutFlag,SDNPCommutative]>;
def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
// Note that TST/TEQ don't set all the same flags that CMP does!
defm TST : AI1_cmp_irs<0b1000, "tst",
- BinOpFrag<(ARMcmpNZ (and node:$LHS, node:$RHS), 0)>, 1>;
+ BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
defm TEQ : AI1_cmp_irs<0b1001, "teq",
- BinOpFrag<(ARMcmpNZ (xor node:$LHS, node:$RHS), 0)>, 1>;
+ BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
-defm CMPnz : AI1_cmp_irs<0b1010, "cmp",
- BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>;
-defm CMNnz : AI1_cmp_irs<0b1011, "cmn",
- BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
+defm CMPz : AI1_cmp_irs<0b1010, "cmp",
+ BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
+defm CMNz : AI1_cmp_irs<0b1011, "cmn",
+ BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
(CMNri GPR:$src, so_imm_neg:$imm)>;
-def : ARMPat<(ARMcmpNZ GPR:$src, so_imm_neg:$imm),
+def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
(CMNri GPR:$src, so_imm_neg:$imm)>;
def tCMN : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
"cmn $lhs, $rhs",
[(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
-def tCMNNZ : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
- "cmn $lhs, $rhs",
- [(ARMcmpNZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
+def tCMNZ : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
+ "cmn $lhs, $rhs",
+ [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
}
// CMP immediate
def tCMPi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs),
"cmp $lhs, $rhs",
[(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
-def tCMPNZi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs),
- "cmp $lhs, $rhs",
- [(ARMcmpNZ tGPR:$lhs, imm0_255:$rhs)]>;
+def tCMPZi8 : T1I<(outs), (ins tGPR:$lhs, i32imm:$rhs),
+ "cmp $lhs, $rhs",
+ [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
}
def tCMPr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
"cmp $lhs, $rhs",
[(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
-def tCMPNZr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
- "cmp $lhs, $rhs",
- [(ARMcmpNZ tGPR:$lhs, tGPR:$rhs)]>;
+def tCMPZr : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
+ "cmp $lhs, $rhs",
+ [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
}
// TODO: A7-37: CMP(3) - cmp hi regs
let isCommutable = 1, Defs = [CPSR] in
def tTST : T1I<(outs), (ins tGPR:$lhs, tGPR:$rhs),
"tst $lhs, $rhs",
- [(ARMcmpNZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
+ [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
// zero-extend byte
def tUXTB : T1I<(outs tGPR:$dst), (ins tGPR:$src),
defm t2CMP : T2I_cmp_is<"cmp",
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
-defm t2CMPnz : T2I_cmp_is<"cmp",
- BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>;
+defm t2CMPz : T2I_cmp_is<"cmp",
+ BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
defm t2CMN : T2I_cmp_is<"cmn",
BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
-defm t2CMNnz : T2I_cmp_is<"cmn",
- BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
+defm t2CMNz : T2I_cmp_is<"cmn",
+ BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
-def : T2Pat<(ARMcmpNZ GPR:$src, t2_so_imm_neg:$imm),
+def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
// FIXME: TST, TEQ, etc.
--- /dev/null
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep {cmn\\W*r\[0-9\],\\W*r\[0-9\]} | count 4
+
+define i1 @f1(i32 %a, i32 %b) {
+ %nb = sub i32 0, %b
+ %tmp = icmp ne i32 %a, %nb
+ ret i1 %tmp
+}
+
+define i1 @f2(i32 %a, i32 %b) {
+ %nb = sub i32 0, %b
+ %tmp = icmp ne i32 %nb, %a
+ ret i1 %tmp
+}
+
+define i1 @f3(i32 %a, i32 %b) {
+ %nb = sub i32 0, %b
+ %tmp = icmp eq i32 %a, %nb
+ ret i1 %tmp
+}
+
+define i1 @f4(i32 %a, i32 %b) {
+ %nb = sub i32 0, %b
+ %tmp = icmp eq i32 %nb, %a
+ ret i1 %tmp
+}