This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: RFC: PR 19650
- From: Roger Sayle <roger at eyesopen dot com>
- To: Dale Johannesen <dalej at apple dot com>
- Cc: gcc mailing list <gcc at gcc dot gnu dot org>
- Date: Fri, 28 Jan 2005 13:05:14 -0700 (MST)
- Subject: Re: RFC: PR 19650
On Fri, 28 Jan 2005, Dale Johannesen wrote:
> fold is presented with the following:
>
> <ne_expr 0x4267e4e0
> type <integer_type 0x4260b680 int public SI
> arg 0 <cond_expr 0x4267e4b0
> type <integer_type 0x4260b700 unsigned int public unsigned SI
> arg 0 <le_expr 0x4267e450 type <integer_type 0x4260b680 int>
> arg 0 <var_decl 0x42680880 i>
> arg 1 <integer_cst 0x42684000 constant invariant 3>>
> arg 1 <plus_expr 0x4267e480 type <integer_type 0x4260b700
> unsigned int>
> arg 0 <var_decl 0x42680880 i>
> arg 1 <integer_cst 0x42684000 3>>
> arg 2 <integer_cst 0x42606640 constant invariant 4294967295>>
> arg 1 <integer_cst 0x42606640 4294967295>>
>
> and the transformation above changes 4294967295 to -1, which compares
> as != 429467295.
> Now what? Perhaps the transformation should not be applied in the
> COND_EXPR case?
Hmm. So there are three types we care about: the type of the result,
the type of CODE's original operands, and the type's of the stripped
operands (TREE_TYPE (cond) and TREE_TYPE (arg)).
I think the best route out of this hole is to pass an additional
"tree arg_type" parameter to the fold_binary_op_with_conditional_arg
function. At both call sites in fold, this is simply the value
"TREE_TYPE (TREE_OPERAND (t, 0))", i.e. the unstripped type of the
first operand. Then inside the function itself we cast "arg",
"true_value" and "false_value" to this "arg_type", before using them
as operands to build a tree with code CODE and result type TYPE.
+ arg = fold_convert (arg_type, arg);
if (lhs == 0)
+ {
+ true_value = fold_convert (arg_type, true_value);
lhs = fold (cond_first_p ? build2 (code, type, true_value, arg)
: build2 (code, type, arg, true_value));
}
if (rhs == 0)
+ {
+ false_value = fold_convert (arg_type, false_value);
rhs = fold (cond_first_p ? build2 (code, type, false_value, arg)
: build2 (code, type, arg, false_value));
+ }
Does this make any sense? Thanks for your persistence. This quirk
might explain why Andrew never followed up on his attempt to solve
this problem.
Roger
--