mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
Fix PR5694. The CMN instructions set the flags differently from CMP, so they
cannot be directly interchanged for comparisons against negated values. Disable the CMN instructions for the time being. llvm-svn: 94119
This commit is contained in:
parent
30dee16eed
commit
231a0d01a9
@ -1539,8 +1539,10 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
|
||||
|
||||
defm CMP : AI1_cmp_irs<0b1010, "cmp",
|
||||
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
|
||||
defm CMN : AI1_cmp_irs<0b1011, "cmn",
|
||||
BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
|
||||
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
|
||||
// Compare-to-zero still works out, just not the relationals
|
||||
//defm CMN : AI1_cmp_irs<0b1011, "cmn",
|
||||
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
|
||||
|
||||
// Note that TST/TEQ don't set all the same flags that CMP does!
|
||||
defm TST : AI1_cmp_irs<0b1000, "tst",
|
||||
@ -1553,11 +1555,11 @@ defm CMPz : AI1_cmp_irs<0b1010, "cmp",
|
||||
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<(ARMcmp GPR:$src, so_imm_neg:$imm),
|
||||
// (CMNri GPR:$src, so_imm_neg:$imm)>;
|
||||
|
||||
def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
|
||||
(CMNri GPR:$src, so_imm_neg:$imm)>;
|
||||
(CMNzri GPR:$src, so_imm_neg:$imm)>;
|
||||
|
||||
|
||||
// Conditional moves
|
||||
|
@ -534,10 +534,12 @@ def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
|
||||
|
||||
// CMN register
|
||||
let Defs = [CPSR] in {
|
||||
def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
|
||||
"cmn", "\t$lhs, $rhs",
|
||||
[(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
|
||||
T1DataProcessing<0b1011>;
|
||||
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
|
||||
// Compare-to-zero still works out, just not the relationals
|
||||
//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
|
||||
// "cmn", "\t$lhs, $rhs",
|
||||
// [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
|
||||
// T1DataProcessing<0b1011>;
|
||||
def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
|
||||
"cmn", "\t$lhs, $rhs",
|
||||
[(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>,
|
||||
|
@ -1609,16 +1609,18 @@ defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
|
||||
defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
|
||||
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
|
||||
|
||||
defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
|
||||
BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
|
||||
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
|
||||
// Compare-to-zero still works out, just not the relationals
|
||||
//defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
|
||||
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
|
||||
defm t2CMNz : T2I_cmp_irs<0b1000, "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<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
|
||||
// (t2CMNri 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)>;
|
||||
(t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
|
||||
|
||||
defm t2TST : T2I_cmp_irs<0b0000, "tst",
|
||||
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
|
||||
|
@ -596,3 +596,12 @@ Make use of the "rbit" instruction.
|
||||
|
||||
Take a look at test/CodeGen/Thumb2/machine-licm.ll. ARM should be taught how
|
||||
to licm and cse the unnecessary load from cp#1.
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
The CMN instruction sets the flags like an ADD instruction, while CMP sets
|
||||
them like a subtract. Therefore to be able to use CMN for comparisons other
|
||||
than the Z bit, we'll need additional logic to reverse the conditionals
|
||||
associated with the comparison. Perhaps a pseudo-instruction for the comparison,
|
||||
with a post-codegen pass to clean up and handle the condition codes?
|
||||
See PR5694 for testcase.
|
||||
|
@ -65,7 +65,8 @@ namespace {
|
||||
{ ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 0 },
|
||||
{ ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 0 },
|
||||
{ ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 0 },
|
||||
{ ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 },
|
||||
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
|
||||
//{ ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 },
|
||||
{ ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0 },
|
||||
{ ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0 },
|
||||
{ ARM::t2CMPzri,ARM::tCMPzi8, 0, 8, 0, 1, 0, 2,0, 0 },
|
||||
|
Loading…
Reference in New Issue
Block a user