Hi Maintainers, This patch fixes the PR 60617 that occurs when we turn on reload pass in thumb2 mode.
It occurs for the pattern "*ior_scc_scc" that gets generated for the 3 argument of the below function call. JIT:emitStoreInt32(dst,regT0m, (op1 == dst || op2 == dst))); (----snip---) (insn 634 633 635 27 (parallel [ (set (reg:SI 3 r3) (ior:SI (eq:SI (reg/v:SI 110 [ dst ]) <== This operand r5 is registers gets assigned (reg/v:SI 112 [ op2 ])) (eq:SI (reg/v:SI 110 [ dst ]) <== This operand (reg/v:SI 111 [ op1 ])))) (clobber (reg:CC 100 cc)) ]) ../Source/JavaScriptCore/jit/JITArithmetic32_64.cpp:179 300 {*ior_scc_scc (----snip---) The issue here is that the above pattern demands 5 registers (LO_REGS). But when we are in reload, registers r0 is used for pointer to the class, r1 and r2 for first and second argument. r7 is used for stack pointer. So we are left with r3,r4,r5 and r6. But the above patterns needs five LO_REGS. Hence we get spill failure when processing the last register operand in that pattern, In ARM port, TARGET_LIKELY_SPILLED_CLASS is defined for Thumb-1 and for thumb 2 mode there is mention of using LO_REG in the comment as below. "Care should be taken to avoid adding thumb-2 patterns that require many low registers" So conservative fix is not to allow this pattern for Thumb-2 mode. I allowed these pattern for Thumb2 when we have constant operands for comparison. That makes the target tests arm/thum2-cond-cmp-1.c to thum2-cond-cmp-4.c pass. Regression tested with gcc 4.9 branch since in trunk this bug is masked revision 209897. Please provide your suggestion on this patch regards, Venkat.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 0284f95..e8fbb11 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -10654,7 +10654,7 @@ [(match_operand:SI 4 "s_register_operand" "r") (match_operand:SI 5 "arm_add_operand" "rIL")]))) (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT + "TARGET_ARM && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) != CCmode)" "#" @@ -10675,6 +10675,36 @@ (set_attr "type" "multiple")] ) +(define_insn_and_split "*ior_scc_scc_imm" + [(set (match_operand:SI 0 "s_register_operand" "=Ts") + (ior:SI (match_operator:SI 3 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_addimm_operand" "IL")]) + (match_operator:SI 6 "arm_comparison_operator" + [(match_operand:SI 4 "s_register_operand" "r") + (match_operand:SI 5 "arm_addimm_operand" "IL")]))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2 + && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) + != CCmode)" + "#" + "TARGET_THUMB2 && reload_completed" + [(set (match_dup 7) + (compare + (ior:SI + (match_op_dup 3 [(match_dup 1) (match_dup 2)]) + (match_op_dup 6 [(match_dup 4) (match_dup 5)])) + (const_int 0))) + (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] + "operands[7] + = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], + DOM_CC_X_OR_Y), + CC_REGNUM);" + [(set_attr "conds" "clob") + (set_attr "length" "16") + (set_attr "type" "multiple")] +) + ; If the above pattern is followed by a CMP insn, then the compare is ; redundant, since we can rework the conditional instruction that follows. (define_insn_and_split "*ior_scc_scc_cmp" @@ -10714,7 +10744,7 @@ [(match_operand:SI 4 "s_register_operand" "r") (match_operand:SI 5 "arm_add_operand" "rIL")]))) (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT + "TARGET_ARM && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) != CCmode)" "#" @@ -10737,6 +10767,38 @@ (set_attr "type" "multiple")] ) +(define_insn_and_split "*and_scc_scc_imm" + [(set (match_operand:SI 0 "s_register_operand" "=Ts") + (and:SI (match_operator:SI 3 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_addimm_operand" "IL")]) + (match_operator:SI 6 "arm_comparison_operator" + [(match_operand:SI 4 "s_register_operand" "r") + (match_operand:SI 5 "arm_addimm_operand" "IL")]))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2 + && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) + != CCmode)" + "#" + "TARGET_THUMB2 && reload_completed + && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) + != CCmode)" + [(set (match_dup 7) + (compare + (and:SI + (match_op_dup 3 [(match_dup 1) (match_dup 2)]) + (match_op_dup 6 [(match_dup 4) (match_dup 5)])) + (const_int 0))) + (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] + "operands[7] + = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], + DOM_CC_X_AND_Y), + CC_REGNUM);" + [(set_attr "conds" "clob") + (set_attr "length" "16") + (set_attr "type" "multiple")] +) + ; If the above pattern is followed by a CMP insn, then the compare is ; redundant, since we can rework the conditional instruction that follows. (define_insn_and_split "*and_scc_scc_cmp"