Hi,
When combine tries to combine:
(insn 37 35 39 3 (set (reg:SI 90)
(plus:SI (mult:SI (reg/v:SI 84 [ i ])
(const_int 4 [0x4]))
(reg:SI 106))) x.i:11 247 {*leasi_2}
(nil))
(insn 39 37 41 3 (set (mem:SI (zero_extend:DI (reg:SI 90)) [3
MEM[symbol: x,
index: D.2741_12, step: 4, offset: 4294967292B]+0 S4 A32])
(reg/v:SI 84 [ i ])) x.i:11 64 {*movsi_internal}
(expr_list:REG_DEAD (reg:SI 90)
(nil)))
it optimizes
(zero_extend:DI (plus:SI (mult:SI (reg/v:SI 84 [ i ])
(const_int 4 [0x4]))
(reg:SI 106)))
into
(and:DI (plus:DI (subreg:DI (mult:SI (reg/v:SI 85 [ i ])
(const_int 4 [0x4])) 0)
(subreg:DI (reg:SI 106) 0))
(const_int 4294967292 [0xfffffffc]))
in make_compound_operation. X86 backend doesn't accept the new
expression as valid address while (zero_extend:DI) works just fine.
This patches keeps ZERO_EXTEND when zero-extending address to Pmode.
It reduces number of lea from 24173 to 21428 in x32 libgfortran.so.
Does it make any senses?
Thanks.
H.J.
---
2011-10-12 H.J. Lu <[email protected]>
PR rtl-optimization/50696
* combine.c (subst): If an address is zero-extended to Pmode,
replace FROM with while keeping ZERO_EXTEND.
diff --git a/gcc/combine.c b/gcc/combine.c
index 6c3b17c..45180e5 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5078,6 +5078,23 @@ subst (rtx x, rtx from, rtx to, int in_dest, int
in_cond, int unique_copy)
}
}
}
+#ifdef POINTERS_EXTEND_UNSIGNED
+ else if (POINTERS_EXTEND_UNSIGNED > 0
+ && code == MEM
+ && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
+ && GET_MODE (XEXP (x, 0)) == Pmode)
+ {
+ /* If an address is zero-extended to Pmode, replace FROM with
+ TO while keeping ZERO_EXTEND. */
+ new_rtx = subst (XEXP (XEXP (x, 0), 0), from, to, 0, 0,
+ unique_copy);
+ /* Drop ZERO_EXTEND on constant. */
+ if (CONST_INT_P (new_rtx))
+ SUBST (XEXP (x, 0), new_rtx);
+ else
+ SUBST (XEXP (XEXP (x, 0), 0), new_rtx);
+ }
+#endif
else
{
len = GET_RTX_LENGTH (code);