]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Fixed the problem of incorrect judgment of the immediate field of the...
authorLulu Cheng <chenglulu@loongson.cn>
Thu, 4 Jan 2024 02:37:53 +0000 (10:37 +0800)
committerLulu Cheng <chenglulu@loongson.cn>
Fri, 5 Jan 2024 12:31:49 +0000 (20:31 +0800)
The [x]vld/[x]vst directive is defined as follows:
  [x]vld/[x]vst {x/v}d, rj, si12

When not modified, the immediate field of [x]vld/[x]vst is between 10 and
14 bits depending on the type. However, in loongarch_valid_offset_p, the
immediate field is restricted first, so there is no error. However, in
some cases redundant instructions will be generated, see test cases.
Now modify it according to the description in the instruction manual.

gcc/ChangeLog:

* config/loongarch/lasx.md (lasx_mxld_<lasxfmt_f>):
Modify the method of determining the memory offset of [x]vld/[x]vst.
(lasx_mxst_<lasxfmt_f>): Likewise.
* config/loongarch/loongarch.cc (loongarch_valid_offset_p): Delete.
(loongarch_address_insns): Likewise.
* config/loongarch/lsx.md (lsx_ld_<lsxfmt_f>): Likewise.
(lsx_st_<lsxfmt_f>): Likewise.
* config/loongarch/predicates.md (aq10b_operand): Likewise.
(aq10h_operand): Likewise.
(aq10w_operand): Likewise.
(aq10d_operand): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/vect-ld-st-imm12.c: New test.

gcc/config/loongarch/lasx.md
gcc/config/loongarch/loongarch.cc
gcc/config/loongarch/lsx.md
gcc/config/loongarch/predicates.md
gcc/testsuite/gcc.target/loongarch/vect-ld-st-imm12.c [new file with mode: 0644]

index 027021b45d5008c8dc7dfa303eced87e7eabbf00..cabf16a8ca0a3f2832e9c4c7df57d93d8a53c6ec 100644 (file)
   DONE;
 })
 
-;; Offset load
-(define_expand "lasx_mxld_<lasxfmt_f>"
-  [(match_operand:LASX 0 "register_operand")
-   (match_operand 1 "pmode_register_operand")
-   (match_operand 2 "aq10<lasxfmt>_operand")]
-  "ISA_HAS_LASX"
-{
-  rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
-                                     INTVAL (operands[2]));
-  loongarch_emit_move (operands[0], gen_rtx_MEM (<MODE>mode, addr));
-  DONE;
-})
-
-;; Offset store
-(define_expand "lasx_mxst_<lasxfmt_f>"
-  [(match_operand:LASX 0 "register_operand")
-   (match_operand 1 "pmode_register_operand")
-   (match_operand 2 "aq10<lasxfmt>_operand")]
-  "ISA_HAS_LASX"
-{
-  rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
-                           INTVAL (operands[2]));
-  loongarch_emit_move (gen_rtx_MEM (<MODE>mode, addr), operands[0]);
-  DONE;
-})
-
 ;; LASX
 (define_insn "add<mode>3"
   [(set (match_operand:ILASX 0 "register_operand" "=f,f,f")
index 28d64135c549bf69189d67466fcaa714cc46a535..ec376a7228aab019cb2521c4c10dd7d2ce7df076 100644 (file)
@@ -2126,21 +2126,11 @@ loongarch_valid_offset_p (rtx x, machine_mode mode)
 
   /* We may need to split multiword moves, so make sure that every word
      is accessible.  */
-  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
+  if (!(LSX_SUPPORTED_MODE_P (mode) || LASX_SUPPORTED_MODE_P (mode))
+      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
       && !IMM12_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
     return false;
 
-  /* LSX LD.* and ST.* supports 10-bit signed offsets.  */
-  if (LSX_SUPPORTED_MODE_P (mode)
-      && !loongarch_signed_immediate_p (INTVAL (x), 10,
-                                       loongarch_ldst_scaled_shift (mode)))
-    return false;
-
-  /* LASX XVLD.B and XVST.B supports 10-bit signed offsets without shift.  */
-  if (LASX_SUPPORTED_MODE_P (mode)
-      && !loongarch_signed_immediate_p (INTVAL (x), 10, 0))
-    return false;
-
   return true;
 }
 
@@ -2376,9 +2366,8 @@ loongarch_address_insns (rtx x, machine_mode mode, bool might_split_p)
       case ADDRESS_REG:
        if (lsx_p)
          {
-           /* LSX LD.* and ST.* supports 10-bit signed offsets.  */
-           if (loongarch_signed_immediate_p (INTVAL (addr.offset), 10,
-                                             loongarch_ldst_scaled_shift (mode)))
+           /* LSX LD.* and ST.* supports 12-bit signed offsets.  */
+           if (IMM12_OPERAND (INTVAL (addr.offset)))
              return 1;
            else
              return 0;
index 76d33a3b88a3c39e552b21aa5d4781f4a2399385..91ce774597aa8dca128bec0c7bf52a8273ad3f5b 100644 (file)
   DONE;
 })
 
-;; Offset load
-(define_expand "lsx_ld_<lsxfmt_f>"
-  [(match_operand:LSX 0 "register_operand")
-   (match_operand 1 "pmode_register_operand")
-   (match_operand 2 "aq10<lsxfmt>_operand")]
-  "ISA_HAS_LSX"
-{
-  rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
-                           INTVAL (operands[2]));
-  loongarch_emit_move (operands[0], gen_rtx_MEM (<MODE>mode, addr));
-  DONE;
-})
-
-;; Offset store
-(define_expand "lsx_st_<lsxfmt_f>"
-  [(match_operand:LSX 0 "register_operand")
-   (match_operand 1 "pmode_register_operand")
-   (match_operand 2 "aq10<lsxfmt>_operand")]
-  "ISA_HAS_LSX"
-{
-  rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
-                           INTVAL (operands[2]));
-  loongarch_emit_move (gen_rtx_MEM (<MODE>mode, addr), operands[0]);
-  DONE;
-})
-
 ;; Integer operations
 (define_insn "add<mode>3"
   [(set (match_operand:ILSX 0 "register_operand" "=f,f,f")
index ba5336cfb3ef2300beecd0699f4597bc1a1f7ee1..01aad8dc631394fd792befbf8f294a43ca8cad9f 100644 (file)
   (and (match_code "const_int")
        (match_test "loongarch_signed_immediate_p (INTVAL (op), 8, 3)")))
 
-(define_predicate "aq10b_operand"
-  (and (match_code "const_int")
-       (match_test "loongarch_signed_immediate_p (INTVAL (op), 10, 0)")))
-
-(define_predicate "aq10h_operand"
-  (and (match_code "const_int")
-       (match_test "loongarch_signed_immediate_p (INTVAL (op), 10, 1)")))
-
-(define_predicate "aq10w_operand"
-  (and (match_code "const_int")
-       (match_test "loongarch_signed_immediate_p (INTVAL (op), 10, 2)")))
-
-(define_predicate "aq10d_operand"
-  (and (match_code "const_int")
-       (match_test "loongarch_signed_immediate_p (INTVAL (op), 10, 3)")))
-
 (define_predicate "aq12b_operand"
   (and (match_code "const_int")
        (match_test "loongarch_signed_immediate_p (INTVAL (op), 12, 0)")))
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-ld-st-imm12.c b/gcc/testsuite/gcc.target/loongarch/vect-ld-st-imm12.c
new file mode 100644 (file)
index 0000000..bfc208e
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-march=loongarch64 -mabi=lp64d -mlasx -O2" } */
+/* { dg-final { scan-assembler-not "addi.d" } } */
+
+extern short a[1000];
+extern short b[1000];
+extern short c[1000];
+
+void
+test (void)
+{
+  for (int i = 501; i < 517; i++)
+    ((int *)(c + 1))[i] = ((int *)(a + 1))[i] + ((int *)(b + 1))[i];
+}
+