OSDN Git Service

PR preprocessor/20348
[pf3gnuchains/gcc-fork.git] / gcc / loop-unroll.c
index fd1821c..4cabfd5 100644 (file)
@@ -15,8 +15,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -520,6 +520,7 @@ peel_loop_completely (struct loops *loops, struct loop *loop)
                                          wont_exit, desc->out_edge,
                                          remove_edges, &n_remove_edges,
                                          DLTHE_FLAG_UPDATE_FREQ
+                                         | DLTHE_FLAG_COMPLETTE_PEEL
                                          | (opt_info
                                             ? DLTHE_RECORD_COPY_NUMBER : 0));
       gcc_assert (ok);
@@ -1573,7 +1574,19 @@ analyze_insn_to_expand_var (struct loop *loop, rtx insn)
       && GET_CODE (src) != MINUS
       && GET_CODE (src) != MULT)
     return NULL;
-  
+
+  /* Hmm, this is a bit paradoxical.  We know that INSN is a valid insn
+     in MD.  But if there is no optab to generate the insn, we can not
+     perform the variable expansion.  This can happen if an MD provides
+     an insn but not a named pattern to generate it, for example to avoid
+     producing code that needs additional mode switches like for x87/mmx.
+
+     So we check have_insn_for which looks for an optab for the operation
+     in SRC.  If it doesn't exist, we can't perform the expansion even
+     though INSN is valid.  */
+  if (!have_insn_for (GET_CODE (src), GET_MODE (src)))
+    return NULL;
+
   if (!XEXP (src, 0))
     return NULL;