Make sure its set for all CMP, CMN, TST instructions, which do work inside IT blocks. Split the TEQ pattern so that it can be predicated in ARM mode for better compare-and-swap generation. --- gcc/config/arm/arm.md | 40 ++++++++++++++++++++++++++++++---------- 1 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index b01343c..3b24627 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -836,7 +836,8 @@ "@ cmn%?\\t%0, %1 cmp%?\\t%0, #%n1" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "predicable" "yes")] ) (define_insn "*compare_negsi_si" @@ -846,7 +847,8 @@ (match_operand:SI 1 "s_register_operand" "r")))] "TARGET_32BIT" "cmn%?\\t%1, %0" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "predicable" "yes")] ) ;; This is the canonicalization of addsi3_compare0_for_combiner when the @@ -947,7 +949,8 @@ "@ cmn%?\\t%0, %1 cmp%?\\t%0, #%n1" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "predicable" "yes")] ) (define_insn "*compare_addsi2_op1" @@ -960,7 +963,8 @@ "@ cmn%?\\t%0, %1 cmp%?\\t%0, #%n1" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "predicable" "yes")] ) (define_insn "*addsi3_carryin_<optab>" @@ -2260,7 +2264,8 @@ output_asm_insn (\"tst%?\\t%0, %1\", operands); return \"\"; " - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "predicable" "yes")] ) (define_insn_and_split "*ne_zeroextractsi" @@ -3074,6 +3079,19 @@ [(set_attr "conds" "set")] ) +(define_insn "*xorsi3_compare0_scratch_arm" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r") + (match_operand:SI 1 "arm_rhs_operand" "rI")) + (const_int 0)))] + "TARGET_ARM" + "teq%?\\t%0, %1" + [(set_attr "conds" "set") + ; Not predicable via IT block (since it doesn't modify the flags there), + ; but we're keen on having this predicate in ARM mode for compare-and-swap. + (set_attr "predicable" "yes")] +) + (define_insn "xorsi3_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r") @@ -3081,8 +3099,7 @@ (const_int 0)))] "TARGET_32BIT" "teq%?\\t%0, %1" - [(set_attr "conds" "set")] -) + [(set_attr "conds" "set")]) ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), ; (NOT D) we can sometimes merge the final NOT into one of the following @@ -4702,7 +4719,8 @@ (const_int 0)))] "TARGET_32BIT" "tst\\t%0, #255" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "predicable" "yes")] ) (define_expand "extendhisi2" @@ -7458,7 +7476,8 @@ cmn%?\\t%0, #%n1" [(set_attr "conds" "set") (set_attr "arch" "t2,t2,any,any") - (set_attr "length" "2,2,4,4")] + (set_attr "length" "2,2,4,4") + (set_attr "predicable" "yes")] ) (define_insn "*cmpsi_shiftsi" @@ -7499,7 +7518,8 @@ [(set_attr "conds" "set") (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") (const_string "alu_shift") - (const_string "alu_shift_reg")))] + (const_string "alu_shift_reg"))) + (set_attr "predicable" "yes")] ) ;; DImode comparisons. The generic code generates branches that -- 1.7.6.4