SuperH: Handle removal of casesi_jump_2
NIIBE Yutaka
gniibe@m17n.org
Fri Nov 9 09:19:00 GMT 2001
There's a case where switch statement will be optimized out.
We need to handle this case.
Here's a patch and a testcase. Bootstrapped (natively) and tested (no
regression) for sh4-linux.
gcc/ChangeLog
2001-11-09 NIIBE Yutaka <gniibe@m17n.org>
* config/sh/sh.c (fixup_addr_diff_vecs): Handle the case we don't
find matching casesi_jump_2. Delete ADDR_DIFF_VEC in such a case.
Index: gcc/config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.123
diff -c -3 -p -r1.123 sh.c
*** gcc/config/sh/sh.c 2001/11/04 02:40:39 1.123
--- gcc/config/sh/sh.c 2001/11/09 17:05:26
*************** fixup_addr_diff_vecs (first)
*** 2862,2868 ****
vec_lab = XEXP (XEXP (pat, 0), 0);
/* Search the matching casesi_jump_2. */
! for (prev = vec_lab; ; prev = PREV_INSN (prev))
{
if (GET_CODE (prev) != JUMP_INSN)
continue;
--- 2862,2868 ----
vec_lab = XEXP (XEXP (pat, 0), 0);
/* Search the matching casesi_jump_2. */
! for (prev = vec_lab; prev; prev = PREV_INSN (prev))
{
if (GET_CODE (prev) != JUMP_INSN)
continue;
*************** fixup_addr_diff_vecs (first)
*** 2875,2880 ****
--- 2875,2886 ----
x = XEXP (x, 0);
if (GET_CODE (x) == LABEL_REF && XEXP (x, 0) == vec_lab)
break;
+ }
+
+ if (prev == NULL)
+ { /* Switch statement has been optimized out. */
+ delete_insn (insn);
+ continue;
}
/* Emit the reference label of the braf where it belongs, right after
-------------------
gcc/testsuite/ChangeLog
2001-11-09 NIIBE Yutaka <gniibe@m17n.org>
* gcc.c-torture/compile/20011109-1.c: New test.
*** /dev/null Fri Nov 9 23:59:11 2001
--- gcc/testsuite/gcc.c-torture/compile/20011109-1.c Sat Nov 10 01:45:11 2001
***************
*** 0 ****
--- 1,44 ----
+ /* Copyright (C) 2001 Free Software Foundation. */
+
+ /* This function can be optimized to just return func2(x), regardless
+ of the value of X. Corresponding addr_diff_vec should be deleted,
+ or else, it may result segmentation fault in fixup_addr_diff_vecs
+ (in case of SuperH) or shorten_branches. */
+
+ extern char *func2(int);
+
+ char *
+ func(int x)
+ {
+ char *mode;
+ switch (x) {
+ case 1:
+ mode = func2(x);
+ x += 2;
+ break;
+ case 2:
+ mode = func2(x);
+ x += 3;
+ break;
+ case 3:
+ mode = func2(x);
+ x += 4;
+ break;
+ case 4:
+ mode = func2(x);
+ x += 5;
+ break;
+ case 5:
+ mode = func2(x);
+ x += 6;
+ break;
+ case 6:
+ mode = func2(x);
+ x += 7;
+ break;
+ default:
+ mode = func2(x);
+ break;
+ }
+ return mode;
+ }
-------------------
--
More information about the Gcc-patches
mailing list