On Fri, Dec 17, 2010 at 8:18 PM, Richard Earnshaw <rearn...@arm.com> wrote: > > On Thu, 2010-12-16 at 14:45 -0800, Carrot Wei wrote: >> Hi >> >> Compile the following c code with options -march=armv7-a -mthumb -Os >> >> int foo (int s) >> { >> return s == 1; >> } >> >> GCC 4.6 generates: >> >> 00000000 <foo>: >> 0: f1a0 0301 sub.w r3, r0, #1 // A >> 4: 4258 negs r0, r3 >> 6: eb40 0003 adc.w r0, r0, r3 // B >> a: 4770 bx lr >> >> Notice that instructions A and B are 32 bits. In thumb2 we can use subs and >> adcs >> instead so they will be 16 bits. >> > > This sequence already contains an instruction that sets the flags as a > necessary part of the sequence. Why doesn't it also generate > flag-corrupting variants of the other two instructions when the > registers selected are suitable? It seems silly to force the compiler > to do yet more work to clean up this code. >
This revised patch uses new adc insn which simply clobber the CC register. For the sub instruction I still use the CC setting form since the existing pattern subsi3_compare does this. Tested on arm qemu without regression. thanks Carrot ChangeLog: 2011-05-16 Wei Guozhi <car...@google.com> PR target/46975 * config/arm/arm.md (*addsi3_carryin_compare0_<optab>): New pattern. (peephole2 for conditional move): Generate 16 bit instructions. ChangeLog: 2010-05-16 Wei Guozhi <car...@google.com> PR target/46975 * gcc.target/arm/pr46975.c: New testcase. Index: testsuite/gcc.target/arm/pr46975.c =================================================================== --- testsuite/gcc.target/arm/pr46975.c (revision 0) +++ testsuite/gcc.target/arm/pr46975.c (revision 0) @@ -0,0 +1,9 @@ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler "subs" } } */ +/* { dg-final { scan-assembler "adcs" } } */ + +int foo (int s) +{ + return s == 1; +} Index: config/arm/arm.md =================================================================== --- config/arm/arm.md (revision 173770) +++ config/arm/arm.md (working copy) @@ -985,6 +985,17 @@ (const_string "alu_shift_reg")))] ) +(define_insn "*addsi3_carryin_clobercc_<optab>" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r") + (match_operand:SI 2 "arm_rhs_operand" "rI")) + (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0)))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_32BIT" + "adc%.\\t%0, %1, %2" + [(set_attr "conds" "set")] +) + (define_expand "incscc" [(set (match_operand:SI 0 "s_register_operand" "=r,r") (plus:SI (match_operator:SI 2 "arm_comparison_operator" @@ -8788,14 +8799,19 @@ (set (match_dup 0) (const_int 1))) (match_scratch:SI 3 "r")] "TARGET_32BIT" - [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2))) + [(parallel + [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 1) (match_dup 2))) + (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))]) (parallel [(set (reg:CC CC_REGNUM) (compare:CC (const_int 0) (match_dup 3))) (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))]) - (set (match_dup 0) - (plus:SI (plus:SI (match_dup 0) (match_dup 3)) - (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]) + (parallel + [(set (match_dup 0) + (plus:SI (plus:SI (match_dup 0) (match_dup 3)) + (geu:SI (reg:CC CC_REGNUM) (const_int 0)))) + (clobber (reg:CC CC_REGNUM))])]) (define_insn "*cond_move" [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")