re PR rtl-optimization/29841 (ICE with scheduling and __builtin_trap)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Thu, 19 Apr 2007 11:19:16 +0000 (13:19 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 19 Apr 2007 11:19:16 +0000 (11:19 +0000)
PR rtl-optimization/29841
* cfgbuild.c (control_flow_insn_p): Return TRUE for unconditional
trap instructions.
* sched-deps.c (sched_analyze_insn): Prevent all non-jump instructions
that may cause control flow transfer from being moved.

From-SVN: r123970

gcc/ChangeLog
gcc/cfgbuild.c
gcc/sched-deps.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/invalid-call-1.c [new file with mode: 0644]

index 2e2fad3..4444365 100644 (file)
@@ -1,3 +1,11 @@
+2007-04-19  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR rtl-optimization/29841
+       * cfgbuild.c (control_flow_insn_p): Return TRUE for unconditional
+       trap instructions.
+       * sched-deps.c (sched_analyze_insn): Prevent all non-jump instructions
+       that may cause control flow transfer from being moved.
+
 2007-04-18  Jan Hubicka  <jh@suse.cz>
 
        * fold-const.c (div_if_zero_remainder): Do signed divide for pointer
index 3d05ebc..642efc3 100644 (file)
@@ -120,6 +120,11 @@ control_flow_insn_p (rtx insn)
              || can_throw_internal (insn));
 
     case INSN:
+      /* Treat trap instructions like noreturn calls (same provision).  */
+      if (GET_CODE (PATTERN (insn)) == TRAP_IF
+         && XEXP (PATTERN (insn), 0) == const1_rtx)
+       return true;
+
       return (flag_non_call_exceptions && can_throw_internal (insn));
 
     case BARRIER:
index c3dc579..5a6a30a 100644 (file)
@@ -1598,8 +1598,12 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn)
 
   /* If this instruction can throw an exception, then moving it changes
      where block boundaries fall.  This is mighty confusing elsewhere.
-     Therefore, prevent such an instruction from being moved.  */
-  if (can_throw_internal (insn))
+     Therefore, prevent such an instruction from being moved.  Same for
+     non-jump instructions that define block boundaries.
+     ??? Unclear whether this is still necessary in EBB mode.  If not,
+     add_branch_dependences should be adjusted for RGN mode instead.  */
+  if (((CALL_P (insn) || JUMP_P (insn)) && can_throw_internal (insn))
+      || (NONJUMP_INSN_P (insn) && control_flow_insn_p (insn)))
     reg_pending_barrier = MOVE_BARRIER;
 
   /* Add dependencies if a scheduling barrier was found.  */
index 06c53cf..501825d 100644 (file)
@@ -1,3 +1,7 @@
+2007-04-19  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/invalid-call-1.c: New test.
+
 2007-04-18  Dirk Mueller  <dmueller@suse.de>
 
        PR diagnostic/31227
diff --git a/gcc/testsuite/gcc.dg/invalid-call-1.c b/gcc/testsuite/gcc.dg/invalid-call-1.c
new file mode 100644 (file)
index 0000000..7474227
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR rtl-optimization/29841 */
+/* Testcase by Khem Raj <raj.khem@gmail.com> */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mtune=i586" { target i?86-*-* } } */
+
+typedef void (*fp)(void);
+extern char* bar(void* a1, int a2);
+extern char* mar(int n);
+char* cptr;
+
+void foo()
+{
+  cptr = mar(6);
+  ((char *(*)(void *,int (*)(void *,unsigned char **),char**))((fp)bar))(0,0,(void*)(0)); /* { dg-warning "" "non-compatible type" } */
+}