diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 87a396c39f9..4404a419663 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2018-01-04 Uros Bizjak + + PR target/83628 + * config/alpha/alpha.md (*sadd): Use ASHIFT + instead of MULT rtx. Update all corresponding splitters. + (*saddl_se): Ditto. + (*ssub): Ditto. + (*ssubl_se): Ditto. + (*cmp_sadd_di): Update split patterns. + (*cmp_sadd_si): Ditto. + (*cmp_sadd_sidi): Ditto. + (*cmp_ssub_di): Ditto. + (*cmp_ssub_si): Ditto. + (*cmp_ssub_sidi): Ditto. + * config/alpha/predicates.md (const23_operand): New predicate. + * config/alpha/alpha.c (alpha_rtx_costs) [PLUS, MINUS]: + Look for ASHIFT, not MULT inner operand. + (alpha_split_conditional_move): Update for *sadd change. + 2018-01-02 Andrew Waterman * config/riscv/linux.h (ICACHE_FLUSH_FUNC): New. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 00a69c1a08d..15011aabcc7 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -1430,8 +1430,8 @@ alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, case MINUS: if (float_mode_p) *total = cost_data->fp_add; - else if (GET_CODE (XEXP (x, 0)) == MULT - && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) + else if (GET_CODE (XEXP (x, 0)) == ASHIFT + && const23_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) { *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode, (enum rtx_code) outer_code, opno, speed) @@ -2929,8 +2929,8 @@ alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond, add_op = GEN_INT (f); if (sext_add_operand (add_op, mode)) { - tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget), - GEN_INT (diff)); + tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget), + GEN_INT (exact_log2 (diff))); tmp = gen_rtx_PLUS (DImode, tmp, add_op); emit_insn (gen_rtx_SET (target, tmp)); } diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 4e213f812e9..9833be7f8a7 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -337,8 +337,8 @@ "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) % 4 == 0" [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3) - (match_dup 5)) + (set (match_dup 0) (sign_extend:DI (plus:SI (ashift:SI (match_dup 3) + (match_dup 5)) (match_dup 1))))] { HOST_WIDE_INT val = INTVAL (operands[2]) / 4; @@ -348,7 +348,7 @@ val /= 2, mult = 8; operands[4] = GEN_INT (val); - operands[5] = GEN_INT (mult); + operands[5] = GEN_INT (exact_log2 (mult)); }) (define_split @@ -519,38 +519,38 @@ (define_insn "*sadd" [(set (match_operand:I48MODE 0 "register_operand" "=r,r") (plus:I48MODE - (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r") - (match_operand:I48MODE 2 "const48_operand" "I,I")) + (ashift:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r") + (match_operand:I48MODE 2 "const23_operand" "I,I")) (match_operand:I48MODE 3 "sext_add_operand" "rI,O")))] "" "@ - s%2add %1,%3,%0 - s%2sub %1,%n3,%0") + s%P2add %1,%3,%0 + s%P2sub %1,%n3,%0") (define_insn "*saddl_se" [(set (match_operand:DI 0 "register_operand" "=r,r") (sign_extend:DI - (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") - (match_operand:SI 2 "const48_operand" "I,I")) + (plus:SI (ashift:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") + (match_operand:SI 2 "const23_operand" "I,I")) (match_operand:SI 3 "sext_add_operand" "rI,O"))))] "" "@ - s%2addl %1,%3,%0 - s%2subl %1,%n3,%0") + s%P2addl %1,%3,%0 + s%P2subl %1,%n3,%0") (define_split [(set (match_operand:DI 0 "register_operand") (sign_extend:DI - (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator" + (plus:SI (ashift:SI (match_operator:SI 1 "comparison_operator" [(match_operand 2) (match_operand 3)]) - (match_operand:SI 4 "const48_operand")) + (match_operand:SI 4 "const23_operand")) (match_operand:SI 5 "sext_add_operand")))) (clobber (match_operand:DI 6 "reg_not_elim_operand"))] "" [(set (match_dup 6) (match_dup 7)) (set (match_dup 0) - (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4)) + (sign_extend:DI (plus:SI (ashift:SI (match_dup 8) (match_dup 4)) (match_dup 5))))] { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode, @@ -621,20 +621,20 @@ (define_insn "*ssub" [(set (match_operand:I48MODE 0 "register_operand" "=r") (minus:I48MODE - (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r") - (match_operand:I48MODE 2 "const48_operand" "I")) + (ashift:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r") + (match_operand:I48MODE 2 "const23_operand" "I")) (match_operand:I48MODE 3 "reg_or_8bit_operand" "rI")))] "" - "s%2sub %1,%3,%0") + "s%P2sub %1,%3,%0") (define_insn "*ssubl_se" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI - (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") - (match_operand:SI 2 "const48_operand" "I")) + (minus:SI (ashift:SI (match_operand:SI 1 "reg_not_elim_operand" "r") + (match_operand:SI 2 "const23_operand" "I")) (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))] "" - "s%2subl %1,%3,%0") + "s%P2subl %1,%3,%0") (define_insn "subv3" [(set (match_operand:I48MODE 0 "register_operand" "=r") @@ -3139,9 +3139,10 @@ [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) - (plus:DI (mult:DI (match_dup 5) (match_dup 3)) + (plus:DI (ashift:DI (match_dup 5) (match_dup 3)) (match_dup 4)))] { + operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3]))); if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) @@ -3164,9 +3165,10 @@ [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) - (plus:SI (mult:SI (match_dup 6) (match_dup 3)) + (plus:SI (ashift:SI (match_dup 6) (match_dup 3)) (match_dup 4)))] { + operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3]))); if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) @@ -3192,9 +3194,10 @@ [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) - (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3)) + (sign_extend:DI (plus:SI (ashift:SI (match_dup 6) (match_dup 3)) (match_dup 4))))] { + operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3]))); if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) @@ -3219,9 +3222,10 @@ [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) - (minus:DI (mult:DI (match_dup 5) (match_dup 3)) + (minus:DI (ashift:DI (match_dup 5) (match_dup 3)) (match_dup 4)))] { + operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3]))); if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) @@ -3244,9 +3248,10 @@ [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) - (minus:SI (mult:SI (match_dup 6) (match_dup 3)) + (minus:SI (ashift:SI (match_dup 6) (match_dup 3)) (match_dup 4)))] { + operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3]))); if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) @@ -3272,9 +3277,10 @@ [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) - (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3)) + (sign_extend:DI (minus:SI (ashift:SI (match_dup 6) (match_dup 3)) (match_dup 4))))] { + operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3]))); if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) diff --git a/gcc/config/alpha/predicates.md b/gcc/config/alpha/predicates.md index 102451ee80c..6fc359ec053 100644 --- a/gcc/config/alpha/predicates.md +++ b/gcc/config/alpha/predicates.md @@ -74,6 +74,11 @@ (and (match_code "const_int,const_wide_int,const_double,const_vector") (not (match_test "op == CONST0_RTX (mode)")))) +;; Return 1 if OP is the constant 2 or 3. +(define_predicate "const23_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) == 2 || INTVAL (op) == 3"))) + ;; Return 1 if OP is the constant 4 or 8. (define_predicate "const48_operand" (and (match_code "const_int") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d7298b8be55..c6c7916ae39 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-01-04 Uros Bizjak + + PR target/83628 + * gcc.target/alpha/pr83628-1.c: New test. + * gcc.target/alpha/pr83628-2.c: Ditto. + 2018-01-02 Jakub Jelinek PR c++/83556 diff --git a/gcc/testsuite/gcc.target/alpha/pr83628-1.c b/gcc/testsuite/gcc.target/alpha/pr83628-1.c new file mode 100644 index 00000000000..a4a32d98969 --- /dev/null +++ b/gcc/testsuite/gcc.target/alpha/pr83628-1.c @@ -0,0 +1,19 @@ +/* PR target/83628 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef __SIZE_TYPE__ size_t; + +int +get_int (int *p, size_t idx) +{ + return p[idx]; +} + +long +get_long (long *p, size_t idx) +{ + return p[idx]; +} + +/* { dg-final { scan-assembler-not "\[ \t\]add\[ql\]" } } */ diff --git a/gcc/testsuite/gcc.target/alpha/pr83628-2.c b/gcc/testsuite/gcc.target/alpha/pr83628-2.c new file mode 100644 index 00000000000..0910d38be00 --- /dev/null +++ b/gcc/testsuite/gcc.target/alpha/pr83628-2.c @@ -0,0 +1,29 @@ +/* PR target/83628 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +s4l (int a, int b) +{ + return a + b * 4; +} + +int +s8l (int a, int b) +{ + return a + b * 8; +} + +long +s4q (long a, long b) +{ + return a + b * 4; +} + +long +s8q (long a, long b) +{ + return a + b * 8; +} + +/* { dg-final { scan-assembler-not "\[ \t\]add\[ql\]" } } */