------- Comment #6 from rguenth at gcc dot gnu dot org  2007-10-27 17:29 -------
"This goes wrong in extract_muldiv..."

sorry for not pasting my complete analysis (actually the testcase is carefuly
crafted from looking at this code ;)).  The recursion through conversions

    case CONVERT_EXPR:  case NON_LVALUE_EXPR:  case NOP_EXPR:
      /* If op0 is an expression ...  */
      if ((COMPARISON_CLASS_P (op0)
           || UNARY_CLASS_P (op0)
           || BINARY_CLASS_P (op0)
           || VL_EXP_CLASS_P (op0)
           || EXPRESSION_CLASS_P (op0))
          /* ... and is unsigned, and its type is smaller than ctype,
             then we cannot pass through as widening.  */
          && ((TYPE_UNSIGNED (TREE_TYPE (op0))
               && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
                     && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
               && (GET_MODE_SIZE (TYPE_MODE (ctype))
                   > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
              /* ... or this is a truncation (t is narrower than op0),
                 then we cannot pass through this narrowing.  */
              || (GET_MODE_SIZE (TYPE_MODE (type))
                  < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
              /* ... or signedness changes for division or modulus,
                 then we cannot pass through this conversion.  */
              || (code != MULT_EXPR
                  && (TYPE_UNSIGNED (ctype)
                      != TYPE_UNSIGNED (TREE_TYPE (op0))))))
        break;

      /* Pass the constant down and see if we can make a simplification.  If
         we can, replace this expression with the inner simplification for
         possible later conversion to our or some other type.  */
      if ((t2 = fold_convert (TREE_TYPE (op0), c)) != 0
          && TREE_CODE (t2) == INTEGER_CST
          && !TREE_OVERFLOW (t2)
          && (0 != (t1 = extract_muldiv (op0, t2, code,
                                         code == MULT_EXPR
                                         ? ctype : NULL_TREE,
                                         strict_overflow_p))))
        return t1;
      break;

is wrong as it might convert the transformation from one in unsigned type
to one in signed type.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33779

Reply via email to