This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Extend MIPS shift-and-truncate patterns
- From: Richard Sandiford <rsandifo at nildram dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 16 Sep 2007 10:46:00 +0100
- Subject: [committed] Extend MIPS shift-and-truncate patterns
While working on the DSE TRULY_NOOP_TRUNCATION patch, I noticed that
mips.md was missing a couple of patterns. We have a pattern to convert:
(truncate:SI (lshiftrt:DI ... (const_int 32)))
into an arithmetic shift (which preserves the required sign-extension),
but we should be doing the same QI and HI truncations too. The patch
below does this.
Note that, thanks to Adam's patches, the RTL optimisers now realise that
a truncation after an lshiftrt by > 32 bits is a no-op. They also know
that truncation after an ashiftrt >= 32 bits is a no-op. Thus lshifrts
by 32 bits are the interesting case.
I think the truncate/ashiftrt pattern is probably redundant now,
but I changed it anyway for consistency. I might look into the effect
of removing it at some point.
Tested on mipsisa64-elfoabi. Applied to trunk.
Richard
gcc/
* config/mips/mips.md (SHORT): Fix long line.
(SUBDI): New mode iterator. Extend the shift-and-truncate insns
to QImode and HImode.
gcc/testsuite/
* gcc.target/mips/truncate-1.c: New test.
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-09-15 18:23:06.000000000 +0100
+++ gcc/config/mips/mips.md 2007-09-15 18:37:18.000000000 +0100
@@ -481,10 +481,13 @@ (define_mode_iterator P [(SI "Pmode == S
;; conditional-move-type condition is needed.
(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
-;; This mode iterator allows the QI and HI extension patterns to be defined from
-;; the same template.
+;; This mode iterator allows the QI and HI extension patterns to be
+;; defined from the same template.
(define_mode_iterator SHORT [QI HI])
+;; Likewise the 64-bit truncate-and-shift patterns.
+(define_mode_iterator SUBDI [QI HI SI])
+
;; This mode iterator allows :ANYF to be used wherever a scalar or vector
;; floating-point mode is allowed.
(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
@@ -2314,19 +2317,20 @@ (define_insn "truncdiqi2"
;; Combiner patterns to optimize shift/truncate combinations.
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI
+ [(set (match_operand:SUBDI 0 "register_operand" "=d")
+ (truncate:SUBDI
(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:DI 2 "const_arith_operand" ""))))]
+ (match_operand:DI 2 "const_arith_operand" ""))))]
"TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
"dsra\t%0,%1,%2"
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
- (const_int 32))))]
+ [(set (match_operand:SUBDI 0 "register_operand" "=d")
+ (truncate:SUBDI
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (const_int 32))))]
"TARGET_64BIT && !TARGET_MIPS16"
"dsra\t%0,%1,32"
[(set_attr "type" "shift")
Index: gcc/testsuite/gcc.target/mips/truncate-1.c
===================================================================
--- /dev/null 2007-09-15 10:15:35.552097000 +0100
+++ gcc/testsuite/gcc.target/mips/truncate-1.c 2007-09-15 18:33:47.000000000 +0100
@@ -0,0 +1,20 @@
+/* { dg-mips-options "-O -mgp64" } */
+
+#define TEST(ID, TYPE, SHIFT) \
+ int __attribute__((nomips16)) \
+ f##ID (unsigned long long y) \
+ { \
+ return (TYPE) ((TYPE) (y >> SHIFT) + 1); \
+ }
+
+TEST (1, int, 32)
+TEST (2, short, 32)
+TEST (3, char, 32)
+TEST (4, int, 33)
+TEST (5, short, 33)
+TEST (6, char, 33)
+TEST (7, int, 61)
+TEST (8, short, 61)
+TEST (9, char, 61)
+
+/* { dg-final { scan-assembler-not "\tsll\t\[^\n\]*,0" } } */