[AArch64] Improve bit-test-branch pattern to avoid unnecessary register clobber
2015-01-27 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> Jiong Wang <jiong.wang@arm.com> gcc/ * config/aarch64/aarch64.md (tb<optab><mode>1): Clobber CC reg instead of scratch reg. (cb<optab><mode>1): Likewise. * config/aarch64/iterators.md (bcond): New define_code_attr. gcc/testsuite/ * gcc.dg/long_branch.c: New testcase. From-SVN: r220170
This commit is contained in:
parent
fb1a3f8f57
commit
096e8448ca
@ -1,3 +1,11 @@
|
||||
2015-01-27 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||
Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* config/aarch64/aarch64.md (tb<optab><mode>1): Clobber CC reg instead
|
||||
of scratch reg.
|
||||
(cb<optab><mode>1): Likewise.
|
||||
* config/aarch64/iterators.md (bcond): New define_code_attr.
|
||||
|
||||
2015-01-27 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
||||
|
||||
* config/s390/s390.c (s390_memory_move_cost): Increase costs for
|
||||
|
@ -499,13 +499,17 @@
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 2 "" ""))
|
||||
(pc)))
|
||||
(clobber (match_scratch:DI 3 "=r"))]
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
""
|
||||
"*
|
||||
if (get_attr_length (insn) == 8)
|
||||
return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
|
||||
return \"<tbz>\\t%<w>0, %1, %l2\";
|
||||
"
|
||||
{
|
||||
if (get_attr_length (insn) == 8)
|
||||
{
|
||||
operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
|
||||
return "tst\t%<w>0, %1\;<bcond>\t%l2";
|
||||
}
|
||||
else
|
||||
return "<tbz>\t%<w>0, %1, %l2";
|
||||
}
|
||||
[(set_attr "type" "branch")
|
||||
(set (attr "length")
|
||||
(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
|
||||
@ -519,13 +523,21 @@
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 1 "" ""))
|
||||
(pc)))
|
||||
(clobber (match_scratch:DI 2 "=r"))]
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
""
|
||||
"*
|
||||
if (get_attr_length (insn) == 8)
|
||||
return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
|
||||
return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
|
||||
"
|
||||
{
|
||||
if (get_attr_length (insn) == 8)
|
||||
{
|
||||
char buf[64];
|
||||
uint64_t val = ((uint64_t ) 1)
|
||||
<< (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
|
||||
sprintf (buf, "tst\t%%<w>0, %"PRId64, val);
|
||||
output_asm_insn (buf, operands);
|
||||
return "<bcond>\t%l1";
|
||||
}
|
||||
else
|
||||
return "<tbz>\t%<w>0, <sizem1>, %l1";
|
||||
}
|
||||
[(set_attr "type" "branch")
|
||||
(set (attr "length")
|
||||
(if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
|
||||
|
@ -814,6 +814,9 @@
|
||||
(smax "s") (umax "u")
|
||||
(smin "s") (umin "u")])
|
||||
|
||||
;; Emit conditional branch instructions.
|
||||
(define_code_attr bcond [(eq "beq") (ne "bne") (lt "bne") (ge "beq")])
|
||||
|
||||
;; Emit cbz/cbnz depending on comparison type.
|
||||
(define_code_attr cbz [(eq "cbz") (ne "cbnz") (lt "cbnz") (ge "cbz")])
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2015-01-27 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* gcc.dg/long_branch.c: New testcase.
|
||||
|
||||
2015-01-27 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/56273
|
||||
|
198
gcc/testsuite/gcc.dg/long_branch.c
Normal file
198
gcc/testsuite/gcc.dg/long_branch.c
Normal file
@ -0,0 +1,198 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2 -fno-reorder-blocks" } */
|
||||
|
||||
void abort ();
|
||||
|
||||
__attribute__((noinline, noclone)) int
|
||||
restore (int a, int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
__attribute__((noinline, noclone)) void
|
||||
do_nothing (int *input)
|
||||
{
|
||||
*input = restore (*input, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
#define CASE_ENTRY(n) \
|
||||
case n: \
|
||||
sum = sum / (n + 1); \
|
||||
sum = restore (sum, n + 1); \
|
||||
if (sum == (n + addend)) \
|
||||
break;\
|
||||
sum = sum / (n + 2); \
|
||||
sum = restore (sum, n + 2); \
|
||||
sum = sum / (n + 3); \
|
||||
sum = restore (sum, n + 3); \
|
||||
sum = sum / (n + 4); \
|
||||
sum = restore (sum, n + 4); \
|
||||
sum = sum / (n + 5); \
|
||||
sum = restore (sum, n + 5); \
|
||||
sum = sum / (n + 6); \
|
||||
sum = restore (sum, n + 6); \
|
||||
sum = sum / (n + 7); \
|
||||
sum = restore (sum, n + 7); \
|
||||
sum = sum / (n + 8); \
|
||||
sum = restore (sum, n + 8); \
|
||||
sum = sum / (n + 9); \
|
||||
sum = restore (sum, n + 9); \
|
||||
sum = sum / (n + 10); \
|
||||
sum = restore (sum, n + 10); \
|
||||
sum = sum / (n + 11); \
|
||||
sum = restore (sum, n + 11); \
|
||||
sum = sum / (n + 12); \
|
||||
sum = restore (sum, n + 12); \
|
||||
sum = sum / (n + 13); \
|
||||
sum = restore (sum, n + 13); \
|
||||
sum = sum / (n + 14); \
|
||||
sum = restore (sum, n + 14); \
|
||||
sum = sum / (n + 15); \
|
||||
sum = restore (sum, n + 15); \
|
||||
sum = sum / (n + 16); \
|
||||
sum = restore (sum, n + 16); \
|
||||
sum = sum / (n + 17); \
|
||||
sum = restore (sum, n + 17); \
|
||||
sum = sum / (n + 18); \
|
||||
sum = restore (sum, n + 18); \
|
||||
sum = sum / (n + 19); \
|
||||
sum = restore (sum, n + 19); \
|
||||
sum = sum / (n + 20); \
|
||||
sum = restore (sum, n + 20); \
|
||||
sum = sum / (n + 21); \
|
||||
sum = restore (sum, n + 21); \
|
||||
sum = sum / (n + 22); \
|
||||
sum = restore (sum, n + 22); \
|
||||
sum = sum / (n + 23); \
|
||||
sum = restore (sum, n + 23); \
|
||||
sum = sum / (n + 24); \
|
||||
sum = restore (sum, n + 24); \
|
||||
sum = sum / (n + 25); \
|
||||
sum = restore (sum, n + 25); \
|
||||
sum = sum / (n + 26); \
|
||||
sum = restore (sum, n + 26); \
|
||||
sum = sum / (n + 27); \
|
||||
sum = restore (sum, n + 27); \
|
||||
sum = sum / (n + 28); \
|
||||
sum = restore (sum, n + 28); \
|
||||
sum = sum / (n + 29); \
|
||||
sum = restore (sum, n + 29); \
|
||||
sum = sum / (n + 30); \
|
||||
sum = restore (sum, n + 30); \
|
||||
sum = sum / (n + 31); \
|
||||
sum = restore (sum, n + 31); \
|
||||
sum = sum / (n + 32); \
|
||||
sum = restore (sum, n + 32); \
|
||||
sum = sum / (n + 33); \
|
||||
sum = restore (sum, n + 33); \
|
||||
sum = sum / (n + 34); \
|
||||
sum = restore (sum, n + 34); \
|
||||
sum = sum / (n + 35); \
|
||||
sum = restore (sum, n + 35); \
|
||||
sum = sum / (n + 36); \
|
||||
sum = restore (sum, n + 36); \
|
||||
break;
|
||||
|
||||
__attribute__((noinline, noclone)) long long
|
||||
test_and_branch (int selector, int addend)
|
||||
{
|
||||
long long sum = selector + 1;
|
||||
|
||||
if (selector > 64)
|
||||
{
|
||||
start:
|
||||
return sum - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (selector)
|
||||
{
|
||||
CASE_ENTRY (1)
|
||||
CASE_ENTRY (2)
|
||||
CASE_ENTRY (3)
|
||||
CASE_ENTRY (4)
|
||||
CASE_ENTRY (5)
|
||||
CASE_ENTRY (6)
|
||||
CASE_ENTRY (7)
|
||||
CASE_ENTRY (8)
|
||||
CASE_ENTRY (9)
|
||||
CASE_ENTRY (10)
|
||||
CASE_ENTRY (11)
|
||||
CASE_ENTRY (12)
|
||||
CASE_ENTRY (13)
|
||||
CASE_ENTRY (14)
|
||||
CASE_ENTRY (15)
|
||||
CASE_ENTRY (16)
|
||||
CASE_ENTRY (17)
|
||||
CASE_ENTRY (18)
|
||||
CASE_ENTRY (19)
|
||||
CASE_ENTRY (20)
|
||||
CASE_ENTRY (21)
|
||||
CASE_ENTRY (22)
|
||||
CASE_ENTRY (23)
|
||||
CASE_ENTRY (24)
|
||||
CASE_ENTRY (25)
|
||||
CASE_ENTRY (26)
|
||||
CASE_ENTRY (27)
|
||||
CASE_ENTRY (28)
|
||||
CASE_ENTRY (29)
|
||||
CASE_ENTRY (30)
|
||||
CASE_ENTRY (31)
|
||||
CASE_ENTRY (32)
|
||||
CASE_ENTRY (33)
|
||||
CASE_ENTRY (34)
|
||||
CASE_ENTRY (35)
|
||||
CASE_ENTRY (36)
|
||||
CASE_ENTRY (37)
|
||||
CASE_ENTRY (38)
|
||||
CASE_ENTRY (39)
|
||||
CASE_ENTRY (40)
|
||||
CASE_ENTRY (41)
|
||||
CASE_ENTRY (42)
|
||||
CASE_ENTRY (43)
|
||||
CASE_ENTRY (44)
|
||||
CASE_ENTRY (45)
|
||||
CASE_ENTRY (46)
|
||||
CASE_ENTRY (47)
|
||||
CASE_ENTRY (48)
|
||||
CASE_ENTRY (49)
|
||||
CASE_ENTRY (50)
|
||||
CASE_ENTRY (51)
|
||||
CASE_ENTRY (52)
|
||||
CASE_ENTRY (53)
|
||||
CASE_ENTRY (54)
|
||||
CASE_ENTRY (55)
|
||||
CASE_ENTRY (56)
|
||||
CASE_ENTRY (57)
|
||||
CASE_ENTRY (58)
|
||||
CASE_ENTRY (59)
|
||||
CASE_ENTRY (60)
|
||||
CASE_ENTRY (61)
|
||||
CASE_ENTRY (62)
|
||||
CASE_ENTRY (63)
|
||||
CASE_ENTRY (64)
|
||||
}
|
||||
|
||||
do_nothing ((int *)&sum);
|
||||
|
||||
if (sum & 0x40)
|
||||
goto start;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
long long ret = test_and_branch (64, 1);
|
||||
if (ret != 64)
|
||||
abort ();
|
||||
|
||||
ret = test_and_branch (7, 1);
|
||||
if (ret != -1)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user