Message ID | 53F35128.9010801@arm.com |
---|---|
State | New |
Headers | show |
On 08/19/2014 06:29 AM, Kyrill Tkachov wrote: > +(define_special_predicate "cc_register_zero" > + (and (match_code "reg") > + (and (match_test "REGNO (op) == CC_REGNUM") > + (ior (match_test "mode == GET_MODE (op)") > + (ior (match_test "mode == VOIDmode > + && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC") > + (match_test "mode == CCmode || mode == CC_Zmode > + || mode == CC_NZmode"))))) > +) Well, you're being too liberal with the modes you're accepting, since 'mode' will always be VOIDmode. And personally I find those match_tests quite ugly. Better as: (define_special_predicate "cc_register_zero" (match_code "reg") { return (REGNO (op) == CC_REGNUM && (GET_MODE (op) == CCmode || GET_MODE (op) == CC_Zmode || GET_MODE (op) == CC_NZmode)); }) r~
> (define_special_predicate "cc_register_zero" > (match_code "reg") > { > return (REGNO (op) == CC_REGNUM > && (GET_MODE (op) == CCmode > || GET_MODE (op) == CC_Zmode > || GET_MODE (op) == CC_NZmode)); > }) ... and now that I read the backend more closely, I see "_zero" was a bad name. But more importantly, I see no connection between the comparison used and the CCmode being accepted. And if we fix that, why are you restricting to just Z and NZ? What's wrong with e.g. CFPmode? In the i386 backend, we check comparison+mode correspondence like (match_operator 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)]) I think you'll want something similar. In the case of CSINC, we can accept all conditions, so let's start with the most general: (match_operator:GPI 2 "aarch64_comparison_operation" [(reg CC_REGNUM) (const_int 0)] or even (match_operand:GPI 2 "aarch64_comparison_operation" "") with (define_predicate "aarch64_comparison_operation" (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu," "unordered,ordered,unlt,unle,unge,ungt") { if (XEXP (op, 1) != const0_rtx) return false; rtx op0 = XEXP (op, 0); if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) return false; return aarch64_get_condition_code (op) >= 0; }) where aarch64_get_condition_code is (1) exported (2) adjusted to return "int" not "unsigned" (3) adjusted to not abort, but return -1 for invalid combinations. and the two existing users of aarch64_get_condition_code are adjusted to gcc_assert that the return value is valid. r~
On 19/08/14 17:09, Richard Henderson wrote: >> (define_special_predicate "cc_register_zero" >> (match_code "reg") >> { >> return (REGNO (op) == CC_REGNUM >> && (GET_MODE (op) == CCmode >> || GET_MODE (op) == CC_Zmode >> || GET_MODE (op) == CC_NZmode)); >> }) > ... and now that I read the backend more closely, I see "_zero" was a bad name. > > But more importantly, I see no connection between the comparison used and the > CCmode being accepted. And if we fix that, why are you restricting to just Z > and NZ? What's wrong with e.g. CFPmode? > > In the i386 backend, we check comparison+mode correspondence like > > (match_operator 4 "ix86_carry_flag_operator" > [(match_operand 3 "flags_reg_operand") (const_int 0)]) > > I think you'll want something similar. In the case of CSINC, we can accept all > conditions, so let's start with the most general: > > (match_operator:GPI 2 "aarch64_comparison_operation" > [(reg CC_REGNUM) (const_int 0)] > > or even > > (match_operand:GPI 2 "aarch64_comparison_operation" "") > > with > > (define_predicate "aarch64_comparison_operation" > (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu," > "unordered,ordered,unlt,unle,unge,ungt") > { > if (XEXP (op, 1) != const0_rtx) > return false; > rtx op0 = XEXP (op, 0); > if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) > return false; > return aarch64_get_condition_code (op) >= 0; > }) > > where aarch64_get_condition_code is > (1) exported > (2) adjusted to return "int" not "unsigned" > (3) adjusted to not abort, but return -1 for invalid combinations. > > and the two existing users of aarch64_get_condition_code are adjusted to > gcc_assert that the return value is valid. Hmm, when I do that combine refuses to match the csinc patterns: Failed to match this instruction: (set (reg:SI 73 [ D.2564 ]) (if_then_else:SI (ne (reg:CC 66 cc) (const_int 0 [0])) (plus:SI (reg:SI 74 [ D.2565 ]) (const_int 1 [0x1])) (const_int 0 [0]))) I probably mistyped something, I'll look into it... Thanks for the help, Kyrill > > > r~ >
commit 6481f4befaadd67d4124e80db4514cf3fd9dbfa6 Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com> Date: Mon Aug 4 16:49:24 2014 +0100 [AArch64] Use CC_NZ in csinc pattern diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 3c51fd3..f172d56 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2599,7 +2599,7 @@ (define_insn "aarch64_<crc_variant>" (define_insn "*csinc2<mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator" - [(match_operand:CC 3 "cc_register" "") (const_int 0)]) + [(match_operand 3 "cc_register_zero" "") (const_int 0)]) (match_operand:GPI 1 "register_operand" "r")))] "" "csinc\\t%<w>0, %<w>1, %<w>1, %M2" @@ -2610,7 +2610,7 @@ (define_insn "csinc3<mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" - [(match_operand:CC 2 "cc_register" "") (const_int 0)]) + [(match_operand 2 "cc_register_zero" "") (const_int 0)]) (plus:GPI (match_operand:GPI 3 "register_operand" "r") (const_int 1)) (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] @@ -2623,7 +2623,7 @@ (define_insn "*csinv3<mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" - [(match_operand:CC 2 "cc_register" "") (const_int 0)]) + [(match_operand 2 "cc_register_zero" "") (const_int 0)]) (not:GPI (match_operand:GPI 3 "register_operand" "r")) (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] "" @@ -2635,7 +2635,7 @@ (define_insn "*csneg3<mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" - [(match_operand:CC 2 "cc_register" "") (const_int 0)]) + [(match_operand 2 "cc_register_zero" "") (const_int 0)]) (neg:GPI (match_operand:GPI 3 "register_operand" "r")) (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))] "" diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 3dd83ca..8c218df 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -26,6 +26,16 @@ (define_special_predicate "cc_register" && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))) ) +(define_special_predicate "cc_register_zero" + (and (match_code "reg") + (and (match_test "REGNO (op) == CC_REGNUM") + (ior (match_test "mode == GET_MODE (op)") + (ior (match_test "mode == VOIDmode + && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC") + (match_test "mode == CCmode || mode == CC_Zmode + || mode == CC_NZmode"))))) +) + (define_predicate "aarch64_call_insn_operand" (ior (match_code "symbol_ref") (match_operand 0 "register_operand")))