re PR middle-end/47968 (ICE: in gen_lowpart_general, at rtlhooks.c:51 when converting...
[gcc.git] / gcc / expmed.c
index 7ff55e7bafd3b75d7a0005356fcef5b48ae7dff5..b0c1e235dd7e80391bcfe27a0be6a176fc50f4fe 100644 (file)
@@ -1,7 +1,8 @@
 /* Medium-level subroutines: convert bit-field store and extract
    and shifts, multiplies and divides to rtl instructions.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -26,7 +27,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "rtl.h"
 #include "tree.h"
 #include "tm_p.h"
@@ -1205,7 +1205,6 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       && GET_MODE_INNER (GET_MODE (op0)) != tmode)
     {
       enum machine_mode new_mode;
-      int nunits = GET_MODE_NUNITS (GET_MODE (op0));
 
       if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
        new_mode = MIN_MODE_VECTOR_FLOAT;
@@ -1221,8 +1220,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
        new_mode = MIN_MODE_VECTOR_INT;
 
       for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode))
-       if (GET_MODE_NUNITS (new_mode) == nunits
-           && GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0))
+       if (GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0))
            && targetm.vector_mode_supported_p (new_mode))
          break;
       if (new_mode != VOIDmode)
@@ -1800,11 +1798,11 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
                {
                  informed_about_misalignment = true;
                  inform (input_location,
-                         "When a volatile object spans multiple type-sized locations,"
+                         "when a volatile object spans multiple type-sized locations,"
                          " the compiler must choose between using a single mis-aligned access to"
                          " preserve the volatility, or using multiple aligned accesses to avoid"
-                         " runtime faults.  This code may fail at runtime if the hardware does"
-                         " not allow this access.");
+                         " runtime faults; this code may fail at runtime if the hardware does"
+                         " not allow this access");
                }
            }
        }
@@ -3189,12 +3187,17 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
                      int unsignedp, optab this_optab)
 {
   bool speed = optimize_insn_for_speed_p ();
+  rtx cop1;
 
   if (CONST_INT_P (op1)
-      && (INTVAL (op1) >= 0
+      && GET_MODE (op0) != VOIDmode
+      && (cop1 = convert_modes (mode, GET_MODE (op0), op1,
+                               this_optab == umul_widen_optab))
+      && CONST_INT_P (cop1)
+      && (INTVAL (cop1) >= 0
          || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
     {
-      HOST_WIDE_INT coeff = INTVAL (op1);
+      HOST_WIDE_INT coeff = INTVAL (cop1);
       int max_cost;
       enum mult_variant variant;
       struct algorithm algorithm;