[PATCH] ARC: Update gcc.target/arc/pr9001184797.c test

2024-07-03 Thread Luis Silva
... to comply with new standards due to stricter analysis in
the latest GCC versions.

gcc/testsuite/ChangeLog:

* gcc.target/arc/pr9001184797.c: (Fix compiler warnings)
---
 gcc/testsuite/ChangeLog | 4 
 gcc/testsuite/gcc.target/arc/pr9001184797.c | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9aeec32f9e6..bd825881b75 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2024-07-03  Luis Silva  
+
+   * gcc.target/arc/pr9001184797.c: (Fix compiler warnings)
+
 2024-07-02  Pengxuan Zheng  
 
PR target/113859
diff --git a/gcc/testsuite/gcc.target/arc/pr9001184797.c 
b/gcc/testsuite/gcc.target/arc/pr9001184797.c
index e76c6769042..6c5de5fe729 100644
--- a/gcc/testsuite/gcc.target/arc/pr9001184797.c
+++ b/gcc/testsuite/gcc.target/arc/pr9001184797.c
@@ -4,13 +4,15 @@
 
 /* This test studies the use of anchors and tls symbols. */
 
+extern int h();
+
 struct a b;
 struct a {
   long c;
   long d
 } e() {
   static __thread struct a f;
-  static __thread g;
+  static __thread int g;
   g = 5;
   h();
   if (f.c)
-- 
2.37.1



[PATCH] arc: testsuite: Scan "rlc" instead of "mov.hs".

2025-03-18 Thread Luis Silva
Due to the patch by Roger Sayle,
09881218137f4af9b7c894c2d350cf2ff8e0ee23, which
introduces the use of the `rlc rX,0` instruction in place
of the `mov.hs`, the add overflow test case needs to be
updated.  The previous test case was validating the `mov.hs`
instruction, but now it must validate the `rlc` instruction
as the new behavior.

gcc/testsuite/ChangeLog:

* gcc.target/arc/overflow-1.c: Replace mov.hs with rlc.

Signed-off-by: Luis Silva 
---
 gcc/testsuite/gcc.target/arc/overflow-1.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arc/overflow-1.c 
b/gcc/testsuite/gcc.target/arc/overflow-1.c
index 01b3e8ad0fa..694c25cfe66 100644
--- a/gcc/testsuite/gcc.target/arc/overflow-1.c
+++ b/gcc/testsuite/gcc.target/arc/overflow-1.c
@@ -31,9 +31,8 @@ bool addi_overflow (int32_t a, int32_t *res)
 /*
  * add.f  r0,r0,r1
  * st_s   r0,[r2]
- * mov_s  r0,1
  * j_s.d  [blink]
- * mov.hs r0,0
+ * rlcr0,0
  */
 bool uadd_overflow (uint32_t a, uint32_t b, uint32_t *res)
 {
@@ -75,9 +74,8 @@ bool addi_overflow_p (int32_t a, int32_t res)
 
 /*
  * add.f   0,r0,r1
- * mov_s   r0,1
  * j_s.d   [blink]
- * mov.hs  r0,0
+ * rlc r0,0
  */
 bool uadd_overflow_p (uint32_t a, uint32_t b, uint32_t res)
 {
@@ -95,6 +93,6 @@ bool uaddi_overflow_p (uint32_t a, uint32_t res)
 
 /* { dg-final { scan-assembler-times "add.f\\s\+"   7 } } */
 /* { dg-final { scan-assembler-times "mov\.nv\\s\+" 4 } } */
-/* { dg-final { scan-assembler-times "mov\.hs\\s\+" 2 } } */
+/* { dg-final { scan-assembler-times "rlc\\s\+" 2 } } */
 /* { dg-final { scan-assembler-times "seths\\s\+"   2 } } */
 /* { dg-final { scan-assembler-not   "cmp" } } */
-- 
2.37.1



[PATCH 2/2] arc: Use intrinsics for __builtin_mul_overflow ()

2025-03-18 Thread Luis Silva
This patch handles both signed and unsigned
builtin multiplication overflow.

Uses the "mpy.f" instruction to set the condition
codes based on the result.  In the event of an
overflow, the V flag is set, triggering a
conditional move depending on the V flag status.

For example, set "1" to "r0" in case of overflow:

mov_s   r0,1
mpy.f   r0,r0,r1
j_s.d   [blink]
mov.nv  r0,0

gcc/ChangeLog:

* config/arc/arc.md (mulvsi4): New define_expand.
(mulsi3_Vcmp): New define_insn.

Signed-off-by: Luis Silva 
---
 gcc/config/arc/arc.md | 33 +
 1 file changed, 33 insertions(+)

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index bc2e8fadd91..dd245d1813c 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -842,6 +842,9 @@ archs4x, archs4xd"
 ; Optab prefix for sign/zero-extending operations
 (define_code_attr su_optab [(sign_extend "") (zero_extend "u")])
 
+;; Code iterator for sign/zero extension
+(define_code_iterator ANY_EXTEND [sign_extend zero_extend])
+
 (define_insn "*xt_cmp0_noout"
   [(set (match_operand 0 "cc_set_register" "")
(compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
@@ -1068,6 +1071,36 @@ archs4x, archs4xd"
(set_attr "cond" "set_zn")
(set_attr "length" "*,4,4,4,8")])
 
+(define_expand "mulvsi4"
+  [(ANY_EXTEND:DI (match_operand:SI 0 "register_operand"))
+   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand"))
+   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand"))
+   (label_ref (match_operand 3 "" ""))]
+  "TARGET_MPY"
+  {
+emit_insn (gen_mulsi3_Vcmp (operands[0], operands[1],
+ operands[2]));
+arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
+DONE;
+  })
+
+(define_insn "mulsi3_Vcmp"
+  [(parallel
+[(set
+  (reg:CC_V CC_REG)
+  (compare:CC_V
+   (mult:DI
+   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand"  "%0,r,r,r"))
+   (ANY_EXTEND:DI (match_operand:SI 2 "nonmemory_operand"  "I,L,r,C32")))
+   (ANY_EXTEND:DI (mult:SI (match_dup 1) (match_dup 2)
+ (set (match_operand:SI 0 "register_operand"  "=r,r,r,r")
+ (mult:SI (match_dup 1) (match_dup 2)))])]
+  "register_operand (operands[1], SImode)
+   || register_operand (operands[2], SImode)"
+  "mpy.f\\t%0,%1,%2"
+  [(set_attr "length" "4,4,4,8")
+   (set_attr "type"   "mpy")])
+
 (define_insn "*mulsi3_cmp0"
   [(set (reg:CC_Z CC_REG)
(compare:CC_Z
-- 
2.37.1



[PATCH 1/2] arc: Add commutative multiplication patterns.

2025-03-18 Thread Luis Silva
This patch introduces two new instruction patterns:

`*mulsi3_cmp0`:  This pattern performs a multiplication
and sets the CC_Z register based on the result, while
also storing the result of the multiplication in a
general-purpose register.

`*mulsi3_cmp0_noout`:  This pattern performs a
multiplication and sets the CC_Z register based on the
result without storing the result in a general-purpose
register.

These patterns are optimized to generate code using the `mpy.f`
instruction, specifically used where the result is compared to zero.

In addition, the previous commutative multiplication implementation
was removed.  It incorrectly took into account the negative flag,
which is wrong.  This new implementation only considers the zero
flag.

A test case has been added to verify the correctness of these
changes.

gcc/ChangeLog:

* config/arc/arc.cc (arc_select_cc_mode): Handle multiplication
results compared against zero, selecting CC_Zmode.
* config/arc/arc.md (*mulsi3_cmp0): New define_insn.
(*mulsi3_cmp0_noout): New define_insn.

gcc/testsuite/ChangeLog:

* gcc.target/arc/mult-cmp0.c: New test.

Signed-off-by: Luis Silva 
---
 gcc/config/arc/arc.cc|  7 +++
 gcc/config/arc/arc.md| 34 ++--
 gcc/testsuite/gcc.target/arc/mult-cmp0.c | 66 
 3 files changed, 103 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/mult-cmp0.c

diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index e3d53576768..8ad5649adc0 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -1555,6 +1555,13 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
   machine_mode mode = GET_MODE (x);
   rtx x1;
 
+  /* Matches all instructions which can do .f and clobbers only Z flag.  */
+  if (GET_MODE_CLASS (mode) == MODE_INT
+  && y == const0_rtx
+  && GET_CODE (x) == MULT
+  && (op == EQ || op == NE))
+return CC_Zmode;
+
   /* For an operation that sets the condition codes as a side-effect, the
  C and V flags is not set as for cmp, so we can only use comparisons where
  this doesn't matter.  (For LT and GE we can use "mi" and "pl"
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 49dfc9d35af..bc2e8fadd91 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -253,7 +253,7 @@
simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
simd_valign, simd_valign_with_acc, simd_vcontrol,
simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
-   fpu, fpu_fuse, fpu_sdiv, fpu_ddiv, fpu_cvt, block"
+   fpu, fpu_fuse, fpu_sdiv, fpu_ddiv, fpu_cvt, block, mpy"
   (cond [(eq_attr "is_sfunc" "yes")
 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || 
GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
(match_test "flag_pic") (const_string "sfunc")]
@@ -1068,11 +1068,37 @@ archs4x, archs4xd"
(set_attr "cond" "set_zn")
(set_attr "length" "*,4,4,4,8")])
 
-;; The next two patterns are for plos, ior, xor, and, and mult.
+(define_insn "*mulsi3_cmp0"
+  [(set (reg:CC_Z CC_REG)
+   (compare:CC_Z
+(mult:SI
+ (match_operand:SI 1 "register_operand"  "%r,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "rL,I,i"))
+(const_int 0)))
+   (set (match_operand:SI 0 "register_operand""=r,r,r")
+   (mult:SI (match_dup 1) (match_dup 2)))]
+ "TARGET_MPY"
+ "mpy%?.f\\t%0,%1,%2"
+ [(set_attr "length" "4,4,8")
+  (set_attr "type" "mpy")])
+
+(define_insn "*mulsi3_cmp0_noout"
+  [(set (reg:CC_Z CC_REG)
+   (compare:CC_Z
+(mult:SI
+ (match_operand:SI 0 "register_operand"   "%r,r,r")
+ (match_operand:SI 1 "nonmemory_operand"  "rL,I,i"))
+(const_int 0)))]
+ "TARGET_MPY"
+ "mpy%?.f\\t0,%0,%1"
+ [(set_attr "length" "4,4,8")
+  (set_attr "type" "mpy")])
+
+;; The next two patterns are for plus, ior, xor, and.
 (define_insn "*commutative_binary_cmp0_noout"
   [(set (match_operand 0 "cc_set_register" "")
(match_operator 4 "zn_compare_operator"
- [(match_operator:SI 3 "commutative_operator"
+ [(match_operator:SI 3 "commutative_operator_sans_mult"
 [(match_operand:SI 1 "register_operand" "%r,r")
  (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
   (const_int 0)]))]
@@ -1085,7 +,7 @@ archs4x, archs4xd"
 (defin