]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Reapply "[PATCH v2] RISC-V: zero_extend(not) -> xor optimization [PR112398]"
authorJeff Law <jlaw@ventanamicro.com>
Wed, 13 Nov 2024 00:12:49 +0000 (17:12 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 13 Nov 2024 04:01:36 +0000 (21:01 -0700)
This reverts commit de3b277247ce98d189f121155b75f490725a42f6.

gcc/simplify-rtx.cc
gcc/testsuite/gcc.target/riscv/pr112398.c [new file with mode: 0644]

index 893c5f6e1ae0b0579da3f98bda4f7d48487b8a84..d05efac20dc86fd4432dcc531f100a5f451e3d9b 100644 (file)
@@ -1842,6 +1842,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
              & ~GET_MODE_MASK (op_mode)) == 0)
        return SUBREG_REG (op);
 
+      /* Trying to optimize:
+        (zero_extend:M (subreg:N (not:M (X:M)))) ->
+        (xor:M (zero_extend:M (subreg:N (X:M)), mask))
+        where the mask is GET_MODE_MASK (N).
+        For the cases when X:M doesn't have any non-zero bits
+        outside of mode N, (zero_extend:M (subreg:N (X:M))
+        will be simplified to just (X:M)
+        and whole optimization will be -> (xor:M (X:M, mask)).  */
+      if (SUBREG_P (op)
+         && GET_CODE (XEXP (op, 0)) == NOT
+         && GET_MODE (XEXP (op, 0)) == mode
+         && subreg_lowpart_p (op)
+         && GET_MODE_SIZE (GET_MODE (op)).is_constant ()
+         && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
+             & ~GET_MODE_MASK (mode)) == 0)
+      {
+       const uint64_t mask = GET_MODE_MASK (GET_MODE (op));
+       return simplify_gen_binary (XOR, mode,
+                                   XEXP (XEXP (op, 0), 0),
+                                   gen_int_mode (mask, mode));
+      }
+
 #if defined(POINTERS_EXTEND_UNSIGNED)
       /* As we do not know which address space the pointer is referring to,
         we can do this only if the target does not support different pointer
diff --git a/gcc/testsuite/gcc.target/riscv/pr112398.c b/gcc/testsuite/gcc.target/riscv/pr112398.c
new file mode 100644 (file)
index 0000000..624a665
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */
+
+#include <stdint.h>
+
+uint8_t neg_u8 (const uint8_t src)
+{
+  return ~src;
+}
+
+/* { dg-final { scan-assembler-times "xori\t" 1 } } */
+/* { dg-final { scan-assembler-not "not\t" } } */
+/* { dg-final { scan-assembler-not "andi\t" } } */