]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Small improvement to "*btrue_INT_MIN"
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Wed, 20 Aug 2025 11:30:05 +0000 (20:30 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Thu, 21 Aug 2025 08:29:02 +0000 (01:29 -0700)
This patch changes the implementation of the insn to test whether the
result itself is negative or not, rather than the MSB of the result of
the ABS machine instruction.  This eliminates the need to consider bit-
endianness and allows for longer branch distances.

     /* example */
     extern void foo(int);
     void test0(int a) {
       if (a == -2147483648)
         foo(a);
     }
     void test1(int a) {
       if (a != -2147483648)
         foo(a);
     }

     ;; before (endianness: little)
     test0:
      entry sp, 32
      abs a8, a2
      bbci a8, 31, .L1
      mov.n a10, a2
      call8 foo
     .L1:
      retw.n
     test1:
      entry sp, 32
      abs a8, a2
      bbsi a8, 31, .L4
      mov.n a10, a2
      call8 foo
     .L4:
      retw.n

     ;; after (endianness-independent)
     test0:
      entry sp, 32
      abs a8, a2
      bgez a8, .L1
      mov.n a10, a2
      call8 foo
     .L1:
      retw.n
     test1:
      entry sp, 32
      abs a8, a2
      bltz a8, .L4
      mov.n a10, a2
      call8 foo
     .L4:
      retw.n

gcc/ChangeLog:

* config/xtensa/xtensa.md (*btrue_INT_MIN):
Change the branch insn condition to test for a negative number
rather than testing for the MSB.

gcc/config/xtensa/xtensa.md

index 629dfdde33cb09ca7fc8842f7cddcf5602916cf6..f38fe6da8e483d61ce9600c97e348a66099d7295 100644 (file)
                        [(match_operand:SI 0 "register_operand" "r")
                         (const_int -2147483648)])
                      (label_ref (match_operand 1 ""))
-                     (pc)))]
+                     (pc)))
+   (clobber (match_scratch:SI 3 "=a"))]
   "TARGET_ABS"
   "#"
-  "&& can_create_pseudo_p ()"
+  "&& 1"
   [(set (match_dup 3)
        (abs:SI (match_dup 0)))
    (set (pc)
        (if_then_else (match_op_dup 2
-                       [(zero_extract:SI (match_dup 3)
-                                         (const_int 1)
-                                         (match_dup 4))
+                       [(match_dup 3)
                         (const_int 0)])
                      (label_ref (match_dup 1))
                      (pc)))]
 {
-  operands[3] = gen_reg_rtx (SImode);
-  operands[4] = GEN_INT (BITS_BIG_ENDIAN ? 0 : 31);
-  operands[2] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[2])),
-                               VOIDmode, XEXP (operands[2], 0),
-                               const0_rtx);
+  if (GET_CODE (operands[3]) == SCRATCH)
+    operands[3] = gen_reg_rtx (SImode);
+  PUT_CODE (operands[2], GET_CODE (operands[2]) == EQ ? LT : GE);
 }
   [(set_attr "type"    "jump")
    (set_attr "mode"    "none")