From: Georg-Johann Lay Date: Tue, 25 Oct 2016 08:26:59 +0000 (+0000) Subject: re PR target/71676 ([avr] casesi won't handle switch values larger than 16 bits) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c7212a155c2f3fdf585f7693159aa4d932d9a585;p=gcc.git re PR target/71676 ([avr] casesi won't handle switch values larger than 16 bits) gcc/ PR target/71676 PR target/71678 * config/avr/avr.md (casesi): Rewrite avoiding subregs of SI. gcc/testsuite/ PR target/71676 PR target/71678 * gcc.target/avr/pr71676-1.c: New test. * gcc.target/avr/pr71676-3.c: New test. * gcc.target/avr/pr71676.c: New test. * gcc.target/avr/pr71678.c: New test. Co-Authored-By: Pitchumani Sivanupandi From-SVN: r241503 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 88bace4ea16..183efac1744 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-10-25 Georg-Johann Lay + Pitchumani Sivanupandi + + PR target/71676 + PR target/71678 + * config/avr/avr.md (casesi): Rewrite avoiding subregs of SI. + 2016-10-24 Jakub Jelinek * dwarf2out.c (gen_subprogram_die): Add DW_AT_reference or diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 97f35616d1f..446ee402d79 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -5154,45 +5154,46 @@ (define_expand "casesi" - [(parallel [(set (match_dup 6) - (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0) - (match_operand:HI 1 "register_operand" ""))) + [(parallel [(set (match_dup 5) + (plus:SI (match_operand:SI 0 "register_operand") + (match_operand:SI 1 "const_int_operand"))) (clobber (scratch:QI))]) (parallel [(set (cc0) - (compare (match_dup 6) - (match_operand:HI 2 "register_operand" ""))) - (clobber (match_scratch:QI 9 ""))]) + (compare (match_dup 5) + (match_operand:SI 2 "const_int_operand"))) + (clobber (scratch:QI))]) (set (pc) (if_then_else (gtu (cc0) (const_int 0)) - (label_ref (match_operand 4 "" "")) + (label_ref (match_operand 4)) (pc))) - (set (match_dup 10) - (match_dup 7)) + (set (match_dup 7) + (match_dup 6)) (parallel [(set (pc) - (unspec:HI [(match_dup 10)] UNSPEC_INDEX_JMP)) + (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP)) (use (label_ref (match_dup 3))) - (clobber (match_dup 10)) + (clobber (match_dup 7)) (clobber (match_dup 8))])] "" { - operands[6] = gen_reg_rtx (HImode); + operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode); + operands[5] = gen_reg_rtx (SImode); + operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0); if (AVR_HAVE_EIJMP_EICALL) { - operands[7] = operands[6]; + operands[7] = gen_rtx_REG (HImode, REG_Z); operands[8] = all_regs_rtx[24]; - operands[10] = gen_rtx_REG (HImode, REG_Z); } else { - operands[7] = gen_rtx_PLUS (HImode, operands[6], + operands[6] = gen_rtx_PLUS (HImode, operands[6], gen_rtx_LABEL_REF (VOIDmode, operands[3])); + operands[7] = gen_reg_rtx (HImode); operands[8] = const0_rtx; - operands[10] = operands[6]; } }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e5497e41cfe..07cc777723f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2016-10-25 Georg-Johann Lay + Pitchumani Sivanupandi + + PR target/71676 + PR target/71678 + * gcc.target/avr/pr71676-1.c: New test. + * gcc.target/avr/pr71676-3.c: New test. + * gcc.target/avr/pr71676.c: New test. + * gcc.target/avr/pr71678.c: New test. + 2016-10-24 Kugan Vivekanandarajah * gcc.target/aarch64/test_frame_common.h: Add noclone attribute diff --git a/gcc/testsuite/gcc.target/avr/pr71676-1.c b/gcc/testsuite/gcc.target/avr/pr71676-1.c new file mode 100644 index 00000000000..0d41a600905 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71676-1.c @@ -0,0 +1,347 @@ +/* { dg-do run } */ +/* { dg-options "-Os -Wno-overflow -fno-tree-switch-conversion" } */ + +#include "exit-abort.h" +volatile unsigned char y; + +unsigned char __attribute__((noinline,noclone)) +foo1 (char x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo2 (char x) +{ + switch (x) + { + case 0x01: y = 7; break; + case 0x02: y = 4; break; + case 0x03: y = 8; break; + case 0x04: y = 21; break; + case 0x05: y = 65; break; + case 0x06: y = 27; break; + case 0x07: y = 72; break; + case 0x08: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo3 (char x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo4 (char x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo5 (int x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo6 (int x) +{ + switch (x) + { + case 0x101: y = 7; break; + case 0x102: y = 4; break; + case 0x103: y = 8; break; + case 0x104: y = 21; break; + case 0x105: y = 65; break; + case 0x106: y = 27; break; + case 0x107: y = 72; break; + case 0x108: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo7 (int x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo8 (int x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo9 (long x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo10 (unsigned long x) +{ + switch (x) + { + case 0x100: y = 39; break; + case 0x101: y = 7; break; + case 0x102: y = 4; break; + case 0x103: y = 8; break; + case 0x104: y = 21; break; + case 0x105: y = 65; break; + case 0x106: y = 27; break; + case 0x107: y = 72; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo11 (long x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo12 (long x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo13 (long long x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo14 (long long x) +{ + switch (x) + { + case 0x101: y = 7; break; + case 0x102: y = 4; break; + case 0x103: y = 8; break; + case 0x104: y = 21; break; + case 0x105: y = 65; break; + case 0x106: y = 27; break; + case 0x107: y = 72; break; + case 0x108: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline,noclone)) +foo15 (long long x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + + +unsigned char __attribute__((noinline,noclone)) +foo16 (long long x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +int main () +{ + if (foo1 (0x13) != 8) + abort(); + + if (foo2 (0x06) != 27) + abort(); + + if (foo3 (0x02) != 4) + abort(); + + if (foo4 (0x01) != 7) + abort(); + + if (foo5 (0x15) != 65) + abort(); + + if (foo6 (0x103) != 8) + abort(); + + if (foo7 (0x04) != 21) + abort(); + + if (foo8 (0x07) != 72) + abort(); + + if (foo9 (0x10000011L) != 0) + abort(); + + if (foo10 (0x1000105L) != 0) + abort(); + + if (foo11 (0x1000008L) != 39) + abort(); + + if (foo12 (0x1000004L) != 0) + abort(); + + if (foo13 (0x109LL) != 0) + abort(); + + if (foo14 (0x108LL) != 39) + abort(); + + if (foo15 (0x1000001LL) != 7) + abort(); + + if (foo16 (0x100000004LL) != 21) + abort(); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/pr71676-3.c b/gcc/testsuite/gcc.target/avr/pr71676-3.c new file mode 100644 index 00000000000..6c10f04b964 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71676-3.c @@ -0,0 +1,80 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion" } */ + +#define MK_FUN(NAME, TYP, V) \ + static __inline__ __attribute__((always_inline)) \ + unsigned char value_## NAME (TYP x, unsigned char y) \ + { \ + switch (x) \ + { \ + case V + 0: return 0 + y; \ + case V + 1: return 1; \ + case V + 2: return 2 + y; \ + case V + 3: return 3; \ + case V + 4: return 4 + y; \ + case V + 5: return 5; \ + case V + 6: return 6 + y; \ + case V + 7: return 7; \ + case V + 8: return 8 + y; \ + case V + 9: return 9; \ + case V + 10: return 10 + y; \ + case V + 11: return 11; \ + case V + 12: return 12 + y; \ + case V + 13: return 13; \ + case V + 14: return 14 + y; \ + case V + 15: return 15; \ + } \ + return x; \ + } \ + \ + __attribute__((noinline,noclone)) \ + unsigned char select_## NAME (TYP x, unsigned char y) \ + { \ + return value_## NAME (x, y); \ + } \ + \ + static __inline__ __attribute__((always_inline)) \ + void test1_## NAME (TYP x) \ + { \ + if (select_## NAME (x, 0) != value_## NAME (x, 0)) \ + __builtin_abort(); \ + } \ + \ + void test_## NAME (void) \ + { \ + test1_## NAME (V); \ + test1_## NAME (V - 1); \ + test1_## NAME (V + 15); \ + test1_## NAME (V + 16); \ + } + +MK_FUN (0_s8, signed char, 0) +MK_FUN (0_u8, unsigned char, 0) +MK_FUN (0_s16, signed int, 0) +MK_FUN (0_u16, unsigned int, 0) + +MK_FUN (m4_s8, signed char, -4) +MK_FUN (m4_s16, signed int, -4) + +MK_FUN (4_s8, signed char, 4) +MK_FUN (4_u8, unsigned char, 4) +MK_FUN (4_s16, signed int, 4) +MK_FUN (4_u16, unsigned int, 4) + +int main (void) +{ + test_0_s8(); + test_0_u8(); + test_0_s16(); + test_0_u16(); + + test_m4_s8(); + test_m4_s16(); + + test_4_s8(); + test_4_u8(); + test_4_s16(); + test_4_u16(); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/pr71676.c b/gcc/testsuite/gcc.target/avr/pr71676.c new file mode 100644 index 00000000000..7737c1e5390 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71676.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-tree-switch-conversion" } */ + +#include "exit-abort.h" + +volatile unsigned char y; + +__attribute__((noinline,noclone)) +unsigned char foo (unsigned long x) +{ + switch (x) + { + case 0: y = 67; break; + case 1: y = 20; break; + case 2: y = 109; break; + case 3: y = 33; break; + case 4: y = 44; break; + case 5: y = 37; break; + case 6: y = 10; break; + case 7: y = 98; break; + } + return y; +} + +int main (void) +{ + if (0 != foo (7L + 0x10000L)) + abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/pr71678.c b/gcc/testsuite/gcc.target/avr/pr71678.c new file mode 100644 index 00000000000..160810f80b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71678.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fno-tree-switch-conversion" } */ + +unsigned char foo (long long x) +{ + unsigned char y = 0; + switch (x) + { + case 0: y = 67; break; + case 1: y = 20; break; + case 2: y = 109; break; + case 3: y = 33; break; + case 4: y = 44; break; + case 5: y = 37; break; + case 6: y = 10; break; + case 7: y = 11; break; + } + return y; +}