Hi,

arm_legitimize_address forces immediates in PLUS to be in REG for no good reason. This patch changes it not to do this.

With the immediate constants directly available in the RTL, it helps the expand more effectively to fold and re-associate the immediates.

The change also helps the following if condition in arm_legitimize_address to have chance to be true:

      if (ARM_BASE_REGISTER_RTX_P (xop0)
          && CONST_INT_P (xop1))
        {

The -fdump-rtl-expand diff for the added test case is:

 ;; Generating RTL for gimple basic block 2
@@ -32,53 +32,50 @@
      (nil))
 (note 4 3 7 2 NOTE_INSN_FUNCTION_BEG)
 (insn 7 4 8 2 (set (reg:SI 116)
-        (const_int 4000 [0xfa0]))
-     (nil))
-(insn 8 7 9 2 (set (reg:SI 117)
         (reg/v:SI 115 [ i ]))
      (nil))
[snip]
-(insn 16 15 17 2 (set (reg/f:SI 124)
-        (plus:SI (reg:SI 123)
-            (reg:SI 116)))
+(insn 15 14 16 2 (set (reg/f:SI 123)
+        (plus:SI (reg:SI 122)
+            (const_int 4000 [0xfa0])))
      (nil))
-(insn 17 16 18 2 (set (reg:SI 125)
+(insn 16 15 17 2 (set (reg:SI 124)
         (const_int 1 [0x1]))
      (nil))
-(insn 18 17 0 2 (set (mem:SI (plus:SI (mult:SI (reg/v:SI 115 [ i ])
+(insn 17 16 0 2 (set (mem:SI (plus:SI (mult:SI (reg/v:SI 115 [ i ])
                     (const_int 4 [0x4]))
-                (reg/f:SI 124)) [2 *_6 S4 A32])
-        (reg:SI 125))
+                (reg/f:SI 123)) [2 *_6 S4 A32])
+        (reg:SI 124))
      (nil))

Passed bootstrapping on cortex-a15 and regtest on arm-none-eabi.

OK for the trunk?

Thanks,
Yufeng


gcc/

        * config/arm/arm.c (arm_legitimize_address): Check xop1 is not
        a constant immediate before force_reg.

gcc/testsuite/

        * gcc.target/arm/20131120.c: New test.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 212a4bc..d5d14e5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -7120,7 +7120,8 @@ arm_legitimize_address (rtx x, rtx orig_x, enum 
machine_mode mode)
       if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
        xop0 = force_reg (SImode, xop0);
 
-      if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
+      if (CONSTANT_P (xop1) && !CONST_INT_P (xop1)
+         && !symbol_mentioned_p (xop1))
        xop1 = force_reg (SImode, xop1);
 
       if (ARM_BASE_REGISTER_RTX_P (xop0)
diff --git a/gcc/testsuite/gcc.target/arm/20131120.c 
b/gcc/testsuite/gcc.target/arm/20131120.c
new file mode 100644
index 0000000..c370ae6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/20131120.c
@@ -0,0 +1,14 @@
+/* Check that CONST_INT is not forced into REG before PLUS.  */
+/* { dg-do compile { target { arm_arm_ok || arm_thumb2_ok} } } */
+/* { dg-options "-O2 -fdump-rtl-expand" } */
+
+typedef int Arr2[50][50];
+
+void
+foo (Arr2 a2, int i)
+{
+  a2[i+20][i] = 1;
+}
+
+/* { dg-final { scan-rtl-dump-not "\\\(set \\\(reg:SI \[0-9\]*\\\)\[\n\r\]+\[ 
\t]*\\\(const_int 4000" "expand" } } */
+/* { dg-final { cleanup-rtl-dump "expand" } } */

Reply via email to