Rather than duplicating the rather verbose integral test, pull it out to a predicate.
* config/aarch64/predicates.md (const_dword_umaxp1): New. * config/aarch64/aarch64.c (aarch64_select_cc_mode): Use it. * config/aarch64/aarch64.md (add*add<GPI>3_carryinC): Likewise. (*add<GPI>3_carryinC_zero): Likewise. (add<mode>3_carryinC): Use <DWI>mode for constant, not TImode. --- gcc/config/aarch64/aarch64.c | 5 +---- gcc/config/aarch64/aarch64.md | 16 +++++++--------- gcc/config/aarch64/predicates.md | 9 +++++++++ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ce306a10de6..f2c14818c79 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -9528,10 +9528,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y) if ((mode_x == DImode || mode_x == TImode) && (code == LTU || code == GEU) && code_x == PLUS - && CONST_SCALAR_INT_P (y) - && (rtx_mode_t (y, mode_x) - == (wi::shwi (1, mode_x) - << (GET_MODE_BITSIZE (mode_x).to_constant () / 2)))) + && const_dword_umaxp1 (y, mode_x)) return CC_ADCmode; /* A test for signed overflow. */ diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index d266a1edd64..6b21cc9c61b 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2659,7 +2659,7 @@ operands[5] = gen_rtx_LTU (<MODE>mode, ccin, const0_rtx); operands[6] = immed_wide_int_const (wi::shwi (1, <DWI>mode) << GET_MODE_BITSIZE (<MODE>mode), - TImode); + <DWI>mode); }) (define_insn "*add<mode>3_carryinC_zero" @@ -2668,13 +2668,12 @@ (plus:<DWI> (match_operand:<DWI> 2 "aarch64_carry_operation" "") (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))) - (match_operand 4 "const_scalar_int_operand" ""))) + (match_operand:<DWI> 4 "const_dword_umaxp1" ""))) (set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (match_operand:GPI 3 "aarch64_carry_operation" "") (match_dup 1)))] - "rtx_mode_t (operands[4], <DWI>mode) - == (wi::shwi (1, <DWI>mode) << (unsigned) GET_MODE_BITSIZE (<MODE>mode))" - "adcs\\t%<w>0, %<w>1, <w>zr" + "" + "adcs\\t%<w>0, %<w>1, <w>zr" [(set_attr "type" "adc_reg")] ) @@ -2686,15 +2685,14 @@ (match_operand:<DWI> 3 "aarch64_carry_operation" "") (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))) (zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r"))) - (match_operand 5 "const_scalar_int_operand" ""))) + (match_operand:<DWI> 5 "const_dword_umaxp1" ""))) (set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (plus:GPI (match_operand:GPI 4 "aarch64_carry_operation" "") (match_dup 1)) (match_dup 2)))] - "rtx_mode_t (operands[5], <DWI>mode) - == (wi::shwi (1, <DWI>mode) << (unsigned) GET_MODE_BITSIZE (<MODE>mode))" - "adcs\\t%<w>0, %<w>1, %<w>2" + "" + "adcs\\t%<w>0, %<w>1, %<w>2" [(set_attr "type" "adc_reg")] ) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 215fcec5955..99c3bfbace4 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -46,6 +46,15 @@ return CONST_INT_P (op) && IN_RANGE (INTVAL (op), 1, 3); }) +;; True for 1 << (GET_MODE_BITSIZE (mode) / 2) +;; I.e UINT_MAX + 1 for a given mode, in the double-word mode. +(define_predicate "const_dword_umaxp1" + (match_code "const_int,const_wide_int") +{ + unsigned bits = GET_MODE_BITSIZE (mode).to_constant () / 2; + return rtx_mode_t (op, mode) == (wi::shwi (1, mode) << bits); +}) + (define_predicate "subreg_lowpart_operator" (ior (match_code "truncate") (and (match_code "subreg") -- 2.20.1