Commit da0a441d by Bernd Schmidt Committed by Bernd Schmidt

re PR target/43137 (redundant register move for sign extending)

	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.

From-SVN: r163935
parent 5c599206
2010-09-07 Bernd Schmidt <bernds@codesourcery.com>
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.
2010-09-06 H.J. Lu <hongjiu.lu@intel.com> 2010-09-06 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/linux-unwind.h (x86_fallback_frame_state): Properly * config/i386/linux-unwind.h (x86_fallback_frame_state): Properly
......
...@@ -4037,71 +4037,80 @@ ...@@ -4037,71 +4037,80 @@
;; Zero and sign extension instructions. ;; Zero and sign extension instructions.
(define_expand "zero_extendsidi2" (define_insn "zero_extend<mode>di2"
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "=r")
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))] (zero_extend:DI (match_operand:QHSI 1 "nonimmediate_operand" "rm")))]
"TARGET_32BIT" "TARGET_32BIT <qhs_zextenddi_cond>"
"" "#"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")]
) )
(define_insn "*arm_zero_extendsidi2" (define_insn "extend<mode>di2"
[(set (match_operand:DI 0 "s_register_operand" "=r") [(set (match_operand:DI 0 "s_register_operand" "=r")
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] (sign_extend:DI (match_operand:QHSI 1 "nonimmediate_operand" "rm")))]
"TARGET_ARM" "TARGET_32BIT <qhs_sextenddi_cond>"
"* "#"
if (REGNO (operands[1])
!= REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
return \"mov%?\\t%R0, #0\";
"
[(set_attr "length" "8") [(set_attr "length" "8")
(set_attr "insn" "mov") (set_attr "ce_count" "2")
(set_attr "shift" "1")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
(define_expand "zero_extendqidi2" ;; Splits for all extensions to DImode
[(set (match_operand:DI 0 "s_register_operand" "") (define_split
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))] [(set (match_operand:DI 0 "s_register_operand" "")
(zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
"TARGET_32BIT" "TARGET_32BIT"
"" [(set (match_dup 0) (match_dup 1))]
) {
rtx insn;
(define_insn "*arm_zero_extendqidi2" rtx lo_part = gen_lowpart (SImode, operands[0]);
[(set (match_operand:DI 0 "s_register_operand" "=r,r") enum machine_mode src_mode = GET_MODE (operands[1]);
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_ARM" if (REG_P (operands[0])
"@ && !reg_overlap_mentioned_p (operands[0], operands[1]))
and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0 emit_clobber (operands[0]);
ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0" if (!REG_P (lo_part) || src_mode != SImode
[(set_attr "length" "8") || !rtx_equal_p (lo_part, operands[1]))
(set_attr "predicable" "yes") {
(set_attr "type" "*,load_byte") if (src_mode == SImode)
(set_attr "pool_range" "*,4092") emit_move_insn (lo_part, operands[1]);
(set_attr "neg_pool_range" "*,4084")] else
) emit_insn (gen_rtx_SET (VOIDmode, lo_part,
gen_rtx_ZERO_EXTEND (SImode, operands[1])));
operands[1] = lo_part;
}
operands[0] = gen_highpart (SImode, operands[0]);
operands[1] = const0_rtx;
})
(define_expand "extendsidi2" (define_split
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
(sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))] (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
"TARGET_32BIT" "TARGET_32BIT"
"" [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
) {
rtx lo_part = gen_lowpart (SImode, operands[0]);
enum machine_mode src_mode = GET_MODE (operands[1]);
(define_insn "*arm_extendsidi2" if (REG_P (operands[0])
[(set (match_operand:DI 0 "s_register_operand" "=r") && !reg_overlap_mentioned_p (operands[0], operands[1]))
(sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] emit_clobber (operands[0]);
"TARGET_ARM"
"* if (!REG_P (lo_part) || src_mode != SImode
if (REGNO (operands[1]) || !rtx_equal_p (lo_part, operands[1]))
!= REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0)) {
output_asm_insn (\"mov%?\\t%Q0, %1\", operands); if (src_mode == SImode)
return \"mov%?\\t%R0, %Q0, asr #31\"; emit_move_insn (lo_part, operands[1]);
" else
[(set_attr "length" "8") emit_insn (gen_rtx_SET (VOIDmode, lo_part,
(set_attr "shift" "1") gen_rtx_SIGN_EXTEND (SImode, operands[1])));
(set_attr "insn" "mov") operands[1] = lo_part;
(set_attr "predicable" "yes")] }
) operands[0] = gen_highpart (SImode, operands[0]);
})
(define_expand "zero_extendhisi2" (define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "s_register_operand" "") [(set (match_operand:SI 0 "s_register_operand" "")
...@@ -4137,26 +4146,22 @@ ...@@ -4137,26 +4146,22 @@
[(set (match_operand:SI 0 "register_operand" "=l,l") [(set (match_operand:SI 0 "register_operand" "=l,l")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))] (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"* {
rtx mem; rtx mem;
if (which_alternative == 0 && arm_arch6) if (which_alternative == 0 && arm_arch6)
return \"uxth\\t%0, %1\"; return "uxth\t%0, %1";
if (which_alternative == 0) if (which_alternative == 0)
return \"#\"; return "#";
mem = XEXP (operands[1], 0); mem = XEXP (operands[1], 0);
if (GET_CODE (mem) == CONST) if (GET_CODE (mem) == CONST)
mem = XEXP (mem, 0); mem = XEXP (mem, 0);
if (GET_CODE (mem) == LABEL_REF)
return \"ldr\\t%0, %1\";
if (GET_CODE (mem) == PLUS) if (GET_CODE (mem) == PLUS)
{ {
rtx a = XEXP (mem, 0); rtx a = XEXP (mem, 0);
rtx b = XEXP (mem, 1);
/* This can happen due to bugs in reload. */ /* This can happen due to bugs in reload. */
if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM) if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
...@@ -4165,24 +4170,19 @@ ...@@ -4165,24 +4170,19 @@
ops[0] = operands[0]; ops[0] = operands[0];
ops[1] = a; ops[1] = a;
output_asm_insn (\"mov %0, %1\", ops); output_asm_insn ("mov\t%0, %1", ops);
XEXP (mem, 0) = operands[0]; XEXP (mem, 0) = operands[0];
} }
else if ( GET_CODE (a) == LABEL_REF
&& GET_CODE (b) == CONST_INT)
return \"ldr\\t%0, %1\";
} }
return \"ldrh\\t%0, %1\"; return "ldrh\t%0, %1";
" }
[(set_attr_alternative "length" [(set_attr_alternative "length"
[(if_then_else (eq_attr "is_arch6" "yes") [(if_then_else (eq_attr "is_arch6" "yes")
(const_int 2) (const_int 4)) (const_int 2) (const_int 4))
(const_int 4)]) (const_int 4)])
(set_attr "type" "alu_shift,load_byte") (set_attr "type" "alu_shift,load_byte")]
(set_attr "pool_range" "*,60")]
) )
(define_insn "*arm_zero_extendhisi2" (define_insn "*arm_zero_extendhisi2"
...@@ -4193,9 +4193,7 @@ ...@@ -4193,9 +4193,7 @@
# #
ldr%(h%)\\t%0, %1" ldr%(h%)\\t%0, %1"
[(set_attr "type" "alu_shift,load_byte") [(set_attr "type" "alu_shift,load_byte")
(set_attr "predicable" "yes") (set_attr "predicable" "yes")]
(set_attr "pool_range" "*,256")
(set_attr "neg_pool_range" "*,244")]
) )
(define_insn "*arm_zero_extendhisi2_v6" (define_insn "*arm_zero_extendhisi2_v6"
...@@ -4206,9 +4204,7 @@ ...@@ -4206,9 +4204,7 @@
uxth%?\\t%0, %1 uxth%?\\t%0, %1
ldr%(h%)\\t%0, %1" ldr%(h%)\\t%0, %1"
[(set_attr "type" "alu_shift,load_byte") [(set_attr "type" "alu_shift,load_byte")
(set_attr "predicable" "yes") (set_attr "predicable" "yes")]
(set_attr "pool_range" "*,256")
(set_attr "neg_pool_range" "*,244")]
) )
(define_insn "*arm_zero_extendhisi2addsi" (define_insn "*arm_zero_extendhisi2addsi"
...@@ -4277,9 +4273,8 @@ ...@@ -4277,9 +4273,8 @@
"@ "@
uxtb\\t%0, %1 uxtb\\t%0, %1
ldrb\\t%0, %1" ldrb\\t%0, %1"
[(set_attr "length" "2,2") [(set_attr "length" "2")
(set_attr "type" "alu_shift,load_byte") (set_attr "type" "alu_shift,load_byte")]
(set_attr "pool_range" "*,32")]
) )
(define_insn "*arm_zero_extendqisi2" (define_insn "*arm_zero_extendqisi2"
...@@ -4291,9 +4286,7 @@ ...@@ -4291,9 +4286,7 @@
ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
[(set_attr "length" "8,4") [(set_attr "length" "8,4")
(set_attr "type" "alu_shift,load_byte") (set_attr "type" "alu_shift,load_byte")
(set_attr "predicable" "yes") (set_attr "predicable" "yes")]
(set_attr "pool_range" "*,4096")
(set_attr "neg_pool_range" "*,4084")]
) )
(define_insn "*arm_zero_extendqisi2_v6" (define_insn "*arm_zero_extendqisi2_v6"
...@@ -4304,9 +4297,7 @@ ...@@ -4304,9 +4297,7 @@
uxtb%(%)\\t%0, %1 uxtb%(%)\\t%0, %1
ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
[(set_attr "type" "alu_shift,load_byte") [(set_attr "type" "alu_shift,load_byte")
(set_attr "predicable" "yes") (set_attr "predicable" "yes")]
(set_attr "pool_range" "*,4096")
(set_attr "neg_pool_range" "*,4084")]
) )
(define_insn "*arm_zero_extendqisi2addsi" (define_insn "*arm_zero_extendqisi2addsi"
......
...@@ -370,6 +370,11 @@ ...@@ -370,6 +370,11 @@
;; Widen. Result is half the number of elements, but widened to double-width. ;; Widen. Result is half the number of elements, but widened to double-width.
(define_mode_attr V_unpack [(V16QI "V8HI") (V8HI "V4SI") (V4SI "V2DI")]) (define_mode_attr V_unpack [(V16QI "V8HI") (V8HI "V4SI") (V4SI "V2DI")])
;; Conditions to be used in extend<mode>di patterns.
(define_mode_attr qhs_zextenddi_cond [(SI "") (HI "&& arm_arch6") (QI "")])
(define_mode_attr qhs_sextenddi_cond [(SI "") (HI "&& arm_arch6")
(QI "&& arm_arch6")])
;;---------------------------------------------------------------------------- ;;----------------------------------------------------------------------------
;; Code attributes ;; Code attributes
;;---------------------------------------------------------------------------- ;;----------------------------------------------------------------------------
......
...@@ -557,145 +557,6 @@ ...@@ -557,145 +557,6 @@
;; Zero and sign extension instructions. ;; Zero and sign extension instructions.
(define_insn_and_split "*thumb2_zero_extendsidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_THUMB2"
"mov%?\\t%Q0, %1\;mov%?\\t%R0, #0"
"&& reload_completed"
[(set (match_dup 0) (match_dup 1))]
"
{
rtx lo_part = gen_lowpart (SImode, operands[0]);
if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
emit_move_insn (lo_part, operands[1]);
operands[0] = gen_highpart (SImode, operands[0]);
operands[1] = const0_rtx;
}
"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")]
)
(define_insn_and_split "*thumb2_zero_extendhidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r,r")
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
"TARGET_THUMB2"
"@
uxth%?\\t%Q0, %1\;mov%?\\t%R0, #0
ldr%(h%)\\t%Q0, %1\;mov%?\\t%R0, #0"
"&& reload_completed"
[(set (match_dup 0) (zero_extend:SI (match_dup 1)))
(set (match_dup 2) (match_dup 3))]
"
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[3] = const0_rtx;
}
"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")
(set_attr "type" "*,load_byte")
(set_attr "pool_range" "*,4092")
(set_attr "neg_pool_range" "*,250")]
)
(define_insn_and_split "*thumb2_zero_extendqidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r,r")
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_THUMB2"
"@
uxtb%?\\t%Q0, %1\;mov%?\\t%R0, #0
ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0"
"&& reload_completed"
[(set (match_dup 0) (zero_extend:SI (match_dup 1)))
(set (match_dup 2) (match_dup 3))]
"
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[3] = const0_rtx;
}
"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")
(set_attr "type" "*,load_byte")
(set_attr "pool_range" "*,4092")
(set_attr "neg_pool_range" "*,250")]
)
(define_insn_and_split "*thumb2_extendsidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_THUMB2"
"mov%?\\t%Q0, %1\;asr?\\t%R0, %1, #31"
"&& reload_completed"
[(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
{
rtx lo_part = gen_lowpart (SImode, operands[0]);
if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
emit_move_insn (lo_part, operands[1]);
operands[0] = gen_highpart (SImode, operands[0]);
}
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "shift" "1")
(set_attr "predicable" "yes")]
)
(define_insn_and_split "*thumb2_extendhidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r,r")
(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
"TARGET_THUMB2"
"@
sxth%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
ldrsh%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
"&& reload_completed"
[(set (match_dup 0) (sign_extend:SI (match_dup 1)))
(set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
"
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
}
"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")
(set_attr "type" "*,load_byte")
(set_attr "pool_range" "*,4092")
(set_attr "neg_pool_range" "*,250")]
)
(define_insn_and_split "*thumb2_extendqidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r,r")
(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_THUMB2"
"@
sxtb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
ldrsb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
"&& reload_completed"
[(set (match_dup 0) (sign_extend:SI (match_dup 1)))
(set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
"
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
}
"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")
(set_attr "type" "*,load_byte")
(set_attr "pool_range" "*,4092")
(set_attr "neg_pool_range" "*,250")]
)
;; All supported Thumb2 implementations are armv6, so only that case is ;; All supported Thumb2 implementations are armv6, so only that case is
;; provided. ;; provided.
(define_insn "*thumb2_extendqisi_v6" (define_insn "*thumb2_extendqisi_v6"
......
2010-09-07 Bernd Schmidt <bernds@codesourcery.com>
PR target/43137
* gcc.target/arm/pr43137.c: New test.
2010-09-06 Thomas Koenig <tkoenig@gcc.gnu.org> 2010-09-06 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/36931 PR fortran/36931
......
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "mov\tr1, r\[1-9\]" } } */
int foo();
long long bar22()
{
int result = foo();
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment