Commit 125e025e by Richard Guenther Committed by Richard Biener

re PR tree-optimization/34651 (ICE in set_value_range, at tree-vrp.c:321)

2008-01-10  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/34651
	* tree-sra.c (sra_build_assignment): Sanitize.  Use the correct
	types and ordering for masking and converting.

	* g++.dg/torture/pr34651.C: New testcase.

From-SVN: r131442
parent 5817ff8e
2008-01-10 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34651
* tree-sra.c (sra_build_assignment): Sanitize. Use the correct
types and ordering for masking and converting.
2008-01-09 Sebastian Pop <sebastian.pop@amd.com> 2008-01-09 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/34017 PR tree-optimization/34017
2008-01-10 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34651
* g++.dg/torture/pr34651.C: New testcase.
2008-01-09 Sebastian Pop <sebastian.pop@amd.com> 2008-01-09 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/34017 PR tree-optimization/34017
/* { dg-do compile } */
typedef bool Bool;
struct CString {
CString (const char * =__null);
CString & operator += (const CString &);
};
struct THotKey {
short Key;
Bool Control;
Bool Shift;
Bool Alt;
};
THotKey m_HotKey;
THotKey GetHotKey () { return m_HotKey; }
void Serialize ()
{
THotKey inHotKey (GetHotKey());
CString outCombinaison (inHotKey.Control
? ((inHotKey.Alt || inHotKey.Shift)
? "ctrl+" : "ctrl")
: __null);
outCombinaison += inHotKey.Alt ? inHotKey.Shift ? "alt+" : "alt" : "";
outCombinaison += inHotKey.Shift ? "shift" : "";
}
...@@ -2127,30 +2127,37 @@ static tree ...@@ -2127,30 +2127,37 @@ static tree
sra_build_assignment (tree dst, tree src) sra_build_assignment (tree dst, tree src)
{ {
/* Turning BIT_FIELD_REFs into bit operations enables other passes /* Turning BIT_FIELD_REFs into bit operations enables other passes
to do a much better job at optimizing the code. */ to do a much better job at optimizing the code.
From dst = BIT_FIELD_REF <var, sz, off> we produce
SR.1 = (scalar type) var;
SR.2 = SR.1 >> off;
SR.3 = SR.2 & ((1 << sz) - 1);
... possible sign extension of SR.3 ...
dst = (destination type) SR.3;
*/
if (scalar_bitfield_p (src)) if (scalar_bitfield_p (src))
{ {
tree cst, cst2, mask, minshift, maxshift; tree var, shift, width;
tree tmp, var, utype, stype; tree utype, stype, stmp, utmp;
tree list, stmt; tree list, stmt;
bool unsignedp = BIT_FIELD_REF_UNSIGNED (src); bool unsignedp = BIT_FIELD_REF_UNSIGNED (src);
var = TREE_OPERAND (src, 0); var = TREE_OPERAND (src, 0);
cst = TREE_OPERAND (src, 2); width = TREE_OPERAND (src, 1);
cst2 = size_binop (PLUS_EXPR, TREE_OPERAND (src, 1), /* The offset needs to be adjusted to a right shift quantity
TREE_OPERAND (src, 2)); depending on the endianess. */
if (BYTES_BIG_ENDIAN) if (BYTES_BIG_ENDIAN)
{ {
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst); tree tmp = size_binop (PLUS_EXPR, width, TREE_OPERAND (src, 2));
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2); shift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), tmp);
} }
else else
{ shift = TREE_OPERAND (src, 2);
maxshift = cst2;
minshift = cst;
}
/* In weird cases we have non-integral types for the source or
destination object.
??? For unknown reasons we also want an unsigned scalar type. */
stype = TREE_TYPE (var); stype = TREE_TYPE (var);
if (!INTEGRAL_TYPE_P (stype)) if (!INTEGRAL_TYPE_P (stype))
stype = lang_hooks.types.type_for_size (TREE_INT_CST_LOW stype = lang_hooks.types.type_for_size (TREE_INT_CST_LOW
...@@ -2166,117 +2173,92 @@ sra_build_assignment (tree dst, tree src) ...@@ -2166,117 +2173,92 @@ sra_build_assignment (tree dst, tree src)
utype = unsigned_type_for (utype); utype = unsigned_type_for (utype);
list = NULL; list = NULL;
stmp = make_rename_temp (stype, "SR");
cst2 = size_binop (MINUS_EXPR, maxshift, minshift); /* Convert the base var of the BIT_FIELD_REF to the scalar type
if (TREE_INT_CST_LOW (cst2) == TYPE_PRECISION (utype)) we use for computation if we cannot use it directly. */
{ if (!useless_type_conversion_p (stype, TREE_TYPE (var)))
unsignedp = true;
mask = NULL_TREE;
}
else
{
mask = build_int_cst_wide (utype, 1, 0);
cst = int_const_binop (LSHIFT_EXPR, mask, cst2, true);
mask = int_const_binop (MINUS_EXPR, cst, mask, true);
}
tmp = make_rename_temp (stype, "SR");
if (TYPE_MAIN_VARIANT (TREE_TYPE (var)) != TYPE_MAIN_VARIANT (stype))
{ {
if (INTEGRAL_TYPE_P (TREE_TYPE (var))) if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
stmt = build_gimple_modify_stmt (tmp, stmt = build_gimple_modify_stmt (stmp,
fold_convert (stype, var)); fold_convert (stype, var));
else else
stmt = build_gimple_modify_stmt (tmp, stmt = build_gimple_modify_stmt (stmp,
fold_build1 (VIEW_CONVERT_EXPR, fold_build1 (VIEW_CONVERT_EXPR,
stype, var)); stype, var));
append_to_statement_list (stmt, &list); append_to_statement_list (stmt, &list);
var = stmp;
var = tmp;
} }
if (!integer_zerop (minshift)) if (!integer_zerop (shift))
{ {
tmp = make_rename_temp (stype, "SR"); stmt = build_gimple_modify_stmt (stmp,
stmt = build_gimple_modify_stmt (tmp,
fold_build2 (RSHIFT_EXPR, stype, fold_build2 (RSHIFT_EXPR, stype,
var, minshift)); var, shift));
append_to_statement_list (stmt, &list); append_to_statement_list (stmt, &list);
var = stmp;
var = tmp;
} }
if (TYPE_MAIN_VARIANT (utype) != TYPE_MAIN_VARIANT (stype)) /* If we need a masking operation, produce one. */
if (TREE_INT_CST_LOW (width) == TYPE_PRECISION (stype))
unsignedp = true;
else
{ {
if (!mask && unsignedp tree one = build_int_cst_wide (stype, 1, 0);
&& (TYPE_MAIN_VARIANT (utype) tree mask = int_const_binop (LSHIFT_EXPR, one, width, 0);
== TYPE_MAIN_VARIANT (TREE_TYPE (dst)))) mask = int_const_binop (MINUS_EXPR, mask, one, 0);
tmp = dst;
else
tmp = make_rename_temp (utype, "SR");
stmt = build_gimple_modify_stmt (tmp, fold_convert (utype, var)); stmt = build_gimple_modify_stmt (stmp,
fold_build2 (BIT_AND_EXPR, stype,
var, mask));
append_to_statement_list (stmt, &list); append_to_statement_list (stmt, &list);
var = stmp;
var = tmp;
} }
if (mask) /* After shifting and masking, convert to the target type. */
utmp = stmp;
if (!useless_type_conversion_p (utype, stype))
{ {
if (!unsignedp utmp = make_rename_temp (utype, "SR");
|| (TYPE_MAIN_VARIANT (TREE_TYPE (dst))
!= TYPE_MAIN_VARIANT (utype)))
tmp = make_rename_temp (utype, "SR");
else
tmp = dst;
stmt = build_gimple_modify_stmt (tmp, stmt = build_gimple_modify_stmt (utmp, fold_convert (utype, var));
fold_build2 (BIT_AND_EXPR, utype,
var, mask));
append_to_statement_list (stmt, &list); append_to_statement_list (stmt, &list);
var = tmp; var = utmp;
} }
/* Perform sign extension, if required.
??? This should never be necessary. */
if (!unsignedp) if (!unsignedp)
{ {
tree signbit = int_const_binop (LSHIFT_EXPR, tree signbit = int_const_binop (LSHIFT_EXPR,
build_int_cst_wide (utype, 1, 0), build_int_cst_wide (utype, 1, 0),
size_binop (MINUS_EXPR, cst2, size_binop (MINUS_EXPR, width,
bitsize_int (1)), bitsize_int (1)), 0);
true);
tmp = make_rename_temp (utype, "SR"); stmt = build_gimple_modify_stmt (utmp,
stmt = build_gimple_modify_stmt (tmp,
fold_build2 (BIT_XOR_EXPR, utype, fold_build2 (BIT_XOR_EXPR, utype,
var, signbit)); var, signbit));
append_to_statement_list (stmt, &list); append_to_statement_list (stmt, &list);
var = tmp; stmt = build_gimple_modify_stmt (utmp,
if (TYPE_MAIN_VARIANT (TREE_TYPE (dst)) != TYPE_MAIN_VARIANT (utype))
tmp = make_rename_temp (utype, "SR");
else
tmp = dst;
stmt = build_gimple_modify_stmt (tmp,
fold_build2 (MINUS_EXPR, utype, fold_build2 (MINUS_EXPR, utype,
var, signbit)); utmp, signbit));
append_to_statement_list (stmt, &list); append_to_statement_list (stmt, &list);
var = tmp; var = utmp;
} }
if (var != dst) /* Finally, move and convert to the destination. */
if (!useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (var)))
{ {
if (INTEGRAL_TYPE_P (TREE_TYPE (dst))) if (INTEGRAL_TYPE_P (TREE_TYPE (dst)))
var = fold_convert (TREE_TYPE (dst), var); var = fold_convert (TREE_TYPE (dst), var);
else else
var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var); var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var);
stmt = build_gimple_modify_stmt (dst, var);
append_to_statement_list (stmt, &list);
} }
stmt = build_gimple_modify_stmt (dst, var);
append_to_statement_list (stmt, &list);
return list; return list;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment