Bug 43137 - redundant register move for sign extending
Summary: redundant register move for sign extending
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.5.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2010-02-22 09:39 UTC by Carrot
Modified: 2010-09-07 11:16 UTC (History)
2 users (show)

See Also:
Host: i686-linux
Target: arm-eabi
Build: i686-linux
Known to work:
Known to fail:
Last reconfirmed: 2010-02-22 14:32:54


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Carrot 2010-02-22 09:39:21 UTC
Compile following code with options -march=armv7-a -mthumb -Os

int foo();
long long bar22()
{
  int result = foo();
  return result;
}

GCC generates:

bar22:
        push    {r3, lr}
        bl      foo
        asrs    r3, r0, #31    // A
        mov     r1, r3         // B
        pop     {r3, pc}

Instruction A,B can be simplified to "asrs r1, r0, #31".

In rtl expand, result was first extended to a DI register and then the DI register was moved to return register. In later passs the low half of the return value and variable result were recognized as in the same register, so the low part move was removed. After register allocation I get:

(call_insn 5 2 7 2 src/t5.c:5 (parallel [
            (set (reg:SI 0 r0)
                (call (mem:SI (symbol_ref:SI ("foo") [flags 0x41]  <function_decl 0x7f6e60fe0600 foo>) [0 S4 A32])
                    (const_int 0 [0x0])))
            (use (const_int 0 [0x0]))
            (clobber (reg:SI 14 lr))
        ]) 255 {*call_value_insn} (nil)
    (nil))

(insn 7 5 22 2 src/t5.c:5 (set (reg:DI 2 r2 [orig:136 result ] [136])
        (sign_extend:DI (reg/v:SI 0 r0 [orig:133 result ] [133]))) 691 {*thumb2_extendsidi2} (nil))

(insn 22 7 15 2 src/t5.c:7 (set (reg:SI 1 r1 [+4 ])
        (reg:SI 3 r3 [ result+4 ])) 658 {*thumb2_movsi_insn} (nil))

The high part register move didn't get any chance to be removed until the end of compilation.
Comment 1 Ramana Radhakrishnan 2010-02-22 14:32:54 UTC
Confirmed.
Comment 2 Bernd Schmidt 2010-09-06 22:32:39 UTC
Subject: Bug 43137

Author: bernds
Date: Mon Sep  6 22:32:26 2010
New Revision: 163935

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163935
Log:
	PR target/43137
	* config/arm/iterators.md (qhs_zextenddi_cond, qhs_sextenddi_cond):
	New define_mode_attrs.
	* config/arm/arm.md (zero_extendsidi2, arm_zero_extendsidi2,
	arm_exxtendsidi2, arm_extendsidi2): Delete patterns.
	(zero_extend<mode>di2, extend<mode>di2 and related splits): New.
	(thumb1_zero_extendhisi2): Remove code to handle LABEL_REFs.
	Remove pool_range attribute.
	(arm_zero_extendhisi2, arm_zero_extendhisi2_v6, arm_zero_extendqisi2,
	arm_zero_extendqisi2_v6, thumb1_zero_extendqisi2_v6): Remove
	pool_range and neg_pool_range attributes.
	* config/arm/thumb2.md (thumb2_zero_extendsidi2,
	thumb2_zero_extendhidi2, thumb2_zero_extendqidi2, thumb2_extendsidi2,
	thumb2_extendhidi2, thumb2_extendqidi2): Delete.

	PR target/43137
	* gcc.target/arm/pr43137.c: New test.


Added:
    trunk/gcc/testsuite/gcc.target/arm/pr43137.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/arm/arm.md
    trunk/gcc/config/arm/iterators.md
    trunk/gcc/config/arm/thumb2.md
    trunk/gcc/testsuite/ChangeLog

Comment 3 Bernd Schmidt 2010-09-07 11:16:45 UTC
Fixed.