Hi!

The testcase in the PR doesn't hoist any memory loads from the large switch
before the switch on aarch64 and arm (unlike e.g. x86), because the
arm/aarch64 casesi patterns don't properly annotate the memory load from the
jump table.  It is created by gen_* and in RTL directly one can't specify
the needed flags (MEM_READONLY_P and MEM_NOTRAP_P).

Fixed thusly, bootstrapped/regtested on armv7hl-linux-gnueabi and
aarch64-linux, ok for trunk?

2019-02-23  Jakub Jelinek  <ja...@redhat.com>

        PR target/70341
        * config/arm/arm.md (arm_casesi_internal): New define_expand.  Rename
        old define_insn to ...
        (*arm_casesi_internal): ... this.  Add mode to LABEL_REFs.
        * config/arm/thumb2.md (thumb2_casesi_internal): New define_expand.
        Rename old define_insn to ...
        (*thumb2_casesi_internal): ... this.  Add mode to LABEL_REFs.
        (thumb2_casesi_internal_pic): New define_expand.  Rename old
        define_insn to ...
        (*thumb2_casesi_internal_pic): ... this.  Add mode to LABEL_REFs.
        * config/aarch64/aarch64.md (casesi): Create the casesi_dispatch
        MEM manually here, set MEM_READONLY_P and MEM_NOTRAP_P on it.

--- gcc/config/arm/arm.md.jj    2019-02-18 20:48:32.643732307 +0100
+++ gcc/config/arm/arm.md       2019-02-21 14:40:50.603452028 +0100
@@ -8914,16 +8914,35 @@ (define_expand "casesi"
 
 ;; The USE in this pattern is needed to tell flow analysis that this is
 ;; a CASESI insn.  It has no other purpose.
-(define_insn "arm_casesi_internal"
+(define_expand "arm_casesi_internal"
+  [(parallel [(set (pc)
+              (if_then_else
+               (leu (match_operand:SI 0 "s_register_operand")
+                    (match_operand:SI 1 "arm_rhs_operand"))
+               (match_dup 4)
+               (label_ref:SI (match_operand 3 ""))))
+             (clobber (reg:CC CC_REGNUM))
+             (use (label_ref:SI (match_operand 2 "")))])]
+  "TARGET_ARM"
+{
+  operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
+  operands[4] = gen_rtx_PLUS (SImode, operands[4],
+                             gen_rtx_LABEL_REF (SImode, operands[2]));
+  operands[4] = gen_rtx_MEM (SImode, operands[4]);
+  MEM_READONLY_P (operands[4]) = 1;
+  MEM_NOTRAP_P (operands[4]) = 1;
+})
+
+(define_insn "*arm_casesi_internal"
   [(parallel [(set (pc)
               (if_then_else
                (leu (match_operand:SI 0 "s_register_operand" "r")
                     (match_operand:SI 1 "arm_rhs_operand" "rI"))
                (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
-                                (label_ref (match_operand 2 "" ""))))
-               (label_ref (match_operand 3 "" ""))))
+                                (label_ref:SI (match_operand 2 "" ""))))
+               (label_ref:SI (match_operand 3 "" ""))))
              (clobber (reg:CC CC_REGNUM))
-             (use (label_ref (match_dup 2)))])]
+             (use (label_ref:SI (match_dup 2)))])]
   "TARGET_ARM"
   "*
     if (flag_pic)
--- gcc/config/arm/thumb2.md.jj 2019-01-01 12:37:28.280792453 +0100
+++ gcc/config/arm/thumb2.md    2019-02-21 15:00:26.811137210 +0100
@@ -1079,17 +1079,37 @@ (define_insn "thumb2_zero_extendqisi2_v6
    (set_attr "neg_pool_range" "*,250")]
 )
 
-(define_insn "thumb2_casesi_internal"
+(define_expand "thumb2_casesi_internal"
+  [(parallel [(set (pc)
+              (if_then_else
+               (leu (match_operand:SI 0 "s_register_operand")
+                    (match_operand:SI 1 "arm_rhs_operand"))
+               (match_dup 4)
+               (label_ref:SI (match_operand 3 ""))))
+             (clobber (reg:CC CC_REGNUM))
+             (clobber (match_scratch:SI 5))
+             (use (label_ref:SI (match_operand 2 "")))])]
+  "TARGET_THUMB2 && !flag_pic"
+{
+  operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
+  operands[4] = gen_rtx_PLUS (SImode, operands[4],
+                             gen_rtx_LABEL_REF (SImode, operands[2]));
+  operands[4] = gen_rtx_MEM (SImode, operands[4]);
+  MEM_READONLY_P (operands[4]) = 1;
+  MEM_NOTRAP_P (operands[4]) = 1;
+})
+
+(define_insn "*thumb2_casesi_internal"
   [(parallel [(set (pc)
               (if_then_else
                (leu (match_operand:SI 0 "s_register_operand" "r")
                     (match_operand:SI 1 "arm_rhs_operand" "rI"))
                (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
-                                (label_ref (match_operand 2 "" ""))))
-               (label_ref (match_operand 3 "" ""))))
+                                (label_ref:SI (match_operand 2 "" ""))))
+               (label_ref:SI (match_operand 3 "" ""))))
              (clobber (reg:CC CC_REGNUM))
              (clobber (match_scratch:SI 4 "=&r"))
-             (use (label_ref (match_dup 2)))])]
+             (use (label_ref:SI (match_dup 2)))])]
   "TARGET_THUMB2 && !flag_pic"
   "* return thumb2_output_casesi(operands);"
   [(set_attr "conds" "clob")
@@ -1097,18 +1117,39 @@ (define_insn "thumb2_casesi_internal"
    (set_attr "type" "multiple")]
 )
 
-(define_insn "thumb2_casesi_internal_pic"
+(define_expand "thumb2_casesi_internal_pic"
+  [(parallel [(set (pc)
+              (if_then_else
+               (leu (match_operand:SI 0 "s_register_operand")
+                    (match_operand:SI 1 "arm_rhs_operand"))
+               (match_dup 4)
+               (label_ref:SI (match_operand 3 ""))))
+             (clobber (reg:CC CC_REGNUM))
+             (clobber (match_scratch:SI 5))
+             (clobber (match_scratch:SI 6))
+             (use (label_ref:SI (match_operand 2 "")))])]
+  "TARGET_THUMB2 && flag_pic"
+{
+  operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
+  operands[4] = gen_rtx_PLUS (SImode, operands[4],
+                             gen_rtx_LABEL_REF (SImode, operands[2]));
+  operands[4] = gen_rtx_MEM (SImode, operands[4]);
+  MEM_READONLY_P (operands[4]) = 1;
+  MEM_NOTRAP_P (operands[4]) = 1;
+})
+
+(define_insn "*thumb2_casesi_internal_pic"
   [(parallel [(set (pc)
               (if_then_else
                (leu (match_operand:SI 0 "s_register_operand" "r")
                     (match_operand:SI 1 "arm_rhs_operand" "rI"))
                (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
-                                (label_ref (match_operand 2 "" ""))))
-               (label_ref (match_operand 3 "" ""))))
+                                (label_ref:SI (match_operand 2 "" ""))))
+               (label_ref:SI (match_operand 3 "" ""))))
              (clobber (reg:CC CC_REGNUM))
              (clobber (match_scratch:SI 4 "=&r"))
              (clobber (match_scratch:SI 5 "=r"))
-             (use (label_ref (match_dup 2)))])]
+             (use (label_ref:SI (match_dup 2)))])]
   "TARGET_THUMB2 && flag_pic"
   "* return thumb2_output_casesi(operands);"
   [(set_attr "conds" "clob")
--- gcc/config/aarch64/aarch64.md.jj    2019-01-19 09:39:18.847831222 +0100
+++ gcc/config/aarch64/aarch64.md       2019-02-21 15:25:27.874532191 +0100
@@ -622,13 +622,27 @@ (define_expand "casesi"
                                    operands[0], operands[2], operands[4]));
 
     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[3]));
-    emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
-                                        operands[3]));
+    operands[2]
+      = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[2], operands[0]),
+                       UNSPEC_CASESI);
+    operands[2] = gen_rtx_MEM (DImode, operands[2]);
+    MEM_READONLY_P (operands[2]) = 1;
+    MEM_NOTRAP_P (operands[2]) = 1;
+    emit_jump_insn (gen_casesi_dispatch (operands[2], operands[3]));
     DONE;
   }
 )
 
-(define_insn "casesi_dispatch"
+(define_expand "casesi_dispatch"
+  [(parallel
+    [(set (pc) (match_operand:DI 0 ""))
+     (clobber (reg:CC CC_REGNUM))
+     (clobber (match_scratch:DI 2))
+     (clobber (match_scratch:DI 3))
+     (use (label_ref:DI (match_operand 1 "")))])]
+  "")
+
+(define_insn "*casesi_dispatch"
   [(parallel
     [(set (pc)
          (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
@@ -637,7 +651,7 @@ (define_insn "casesi_dispatch"
      (clobber (reg:CC CC_REGNUM))
      (clobber (match_scratch:DI 3 "=r"))
      (clobber (match_scratch:DI 4 "=r"))
-     (use (label_ref (match_operand 2 "" "")))])]
+     (use (label_ref:DI (match_operand 2 "" "")))])]
   ""
   "*
   return aarch64_output_casesi (operands);

        Jakub

Reply via email to