[PATCH v2] LoongArch: Fix inconsistent description in *sge_

2024-03-05 Thread Guo Jie
The constraint of op[1] is inconsistent with the output template.

gcc/ChangeLog:

* config/loongarch/loongarch.md
(define_insn "*sge_"): Fix inconsistency
error.

---
Update in v2:
Remove useless support for op[1] is const_imm12_operand.

---
 gcc/config/loongarch/loongarch.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index f3b5c641fce..e35a001e0ed 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3360,7 +3360,7 @@ (define_insn "*sge_"
(any_ge:GPR (match_operand:X 1 "register_operand" "r")
 (const_int 1)))]
   ""
-  "slti\t%0,%.,%1"
+  "slt\t%0,%.,%1"
   [(set_attr "type" "slt")
(set_attr "mode" "")])
 
-- 
2.20.1



Re: [PATCH] LoongArch: Fix inconsistent description in *sge_

2024-03-04 Thread Guo Jie

Thanks for the feedback.

The comparison between a const_imm12_operand and (const_int 1) does indeed

perform a universal process of constant folding before any tree based 
optimization.


I will fix it in patch v2.


在 2024/3/4 下午5:18, Xi Ruoyao 写道:

On Mon, 2024-03-04 at 11:03 +0800, Guo Jie wrote:

The constraint of op[1] is inconsistent with the output template.

gcc/ChangeLog:

* config/loongarch/loongarch.md
(define_insn "*sge_"): Fix inconsistency
error.

---
  gcc/config/loongarch/loongarch.md | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.md
b/gcc/config/loongarch/loongarch.md
index f3b5c641fce..2d25374bdc9 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3357,10 +3357,10 @@ (define_insn "*sgt_"
  
  (define_insn "*sge_"

    [(set (match_operand:GPR 0 "register_operand" "=r")
-   (any_ge:GPR (match_operand:X 1 "register_operand" "r")
+   (any_ge:GPR (match_operand:X 1 "arith_operand" "rI")
     (const_int 1)))]

No, arith_operand is just register_operand or const_imm12_operand, but
comparing a const_imm12_operand with (const_int 1) should be folded into
a constant (even at -O0, AFAIK).  So allowing const_imm12_operand here
makes no benefit.


    ""
-  "slti\t%0,%.,%1"
+  "slt%i1\t%0,%.,%1"
    [(set_attr "type" "slt")
     (set_attr "mode" "")])
  


[PATCH] LoongArch: Fix inconsistent description in *sge_

2024-03-03 Thread Guo Jie
The constraint of op[1] is inconsistent with the output template.

gcc/ChangeLog:

* config/loongarch/loongarch.md
(define_insn "*sge_"): Fix inconsistency
error.

---
 gcc/config/loongarch/loongarch.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index f3b5c641fce..2d25374bdc9 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3357,10 +3357,10 @@ (define_insn "*sgt_"
 
 (define_insn "*sge_"
   [(set (match_operand:GPR 0 "register_operand" "=r")
-   (any_ge:GPR (match_operand:X 1 "register_operand" "r")
+   (any_ge:GPR (match_operand:X 1 "arith_operand" "rI")
 (const_int 1)))]
   ""
-  "slti\t%0,%.,%1"
+  "slt%i1\t%0,%.,%1"
   [(set_attr "type" "slt")
(set_attr "mode" "")])
 
-- 
2.20.1



[PATCH] LoongArch: Fix runtime error in a gcc build with --with-build-config=bootstrap-ubsan

2023-11-22 Thread Guo Jie
gcc/ChangeLog:

* config/loongarch/loongarch.cc (loongarch_split_plus_constant):
avoid left shift of negative value -0x8000.

---
 gcc/config/loongarch/loongarch.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 33357c670e1..81cd9fa1e7c 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -4249,7 +4249,7 @@ loongarch_split_plus_constant (rtx *op, machine_mode mode)
   else if (loongarch_addu16i_imm12_operand_p (v, mode))
 a = (v & ~HWIT_UC_0xFFF) + ((v & 0x800) << 1);
   else if (mode == DImode && DUAL_ADDU16I_OPERAND (v))
-a = (v > 0 ? 0x7fff : -0x8000) << 16;
+a = (v > 0 ? 0x7fff : ~0x7fff);
   else
 gcc_unreachable ();
 
-- 
2.20.1



[PATCH v2] LoongArch: Optimize the loading of immediate numbers with the same high and low 32-bit values

2023-11-22 Thread Guo Jie
For the following immediate load operation in 
gcc/testsuite/gcc.target/loongarch/imm-load1.c:

long long r = 0x0101010101010101;

Before this patch:

lu12i.w $r15,16842752>>12
ori $r15,$r15,257
lu32i.d $r15,0x10101>>32
lu52i.d $r15,$r15,0x100>>52

After this patch:

lu12i.w $r15,16842752>>12
ori $r15,$r15,257
bstrins.d   $r15,$r15,63,32

gcc/ChangeLog:

* config/loongarch/loongarch.cc
(enum loongarch_load_imm_method): Add new method.
(loongarch_build_integer): Add relevant implementations for
new method.
(loongarch_move_integer): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/imm-load1.c: Change old check.

---
Update in v2:
1. Correct the format of ChangeLog.
2. Avoid left shift of negative value in loongarch_build_integer.

---
 gcc/config/loongarch/loongarch.cc | 22 ++-
 .../gcc.target/loongarch/imm-load1.c  |  3 ++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index d05743bec87..f95507e2348 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -142,12 +142,16 @@ struct loongarch_address_info
 
METHOD_LU52I:
  Load 52-63 bit of the immediate number.
+
+   METHOD_MIRROR:
+ Copy 0-31 bit of the immediate number to 32-63bit.
 */
 enum loongarch_load_imm_method
 {
   METHOD_NORMAL,
   METHOD_LU32I,
-  METHOD_LU52I
+  METHOD_LU52I,
+  METHOD_MIRROR
 };
 
 struct loongarch_integer_op
@@ -1556,11 +1560,23 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
 
   int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;
   int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
+
+  uint32_t hival = (uint32_t) (value >> 32);
+  uint32_t loval = (uint32_t) value;
+
   /* Determine whether the upper 32 bits are sign-extended from the lower
 32 bits. If it is, the instructions to load the high order can be
 ommitted.  */
   if (lu32i[sign31] && lu52i[sign31])
return cost;
+  /* If the lower 32 bits are the same as the upper 32 bits, just copy
+the lower 32 bits to the upper 32 bits.  */
+  else if (loval == hival)
+   {
+ codes[cost].method = METHOD_MIRROR;
+ codes[cost].curr_value = value;
+ return cost + 1;
+   }
   /* Determine whether bits 32-51 are sign-extended from the lower 32
 bits. If so, directly load 52-63 bits.  */
   else if (lu32i[sign31])
@@ -3230,6 +3246,10 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned 
HOST_WIDE_INT value)
   gen_rtx_AND (DImode, x, GEN_INT (0xf)),
   GEN_INT (codes[i].value));
  break;
+   case METHOD_MIRROR:
+ gcc_assert (mode == DImode);
+ emit_insn (gen_insvdi (x, GEN_INT (32), GEN_INT (32), x));
+ break;
default:
  gcc_unreachable ();
}
diff --git a/gcc/testsuite/gcc.target/loongarch/imm-load1.c 
b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
index 2ff02971239..f64cc2956a3 100644
--- a/gcc/testsuite/gcc.target/loongarch/imm-load1.c
+++ b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-mabi=lp64d -O2" } */
-/* { dg-final { scan-assembler "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
+/* { dg-final { scan-assembler-not "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } 
*/
+/* { dg-final { scan-assembler "test:.*lu12i\.w.*\n\tbstrins\.d.*\n\.L2:" } } 
*/
 
 
 extern long long b[10];
-- 
2.36.0



Re: [PATCH] LoongArch: Optimize the loading of immediate numbers with the same high and low 32-bit values

2023-11-20 Thread Guo Jie

Thanks for your advice! I will fix it in patch v2.


在 2023/11/18 下午5:09, Xi Ruoyao 写道:

On Sat, 2023-11-18 at 14:59 +0800, Guo Jie wrote:

For the following immediate load operation in 
gcc/testsuite/gcc.target/loongarch/imm-load1.c:

long long r = 0x0101010101010101;

Before this patch:

lu12i.w     $r15,16842752>>12
ori     $r15,$r15,257
lu32i.d     $r15,0x10101>>32
lu52i.d     $r15,$r15,0x100>>52

After this patch:

lu12i.w $r15,16842752>>12
ori $r15,$r15,257
bstrins.d   $r15,$r15,63,32

gcc/ChangeLog:

* config/loongarch/loongarch.cc (enum loongarch_load_imm_method): Add 
new method.
(loongarch_build_integer): Add relevant implementations for new method.
(loongarch_move_integer): Ditto.

IIRC the ChangeLog line should be wrapped at 72 characters.

/* snip */


  struct loongarch_integer_op
@@ -1556,11 +1560,23 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
  
    int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;

    int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
+
+  unsigned HOST_WIDE_INT hival = value >> 32;
+  unsigned HOST_WIDE_INT loval = value << 32 >> 32;

Use

uint32_t hival = (uint32_t) (value >> 32);
uint32_t loval = (uint32_t) value;

instead, because "value << 32" may trigger a left-shift of negative
value.

C++11 doesn't allow shifting left any negative value.  Yes it's allowed
as a GCC extension and it's also allowed by C++23, but GCC codebase is
still C++11.  So it may break GCC if bootstrapping from a different
compiler, and --with-build-config=bootstrap-ubsan will complain.

Otherwise LGTM.





[PATCH] LoongArch: Optimize the loading of immediate numbers with the same high and low 32-bit values

2023-11-17 Thread Guo Jie
For the following immediate load operation in 
gcc/testsuite/gcc.target/loongarch/imm-load1.c:

long long r = 0x0101010101010101;

Before this patch:

lu12i.w $r15,16842752>>12
ori $r15,$r15,257
lu32i.d $r15,0x10101>>32
lu52i.d $r15,$r15,0x100>>52

After this patch:

lu12i.w $r15,16842752>>12
ori $r15,$r15,257
bstrins.d   $r15,$r15,63,32

gcc/ChangeLog:

* config/loongarch/loongarch.cc (enum loongarch_load_imm_method): Add 
new method.
(loongarch_build_integer): Add relevant implementations for new method.
(loongarch_move_integer): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/imm-load1.c: Change old check.
---
 gcc/config/loongarch/loongarch.cc | 22 ++-
 .../gcc.target/loongarch/imm-load1.c  |  3 ++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index d05743bec87..58c00344d09 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -142,12 +142,16 @@ struct loongarch_address_info
 
METHOD_LU52I:
  Load 52-63 bit of the immediate number.
+
+   METHOD_MIRROR:
+ Copy 0-31 bit of the immediate number to 32-63bit.
 */
 enum loongarch_load_imm_method
 {
   METHOD_NORMAL,
   METHOD_LU32I,
-  METHOD_LU52I
+  METHOD_LU52I,
+  METHOD_MIRROR
 };
 
 struct loongarch_integer_op
@@ -1556,11 +1560,23 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
 
   int sign31 = (value & (HOST_WIDE_INT_1U << 31)) >> 31;
   int sign51 = (value & (HOST_WIDE_INT_1U << 51)) >> 51;
+
+  unsigned HOST_WIDE_INT hival = value >> 32;
+  unsigned HOST_WIDE_INT loval = value << 32 >> 32;
+
   /* Determine whether the upper 32 bits are sign-extended from the lower
 32 bits. If it is, the instructions to load the high order can be
 ommitted.  */
   if (lu32i[sign31] && lu52i[sign31])
return cost;
+  /* If the lower 32 bits are the same as the upper 32 bits, just copy
+the lower 32 bits to the upper 32 bits.  */
+  else if (loval == hival)
+   {
+ codes[cost].method = METHOD_MIRROR;
+ codes[cost].curr_value = value;
+ return cost + 1;
+   }
   /* Determine whether bits 32-51 are sign-extended from the lower 32
 bits. If so, directly load 52-63 bits.  */
   else if (lu32i[sign31])
@@ -3230,6 +3246,10 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned 
HOST_WIDE_INT value)
   gen_rtx_AND (DImode, x, GEN_INT (0xf)),
   GEN_INT (codes[i].value));
  break;
+   case METHOD_MIRROR:
+ gcc_assert (mode == DImode);
+ emit_insn (gen_insvdi (x, GEN_INT (32), GEN_INT (32), x));
+ break;
default:
  gcc_unreachable ();
}
diff --git a/gcc/testsuite/gcc.target/loongarch/imm-load1.c 
b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
index 2ff02971239..f64cc2956a3 100644
--- a/gcc/testsuite/gcc.target/loongarch/imm-load1.c
+++ b/gcc/testsuite/gcc.target/loongarch/imm-load1.c
@@ -1,6 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-mabi=lp64d -O2" } */
-/* { dg-final { scan-assembler "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */
+/* { dg-final { scan-assembler-not "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } 
*/
+/* { dg-final { scan-assembler "test:.*lu12i\.w.*\n\tbstrins\.d.*\n\.L2:" } } 
*/
 
 
 extern long long b[10];
-- 
2.20.1



[PATCH] LoongArch: Optimizations of vector construction.

2023-09-20 Thread Guo Jie
gcc/ChangeLog:

* config/loongarch/lasx.md (lasx_vecinit_merge_): New
pattern for vector construction.
(vec_set_internal): Ditto.
(lasx_xvinsgr2vr__internal): Ditto.
(lasx_xvilvl__internal): Ditto.
* config/loongarch/loongarch.cc (loongarch_expand_vector_init):
Optimized the implementation of vector construction.
(loongarch_expand_vector_init_same): New function.
* config/loongarch/lsx.md (lsx_vilvl__internal): New
pattern for vector construction.
(lsx_vreplvei_mirror_): New pattern for vector
construction.
(vec_concatv2df): Ditto.
(vec_concatv4sf): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/vector/lasx/lasx-vec-construct-opt.c: New test.
* gcc.target/loongarch/vector/lsx/lsx-vec-construct-opt.c: New test.
---
 gcc/config/loongarch/lasx.md  |  69 ++
 gcc/config/loongarch/loongarch.cc | 716 +-
 gcc/config/loongarch/lsx.md   | 134 
 .../vector/lasx/lasx-vec-construct-opt.c  | 102 +++
 .../vector/lsx/lsx-vec-construct-opt.c|  85 +++
 5 files changed, 732 insertions(+), 374 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vec-construct-opt.c
 create mode 100644 
gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-construct-opt.c

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 8111c8bb79a..2bc5d47ed4a 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -186,6 +186,9 @@ (define_c_enum "unspec" [
   UNSPEC_LASX_XVLDI
   UNSPEC_LASX_XVLDX
   UNSPEC_LASX_XVSTX
+  UNSPEC_LASX_VECINIT_MERGE
+  UNSPEC_LASX_VEC_SET_INTERNAL
+  UNSPEC_LASX_XVILVL_INTERNAL
 ])
 
 ;; All vector modes with 256 bits.
@@ -255,6 +258,15 @@ (define_mode_attr VFHMODE256
[(V8SF "V4SF")
(V4DF "V2DF")])
 
+;; The attribute gives half int/float modes for vector modes.
+(define_mode_attr VHMODE256_ALL
+  [(V32QI "V16QI")
+   (V16HI "V8HI")
+   (V8SI "V4SI")
+   (V4DI "V2DI")
+   (V8SF "V4SF")
+   (V4DF "V2DF")])
+
 ;; The attribute gives double modes for vector modes in LASX.
 (define_mode_attr VDMODE256
   [(V8SI "V4DI")
@@ -312,6 +324,11 @@ (define_mode_attr mode256_f
(V4DI "v4df")
(V8SI "v8sf")])
 
+;; This attribute gives V32QI mode and V16HI mode with half size.
+(define_mode_attr mode256_i_half
+  [(V32QI "v16qi")
+   (V16HI "v8hi")])
+
  ;; This attribute gives suffix for LASX instructions.  HOW?
 (define_mode_attr lasxfmt
   [(V4DF "d")
@@ -756,6 +773,20 @@ (define_insn "lasx_xvpermi_q_"
   [(set_attr "type" "simd_splat")
(set_attr "mode" "")])
 
+;; Only for loongarch_expand_vector_init in loongarch.cc.
+;; Support a LSX-mode input op2.
+(define_insn "lasx_vecinit_merge_"
+  [(set (match_operand:LASX 0 "register_operand" "=f")
+   (unspec:LASX
+ [(match_operand:LASX 1 "register_operand" "0")
+  (match_operand: 2 "register_operand" "f")
+  (match_operand 3 "const_uimm8_operand")]
+  UNSPEC_LASX_VECINIT_MERGE))]
+  "ISA_HAS_LASX"
+  "xvpermi.q\t%u0,%u2,%3"
+  [(set_attr "type" "simd_splat")
+   (set_attr "mode" "")])
+
 (define_insn "lasx_xvpickve2gr_d"
   [(set (match_operand:DI 0 "register_operand" "=r")
(any_extend:DI
@@ -779,6 +810,33 @@ (define_expand "vec_set"
   DONE;
 })
 
+;; Only for loongarch_expand_vector_init in loongarch.cc.
+;; Simulate missing instructions xvinsgr2vr.b and xvinsgr2vr.h.
+(define_expand "vec_set_internal"
+  [(match_operand:ILASX_HB 0 "register_operand")
+   (match_operand: 1 "reg_or_0_operand")
+   (match_operand 2 "const__operand")]
+  "ISA_HAS_LASX"
+{
+  rtx index = GEN_INT (1 << INTVAL (operands[2]));
+  emit_insn (gen_lasx_xvinsgr2vr__internal
+(operands[0], operands[1], operands[0], index));
+  DONE;
+})
+
+(define_insn "lasx_xvinsgr2vr__internal"
+  [(set (match_operand:ILASX_HB 0 "register_operand" "=f")
+   (unspec:ILASX_HB [(match_operand: 1 "reg_or_0_operand" "rJ")
+ (match_operand:ILASX_HB 2 "register_operand" "0")
+ (match_operand 3 "const__operand" "")]
+UNSPEC_LASX_VEC_SET_INTERNAL))]
+  "ISA_HAS_LASX"
+{
+  return "vinsgr2vr.\t%w0,%z1,%y3";
+}
+  [(set_attr "type" "simd_insert")
+   (set_attr "mode" "")])
+
 (define_expand "vec_set"
   [(match_operand:FLASX 0 "register_operand")
(match_operand: 1 "reg_or_0_operand")
@@ -1567,6 +1625,17 @@ (define_insn "logb2"
   [(set_attr "type" "simd_flog2")
(set_attr "mode" "")])
 
+;; Only for loongarch_expand_vector_init in loongarch.cc.
+;; Merge two scalar floating-point op1 and op2 into a LASX op0.
+(define_insn "lasx_xvilvl__internal"
+  [(set (match_operand:FLASX 0 "register_operand" "=f")
+   (unspec:FLASX [(match_operand: 1 "register_operand" "f")
+  (match_operand: 2 "register_operand" "f")]
+ UNSPEC_LASX_XVILVL_INTERNAL))]
+  "ISA_H

[PATCH] LoongArch: Optimizations of vector construction.

2023-09-20 Thread Guo Jie
Change-Id: I327f68ab482b94073974e672c71d25c98b35a080

gcc/ChangeLog:

* config/loongarch/lasx.md (lasx_vecinit_merge_): New
pattern for vector construction.
(vec_set_internal): Ditto.
(lasx_xvinsgr2vr__internal): Ditto.
(lasx_xvilvl__internal): Ditto.
* config/loongarch/loongarch.cc (loongarch_expand_vector_init):
Optimized the implementation of vector construction.
(loongarch_expand_vector_init_same): New function.
* config/loongarch/lsx.md (lsx_vilvl__internal): New
pattern for vector construction.
(lsx_vreplvei_mirror_): New pattern for vector
construction.
(vec_concatv2df): Ditto.
(vec_concatv4sf): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/vector/lasx/lasx-vec-construct-opt.c: New test.
* gcc.target/loongarch/vector/lsx/lsx-vec-construct-opt.c: New test.
---
 gcc/config/loongarch/lasx.md  |  69 ++
 gcc/config/loongarch/loongarch.cc | 716 +-
 gcc/config/loongarch/lsx.md   | 134 
 .../vector/lasx/lasx-vec-construct-opt.c  | 102 +++
 .../vector/lsx/lsx-vec-construct-opt.c|  85 +++
 5 files changed, 732 insertions(+), 374 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-vec-construct-opt.c
 create mode 100644 
gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-vec-construct-opt.c

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 8111c8bb79a..2bc5d47ed4a 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -186,6 +186,9 @@ (define_c_enum "unspec" [
   UNSPEC_LASX_XVLDI
   UNSPEC_LASX_XVLDX
   UNSPEC_LASX_XVSTX
+  UNSPEC_LASX_VECINIT_MERGE
+  UNSPEC_LASX_VEC_SET_INTERNAL
+  UNSPEC_LASX_XVILVL_INTERNAL
 ])
 
 ;; All vector modes with 256 bits.
@@ -255,6 +258,15 @@ (define_mode_attr VFHMODE256
[(V8SF "V4SF")
(V4DF "V2DF")])
 
+;; The attribute gives half int/float modes for vector modes.
+(define_mode_attr VHMODE256_ALL
+  [(V32QI "V16QI")
+   (V16HI "V8HI")
+   (V8SI "V4SI")
+   (V4DI "V2DI")
+   (V8SF "V4SF")
+   (V4DF "V2DF")])
+
 ;; The attribute gives double modes for vector modes in LASX.
 (define_mode_attr VDMODE256
   [(V8SI "V4DI")
@@ -312,6 +324,11 @@ (define_mode_attr mode256_f
(V4DI "v4df")
(V8SI "v8sf")])
 
+;; This attribute gives V32QI mode and V16HI mode with half size.
+(define_mode_attr mode256_i_half
+  [(V32QI "v16qi")
+   (V16HI "v8hi")])
+
  ;; This attribute gives suffix for LASX instructions.  HOW?
 (define_mode_attr lasxfmt
   [(V4DF "d")
@@ -756,6 +773,20 @@ (define_insn "lasx_xvpermi_q_"
   [(set_attr "type" "simd_splat")
(set_attr "mode" "")])
 
+;; Only for loongarch_expand_vector_init in loongarch.cc.
+;; Support a LSX-mode input op2.
+(define_insn "lasx_vecinit_merge_"
+  [(set (match_operand:LASX 0 "register_operand" "=f")
+   (unspec:LASX
+ [(match_operand:LASX 1 "register_operand" "0")
+  (match_operand: 2 "register_operand" "f")
+  (match_operand 3 "const_uimm8_operand")]
+  UNSPEC_LASX_VECINIT_MERGE))]
+  "ISA_HAS_LASX"
+  "xvpermi.q\t%u0,%u2,%3"
+  [(set_attr "type" "simd_splat")
+   (set_attr "mode" "")])
+
 (define_insn "lasx_xvpickve2gr_d"
   [(set (match_operand:DI 0 "register_operand" "=r")
(any_extend:DI
@@ -779,6 +810,33 @@ (define_expand "vec_set"
   DONE;
 })
 
+;; Only for loongarch_expand_vector_init in loongarch.cc.
+;; Simulate missing instructions xvinsgr2vr.b and xvinsgr2vr.h.
+(define_expand "vec_set_internal"
+  [(match_operand:ILASX_HB 0 "register_operand")
+   (match_operand: 1 "reg_or_0_operand")
+   (match_operand 2 "const__operand")]
+  "ISA_HAS_LASX"
+{
+  rtx index = GEN_INT (1 << INTVAL (operands[2]));
+  emit_insn (gen_lasx_xvinsgr2vr__internal
+(operands[0], operands[1], operands[0], index));
+  DONE;
+})
+
+(define_insn "lasx_xvinsgr2vr__internal"
+  [(set (match_operand:ILASX_HB 0 "register_operand" "=f")
+   (unspec:ILASX_HB [(match_operand: 1 "reg_or_0_operand" "rJ")
+ (match_operand:ILASX_HB 2 "register_operand" "0")
+ (match_operand 3 "const__operand" "")]
+UNSPEC_LASX_VEC_SET_INTERNAL))]
+  "ISA_HAS_LASX"
+{
+  return "vinsgr2vr.\t%w0,%z1,%y3";
+}
+  [(set_attr "type" "simd_insert")
+   (set_attr "mode" "")])
+
 (define_expand "vec_set"
   [(match_operand:FLASX 0 "register_operand")
(match_operand: 1 "reg_or_0_operand")
@@ -1567,6 +1625,17 @@ (define_insn "logb2"
   [(set_attr "type" "simd_flog2")
(set_attr "mode" "")])
 
+;; Only for loongarch_expand_vector_init in loongarch.cc.
+;; Merge two scalar floating-point op1 and op2 into a LASX op0.
+(define_insn "lasx_xvilvl__internal"
+  [(set (match_operand:FLASX 0 "register_operand" "=f")
+   (unspec:FLASX [(match_operand: 1 "register_operand" "f")
+  (match_operand: 2 "register_operand" "f")]
+   

Re: [PATCH] LoongArch: Enable -fsched-pressure by default at -O1 and higher.

2023-09-08 Thread Guo Jie

Hi,

What I wanna change is "gcc/common/config/loongarch/loongarch-common.cc",

and the patch is automatically generated by "git gcc-commit-mklog".

Is it necessary to  to remove "common/" ?

Thanks for the review.


在 2023/9/8 下午4:06, Xi Ruoyao 写道:

On Fri, 2023-09-08 at 10:00 +0800, Guo Jie wrote:

gcc/ChangeLog:

 * common/config/loongarch/loongarch-common.cc:

"common/" should be removed.  You can use "git gcc-verify" to figure out
this kind of error before sending a patch in the future.


 (default_options loongarch_option_optimization_table):
 Default to -fsched-pressure.

"Default to -fsched-pressure at -O1 or above."

Otherwise OK.


---
  gcc/common/config/loongarch/loongarch-common.cc | 1 +
  1 file changed, 1 insertion(+)

diff --git a/gcc/common/config/loongarch/loongarch-common.cc
b/gcc/common/config/loongarch/loongarch-common.cc
index c5ed37d27a6..b6901910b70 100644
--- a/gcc/common/config/loongarch/loongarch-common.cc
+++ b/gcc/common/config/loongarch/loongarch-common.cc
@@ -36,6 +36,7 @@ static const struct default_options
loongarch_option_optimization_table[] =
    { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 },
    { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
    { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 },
+  { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
    { OPT_LEVELS_NONE, 0, NULL, 0 }
  };
  




[PATCH] LoongArch: Enable -fsched-pressure by default at -O1 and higher.

2023-09-07 Thread Guo Jie
gcc/ChangeLog:

* common/config/loongarch/loongarch-common.cc:
(default_options loongarch_option_optimization_table):
Default to -fsched-pressure.

---
 gcc/common/config/loongarch/loongarch-common.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/common/config/loongarch/loongarch-common.cc 
b/gcc/common/config/loongarch/loongarch-common.cc
index c5ed37d27a6..b6901910b70 100644
--- a/gcc/common/config/loongarch/loongarch-common.cc
+++ b/gcc/common/config/loongarch/loongarch-common.cc
@@ -36,6 +36,7 @@ static const struct default_options 
loongarch_option_optimization_table[] =
   { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 },
   { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
   { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 },
+  { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
   { OPT_LEVELS_NONE, 0, NULL, 0 }
 };
 
-- 
2.20.1



[PATCH v2] LoongArch: Support storing floating-point zero into MEM[base + index].

2023-09-02 Thread Guo Jie
v2: Modify commit message.

gcc/ChangeLog:

* config/loongarch/loongarch.md: Support 'G' -> 'k' in
movsf_hardfloat and movdf_hardfloat.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/const-double-zero-stx.c: New test.

---
 gcc/config/loongarch/loongarch.md  | 12 ++--
 .../loongarch/const-double-zero-stx.c  | 18 ++
 2 files changed, 24 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index b37e070660f..6f47c23a79c 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -1915,13 +1915,13 @@ (define_expand "movsf"
 })
 
 (define_insn "*movsf_hardfloat"
-  [(set (match_operand:SF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,*f,*r,*r,*r,*m")
-   (match_operand:SF 1 "move_operand" "f,G,m,f,k,f,G,*r,*f,*G*r,*m,*r"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,k,*f,*r,*r,*r,*m")
+   (match_operand:SF 1 "move_operand" "f,G,m,f,k,f,G,G,*r,*f,*G*r,*m,*r"))]
   "TARGET_HARD_FLOAT
&& (register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode))"
   { return loongarch_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,mgtf,mftg,move,load,store")
+  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,store,mgtf,mftg,move,load,store")
(set_attr "mode" "SF")])
 
 (define_insn "*movsf_softfloat"
@@ -1946,13 +1946,13 @@ (define_expand "movdf"
 })
 
 (define_insn "*movdf_hardfloat"
-  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,*f,*r,*r,*r,*m")
-   (match_operand:DF 1 "move_operand" "f,G,m,f,k,f,G,*r,*f,*r*G,*m,*r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,k,*f,*r,*r,*r,*m")
+   (match_operand:DF 1 "move_operand" "f,G,m,f,k,f,G,G,*r,*f,*r*G,*m,*r"))]
   "TARGET_DOUBLE_FLOAT
&& (register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))"
   { return loongarch_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,mgtf,mftg,move,load,store")
+  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,store,mgtf,mftg,move,load,store")
(set_attr "mode" "DF")])
 
 (define_insn "*movdf_softfloat"
diff --git a/gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c 
b/gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c
new file mode 100644
index 000..8fb04be8ff5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times {stx\..\t\$r0} 2 } } */
+
+extern float arr_f[];
+extern double arr_d[];
+
+void
+test_f (int base, int index)
+{
+  arr_f[base + index] = 0.0;
+}
+
+void
+test_d (int base, int index)
+{
+  arr_d[base + index] = 0.0;
+}
-- 
2.20.1



[PATCH] LoongArch: Support loading floating-point zero into MEM[base + index].

2023-09-01 Thread Guo Jie
gcc/ChangeLog:

* config/loongarch/loongarch.md: Support 'G' -> 'k' in
movsf_hardfloat and movdf_hardfloat.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/const-double-zero-stx.c: New test.

---
 gcc/config/loongarch/loongarch.md  | 12 ++--
 .../loongarch/const-double-zero-stx.c  | 18 ++
 2 files changed, 24 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index b37e070660f..6f47c23a79c 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -1915,13 +1915,13 @@ (define_expand "movsf"
 })
 
 (define_insn "*movsf_hardfloat"
-  [(set (match_operand:SF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,*f,*r,*r,*r,*m")
-   (match_operand:SF 1 "move_operand" "f,G,m,f,k,f,G,*r,*f,*G*r,*m,*r"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,k,*f,*r,*r,*r,*m")
+   (match_operand:SF 1 "move_operand" "f,G,m,f,k,f,G,G,*r,*f,*G*r,*m,*r"))]
   "TARGET_HARD_FLOAT
&& (register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode))"
   { return loongarch_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,mgtf,mftg,move,load,store")
+  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,store,mgtf,mftg,move,load,store")
(set_attr "mode" "SF")])
 
 (define_insn "*movsf_softfloat"
@@ -1946,13 +1946,13 @@ (define_expand "movdf"
 })
 
 (define_insn "*movdf_hardfloat"
-  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,*f,*r,*r,*r,*m")
-   (match_operand:DF 1 "move_operand" "f,G,m,f,k,f,G,*r,*f,*r*G,*m,*r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" 
"=f,f,f,m,f,k,m,k,*f,*r,*r,*r,*m")
+   (match_operand:DF 1 "move_operand" "f,G,m,f,k,f,G,G,*r,*f,*r*G,*m,*r"))]
   "TARGET_DOUBLE_FLOAT
&& (register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))"
   { return loongarch_output_move (operands[0], operands[1]); }
-  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,mgtf,mftg,move,load,store")
+  [(set_attr "move_type" 
"fmove,mgtf,fpload,fpstore,fpload,fpstore,store,store,mgtf,mftg,move,load,store")
(set_attr "mode" "DF")])
 
 (define_insn "*movdf_softfloat"
diff --git a/gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c 
b/gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c
new file mode 100644
index 000..8fb04be8ff5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/const-double-zero-stx.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times {stx\..\t\$r0} 2 } } */
+
+extern float arr_f[];
+extern double arr_d[];
+
+void
+test_f (int base, int index)
+{
+  arr_f[base + index] = 0.0;
+}
+
+void
+test_d (int base, int index)
+{
+  arr_d[base + index] = 0.0;
+}
-- 
2.20.1



[PATCH] Loongarch: Fix plugin header missing install.

2023-08-15 Thread Guo Jie
gcc/ChangeLog:

* config/loongarch/t-loongarch: Add loongarch-driver.h into
TM_H. Add loongarch-def.h and loongarch-tune.h into
OPTIONS_H_EXTRA.

Co-authored-by: Lulu Cheng 
---
 gcc/config/loongarch/t-loongarch | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/loongarch/t-loongarch b/gcc/config/loongarch/t-loongarch
index 6d6e3435d59..e73f4f437ef 100644
--- a/gcc/config/loongarch/t-loongarch
+++ b/gcc/config/loongarch/t-loongarch
@@ -16,6 +16,10 @@
 # along with GCC; see the file COPYING3.  If not see
 # .
 
+TM_H += $(srcdir)/config/loongarch/loongarch-driver.h
+OPTIONS_H_EXTRA += $(srcdir)/config/loongarch/loongarch-def.h \
+  $(srcdir)/config/loongarch/loongarch-tune.h
+
 # Canonical target triplet from config.gcc
 LA_MULTIARCH_TRIPLET = $(patsubst LA_MULTIARCH_TRIPLET=%,%,$\
 $(filter LA_MULTIARCH_TRIPLET=%,$(tm_defines)))
-- 
2.20.1



[PATCH] LoongArch: Fix the missing include file when using gcc plugins.

2023-07-11 Thread Guo Jie
From: Sun Haiyong 

gcc/ChangeLog:

* config.gcc: Add some include file in tm_file.

---
 gcc/config.gcc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 51ca5311fa4..b901aa8e5dc 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2478,7 +2478,7 @@ riscv*-*-freebsd*)
 
 loongarch*-*-linux*)
tm_file="elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h 
${tm_file}"
-   tm_file="${tm_file} loongarch/gnu-user.h loongarch/linux.h"
+   tm_file="${tm_file} loongarch/gnu-user.h loongarch/linux.h 
loongarch/loongarch-def.h loongarch/loongarch-tune.h 
loongarch/loongarch-driver.h"
extra_options="${extra_options} linux-android.opt"
tmake_file="${tmake_file} loongarch/t-linux"
gnu_ld=yes
-- 
2.20.1



Re: [PATCH] LoongArch: Enable shrink wrapping

2023-04-25 Thread Guo Jie

/* snip */

  diff --git a/gcc/testsuite/gcc.target/loongarch/shrink-wrap.c 
b/gcc/testsuite/gcc.target/loongarch/shrink-wrap.c

new file mode 100644
index 000..f2c867a2769
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/shrink-wrap.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fshrink-wrap" } */
+
+/* f(x) should do nothing if x is 0.  */
+/* { dg-final { scan-assembler "bnez\t\\\$r4,\[^\n\]*\n\tjr\t\\\$r1" 
} } */

+
+void g(void);
+
+void
+f(int x)
+{
+  if (x)
+    {
+  register int s0 asm("s0") = x;
+  register int s1 asm("s1") = x;
+  register int s2 asm("s2") = x;
+  asm("" : : "r"(s0));
+  asm("" : : "r"(s1));
+  asm("" : : "r"(s2));
+  g();
+    }
+}


I think the test case cannot fully reflect the optimization effect of 
the current patch,


because even without the patch, -O -fshrink-wrap will still perform 
architecture independent optimization.


This patch considers architecture related registers as finer grained 
optimization for shrink wrapping,


I think a test case like the one below is more suitable:


int foo(int x)
{
  if (x)
  {
    __asm__ ("":::"s0","s1");
    return x;
  }

  __asm__ ("":::"s2","s3");
  return 0;
}

Otherwise LGTM, thanks!