]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR target/115478] Accept ADD, IOR or XOR when combining objects with no bits in...
authorJeff Law <jlaw@ventanamicro.com>
Tue, 11 Feb 2025 23:55:03 +0000 (16:55 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Tue, 11 Feb 2025 23:55:03 +0000 (16:55 -0700)
So the change to prefer ADD over IOR for combining two objects with no bits in
common is (IMHO) generally good.  It has some minor fallout.

In particular the aarch64 port (and I suspect others) have patterns that
recognize IOR, but not PLUS or XOR for these cases and thus tests which
expected to optimize with IOR are no longer optimizing.

Roger suggested using a code iterator for this purpose.  Richard S. suggested a
new match operator to cover those cases.

I really like the match operator idea, but as Richard S. notes in the PR it
would require either not validating the "no bits in common", which dramatically
reduces the utility IMHO or we'd need some work to allow consistent results
without polluting the nonzero bits cache.

So this patch goes back to Roger's idea of just using a match iterator in the
aarch64 backend (and presumably anywhere else we see this popping up).

Bootstrapped and regression tested on aarch64-linux-gnu where it fixes
bitint-args.c (as expected).

PR target/115478
gcc/
* config/aarch64/iterators.md (any_or_plus): New code iterator.
* config/aarch64/aarch64.md (extr<mode>5_insn): Use any_or_plus.
(extr<mode>5_insn_alt, extrsi5_insn_uxtw): Likewise.
(extrsi5_insn_uxtw_alt, extrsi5_insn_di): Likewise.

gcc/testsuite/
* gcc.target/aarch64/bitint-args.c: Update expected output.

gcc/config/aarch64/aarch64.md
gcc/config/aarch64/iterators.md
gcc/testsuite/gcc.target/aarch64/bitint-args.c

index 071058dbeb33297e94f862e029253f0202799978..cfe730f3732ce45c914b30a908851a4a7dd77c0f 100644 (file)
 
 (define_insn "*extr<mode>5_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
-       (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
-                            (match_operand 3 "const_int_operand" "n"))
-                (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
-                              (match_operand 4 "const_int_operand" "n"))))]
+       (any_or_plus:GPI
+         (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
+                     (match_operand 3 "const_int_operand" "n"))
+         (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
+                     (match_operand 4 "const_int_operand" "n"))))]
   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
   "extr\\t%<w>0, %<w>1, %<w>2, %4"
 ;; so we have to match both orderings.
 (define_insn "*extr<mode>5_insn_alt"
   [(set (match_operand:GPI 0 "register_operand" "=r")
-       (ior:GPI  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
-                               (match_operand 4 "const_int_operand" "n"))
-                 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
-                             (match_operand 3 "const_int_operand" "n"))))]
+       (any_or_plus:GPI
+         (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
+                       (match_operand 4 "const_int_operand" "n"))
+         (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
+                     (match_operand 3 "const_int_operand" "n"))))]
   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
    && (UINTVAL (operands[3]) + UINTVAL (operands[4])
        == GET_MODE_BITSIZE (<MODE>mode))"
 (define_insn "*extrsi5_insn_uxtw"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
-                           (match_operand 3 "const_int_operand" "n"))
-                (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
-                             (match_operand 4 "const_int_operand" "n")))))]
+        (any_or_plus:SI
+          (ashift:SI (match_operand:SI 1 "register_operand" "r")
+                     (match_operand 3 "const_int_operand" "n"))
+          (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                     (match_operand 4 "const_int_operand" "n")))))]
   "UINTVAL (operands[3]) < 32 &&
    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
   "extr\\t%w0, %w1, %w2, %4"
 (define_insn "*extrsi5_insn_uxtw_alt"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-        (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
-                              (match_operand 4 "const_int_operand" "n"))
-                (ashift:SI (match_operand:SI 1 "register_operand" "r")
-                           (match_operand 3 "const_int_operand" "n")))))]
+        (any_or_plus:SI
+          (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                       (match_operand 4 "const_int_operand" "n"))
+          (ashift:SI (match_operand:SI 1 "register_operand" "r")
+                     (match_operand 3 "const_int_operand" "n")))))]
   "UINTVAL (operands[3]) < 32 &&
    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
   "extr\\t%w0, %w1, %w2, %4"
 
 (define_insn "*extrsi5_insn_di"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
-                          (match_operand 3 "const_int_operand" "n"))
-               (match_operator:SI 6 "subreg_lowpart_operator"
-                 [(zero_extract:DI
-                    (match_operand:DI 2 "register_operand" "r")
-                    (match_operand 5 "const_int_operand" "n")
-                    (match_operand 4 "const_int_operand" "n"))])))]
+       (any_or_plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+                                   (match_operand 3 "const_int_operand" "n"))
+                        (match_operator:SI 6 "subreg_lowpart_operator"
+                         [(zero_extract:DI
+                            (match_operand:DI 2 "register_operand" "r")
+                            (match_operand 5 "const_int_operand" "n")
+                            (match_operand 4 "const_int_operand" "n"))])))]
   "UINTVAL (operands[3]) < 32
    && UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32
    && INTVAL (operands[3]) == INTVAL (operands[5])"
index 9fbd749398823b70953c29d8b9844cb78532b708..5bfd6e7d362af0b5160d50c6d117e60790af7f3d 100644 (file)
 ;; Code iterator for logical operations
 (define_code_iterator LOGICAL [and ior xor])
 
+;; Code iterator for operations that are equivalent when the
+;; two input operands are known have disjoint bits set.
+(define_code_iterator any_or_plus [plus ior xor])
+
 ;; LOGICAL with plus, for when | gets converted to +.
 (define_code_iterator LOGICAL_OR_PLUS [and ior xor plus])
 
index e7e1099c303b950b73e3ccd7b93d60b9182463fc..06b47246fa50809e95a3ba1eb9cd029f2cd4a627 100644 (file)
@@ -69,7 +69,7 @@ CHECK_ARG(65)
 ** f65:
 **     extr    (x[0-9]+), x3, x2, 1
 **     and     (x[0-9]+), x2, 1
-**     orr     (x[0-9]+), \2, \1, lsl 1
+**     add     (x[0-9]+), \2, \1, lsl 1
 **     asr     (x[0-9]+), \1, 63
 **     stp     \3, \4, \[x0\]
 **     ret
@@ -80,7 +80,7 @@ CHECK_ARG(127)
 ** f127:
 **     extr    (x[0-9]+), x3, x2, 63
 **     and     (x[0-9]+), x2, 9223372036854775807
-**     orr     (x[0-9]+), \2, \1, lsl 63
+**     add     (x[0-9]+), \2, \1, lsl 63
 **     asr     (x[0-9]+), \1, 1
 **     stp     \3, \4, \[x0\]
 **     ret