mirror of git://gcc.gnu.org/git/gcc.git
re PR target/59216 (ARM negdi*extendsidi regression)
PR target/59216 gcc/ * arm.md (negdi_extendsidi): Fix invalid split. gcc/testsuite/ * gcc.target/arm/negdi-4.c: Delete invalid test. * gcc.dg/torture/pr59216.c: New test. From-SVN: r205271
This commit is contained in:
parent
1e09922c5f
commit
8f1c326dea
|
|
@ -1,3 +1,8 @@
|
|||
2013-11-22 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
PR target/59216
|
||||
* arm.md (negdi_extendsidi): Fix invalid split.
|
||||
|
||||
2013-11-22 Alex Velenko <Alex.Velenko@arm.com>
|
||||
|
||||
* config/aarch64/arm_neon.h (vmov_n_f32): Implemented in C.
|
||||
|
|
|
|||
|
|
@ -4710,47 +4710,74 @@
|
|||
|
||||
;; Negate an extended 32-bit value.
|
||||
(define_insn_and_split "*negdi_extendsidi"
|
||||
[(set (match_operand:DI 0 "s_register_operand" "=r,&r,l,&l")
|
||||
(neg:DI (sign_extend:DI (match_operand:SI 1 "s_register_operand" "0,r,0,l"))))
|
||||
[(set (match_operand:DI 0 "s_register_operand" "=l,r")
|
||||
(neg:DI (sign_extend:DI
|
||||
(match_operand:SI 1 "s_register_operand" "l,r"))))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
"TARGET_32BIT"
|
||||
"#" ; rsb\\t%Q0, %1, #0\;asr\\t%R0, %Q0, #31
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
operands[2] = gen_highpart (SImode, operands[0]);
|
||||
operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
rtx tmp = gen_rtx_SET (VOIDmode,
|
||||
operands[0],
|
||||
rtx low = gen_lowpart (SImode, operands[0]);
|
||||
rtx high = gen_highpart (SImode, operands[0]);
|
||||
|
||||
if (reg_overlap_mentioned_p (low, operands[1]))
|
||||
{
|
||||
/* Input overlaps the low word of the output. Use:
|
||||
asr Rhi, Rin, #31
|
||||
rsbs Rlo, Rin, #0
|
||||
rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
|
||||
rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, high,
|
||||
gen_rtx_ASHIFTRT (SImode, operands[1],
|
||||
GEN_INT (31))));
|
||||
|
||||
emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
|
||||
if (TARGET_ARM)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, high,
|
||||
gen_rtx_MINUS (SImode,
|
||||
gen_rtx_MINUS (SImode,
|
||||
const0_rtx,
|
||||
operands[1]));
|
||||
if (TARGET_ARM)
|
||||
high),
|
||||
gen_rtx_LTU (SImode,
|
||||
cc_reg,
|
||||
const0_rtx))));
|
||||
else
|
||||
{
|
||||
emit_insn (tmp);
|
||||
rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, high,
|
||||
gen_rtx_MINUS (SImode,
|
||||
gen_rtx_MINUS (SImode,
|
||||
high,
|
||||
two_x),
|
||||
gen_rtx_LTU (SImode,
|
||||
cc_reg,
|
||||
const0_rtx))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the flags, to emit the short encoding in Thumb2. */
|
||||
rtx flags = gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_REG (CCmode, CC_REGNUM),
|
||||
gen_rtx_COMPARE (CCmode,
|
||||
const0_rtx,
|
||||
operands[1]));
|
||||
emit_insn (gen_rtx_PARALLEL (VOIDmode,
|
||||
gen_rtvec (2,
|
||||
flags,
|
||||
tmp)));
|
||||
}
|
||||
emit_insn (gen_rtx_SET (VOIDmode,
|
||||
operands[2],
|
||||
gen_rtx_ASHIFTRT (SImode,
|
||||
operands[0],
|
||||
/* No overlap, or overlap on high word. Use:
|
||||
rsb Rlo, Rin, #0
|
||||
bic Rhi, Rlo, Rin
|
||||
asr Rhi, Rhi, #31
|
||||
Flags not needed for this sequence. */
|
||||
emit_insn (gen_rtx_SET (VOIDmode, low,
|
||||
gen_rtx_NEG (SImode, operands[1])));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, high,
|
||||
gen_rtx_AND (SImode,
|
||||
gen_rtx_NOT (SImode, operands[1]),
|
||||
low)));
|
||||
emit_insn (gen_rtx_SET (VOIDmode, high,
|
||||
gen_rtx_ASHIFTRT (SImode, high,
|
||||
GEN_INT (31))));
|
||||
}
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "length" "8,8,4,4")
|
||||
(set_attr "arch" "a,a,t2,t2")
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "arch" "t2,*")
|
||||
(set_attr "type" "multiple")]
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
2013-11-22 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
PR target/59216
|
||||
* gcc.target/arm/negdi-4.c: Delete invalid test.
|
||||
* gcc.dg/torture/pr59216.c: New test.
|
||||
|
||||
2013-11-22 Alex Velenko <Alex.Velenko@arm.com>
|
||||
|
||||
* gcc.target/aarch64/vmov_n_1.c: New testcase.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
long long __attribute__((noinline)) f(int a)
|
||||
{
|
||||
return -(long long) a;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
if (f(0) != 0)
|
||||
abort ();
|
||||
|
||||
if (f(1) != -(long long)1)
|
||||
abort ();
|
||||
|
||||
if (f(-1) != -(long long)-1)
|
||||
abort ();
|
||||
|
||||
if (f(INT_MIN) != -(long long)INT_MIN)
|
||||
abort ();
|
||||
|
||||
if (f(INT_MAX) != -(long long)INT_MAX)
|
||||
abort ();
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target arm32 } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
signed long long negdi_extendsidi (signed int x)
|
||||
{
|
||||
return -((signed long long) x);
|
||||
}
|
||||
/*
|
||||
Expected output:
|
||||
rsbs r0, r0, #0
|
||||
mov r1, r0, asr #31
|
||||
*/
|
||||
/* { dg-final { scan-assembler-times "rsb" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "asr" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "rsc" 0 } } */
|
||||
Loading…
Reference in New Issue