[ARM] Fix -mpure-code for v6m
authorChristophe Lyon <christophe.lyon@linaro.org>
Tue, 25 Feb 2020 15:54:14 +0000 (15:54 +0000)
committerChristophe Lyon <christophe.lyon@linaro.org>
Tue, 25 Feb 2020 15:54:14 +0000 (15:54 +0000)
When running the testsuite with -fdisable-rtl-fwprop2 and -mpure-code
for cortex-m0, I noticed that some testcases were failing because we
still generate "ldr rX, .LCY", which is what we want to avoid with
-mpure-code. This is latent since a recent improvement in fwprop
(PR88833).

In this patch I change the thumb1_movsi_insn pattern so that it emits
the desired instruction sequence when arm_disable_literal_pool is set.

To achieve that, I introduce a new required_for_purecode attribute to
enable the corresponding alternative in thumb1_movsi_insn and take the
actual instruction sequence length into account.

gcc/ChangeLog:

2020-02-13  Christophe Lyon  <christophe.lyon@linaro.org>

* config/arm/arm.md (required_for_purecode): New attribute.
(enabled): Handle required_for_purecode.
* config/arm/thumb1.md (thumb1_movsi_insn): Add alternative to
work with -mpure-code.

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/thumb1.md

index 78a8d94eab9ce6ba144a9359a7fed2878bdb3f07..14a4b1a06e8eb16eaf8c2867bb55a775c35f7e49 100644 (file)
@@ -1,3 +1,10 @@
+2020-02-25  Christophe Lyon  <christophe.lyon@linaro.org>
+
+       * config/arm/arm.md (required_for_purecode): New attribute.
+       (enabled): Handle required_for_purecode.
+       * config/arm/thumb1.md (thumb1_movsi_insn): Add alternative to
+       work with -mpure-code.
+
 2020-02-25  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/93908
index 951596217ad2505d1e6232c2e592db595245bf65..b48a4f45ffa7ab763917b6e0998f91484af9d138 100644 (file)
 ; an IT block in their expansion which is not a short IT.
 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
 
+; Mark an instruction sequence as the required way of loading a
+; constant when -mpure-code is enabled (which implies
+; arm_disable_literal_pool)
+(define_attr "required_for_purecode" "no,yes" (const_string "no"))
+
 ;; Operand number of an input operand that is shifted.  Zero if the
 ;; given instruction does not shift one of its input operands.
 (define_attr "shift" "" (const_int 0))
               (match_test "arm_restrict_it"))
          (const_string "no")
 
+         (and (eq_attr "required_for_purecode" "yes")
+              (not (match_test "arm_disable_literal_pool")))
+         (const_string "no")
+
          (eq_attr "arch_enabled" "no")
          (const_string "no")]
         (const_string "yes")))
index 613cf9ccc30832474a5edf25ceff7247ad2f39f8..24861635fa537fbf1b957dfdcae7f090db0e3873 100644 (file)
 )
 
 (define_insn "*thumb1_movsi_insn"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,r,l,l,l,>,l, m,*l*h*k")
-       (match_operand:SI 1 "general_operand"      "l, I,j,J,K,>,l,mi,l,*l*h*k"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,r,l,l,l,>,l, l, m,*l*h*k")
+       (match_operand:SI 1 "general_operand"      "l, I,j,J,K,>,l,i, mi,l,*l*h*k"))]
   "TARGET_THUMB1
    && (   register_operand (operands[0], SImode)
        || register_operand (operands[1], SImode))"
    #
    ldmia\\t%1, {%0}
    stmia\\t%0, {%1}
+   movs\\t%0, #:upper8_15:%1; lsls\\t%0, #8; adds\\t%0, #:upper0_7:%1; lsls\\t%0, #8; adds\\t%0, #:lower8_15:%1; lsls\\t%0, #8; adds\\t%0, #:lower0_7:%1
    ldr\\t%0, %1
    str\\t%1, %0
    mov\\t%0, %1"
-  [(set_attr "length" "2,2,4,4,4,2,2,2,2,2")
-   (set_attr "type" "mov_reg,mov_imm,mov_imm,multiple,multiple,load_4,store_4,load_4,store_4,mov_reg")
-   (set_attr "pool_range" "*,*,*,*,*,*,*,1018,*,*")
-   (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1")
-   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond")])
+  [(set_attr "length" "2,2,4,4,4,2,2,14,2,2,2")
+   (set_attr "type" "mov_reg,mov_imm,mov_imm,multiple,multiple,load_4,store_4,alu_sreg,load_4,store_4,mov_reg")
+   (set_attr "pool_range" "*,*,*,*,*,*,*, *,1018,*,*")
+   (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1,t1")
+   (set_attr "required_for_purecode" "no,no,no,no,no,no,no,yes,no,no,no")
+   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond,nocond")])
 
 ; Split the load of 64-bit constant into two loads for high and low 32-bit parts respectively
 ; to see if we can load them in fewer instructions or fewer cycles.