Re: [PATCH 2/2] ARC: Use intrinsics for __builtin_sub_overflow*()
Hi Claudiu, On 9/7/23 12:15, Claudiu Zissulescu Ianculescu wrote: > OK, > > Thank you for your contribution, > Claudiu Could you commit this patch? > > On Wed, Sep 6, 2023 at 3:50 PM Shahab Vahedi > wrote: >> >> This patch covers signed and unsigned subtractions. The generated code >> would be something along these lines: >> >> signed: >> sub.f r0, r1, r2 >> b.v @label >> >> unsigned: >> sub.f r0, r1, r2 >> b.c @label >> >> gcc/ChangeLog: >> >> * config/arc/arc.md (subsi3_v): New insn. >> (subvsi4): New expand. >> (subsi3_c): New insn. >> (usubvsi4): New expand. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.target/arc/overflow-2.c: New. >> >> Signed-off-by: Shahab Vahedi >> --- >> gcc/config/arc/arc.md | 48 +++ >> gcc/testsuite/gcc.target/arc/overflow-2.c | 97 +++ >> 2 files changed, 145 insertions(+) >> create mode 100644 gcc/testsuite/gcc.target/arc/overflow-2.c >> >> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md >> index 9d011f6b4a9..34e9e1a7f1d 100644 >> --- a/gcc/config/arc/arc.md >> +++ b/gcc/config/arc/arc.md >> @@ -2973,6 +2973,54 @@ archs4x, archs4xd" >>(set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*") >>]) >> >> +(define_insn "subsi3_v" >> + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") >> + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") >> + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) >> + (set (reg:CC_V CC_REG) >> + (compare:CC_V (sign_extend:DI (minus:SI (match_dup 1) >> + (match_dup 2))) >> + (minus:DI (sign_extend:DI (match_dup 1)) >> + (sign_extend:DI (match_dup 2)] >> + "" >> + "sub.f\\t%0,%1,%2" >> + [(set_attr "cond" "set") >> +(set_attr "type" "compare") >> +(set_attr "length" "4,4,4,8")]) >> + >> +(define_expand "subvsi4" >> + [(match_operand:SI 0 "register_operand") >> + (match_operand:SI 1 "register_operand") >> + (match_operand:SI 2 "nonmemory_operand") >> + (label_ref (match_operand 3 "" ""))] >> + "" >> + "emit_insn (gen_subsi3_v (operands[0], operands[1], operands[2])); >> + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); >> + DONE;") >> + >> +(define_insn "subsi3_c" >> + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") >> + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") >> + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) >> + (set (reg:CC_C CC_REG) >> + (compare:CC_C (match_dup 1) >> + (match_dup 2)))] >> + "" >> + "sub.f\\t%0,%1,%2" >> + [(set_attr "cond" "set") >> +(set_attr "type" "compare") >> +(set_attr "length" "4,4,4,8")]) >> + >> +(define_expand "usubvsi4" >> + [(match_operand:SI 0 "register_operand") >> + (match_operand:SI 1 "register_operand") >> + (match_operand:SI 2 "nonmemory_operand") >> + (label_ref (match_operand 3 "" ""))] >> + "" >> + "emit_insn (gen_subsi3_c (operands[0], operands[1], operands[2])); >> +arc_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); >> +DONE;") >> + >> (define_expand "subdi3" >>[(set (match_operand:DI 0 "register_operand" "") >> (minus:DI (match_operand:DI 1 "register_operand" "") >> diff --git a/gcc/testsuite/gcc.target/arc/overflow-2.c >> b/gcc/testsuite/gcc.target/arc/overflow-2.c >> new file mode 100644 >> index 000..b4de8c03b22 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/arc/overflow-2.c >> @@ -0,0 +1,97 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O1" } */ >> + >> +#include >> +#include >> + >> +/* >> + * sub.f r0,r0,r1 >> + * st_s r
Re: [PATCH 1/2] ARC: Use intrinsics for __builtin_add_overflow*()
Hi Clauudiu, On 9/7/23 12:15, Claudiu Zissulescu Ianculescu wrote: > Ok. > > Thank you for your contribution, > Claudiu Could you commit this patch? > > On Wed, Sep 6, 2023 at 3:50 PM Shahab Vahedi > wrote: >> >> This patch covers signed and unsigned additions. The generated code >> would be something along these lines: >> >> signed: >> add.f r0, r1, r2 >> b.v @label >> >> unsigned: >> add.f r0, r1, r2 >> b.c @label >> >> gcc/ChangeLog: >> >> * config/arc/arc-modes.def: Add CC_V mode. >> * config/arc/predicates.md (proper_comparison_operator): Handle >> E_CC_Vmode. >> (equality_comparison_operator): Exclude CC_Vmode from eq/ne. >> (cc_set_register): Handle CC_Vmode. >> (cc_use_register): Likewise. >> * config/arc/arc.md (addsi3_v): New insn. >> (addvsi4): New expand. >> (addsi3_c): New insn. >> (uaddvsi4): New expand. >> * config/arc/arc-protos.h (arc_gen_unlikely_cbranch): New. >> * config/arc/arc.cc (arc_gen_unlikely_cbranch): New. >> (get_arc_condition_code): Handle E_CC_Vmode. >> (arc_init_reg_tables): Handle CC_Vmode. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.target/arc/overflow-1.c: New. >> >> Signed-off-by: Shahab Vahedi >> --- >> gcc/config/arc/arc-modes.def | 1 + >> gcc/config/arc/arc-protos.h | 1 + >> gcc/config/arc/arc.cc | 26 +- >> gcc/config/arc/arc.md | 49 +++ >> gcc/config/arc/predicates.md | 14 ++- >> gcc/testsuite/gcc.target/arc/overflow-1.c | 100 ++ >> 6 files changed, 187 insertions(+), 4 deletions(-) >> create mode 100644 gcc/testsuite/gcc.target/arc/overflow-1.c >> >> diff --git a/gcc/config/arc/arc-modes.def b/gcc/config/arc/arc-modes.def >> index 763e880317d..69eeec5935a 100644 >> --- a/gcc/config/arc/arc-modes.def >> +++ b/gcc/config/arc/arc-modes.def >> @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see >> >> CC_MODE (CC_ZN); >> CC_MODE (CC_Z); >> +CC_MODE (CC_V); >> CC_MODE (CC_C); >> CC_MODE (CC_FP_GT); >> CC_MODE (CC_FP_GE); >> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h >> index 4f2db7ffb59..bc78fb0b370 100644 >> --- a/gcc/config/arc/arc-protos.h >> +++ b/gcc/config/arc/arc-protos.h >> @@ -50,6 +50,7 @@ extern bool arc_check_mov_const (HOST_WIDE_INT ); >> extern bool arc_split_mov_const (rtx *); >> extern bool arc_can_use_return_insn (void); >> extern bool arc_split_move_p (rtx *); >> +extern void arc_gen_unlikely_cbranch (enum rtx_code, machine_mode, rtx); >> #endif /* RTX_CODE */ >> >> extern bool arc_ccfsm_branch_deleted_p (void); >> diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc >> index f8c9bf17e2c..ec93d40aeb9 100644 >> --- a/gcc/config/arc/arc.cc >> +++ b/gcc/config/arc/arc.cc >> @@ -1538,6 +1538,13 @@ get_arc_condition_code (rtx comparison) >> case GEU : return ARC_CC_NC; >> default : gcc_unreachable (); >> } >> +case E_CC_Vmode: >> + switch (GET_CODE (comparison)) >> + { >> + case EQ : return ARC_CC_NV; >> + case NE : return ARC_CC_V; >> + default : gcc_unreachable (); >> + } >> case E_CC_FP_GTmode: >>if (TARGET_ARGONAUT_SET && TARGET_SPFP) >> switch (GET_CODE (comparison)) >> @@ -1868,7 +1875,7 @@ arc_init_reg_tables (void) >> /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so >> we must explicitly check for them here. */ >> if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) >> CC_Zmode >> - || i == (int) CC_Cmode >> + || i == (int) CC_Cmode || i == (int) CC_Vmode >> || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode >> || i == CC_FPUmode || i == CC_FPUEmode || i == CC_FPU_UNEQmode) >> arc_mode_class[i] = 1 << (int) C_MODE; >> @@ -11852,6 +11859,23 @@ arc_libm_function_max_error (unsigned cfn, >> machine_mode mode, >>return default_libm_function_max_error (cfn, mode, boundary_p); >> } >> >> +/* Generate RTL for conditional branch with rtx comparison CODE in mode >> + CC_MODE. */ >> + >> +void >> +arc_gen_unlikely_cbranch (enum rtx_code cm
[PATCH 2/2] ARC: Use intrinsics for __builtin_sub_overflow*()
This patch covers signed and unsigned subtractions. The generated code would be something along these lines: signed: sub.f r0, r1, r2 b.v @label unsigned: sub.f r0, r1, r2 b.c @label gcc/ChangeLog: * config/arc/arc.md (subsi3_v): New insn. (subvsi4): New expand. (subsi3_c): New insn. (usubvsi4): New expand. gcc/testsuite/ChangeLog: * gcc.target/arc/overflow-2.c: New. Signed-off-by: Shahab Vahedi --- gcc/config/arc/arc.md | 48 +++ gcc/testsuite/gcc.target/arc/overflow-2.c | 97 +++ 2 files changed, 145 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arc/overflow-2.c diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 9d011f6b4a9..34e9e1a7f1d 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -2973,6 +2973,54 @@ archs4x, archs4xd" (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*") ]) +(define_insn "subsi3_v" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_V CC_REG) + (compare:CC_V (sign_extend:DI (minus:SI (match_dup 1) + (match_dup 2))) + (minus:DI (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2)] + "" + "sub.f\\t%0,%1,%2" + [(set_attr "cond" "set") +(set_attr "type" "compare") +(set_attr "length" "4,4,4,8")]) + +(define_expand "subvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_subsi3_v (operands[0], operands[1], operands[2])); + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE;") + +(define_insn "subsi3_c" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_C CC_REG) + (compare:CC_C (match_dup 1) + (match_dup 2)))] + "" + "sub.f\\t%0,%1,%2" + [(set_attr "cond" "set") +(set_attr "type" "compare") +(set_attr "length" "4,4,4,8")]) + +(define_expand "usubvsi4" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "nonmemory_operand") + (label_ref (match_operand 3 "" ""))] + "" + "emit_insn (gen_subsi3_c (operands[0], operands[1], operands[2])); +arc_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); +DONE;") + (define_expand "subdi3" [(set (match_operand:DI 0 "register_operand" "") (minus:DI (match_operand:DI 1 "register_operand" "") diff --git a/gcc/testsuite/gcc.target/arc/overflow-2.c b/gcc/testsuite/gcc.target/arc/overflow-2.c new file mode 100644 index 000..b4de8c03b22 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/overflow-2.c @@ -0,0 +1,97 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +#include +#include + +/* + * sub.f r0,r0,r1 + * st_s r0,[r2] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool sub_overflow (int32_t a, int32_t b, int32_t *res) +{ + return __builtin_sub_overflow (a, b, res); +} + +/* + * sub.f r0,r0,-1234 + * st_s r0,[r1] + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool subi_overflow (int32_t a, int32_t *res) +{ + return __builtin_sub_overflow (a, -1234, res); +} + +/* + * sub.f r3,r0,r1 + * st_s r3,[r2] + * j_s.d [blink] + * setlo r0,r0,r1 + */ +bool usub_overflow (uint32_t a, uint32_t b, uint32_t *res) +{ + return __builtin_sub_overflow (a, b, res); +} + +/* + * sub.f r2,r0,4321 + * seths r0,4320,r0 + * j_s.d [blink] + * st_s r2,[r1] + */ +bool usubi_overflow (uint32_t a, uint32_t *res) +{ + return __builtin_sub_overflow (a, 4321, res); +} + +/* + * sub.f r0,r0,r1 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool sub_overflow_p (int32_t a, int32_t b, int32_t res) +{ + return __builtin_sub_overflow_p (a, b, res); +} + +/* + * sub.f r0,r0,-1000 + * mov_s r0,1 + * j_s.d [blink] + * mov.nv r0,0 + */ +bool subi_overflow_p (int32_t a, int32_t res) +{ + return __builtin_sub_overflow_p (a, -1000, res); +} + +/* + * j_s.
[PATCH 1/2] ARC: Use intrinsics for __builtin_add_overflow*()
This patch covers signed and unsigned additions. The generated code would be something along these lines: signed: add.f r0, r1, r2 b.v @label unsigned: add.f r0, r1, r2 b.c @label gcc/ChangeLog: * config/arc/arc-modes.def: Add CC_V mode. * config/arc/predicates.md (proper_comparison_operator): Handle E_CC_Vmode. (equality_comparison_operator): Exclude CC_Vmode from eq/ne. (cc_set_register): Handle CC_Vmode. (cc_use_register): Likewise. * config/arc/arc.md (addsi3_v): New insn. (addvsi4): New expand. (addsi3_c): New insn. (uaddvsi4): New expand. * config/arc/arc-protos.h (arc_gen_unlikely_cbranch): New. * config/arc/arc.cc (arc_gen_unlikely_cbranch): New. (get_arc_condition_code): Handle E_CC_Vmode. (arc_init_reg_tables): Handle CC_Vmode. gcc/testsuite/ChangeLog: * gcc.target/arc/overflow-1.c: New. Signed-off-by: Shahab Vahedi --- gcc/config/arc/arc-modes.def | 1 + gcc/config/arc/arc-protos.h | 1 + gcc/config/arc/arc.cc | 26 +- gcc/config/arc/arc.md | 49 +++ gcc/config/arc/predicates.md | 14 ++- gcc/testsuite/gcc.target/arc/overflow-1.c | 100 ++ 6 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/overflow-1.c diff --git a/gcc/config/arc/arc-modes.def b/gcc/config/arc/arc-modes.def index 763e880317d..69eeec5935a 100644 --- a/gcc/config/arc/arc-modes.def +++ b/gcc/config/arc/arc-modes.def @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see CC_MODE (CC_ZN); CC_MODE (CC_Z); +CC_MODE (CC_V); CC_MODE (CC_C); CC_MODE (CC_FP_GT); CC_MODE (CC_FP_GE); diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h index 4f2db7ffb59..bc78fb0b370 100644 --- a/gcc/config/arc/arc-protos.h +++ b/gcc/config/arc/arc-protos.h @@ -50,6 +50,7 @@ extern bool arc_check_mov_const (HOST_WIDE_INT ); extern bool arc_split_mov_const (rtx *); extern bool arc_can_use_return_insn (void); extern bool arc_split_move_p (rtx *); +extern void arc_gen_unlikely_cbranch (enum rtx_code, machine_mode, rtx); #endif /* RTX_CODE */ extern bool arc_ccfsm_branch_deleted_p (void); diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc index f8c9bf17e2c..ec93d40aeb9 100644 --- a/gcc/config/arc/arc.cc +++ b/gcc/config/arc/arc.cc @@ -1538,6 +1538,13 @@ get_arc_condition_code (rtx comparison) case GEU : return ARC_CC_NC; default : gcc_unreachable (); } +case E_CC_Vmode: + switch (GET_CODE (comparison)) + { + case EQ : return ARC_CC_NV; + case NE : return ARC_CC_V; + default : gcc_unreachable (); + } case E_CC_FP_GTmode: if (TARGET_ARGONAUT_SET && TARGET_SPFP) switch (GET_CODE (comparison)) @@ -1868,7 +1875,7 @@ arc_init_reg_tables (void) /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so we must explicitly check for them here. */ if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode - || i == (int) CC_Cmode + || i == (int) CC_Cmode || i == (int) CC_Vmode || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode || i == CC_FPUmode || i == CC_FPUEmode || i == CC_FPU_UNEQmode) arc_mode_class[i] = 1 << (int) C_MODE; @@ -11852,6 +11859,23 @@ arc_libm_function_max_error (unsigned cfn, machine_mode mode, return default_libm_function_max_error (cfn, mode, boundary_p); } +/* Generate RTL for conditional branch with rtx comparison CODE in mode + CC_MODE. */ + +void +arc_gen_unlikely_cbranch (enum rtx_code cmp, machine_mode cc_mode, rtx label) +{ + rtx cc_reg, x; + + cc_reg = gen_rtx_REG (cc_mode, CC_REG); + label = gen_rtx_LABEL_REF (VOIDmode, label); + + x = gen_rtx_fmt_ee (cmp, VOIDmode, cc_reg, const0_rtx); + x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx); + + emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); +} + #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index d37ecbf4292..9d011f6b4a9 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -2725,6 +2725,55 @@ archs4x, archs4xd" } ") +(define_insn "addsi3_v" + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") + (plus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) + (set (reg:CC_V CC_REG) + (compare:CC_V (sign_extend:DI (plus:SI (match_dup 1) + (match_dup 2))) +(plus:DI (sign_extend:DI (match_dup 1)) +
[PATCH] [ARC] Pass along -mcode-density flag to the assembler
From: Shahab Vahedi This change makes sure that if the driver is invoked with "-mcode-density" flag, then the assembler will receive it too. gcc/ 2019-09-03 Sahahb Vahedi * config/arc/arc.h (ASM_SPEC): pass -mcode-density * gcc.target/arc/code-density-flag.c: New test. Signed-off-by: Shahab Vahedi --- gcc/config/arc/arc.h | 5 +-- .../gcc.target/arc/code-density-flag.c| 34 +++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/code-density-flag.c diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 8dca0d2c4b2..05fba539295 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -96,8 +96,9 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); #endif #undef ASM_SPEC -#define ASM_SPEC "%{mbig-endian|EB:-EB} %{EL} " \ - "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}" +#define ASM_SPEC "%{mbig-endian|EB:-EB} %{EL} " \ + "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} " \ + "%{mfpu=fpuda*:-mfpuda} %{mcode-density}" #define OPTION_DEFAULT_SPECS \ {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}" } diff --git a/gcc/testsuite/gcc.target/arc/code-density-flag.c b/gcc/testsuite/gcc.target/arc/code-density-flag.c new file mode 100644 index 000..1ecf1a2ca29 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/code-density-flag.c @@ -0,0 +1,34 @@ +/* Produce code-dense instructions and the assembler must * + * be okay with it. An example would be:* + * * + * sub_s r3, r1, r3* + * * + * While generally for _short instructions_ , it is not * + * allowed to have different registers as the first and * + * second operands, the code-dense mode allows it. * + * This test is about the fact that if "-mcode-density" is * + * passed to gcc driver as the flag, "as" must receive it * + * as well, else it is going to choke on such encodings.*/ + +/* { dg-do assemble } */ +/* { dg-skip-if "" { ! { clmcpu } } } */ +/* { dg-options "-mcpu=em_mini -mcode-density" }*/ + +typedef long long uint64_t; + +uint64_t f1(void) +{ + return 1; +} + +void f2(void) +{ + uint64_t start_us = 0; + while ((f1() - start_us) < 2); +} + +/* This is a tricky check, because it hardcodes register * + * numbers. Nevertheless, it is easier than coming up with * + * a regular expression that the first two operands should * + * not be the same. */ +/* { dg-final { scan-assembler "sub_s\\s+r3,r1,r3" } } */ -- 2.23.0