]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Fix wrong code with <optab>_alsl_reversesi_extended
authorXi Ruoyao <xry111@xry111.site>
Tue, 21 Jan 2025 15:01:38 +0000 (23:01 +0800)
committerXi Ruoyao <xry111@xry111.site>
Wed, 22 Jan 2025 08:41:38 +0000 (16:41 +0800)
The second source register of this insn cannot be the same as the
destination register.

gcc/ChangeLog:

* config/loongarch/loongarch.md
(<optab>_alsl_reversesi_extended): Add '&' to the destination
register constraint and append '0' to the first source register
constraint to indicate the destination register cannot be same
as the second source register, and change the split condition to
reload_completed so that the insn will be split only after RA in
order to obtain allocated registers that satisfy the above
constraints.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/bitwise-shift-reassoc-clobber.c: New
test.

gcc/config/loongarch/loongarch.md
gcc/testsuite/gcc.target/loongarch/bitwise-shift-reassoc-clobber.c [new file with mode: 0644]

index 223e2b9f37f1f72cf23402d46a1993086d3c1653..1392325038cd3a0ce6157071bab461f268e46aeb 100644 (file)
 ;; add.w => alsl.w, so implement slli.d + and + add.w => and + alsl.w on
 ;; our own.
 (define_insn_and_split "<optab>_alsl_reversesi_extended"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
        (sign_extend:DI
          (plus:SI
            (subreg:SI
              (any_bitwise:DI
                (ashift:DI
-                 (match_operand:DI 1 "register_operand" "r")
+                 (match_operand:DI 1 "register_operand" "r0")
                  (match_operand:SI 2 "const_immalsl_operand" ""))
                (match_operand:DI 3 "const_int_operand" "i"))
              0)
    && loongarch_reassoc_shift_bitwise (<is_and>, operands[2], operands[3],
                                       SImode)"
   "#"
-  "&& true"
+  "&& reload_completed"
   [; r0 = r1 [&|^] r3 is emitted in PREPARATION-STATEMENTS because we
    ; need to handle a special case, see below.
    (set (match_dup 0)
diff --git a/gcc/testsuite/gcc.target/loongarch/bitwise-shift-reassoc-clobber.c b/gcc/testsuite/gcc.target/loongarch/bitwise-shift-reassoc-clobber.c
new file mode 100644 (file)
index 0000000..9985a18
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+register long x asm ("s0");
+
+#define TEST(x) (int)(((x & 0x114) << 3) + x)
+
+[[gnu::noipa]] void
+test (void)
+{
+  x = TEST (x);
+}
+
+int
+main (void)
+{
+  x = 0xffff;
+  test ();
+  if (x != TEST (0xffff))
+    __builtin_trap ();
+}