diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 472145b6cb7..0aad5838664 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,42 @@ +2019-01-07 Richard Earnshaw + + PR target/86891 + * config/aarch64/aarch64.c (aarch64_expand_subvti): New parameter + unsigned_p. Handle signed and unsigned overflow correction as + required. + * config/aarch64/aarch64-protos.h (aarch64_expand_subvti): Update + prototype. + * config/aarch64/aarch64.md (addv4): Use aarch64_plus_operand + for operand 2. + (add3_compareV_imm): Make this callable for expanding. + (subv4): Use register_operand for operand 1. Use + aarch64_plus_operand for operand 2. + (subv_insn): New insn pattern. + (subv_imm): Likewise. + (negv3): New expand pattern. + (negv_insn): New insn pattern. + (negv_cmp_only): Likewise. + (cmpv_insn): Likewise. + (subvti4): Use register_operand for operand 1. Update call to + aarch64_expand_subvti. + (usubvti4): Likewise. + (negvti3): New expand pattern. + (negdi_carryout): New insn pattern. + (negvdi_carryinV): New insn pattern. + (sub_compare1_imm): Delete named insn pattern, make anonymous + version the named version. + (peepholes to convert to sub_compare1_imm): Adjust order of + operands. + (usub3_carryinC, usub3_carryinC_z1): New insn + patterns. + (usub3_carryinC_z2, usub3_carryinC): New insn + patterns. + (sub3_carryinCV, sub3_carryinCV_z1_z2): Delete. + (sub3_carryinCV_z1, sub3_carryinCV_z2): Delete. + (sub3_carryinCV): Delete. + (sub3_carryinV): New expand pattern. + sub3_carryinV, sub3_carryinV_z2): New insn patterns. + 2019-01-07 Richard Biener * tree-ssa-uncprop.c (ssa_equip_hash_traits): Remove in favor diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 9a8f81ee134..209c09be669 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -530,7 +530,7 @@ void aarch64_subvti_scratch_regs (rtx, rtx, rtx *, rtx *, rtx *, rtx *, rtx *, rtx *); void aarch64_expand_subvti (rtx, rtx, rtx, - rtx, rtx, rtx, rtx); + rtx, rtx, rtx, rtx, bool); /* Initialize builtins for SIMD intrinsics. */ diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index c5036c83531..c87994011bb 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -16668,32 +16668,38 @@ aarch64_subvti_scratch_regs (rtx op1, rtx op2, rtx *low_dest, LOW_IN2 represents the low half (DImode) of TImode operand 2 HIGH_DEST represents the high half (DImode) of TImode operand 0 HIGH_IN1 represents the high half (DImode) of TImode operand 1 - HIGH_IN2 represents the high half (DImode) of TImode operand 2. */ - + HIGH_IN2 represents the high half (DImode) of TImode operand 2 + UNSIGNED_P is true if the operation is being performed on unsigned + values. */ void aarch64_expand_subvti (rtx op0, rtx low_dest, rtx low_in1, rtx low_in2, rtx high_dest, rtx high_in1, - rtx high_in2) + rtx high_in2, bool unsigned_p) { if (low_in2 == const0_rtx) { low_dest = low_in1; - emit_insn (gen_subdi3_compare1 (high_dest, high_in1, - force_reg (DImode, high_in2))); + high_in2 = force_reg (DImode, high_in2); + if (unsigned_p) + emit_insn (gen_subdi3_compare1 (high_dest, high_in1, high_in2)); + else + emit_insn (gen_subvdi_insn (high_dest, high_in1, high_in2)); } else { if (CONST_INT_P (low_in2)) { - low_in2 = force_reg (DImode, GEN_INT (-UINTVAL (low_in2))); high_in2 = force_reg (DImode, high_in2); - emit_insn (gen_adddi3_compareC (low_dest, low_in1, low_in2)); + emit_insn (gen_subdi3_compare1_imm (low_dest, low_in1, low_in2, + GEN_INT (-INTVAL (low_in2)))); } else emit_insn (gen_subdi3_compare1 (low_dest, low_in1, low_in2)); - emit_insn (gen_subdi3_carryinCV (high_dest, - force_reg (DImode, high_in1), - high_in2)); + + if (unsigned_p) + emit_insn (gen_usubdi3_carryinC (high_dest, high_in1, high_in2)); + else + emit_insn (gen_subdi3_carryinV (high_dest, high_in1, high_in2)); } emit_move_insn (gen_lowpart (DImode, op0), low_dest); diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index d2642ef328c..37322fbbfa3 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1842,11 +1842,15 @@ (define_expand "addv4" [(match_operand:GPI 0 "register_operand") (match_operand:GPI 1 "register_operand") - (match_operand:GPI 2 "register_operand") + (match_operand:GPI 2 "aarch64_plus_operand") (label_ref (match_operand 3 "" ""))] "" { - emit_insn (gen_add3_compareV (operands[0], operands[1], operands[2])); + if (CONST_INT_P (operands[2])) + emit_insn (gen_add3_compareV_imm (operands[0], operands[1], + operands[2])); + else + emit_insn (gen_add3_compareV (operands[0], operands[1], operands[2])); aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; @@ -2093,7 +2097,7 @@ [(set_attr "type" "alus_sreg")] ) -(define_insn "*add3_compareV_imm" +(define_insn "add3_compareV_imm" [(set (reg:CC_V CC_REGNUM) (compare:CC_V (plus: @@ -2723,19 +2727,109 @@ (set_attr "arch" "*,simd")] ) -(define_expand "subv4" +(define_expand "subv4" [(match_operand:GPI 0 "register_operand") - (match_operand:GPI 1 "aarch64_reg_or_zero") - (match_operand:GPI 2 "aarch64_reg_or_zero") + (match_operand:GPI 1 "register_operand") + (match_operand:GPI 2 "aarch64_plus_operand") (label_ref (match_operand 3 "" ""))] "" { - emit_insn (gen_sub3_compare1 (operands[0], operands[1], operands[2])); + if (CONST_INT_P (operands[2])) + emit_insn (gen_subv_imm (operands[0], operands[1], operands[2])); + else + emit_insn (gen_subv_insn (operands[0], operands[1], operands[2])); aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; }) +(define_insn "subv_insn" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (sign_extend: + (minus:GPI + (match_operand:GPI 1 "register_operand" "rk") + (match_operand:GPI 2 "register_operand" "r"))) + (minus: (sign_extend: (match_dup 1)) + (sign_extend: (match_dup 2))))) + (set (match_operand:GPI 0 "register_operand" "=r") + (minus:GPI (match_dup 1) (match_dup 2)))] + "" + "subs\\t%0, %1, %2" + [(set_attr "type" "alus_sreg")] +) + +(define_insn "subv_imm" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (sign_extend: + (minus:GPI + (match_operand:GPI 1 "register_operand" "rk,rk") + (match_operand:GPI 2 "aarch64_plus_immediate" "I,J"))) + (minus: (sign_extend: (match_dup 1)) + (match_dup 2)))) + (set (match_operand:GPI 0 "register_operand" "=r,r") + (minus:GPI (match_dup 1) (match_dup 2)))] + "" + "@ + subs\\t%0, %1, %2 + adds\\t%0, %1, #%n2" + [(set_attr "type" "alus_sreg")] +) + +(define_expand "negv3" + [(match_operand:GPI 0 "register_operand") + (match_operand:GPI 1 "register_operand") + (label_ref (match_operand 2 "" ""))] + "" + { + emit_insn (gen_negv_insn (operands[0], operands[1])); + aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); + + DONE; + } +) + +(define_insn "negv_insn" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (sign_extend: + (neg:GPI (match_operand:GPI 1 "register_operand" "r"))) + (neg: (sign_extend: (match_dup 1))))) + (set (match_operand:GPI 0 "register_operand" "=r") + (neg:GPI (match_dup 1)))] + "" + "negs\\t%0, %1" + [(set_attr "type" "alus_sreg")] +) + +(define_insn "negv_cmp_only" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (sign_extend: + (neg:GPI (match_operand:GPI 0 "register_operand" "r"))) + (neg: (sign_extend: (match_dup 0)))))] + "" + "negs\\t%zr, %0" + [(set_attr "type" "alus_sreg")] +) + +(define_insn "*cmpv_insn" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (sign_extend: + (minus:GPI (match_operand:GPI 0 "register_operand" "r,r,r") + (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))) + (minus: (sign_extend: (match_dup 0)) + (sign_extend: (match_dup 1)))))] + "" + "@ + cmp\\t%0, %1 + cmp\\t%0, %1 + cmp\\t%0, #%n1" + [(set_attr "type" "alus_sreg")] +) + (define_expand "usubv4" [(match_operand:GPI 0 "register_operand") (match_operand:GPI 1 "aarch64_reg_or_zero") @@ -2771,7 +2865,7 @@ (define_expand "subvti4" [(match_operand:TI 0 "register_operand") - (match_operand:TI 1 "aarch64_reg_or_zero") + (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm") (label_ref (match_operand 3 "" ""))] "" @@ -2782,7 +2876,7 @@ &low_dest, &op1_low, &op2_low, &high_dest, &op1_high, &op2_high); aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low, - high_dest, op1_high, op2_high); + high_dest, op1_high, op2_high, false); aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; @@ -2790,7 +2884,7 @@ (define_expand "usubvti4" [(match_operand:TI 0 "register_operand") - (match_operand:TI 1 "aarch64_reg_or_zero") + (match_operand:TI 1 "register_operand") (match_operand:TI 2 "aarch64_reg_or_imm") (label_ref (match_operand 3 "" ""))] "" @@ -2801,12 +2895,56 @@ &low_dest, &op1_low, &op2_low, &high_dest, &op1_high, &op2_high); aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low, - high_dest, op1_high, op2_high); + high_dest, op1_high, op2_high, true); aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]); DONE; }) +(define_expand "negvti3" + [(match_operand:TI 0 "register_operand") + (match_operand:TI 1 "register_operand") + (label_ref (match_operand 2 "" ""))] + "" + { + emit_insn (gen_negdi_carryout (gen_lowpart (DImode, operands[0]), + gen_lowpart (DImode, operands[1]))); + emit_insn (gen_negvdi_carryinV (gen_highpart (DImode, operands[0]), + gen_highpart (DImode, operands[1]))); + aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); + + DONE; + } +) + +(define_insn "negdi_carryout" + [(set (reg:CC CC_REGNUM) + (compare:CC + (const_int 0) (match_operand:DI 1 "register_operand" "r"))) + (set (match_operand:DI 0 "register_operand" "=r") + (neg:DI (match_dup 1)))] + "" + "negs\\t%0, %1" + [(set_attr "type" "alus_sreg")] +) + +(define_insn "negvdi_carryinV" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (neg:TI (plus:TI + (ltu:TI (reg:CC CC_REGNUM) (const_int 0)) + (sign_extend:TI (match_operand:DI 1 "register_operand" "r")))) + (sign_extend:TI + (neg:DI (plus:DI (ltu:DI (reg:CC CC_REGNUM) (const_int 0)) + (match_dup 1)))))) + (set (match_operand:DI 0 "register_operand" "=r") + (neg:DI (plus:DI (ltu:DI (reg:CC CC_REGNUM) (const_int 0)) + (match_dup 1))))] + "" + "ngcs\\t%0, %1" + [(set_attr "type" "alus_sreg")] +) + (define_insn "*sub3_compare0" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r") @@ -2832,7 +2970,7 @@ [(set_attr "type" "alus_sreg")] ) -(define_insn "*sub3_compare1_imm" +(define_insn "sub3_compare1_imm" [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ,rZ") @@ -2843,8 +2981,8 @@ (match_operand:GPI 3 "aarch64_plus_immediate" "J,I")))] "UINTVAL (operands[2]) == -UINTVAL (operands[3])" "@ - subs\\t%0, %1, #%n3 - adds\\t%0, %1, %3" + subs\\t%0, %1, %2 + adds\\t%0, %1, #%n2" [(set_attr "type" "alus_imm")] ) @@ -2860,19 +2998,6 @@ [(set_attr "type" "alus_sreg")] ) -(define_insn "sub3_compare1_imm" - [(set (reg:CC CC_REGNUM) - (compare:CC - (match_operand:GPI 1 "register_operand" "r") - (match_operand:GPI 3 "const_int_operand" "n"))) - (set (match_operand:GPI 0 "register_operand" "=r") - (plus:GPI (match_dup 1) - (match_operand:GPI 2 "aarch64_sub_immediate" "J")))] - "INTVAL (operands[3]) == -INTVAL (operands[2])" - "subs\\t%0, %1, #%n2" - [(set_attr "type" "alus_sreg")] -) - (define_peephole2 [(set (match_operand:GPI 0 "register_operand") (minus:GPI (match_operand:GPI 1 "aarch64_reg_or_zero") @@ -2914,7 +3039,7 @@ (define_peephole2 [(set (match_operand:GPI 0 "register_operand") (plus:GPI (match_operand:GPI 1 "register_operand") - (match_operand:GPI 2 "aarch64_sub_immediate"))) + (match_operand:GPI 2 "aarch64_plus_immediate"))) (set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) @@ -2924,7 +3049,7 @@ [(const_int 0)] { emit_insn (gen_sub3_compare1_imm (operands[0], operands[1], - operands[2], operands[3])); + operands[3], operands[2])); DONE; } ) @@ -2939,12 +3064,12 @@ (match_operand:GPI 3 "const_int_operand"))) (set (match_operand:GPI 0 "register_operand") (plus:GPI (match_dup 1) - (match_operand:GPI 2 "aarch64_sub_immediate")))] + (match_operand:GPI 2 "aarch64_plus_immediate")))] "INTVAL (operands[3]) == -INTVAL (operands[2])" [(const_int 0)] { emit_insn (gen_sub3_compare1_imm (operands[0], operands[1], - operands[2], operands[3])); + operands[3], operands[2])); DONE; } ) @@ -3164,14 +3289,14 @@ [(set_attr "type" "adc_reg")] ) -(define_expand "sub3_carryinCV" +(define_expand "usub3_carryinC" [(parallel [(set (reg:CC CC_REGNUM) (compare:CC - (sign_extend: + (zero_extend: (match_operand:GPI 1 "aarch64_reg_or_zero" "")) (plus: - (sign_extend: + (zero_extend: (match_operand:GPI 2 "register_operand" "")) (ltu: (reg:CC CC_REGNUM) (const_int 0))))) (set (match_operand:GPI 0 "register_operand" "") @@ -3181,24 +3306,12 @@ "" ) -(define_insn "*sub3_carryinCV_z1_z2" - [(set (reg:CC CC_REGNUM) - (compare:CC - (const_int 0) - (match_operand: 2 "aarch64_borrow_operation" ""))) - (set (match_operand:GPI 0 "register_operand" "=r") - (neg:GPI (match_operand:GPI 1 "aarch64_borrow_operation" "")))] - "" - "sbcs\\t%0, zr, zr" - [(set_attr "type" "adc_reg")] -) - -(define_insn "*sub3_carryinCV_z1" +(define_insn "*usub3_carryinC_z1" [(set (reg:CC CC_REGNUM) (compare:CC (const_int 0) (plus: - (sign_extend: + (zero_extend: (match_operand:GPI 1 "register_operand" "r")) (match_operand: 2 "aarch64_borrow_operation" "")))) (set (match_operand:GPI 0 "register_operand" "=r") @@ -3210,10 +3323,10 @@ [(set_attr "type" "adc_reg")] ) -(define_insn "*sub3_carryinCV_z2" +(define_insn "*usub3_carryinC_z2" [(set (reg:CC CC_REGNUM) (compare:CC - (sign_extend: + (zero_extend: (match_operand:GPI 1 "register_operand" "r")) (match_operand: 2 "aarch64_borrow_operation" ""))) (set (match_operand:GPI 0 "register_operand" "=r") @@ -3225,13 +3338,13 @@ [(set_attr "type" "adc_reg")] ) -(define_insn "*sub3_carryinCV" +(define_insn "*usub3_carryinC" [(set (reg:CC CC_REGNUM) (compare:CC - (sign_extend: + (zero_extend: (match_operand:GPI 1 "register_operand" "r")) (plus: - (sign_extend: + (zero_extend: (match_operand:GPI 2 "register_operand" "r")) (match_operand: 3 "aarch64_borrow_operation" "")))) (set (match_operand:GPI 0 "register_operand" "=r") @@ -3243,6 +3356,69 @@ [(set_attr "type" "adc_reg")] ) +(define_expand "sub3_carryinV" + [(parallel + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus: + (sign_extend: + (match_operand:GPI 1 "aarch64_reg_or_zero" "")) + (plus: + (sign_extend: + (match_operand:GPI 2 "register_operand" "")) + (ltu: (reg:CC CC_REGNUM) (const_int 0)))) + (sign_extend: + (minus:GPI (match_dup 1) + (plus:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)) + (match_dup 2)))))) + (set (match_operand:GPI 0 "register_operand" "") + (minus:GPI + (minus:GPI (match_dup 1) (match_dup 2)) + (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))))])] + "" +) + +(define_insn "*sub3_carryinV_z2" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus: + (sign_extend: (match_operand:GPI 1 "register_operand" "r")) + (match_operand: 2 "aarch64_borrow_operation" "")) + (sign_extend: + (minus:GPI (match_dup 1) + (match_operand:GPI 3 "aarch64_borrow_operation" ""))))) + (set (match_operand:GPI 0 "register_operand" "=r") + (minus:GPI + (match_dup 1) (match_dup 3)))] + "" + "sbcs\\t%0, %1, zr" + [(set_attr "type" "adc_reg")] +) + +(define_insn "*sub3_carryinV" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus: + (sign_extend: + (match_operand:GPI 1 "register_operand" "r")) + (plus: + (sign_extend: + (match_operand:GPI 2 "register_operand" "r")) + (match_operand: 3 "aarch64_borrow_operation" ""))) + (sign_extend: + (minus:GPI + (match_dup 1) + (plus:GPI (match_operand:GPI 4 "aarch64_borrow_operation" "") + (match_dup 2)))))) + (set (match_operand:GPI 0 "register_operand" "=r") + (minus:GPI + (minus:GPI (match_dup 1) (match_dup 2)) + (match_dup 4)))] + "" + "sbcs\\t%0, %1, %2" + [(set_attr "type" "adc_reg")] +) + (define_insn "*sub_uxt_shift2" [(set (match_operand:GPI 0 "register_operand" "=rk") (minus:GPI (match_operand:GPI 4 "register_operand" "rk") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0dc5707e7b7..13d8c065b11 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-01-07 Richard Earnshaw + + * gcc.target/aarch64/subs_compare_2.c: Make '#' immediate prefix + optional in scan pattern. + 2019-01-07 Richard Sandiford PR tree-optimization/88598 diff --git a/gcc/testsuite/gcc.target/aarch64/subs_compare_2.c b/gcc/testsuite/gcc.target/aarch64/subs_compare_2.c index 60c6d9e5ccd..41a256619b7 100644 --- a/gcc/testsuite/gcc.target/aarch64/subs_compare_2.c +++ b/gcc/testsuite/gcc.target/aarch64/subs_compare_2.c @@ -11,5 +11,5 @@ foo (int a, int b) return 0; } -/* { dg-final { scan-assembler-times "subs\\tw\[0-9\]+, w\[0-9\]+, #4" 1 } } */ +/* { dg-final { scan-assembler-times "subs\\tw\[0-9\]+, w\[0-9\]+, \[#\]?4" 1 } } */ /* { dg-final { scan-assembler-not "cmp\\tw\[0-9\]+, w\[0-9\]+" } } */