arm: Improve immediate generation for thumb-1 with -mpurecode [PR96769]
authorChristophe Lyon <christophe.lyon@linaro.org>
Fri, 4 Sep 2020 11:48:36 +0000 (11:48 +0000)
committerChristophe Lyon <christophe.lyon@linaro.org>
Fri, 4 Sep 2020 11:48:36 +0000 (11:48 +0000)
This patch moves the move-immediate splitter after the regular ones so
that it has lower precedence, and updates its constraints.

For
int f3 (void) { return 0x11000000; }
int f3_2 (void) { return 0x12345678; }

we now generate:
* with -O2 -mcpu=cortex-m0 -mpure-code:
f3:
movs    r0, #136
lsls    r0, r0, #21
bx      lr
f3_2:
movs    r0, #18
lsls    r0, r0, #8
adds    r0, r0, #52
lsls    r0, r0, #8
adds    r0, r0, #86
lsls    r0, r0, #8
adds    r0, r0, #121
bx      lr

* with -O2 -mcpu=cortex-m23 -mpure-code:
f3:
movs    r0, #136
lsls    r0, r0, #21
bx      lr
f3_2:
movw    r0, #22136
movt    r0, 4660
bx      lr

2020-09-04  Christophe Lyon  <christophe.lyon@linaro.org>

PR target/96769
gcc/
* config/arm/thumb1.md: Move movsi splitter for
arm_disable_literal_pool after the other movsi splitters.

gcc/testsuite/
* gcc.target/arm/pure-code/pr96769.c: New test.

gcc/config/arm/thumb1.md
gcc/testsuite/gcc.target/arm/pure-code/pr96769.c [new file with mode: 0644]

index f0129db..b5377a3 100644 (file)
    (set_attr "conds" "clob")]
 )
 
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-       (match_operand:SI 1 "immediate_operand" ""))]
-  "TARGET_THUMB1
-   && arm_disable_literal_pool
-   && GET_CODE (operands[1]) == CONST_INT
-   && !TARGET_HAVE_MOVT
-   && !satisfies_constraint_I (operands[1])"
-  [(clobber (const_int 0))]
-  "
-    thumb1_gen_const_int (operands[0], INTVAL (operands[1]));
-    DONE;
-  "
-)
-
 (define_insn "*thumb1_adddi3"
   [(set (match_operand:DI          0 "register_operand" "=l")
        (plus:DI (match_operand:DI 1 "register_operand" "%0")
   }"
 )
 
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+       (match_operand:SI 1 "const_int_operand" ""))]
+  "TARGET_THUMB1
+   && arm_disable_literal_pool
+   && GET_CODE (operands[1]) == CONST_INT
+   && !TARGET_HAVE_MOVT
+   && !satisfies_constraint_K (operands[1])"
+  [(clobber (const_int 0))]
+  "
+    thumb1_gen_const_int (operands[0], INTVAL (operands[1]));
+    DONE;
+  "
+)
+
 (define_insn "*thumb1_movhi_insn"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,l*r,*h,l,r")
        (match_operand:HI 1 "general_operand"       "l,m,l,k*h,*r,I,n"))]
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96769.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96769.c
new file mode 100644 (file)
index 0000000..c90981f
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+
+int f3 (void) { return 0x11000000; }
+int f3_2 (void) { return 0x12345678; }
+int f3_3 (void) { return -1; }
+int f3_4 (void) { return 511; }
+
+/* For cortex-m0 (thumb-1/v6m), we generate 1 lsls in f3 3 lsls in f3_2 and 1 in f3_4; 1 rsbs in f3_3.  */
+/* { dg-final { scan-assembler-times "lsls" 5 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
+/* { dg-final { scan-assembler-times "rsbs" 1 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
+
+/* For cortex-m23 (thumb-1/v8m.base), we generate 1 lsls in f3, and none in f3_2 nor f3_4; 1 rsbs in f3_3.  */
+/* { dg-final { scan-assembler-times "lsls" 1 { target { arm_thumb1_movt_ok && { ! arm_thumb2_ok } } } } } */
+/* { dg-final { scan-assembler-times "rsbs" 1 { target { arm_thumb1_movt_ok && { ! arm_thumb2_ok } } } } } */
+
+/* For cortex-m3 (thumb-2/v7m), we generate no lsls and no rsbs.  */
+/* { dg-final { scan-assembler-times "lsls" 0 { target { arm_thumb2_ok } } } } */
+/* { dg-final { scan-assembler-times "rsbs" 0 { target { arm_thumb2_ok } } } } */
+