diff mbox

[RFC] PR 58542: const_int vs lost modes

Message ID 52686543.1000506@redhat.com
State New
Headers show

Commit Message

Richard Henderson Oct. 24, 2013, 12:09 a.m. UTC
In this pr, we have a -1 in type __int128.  Since this value can be
represented in a HOST_WIDE_INT, we expand this to a const_int.

The expansion from tree to rtl happens in expand_builtin_atomic_store.  And as
with most of our builtins, we then pass off the rtl to another routine for
expansion.  When we fill in the blanks of the expand_operand in
expand_atomic_compare_and_swap, we've forgotten that the const_int is of
TImode.  Then convert_modes attempts to zero-extend what it assumes is a
narrower mode and we get corrupt data.

For a bit I thought that the bug was in convert_modes, but honestly any
change I make there merely moves the bug around.  The biggest problem is
that we've lost the mode.

Given that we lose the mode through any of 10 stack frames, I believe it
to be implausible to adjust all of the call frames in optabs.c.  The real
bug is that const_int doesn't carry a mode.

The most isolated patch I can come up with, especially since we ought to
fix this in 4.8 branch as well, is to only allow expansion of wide int
modes to const_int when they're positive.

Thoughts?


r~
PR rtl/58542
	* emit-rtl.c (immed_double_const): Use const_double for negative
	numbers of very wide modes.

Comments

Eric Botcazou Oct. 24, 2013, 8:43 a.m. UTC | #1
> The most isolated patch I can come up with, especially since we ought to
> fix this in 4.8 branch as well, is to only allow expansion of wide int
> modes to const_int when they're positive.
> 
> Thoughts?

That's a fairly dangerous hack in my opinion, in particular this breaks the 
uniqueness of representation of -1 as constm1_rtx.  Can't we find a really 
contained hack instead, especially if we want to backport it to 4.8?
Richard Biener Oct. 24, 2013, 10 a.m. UTC | #2
On Thu, Oct 24, 2013 at 10:43 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> The most isolated patch I can come up with, especially since we ought to
>> fix this in 4.8 branch as well, is to only allow expansion of wide int
>> modes to const_int when they're positive.
>>
>> Thoughts?
>
> That's a fairly dangerous hack in my opinion, in particular this breaks the
> uniqueness of representation of -1 as constm1_rtx.  Can't we find a really
> contained hack instead, especially if we want to backport it to 4.8?

Pass the mode through all 10 stackframes is the only good fix given
recent activity on modes vs. const_int.

Richard.

> --
> Eric Botcazou
Eric Botcazou Oct. 24, 2013, 11:19 a.m. UTC | #3
> That's a fairly dangerous hack in my opinion, in particular this breaks the
> uniqueness of representation of -1 as constm1_rtx.  Can't we find a really
> contained hack instead, especially if we want to backport it to 4.8?

In particular, can't Uros' patch be considered as such here?  Frankly, the 
choice of 'true' vs 'false' for create_convert_operand_to in optabs isn't 
crystal clear...
Richard Sandiford Oct. 24, 2013, 12:02 p.m. UTC | #4
Eric Botcazou <ebotcazou@adacore.com> writes:
>> That's a fairly dangerous hack in my opinion, in particular this breaks the
>> uniqueness of representation of -1 as constm1_rtx.  Can't we find a really
>> contained hack instead, especially if we want to backport it to 4.8?
>
> In particular, can't Uros' patch be considered as such here?  Frankly, the 
> choice of 'true' vs 'false' for create_convert_operand_to in optabs isn't 
> crystal clear...

Do we actually need to do a conversion here at all?  It looks like the
modes of "expected" and "desired" should already match "mem", so we could
just use create_input_operand.

Thanks,
Richard
diff mbox

Patch

diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index b0fc846..d055f56 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -545,7 +545,10 @@  immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode)
     }
 
   /* If this integer fits in one word, return a CONST_INT.  */
-  if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
+  /* ??? On occasion we lose track of the original mode, and a CONST_INT gets
+     interpreted incorrectly for modes larger than HOST_BITS_PER_WIDE_INT.
+     If we only use CONST_INT for positive values, we work around that.  */
+  if (i1 == 0 && i0 >= 0)
     return GEN_INT (i0);
 
   /* We use VOIDmode for integers.  */