[PATCH] Fix PR40741 (ARM pessimization)

Richard Earnshaw rearnsha@arm.com
Mon Aug 3 12:12:00 GMT 2009


On Sat, 2009-08-01 at 23:24 +0200, Paolo Bonzini wrote:
> This patch fixes PR40741, an ARM pessimization introduced by the
> second round of cond-optab changes (the post-merge changes).
> 
> The main reason here is that the new optimization possibilities
> in emit_store_flag were not conditionalized on their costs.
> This is what this patch does.
> 
> In addition, I took the occasion to tweak the patterns and costs
> for Thumb AND/IOR/XOR.  This saved one instruction even without
> the target-independent patch.  The change to the pattern is to
> exchange the arguments of
> 
>    (set (reg:SI A) (and/ior/xor:SI (reg:SI B) (const_int N)))
> 
> thus generating
> 
>    (set (reg:SI C) (const_int N))         ;; any non-reg actually
>    (set (reg:SI A) (reg:SI C) (reg:SI B))
> 
> and simplifying the task of tying regs A and C to the same register.
> 

Hm, sounds like the register allocator isn't dealing with this case
properly...  :-(  The patterns are correctly marked as commutative.

> On ARM, in addition, in the presence of a complex constant the
> XOR can be done piecewise.
> 
> Tested i686-pc-linux-gnu, plus on arm-elf I looked by hand at some
> testcases to test the paths I modified, but building a combined
> tree failed with an internal assembler error.
> 
> Ok?
> 
> Paolo
> 
> 2009-08-01  Paolo Bonzini  <bonzini@gnu.org>
> 
> 	PR rtl-optimization/40741
> 	* config/arm/arm.c (thumb1_rtx_costs): IOR or XOR with
> 	a small constant is cheap.
> 	* config/arm/arm.c (andsi3, iorsi3): Try to place the
                          ^^^
ITYM arm.md

> 	result of force_reg on the LHS.
> 	(xorsi3): Likewise, and split the XOR if the constant
> 	is complex and not in Thumb mode.
> 	* expmed.c (emit_store_flag): Check costs before
> 	transforming to the opposite representation.
> 
> 2009-08-01  Paolo Bonzini  <bonzini@gnu.org>
> 
> 	* gcc.target/arm/thumb-branch1.c: New.
> 
> Index: gcc/config/arm/arm.c
> ===================================================================
> --- gcc/config/arm/arm.c	(branch cond-optab2)
> +++ gcc/config/arm/arm.c	(working copy)
> @@ -5124,6 +5124,9 @@ thumb1_rtx_costs (rtx x, enum rtx_code c
>        else if ((outer == PLUS || outer == COMPARE)
>  	       && INTVAL (x) < 256 && INTVAL (x) > -256)
>  	return 0;
> +      else if ((outer == IOR || outer == XOR)
> +	       && INTVAL (x) < 256 && INTVAL (x) >= 0)
> +	return COSTS_N_INSNS (1);

This should be merged into the following case (all of these operations
can use -256...255 with one insn cost by using either mov or mvn
immediate).

Otherwise OK.

R.

btw adding "-F ^(define" to your diff options makes patches to .md files
much easier to read.



More information about the Gcc-patches mailing list