aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>2022-06-14 12:37:54 +0900
committerMax Filippov <jcmvbkbc@gmail.com>2022-06-15 16:55:36 -0700
commitc95e307e3a978166cd5d6817ec9d8293825ff3fb (patch)
treea46f88caa9faa71f07424a32391b8585d577f401
parent43b0c56fda4bc990e8ee8d6a0b376de7b663bb06 (diff)
downloadgcc-c95e307e3a978166cd5d6817ec9d8293825ff3fb.zip
gcc-c95e307e3a978166cd5d6817ec9d8293825ff3fb.tar.gz
gcc-c95e307e3a978166cd5d6817ec9d8293825ff3fb.tar.bz2
xtensa: Add some dedicated patterns that correspond to GIMPLE canonicalizations
This patch offers better RTL representations against straightforward derivations from some tree optimizers' canonicalized forms. - rounding up to even, such as '(x + (x & 1))', is canonicalized to '((x + 1) & -2)', but the former is one instruction less than the latter in Xtensa ISA. - signed greater or equal to zero as logical value '((signed)x >= 0)', is canonicalized to '((unsigned)(x ^ -1) >> 31)', but the equivalent '(((signed)x >> 31) + 1)' is one instruction less. gcc/ChangeLog: * config/xtensa/xtensa.md (*round_up_to_even): New insn-and-split pattern. (*signed_ge_zero): Ditto.
-rw-r--r--gcc/config/xtensa/xtensa.md45
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 3b05166..fa2a4a0 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2704,3 +2704,48 @@
xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);
DONE;
})
+
+(define_insn_and_split "*round_up_to_even"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 1))
+ (const_int -2)))]
+ ""
+ "#"
+ "can_create_pseudo_p ()"
+ [(set (match_dup 2)
+ (and:SI (match_dup 1)
+ (const_int 1)))
+ (set (match_dup 0)
+ (plus:SI (match_dup 2)
+ (match_dup 1)))]
+{
+ operands[2] = gen_reg_rtx (SImode);
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set (attr "length")
+ (if_then_else (match_test "TARGET_DENSITY")
+ (const_int 5)
+ (const_int 6)))])
+
+(define_insn_and_split "*signed_ge_zero"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (ge:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 0)))]
+ ""
+ "#"
+ ""
+ [(set (match_dup 0)
+ (ashiftrt:SI (match_dup 1)
+ (const_int 31)))
+ (set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (const_int 1)))]
+ ""
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set (attr "length")
+ (if_then_else (match_test "TARGET_DENSITY")
+ (const_int 5)
+ (const_int 6)))])