Commit 498b13e2 by Kyrylo Tkachov Committed by Kyrylo Tkachov

[AArch64] Fix wrong-code bug in right-shift SISD patterns

	* config/aarch64/aarch64.md (*aarch64_lshr_sisd_or_int_<mode>3):
	Mark operand 0 as earlyclobber in 2nd alternative.
	(1st define_split below *aarch64_lshr_sisd_or_int_<mode>3):
	Write negated shift amount into QI lowpart operand 0 and use it
	in the shift step.
	(2nd define_split below *aarch64_lshr_sisd_or_int_<mode>3): Likewise.

	* gcc.target/aarch64/sisd-shft-neg_1.c: New test.

From-SVN: r220860
parent 739b41eb
2015-02-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64.md (*aarch64_lshr_sisd_or_int_<mode>3):
Mark operand 0 as earlyclobber in 2nd alternative.
(1st define_split below *aarch64_lshr_sisd_or_int_<mode>3):
Write negated shift amount into QI lowpart operand 0 and use it
in the shift step.
(2nd define_split below *aarch64_lshr_sisd_or_int_<mode>3): Likewise.
2015-02-20 Bernd Schmidt <bernds@codesourcery.com>
* cgraph.h (clone_function_name_1): Declare.
......
......@@ -3360,7 +3360,7 @@
;; Logical right shift using SISD or Integer instruction
(define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
[(set (match_operand:GPI 0 "register_operand" "=w,w,r")
[(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
(lshiftrt:GPI
(match_operand:GPI 1 "register_operand" "w,w,r")
(match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
......@@ -3379,11 +3379,13 @@
(match_operand:DI 1 "aarch64_simd_register")
(match_operand:QI 2 "aarch64_simd_register")))]
"TARGET_SIMD && reload_completed"
[(set (match_dup 2)
[(set (match_dup 3)
(unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
(set (match_dup 0)
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
""
(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
{
operands[3] = gen_lowpart (QImode, operands[0]);
}
)
(define_split
......@@ -3392,11 +3394,13 @@
(match_operand:SI 1 "aarch64_simd_register")
(match_operand:QI 2 "aarch64_simd_register")))]
"TARGET_SIMD && reload_completed"
[(set (match_dup 2)
[(set (match_dup 3)
(unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
(set (match_dup 0)
(unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
""
(unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
{
operands[3] = gen_lowpart (QImode, operands[0]);
}
)
;; Arithmetic right shift using SISD or Integer instruction
......
2015-02-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/aarch64/sisd-shft-neg_1.c: New test.
2015-02-20 Georg-Johann Lay <avr@gjlay.de>
PR target/64452
......
/* { dg-do run } */
/* { dg-options "-O2 -fno-inline" } */
extern void abort (void);
#define force_simd_si(v) asm volatile ("mov %s0, %1.s[0]" :"=w" (v) :"w" (v) :)
unsigned int
shft_add (unsigned int a, unsigned int b)
{
unsigned int c;
force_simd_si (a);
force_simd_si (b);
c = a >> b;
force_simd_si (c);
return c + b;
}
int
main (void)
{
unsigned int i = 0;
unsigned int a = 0xdeadbeef;
for (i = 0; i < 32; i++)
{
unsigned int exp = (a / (1 << i) + i);
unsigned int got = shft_add (a, i);
if (exp != got)
abort ();
}
return 0;
}
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