diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-01-22 00:08:13 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-01-22 00:08:13 +0000 |
commit | d5d2baec2609da3ade9ca205e87c88d35e9e6976 (patch) | |
tree | 0250b253e3176ffc8d6f5655b0de22bb09b56270 /lib/Target | |
parent | 8767d32e758db3ffef796342a2650f337cf3404a (diff) | |
download | external_llvm-d5d2baec2609da3ade9ca205e87c88d35e9e6976.zip external_llvm-d5d2baec2609da3ade9ca205e87c88d35e9e6976.tar.gz external_llvm-d5d2baec2609da3ade9ca205e87c88d35e9e6976.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94119 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 12 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 10 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 12 | ||||
-rw-r--r-- | lib/Target/ARM/README.txt | 9 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2SizeReduction.cpp | 3 |
5 files changed, 31 insertions, 15 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index b1efab1..af508ee 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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 diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index c304ff9..746caff 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -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))]>, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 34a793c..c7591d2 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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)>>; diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt index 11c48ad..a6f26a5 100644 --- a/lib/Target/ARM/README.txt +++ b/lib/Target/ARM/README.txt @@ -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. diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp index 35359aa..95288bf 100644 --- a/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -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 }, |