structure offset to structure name conversion.

2011-10-27 Thread James Courtier-Dutton
Hi,

If I have a structure e.g.
struct test_s {
int32_t var1;
int32_t var2;
uint64_t var3;
int var4;
} test;

If I have an offset value of 8, I wish to do a lookup and get to:
test.var3

Is there some part of gcc that I could use to parse .h files and
produce a table for me of offset against each variable in the
structure to permit this sort of lookup?

Kind Regards

James


Re: Memory corruption due to word sharing

2012-02-02 Thread James Courtier-Dutton
On 1 February 2012 15:19, Jan Kara  wrote:
>  Hello,
>
>  we've spotted the following mismatch between what kernel folks expect
> from a compiler and what GCC really does, resulting in memory corruption on
> some architectures. Consider the following structure:
> struct x {
>    long a;
>    unsigned int b1;
>    unsigned int b2:1;
> };
>
> We have two processes P1 and P2 where P1 updates field b1 and P2 updates
> bitfield b2. The code GCC generates for b2 = 1 e.g. on ia64 is:
>   0:   09 00 21 40 00 21       [MMI]       adds r32=8,r32
>   6:   00 00 00 02 00 e0                   nop.m 0x0
>   c:   11 00 00 90                         mov r15=1;;
>  10:   0b 70 00 40 18 10       [MMI]       ld8 r14=[r32];;
>  16:   00 00 00 02 00 c0                   nop.m 0x0
>  1c:   f1 70 c0 47                         dep r14=r15,r14,32,1;;
>  20:   11 00 38 40 98 11       [MIB]       st8 [r32]=r14
>  26:   00 00 00 02 00 80                   nop.i 0x0
>  2c:   08 00 84 00                         br.ret.sptk.many b0;;
>
> Note that gcc used 64-bit read-modify-write cycle to update b2. Thus if P1
> races with P2, update of b1 can get lost. BTW: I've just checked on x86_64
> and there GCC uses 8-bit bitop to modify the bitfield.
>
> We actually spotted this race in practice in btrfs on structure
> fs/btrfs/ctree.h:struct btrfs_block_rsv where spinlock content got
> corrupted due to update of following bitfield and there seem to be other
> places in kernel where this could happen.
>
> I've raised the issue with our GCC guys and they said to me that: "C does
> not provide such guarantee, nor can you reliably lock different
> structure fields with different locks if they share naturally aligned
> word-size memory regions.  The C++11 memory model would guarantee this,
> but that's not implemented nor do you build the kernel with a C++11
> compiler."
>
> So it seems what C/GCC promises does not quite match with what kernel
> expects. I'm not really an expert in this area so I wanted to report it
> here so that more knowledgeable people can decide how to solve the issue...
>
>                                                                Honza
> --
> Jan Kara 
> SUSE Labs, CR

What is the recommended work around for this problem?


Re: weird optimization in sin+cos, x86 backend

2012-02-03 Thread James Courtier-Dutton
On 3 February 2012 16:24, Vincent Lefevre  wrote:
> On 2012-02-03 16:57:19 +0100, Michael Matz wrote:
>> > And it may be important that some identities (like cos^2+sin^2=1) be
>> > preserved.
>>
>> Well, you're not going to get this without much more work in sin/cos.
>
> If you use the glibc sin() and cos(), you already have this (possibly
> up to a few ulp's).
>
>> > For the glibc, I've finally reported a bug here:
>> >
>> >   http://sourceware.org/bugzilla/show_bug.cgi?id=13658
>>
>> That is about 1.0e22, not the obscene 4.47460300787e+182 of the original
>> poster.
>
> But 1.0e22 cannot be handled correctly.
>

Of course it can't.
You only have 52 bits of precision in double floating point numbers.
So, although you can have 1.0e22, you cannot represent (1.0e22 + 1)
If you understood how the sin and cos functions actually get
calculated, you would understand why the ability to handle +1 is so
important.
sin and cos first have to translate the input value into a range of 0
to 2Pi, so if you cannot represent (1.0e22) and (1.0e22 +  2Pi), it is
not possible to translate the input value with any sort of way that
makes sense.

To represent the 1.0e22+1, you need more than 52 bits of precision.
If you move down to the 1.0e14 range, things start making sense again.

The easiest way to ensure correct calculations in floating point maths
is to convert everything into binary and then make sure you have
enough bits of precision at every stage.

Summary: 1.0e22 is just as obscene as 4.47460300787e+182 from the
point of view of sin and cos.


Kind Regards

James


Re: weird optimization in sin+cos, x86 backend

2012-02-03 Thread James Courtier-Dutton
On 3 February 2012 18:12, Konstantin Vladimirov
 wrote:
> Hi,
>
> I agree, that this case have no practical value. It was autogenerated
> between other thousands of tests and showed really strange results, so
> I decided to ask. I thought, this value fits double precision range
> and, according to C standard, all double-precision arithmetics must be
> avaliable for it.
>
> Thanks everybody for explanation, I will constrain trig function
> arguments, according to "x is separable with x+pi/4" rule. It seems,
> everything works inside this range.
>

The important bit is ensuring the input can be represented in 52 bits
of precision of the double floating point number.
The higher the input number, the fewer discrete real values you can
represent in the 0 to pi/4 range.

I will try to explain in base 10, with 3 digits of precision.
Take the range change to between 0 to 9 (instead of 0 to pi/4)
Input value 3.21, no range change (like a "n mod 10" but for reals)
needed, I can have input after the range change of values 1.00, 1.01,
1.02 ... 3.21 ... 9.99.  I.e 1000 discrete values between 0 and 10.

Input value 32.1, range change to 2.1, I can have input values 1.0,
1.1, 1.2, ... 9.9. I.e. Only 100 discrete values between 0 and 10.
Input value 321, range change to 1, I can have input values of 1, 2,
3, ... 9. I.e. Only 10 discrete values between 0 and 10.
Input value 3210, range change to 0, I can have input values of 0.
I.e. Only 1 discrete value between 0 and 10.
Input value 32100...  etc. (note the 3 digits of precision)

Kind Regards

James


Re: weird optimization in sin+cos, x86 backend

2012-02-04 Thread James Courtier-Dutton
On 4 February 2012 00:06, Vincent Lefevre  wrote:
> On 2012-02-03 17:40:05 +0100, Dominique Dhumieres wrote:
>> While I fail to see how the "correct value" of
>> cos(4.47460300787e+182)+sin(4.47460300787e+182)
>> can be defined in the 'double' world, cos^2(x)+sin^2(x)=1 and
>> sin(2*x)=2*sin(x)*cos(x) seems to be verified (at least for this value)
>> even if the actual values of sin and cos depends on the optimisation level.
>
> Actually this depends on the context. It is even worse: the value
> of sin(some_value) depends on the context. Consider the following
> program:
>
> #include 
> #include 
>
> int main (void)
> {
>  double x, c, s;
>  volatile double v;
>
>  x = 1.0e22;
>  s = sin (x);
>  printf ("sin(%.17g) = %.17g\n", x, s);
>
>  v = x;
>  x = v;
>  c = cos (x);
>  s = sin (x);
>  printf ("sin(%.17g) = %.17g\n", x, s);
>
>  return c == 0;
> }
>
> With "gcc -O" on x86_64 with glibc 2.13, one gets:
>
> sin(1e+22) = -0.85220084976718879
> sin(1e+22) = 0.46261304076460175
>
> In the program, you can replace 1.0e22 by 4.47460300787e+182 or
> whatever large constant you want. You'll get the same problem.
>

Ok, so the value -0.85... seems to be the correct value.

If you convert all the doubles into long doubles.
You get:
gcc -O0 -c -o sincos.o sincos.c
gcc sincos.o -lm
sinl(100.0) = 0.46261304076460176
sinl(100.0) = 0.46261304076460176
gcc sincos.o -lm
gcc -O2 -c -o sincos.o sincos.c
sin(100.0) = -0.85220084976718880
sin(100.0) = 0.46261304076460176

So, I agree with Vincent Lefevre, my earlier statements are wrong.
There is definitely something going wrong either in gcc or libm.


Re: weird optimization in sin+cos, x86 backend

2012-02-05 Thread James Courtier-Dutton
Hi,

I looked at this a bit closer.
sin(1.0e22) is outside the +-2^63 range, so FPREM1 is used to bring it
inside the range.
So, I looked at FPREM1 a bit closer.

#include 
#include 

int main (void)
{
 long double x, r, m;

 x = 1.0e22;
// x = 5.26300791462049950360708478127784;  <- This is what the answer
should be give or take 2PI.
 m =  M_PIl * 2.0;
 r = remainderl(x, m);   // Utilizes FPREM1

 printf ("x = %.17Lf\n", x);
 printf ("m = %.17Lf\n", m);
 printf ("r = %.17Lf\n", r);

 return 1;
}

This outputs:
x = 100.0
m = 6.28318530717958648
r = 2.66065232182161996

But, r should be
5.26300791462049950360708478127784... or
-1.020177392559086973318201985281...
according to wolfram alpha and most arbitrary maths libs I tried.

I need to do a bit more digging, but this might point to a bug in the
cpu instruction FPREM1

Kind Regards

James


Transforms on SSA form

2008-12-03 Thread James Courtier-Dutton
Hi,

I am looking to transform a tree in SSA form into a representation of it in C.

Example C code:
a = 1;
if (condition) a = 2;
b = a;

In SSA  (use $ for the Phi, Φ)
a1 = 1;
if (condition) a2 = 2;
a3 = $(a1, a2);
b1 = a3;

My problem is how do I convert the "a3 = $(a1, a2);" back to normal C code?

Kind Regards

James


Re: Transforms on SSA form

2008-12-05 Thread James Courtier-Dutton
2008/12/4 Diego Novillo <[EMAIL PROTECTED]>:
> On Thu, Dec 4, 2008 at 11:20, John Freeman <[EMAIL PROTECTED]> wrote:
>> There are documented methods of SSA decomposition.  The naive method is a
>> simple reversal of SSA composition:
>>
>> SSA composition: rename variables (typically by adding suffix), add phi
>> nodes
>> SSA decomposition: rename variables (by dropping suffix), remove phi nodes
>>
>> The short answer to your question is that there is no C equivalent of a phi
>> node.  You simply drop it.
>
> That's only true if the program was not rewritten into SSA form or no
> overlapping live ranges in SSA names exist.
>
> If the program was rewritten into SSA and different SSA names for the
> same symbol have overlapping live ranges (due to code motion and copy
> propagation mostly), then dropping the PHIs gives you an invalid
> program.  You have to convert the PHIs into copies.
>
> If the SSA form you use is simply a factored use-def representation,
> then dropping the PHIs is fine, of course.  GCC uses both forms: local
> scalars are rewritten into SSA.  Memory symbols (arrays, aggregates,
> aliased symbols) are represented with a FUD web.
>
>
> Diego.
>

The actual task I am doing is transforming a .o file back to a .c file.
The aim is only that the resulting .c can be recompiled and
functionally perform identically to the original .o file.
I have done the work so far that converts the .o file back to a form
of SSA contained in a bi-directional tree so it is easy to step
forwards and backwards through a particular branch of the tree.
I started using a method I thought I invented of renaming the variable
each time it changed. I ran into the problem of what to do when
program joins two branches. I searched and found that SSA is
essentially the same problem. So, I wanted to use SSA so that the
resulting .c file would be able to better describe the scope of use of
each variable so the observer could easily see that variable X is a
temporary one, only used in loop X, for example.
So, I think the solution is therefore to only rename the variables
contained in the Phi statement.
a3 = $(a1, a2);
would result in all instances of a1 to be renamed to a3, and all
instances of a2 to be renamed to a3. I can see problems with this
approach, but they only occur when complexity increases, so I will
cross that bridge when I come to it. I am just doing a proof of
concept at the moment and have written 30 sample .o files that I would
like my tool to be able to process.

Kind Regards

James


Re: weird optimization in sin+cos, x86 backend

2012-02-09 Thread James Courtier-Dutton
On 3 February 2012 21:48, Vincent Lefevre  wrote:
> On 2012-02-03 17:44:21 +0100, Michael Matz wrote:
>> Hi,
>>
>> On Fri, 3 Feb 2012, Vincent Lefevre wrote:
>>
>> > > > For the glibc, I've finally reported a bug here:
>> > > >
>> > > >   http://sourceware.org/bugzilla/show_bug.cgi?id=13658
>> > >
>> > > That is about 1.0e22, not the obscene 4.47460300787e+182 of the
>> > > original poster.
>> >
>> > But 1.0e22 cannot be handled correctly.
>>
>> I'm not sure what you're getting at.  Yes, 1e22 isn't handled correctly,
>> but this thread was about 4.47460300787e+182 until you changed topics.
>
> No, the topic is: "weird optimization in sin+cos, x86 backend".
> But actually, as said by Richard Guenther, the bug is not the
> optimization, but the behavior of the sincos function. What I'm
> saying is that this wrong behavior can also be seen on 1.0e22
> (at least with the glibc, and any implementation that uses the
> fsincos x86 instruction).
>
>> > > If you want to have precise numbers use an arbitrary precision math
>> > > library.
>> >
>> > This is double precision. An arbitrary precision math library (even
>> > though I develop one) shouldn't be needed.
>>
>> But the reduction step needs much more precision than it currently uses to
>> handle inputs as large as 4e182 correctly.
>
> No, the range reduction can cleverly be done using the working
> precision (such as with Payne and Hanek's algorithm).
>
From what I can see, on x86_64, the hardware fsin(x) is more accurate
than the hardware fsincos(x).
As you gradually increase the size of X from 0 to 10e22, fsincos(x)
diverges from the correct accurate value quicker than fsin(x) does.

So, from this I would say that using fsincos instead of fsin is not a
good idea, at least on x86_64 platforms.
So, I suggest that:
1) sin() uses fsin
2) cos() uses fcos
3) sincos() uses fsincos(might be a contentious point?)
4) If a program is using sin(x) close to cos(x), do not optimize it to
a sincos()


Re: weird optimization in sin+cos, x86 backend

2012-02-09 Thread James Courtier-Dutton
2012/2/9 Andrew Haley :
> On 02/09/2012 01:38 PM, Tim Prince wrote:
>> x87 built-ins should be a fair compromise between speed, code size, and
>> accuracy, for long double, on most CPUs.  As Richard says, it's
>> certainly possible to do better in the context of SSE, but gcc doesn't
>> know anything about the quality of math libraries present; it doesn't
>> even take into account whether it's glibc or something else.
>
> Yeah.  On x86_64 glibc, we should really get the sincos bg fixed.  And
> it really is a bug: cos() and sin() are correctly rounded but sincos()
> isn't.
>
> Andrew.

Given:

gcc -g -O0 -c -o sincos1.o sincos1.c
gcc -static -g -o sincos1 sincos1.o -lm

./sincos1
sin = -8.52200849767188795e-01(uses xmm register intructions)
sinl = 0.46261304076460176  (uses fprem and fsin)
sincos = 4.62613040764601746e-01 (uses fprem and fsin)
sincosl = 0.46261304076460176   (uses fprem and fsin)

It looks to me that only sin() is evaluation correctly using xmm
register instructions.
sinl, sincos, and sincosl all use fprem and fsin and fsincos.

From my analysis, fprem is causing a lot of the problems.
Using a combination of xmm register instructions instead of fprem
might cure our problems with fsincos.
Alternatively, make both sin() and sinl() use xmm register intructions.


Re: weird optimization in sin+cos, x86 backend

2012-02-09 Thread James Courtier-Dutton
On 9 February 2012 14:51, James Courtier-Dutton  wrote:
> 2012/2/9 Andrew Haley :
>> On 02/09/2012 01:38 PM, Tim Prince wrote:
>>> x87 built-ins should be a fair compromise between speed, code size, and
>>> accuracy, for long double, on most CPUs.  As Richard says, it's
>>> certainly possible to do better in the context of SSE, but gcc doesn't
>>> know anything about the quality of math libraries present; it doesn't
>>> even take into account whether it's glibc or something else.
>>
>> Yeah.  On x86_64 glibc, we should really get the sincos bg fixed.  And
>> it really is a bug: cos() and sin() are correctly rounded but sincos()
>> isn't.
>>
>> Andrew.
>
> Given:
>
> gcc -g -O0 -c -o sincos1.o sincos1.c
> gcc -static -g -o sincos1 sincos1.o -lm
>
> ./sincos1
> sin = -8.52200849767188795e-01    (uses xmm register intructions)
> sinl = 0.46261304076460176          (uses fprem and fsin)
> sincos = 4.62613040764601746e-01 (uses fprem and fsin)
> sincosl = 0.46261304076460176       (uses fprem and fsin)
>
> It looks to me that only sin() is evaluation correctly using xmm
> register instructions.
> sinl, sincos, and sincosl all use fprem and fsin and fsincos.
>
> From my analysis, fprem is causing a lot of the problems.
> Using a combination of xmm register instructions instead of fprem
> might cure our problems with fsincos.
> Alternatively, make both sin() and sinl() use xmm register intructions.

Results for x86_64
gcc -g -O0 -c -o sincos1.o sincos1.c
gcc -static -g -o sincos1 sincos1.o -lm

./sincos1
sin = -8.52200849767188795e-01(uses xmm register intructions)
sinl = 0.46261304076460176  (uses fprem and fsin)
sincos = 4.62613040764601746e-01 (uses fprem and fsin)
sincosl = 0.46261304076460176   (uses fprem and fsin)

Only sin() gets an accurate answer.

Results when compiled for 32bit x86.
gcc -m32 -g -O0 -c -o sincos1.o sincos1.c
gcc -m32 -static -g -o sincos1 sincos1.o -lm

./sincos1
sin = 4.62613040764601746e-01
sinl = 0.46261304076460176
sincos = 4.62613040764601746e-01
sincosl = 0.46261304076460176

Which are all inaccurate.

So, we have a case of the same program compiled for 32bit might give
different floating point results than the same source compiled for
64bit.

From what I can tell, the xmm register instructions on x86_64 are
using 128bit precision which probably explains why the result is more
accurate.


Re: weird optimization in sin+cos, x86 backend

2012-02-10 Thread James Courtier-Dutton
On 10 February 2012 10:42, Andrew Haley  wrote:
> On 02/10/2012 10:07 AM, Richard Guenther wrote:
>>
>> The issue with libm in glibc here is that Drepper absolutely does
>> not want new ABIs in libm - he believes that for example vectorized
>> routines do not belong there (nor the SSE calling-convention variants
>> for i686 I tried to push once).
>
> That's a good reason why we can't do this in glibc.  I accept
> the point; it'll have to be GNU libm.
>
> Andrew.

I think a starting point would be at least documenting correctly the
accuracy of the current libm, because what is currently in the
documents is obviously wrong.
It certainly does not document that sin() is currently more accurate
than sinl() on x86_64 platforms, even with -O0.
I think the documentation should be along the lines of for
Function name: sin(x)
-pi/2 < x < pi/2, accuracy is +-N
pi/2 < x < large number, accuracy is +-N
large number < x < max_float, accuracy is +-N
If a performance figure could also be added, so much the better. We
could then know that implementation 1 is quicker than implementation 2
and the programmer can do the trade offs.

And have the figures repeated for various options such as -ffast-math
etc, and also repeated for different CPUs etc.

Once we have the documentation, we can then ensure, using automated
testing, that the libm actually performs as designed.


Re: weird optimization in sin+cos, x86 backend

2012-02-10 Thread James Courtier-Dutton
On 10 February 2012 14:05, Andrew Haley  wrote:
> On 02/10/2012 01:30 PM, James Courtier-Dutton wrote:
>> On 10 February 2012 10:42, Andrew Haley  wrote:
>>
>> I think a starting point would be at least documenting correctly the
>> accuracy of the current libm, because what is currently in the
>> documents is obviously wrong.
>> It certainly does not document that sin() is currently more accurate
>> than sinl() on x86_64 platforms, even with -O0.
>
> It isn't.
>
>  cout << scientific << setprecision(20) << sin(0.5) << "\n";
>  cout << scientific << setprecision(20) << sinl(0.5) << "\n";
>  cout << Sin(Real("0.5")).toString(20,10) << "\n";
>
> gives:
>
> 4.79425538604203005377e-01
> 4.79425538604203000282e-01
> 4.79425538604203000273e-01
>
> The last one is from MPFR.
>
> In most cases you'll get more accurate results from sinl().
>

but if you replace 0.5 with 1.0e22 ?


Re: weird optimization in sin+cos, x86 backend

2012-02-10 Thread James Courtier-Dutton
On 10 February 2012 14:36, Andrew Haley  wrote:
> On 02/10/2012 02:24 PM, James Courtier-Dutton wrote:
>> On 10 February 2012 14:05, Andrew Haley  wrote:
>>> On 02/10/2012 01:30 PM, James Courtier-Dutton wrote:
>>>> On 10 February 2012 10:42, Andrew Haley  wrote:
>>>>
>>>> I think a starting point would be at least documenting correctly the
>>>> accuracy of the current libm, because what is currently in the
>>>> documents is obviously wrong.
>>>> It certainly does not document that sin() is currently more accurate
>>>> than sinl() on x86_64 platforms, even with -O0.
>>>
>>> It isn't.
>>>
>>>  cout << scientific << setprecision(20) << sin(0.5) << "\n";
>>>  cout << scientific << setprecision(20) << sinl(0.5) << "\n";
>>>  cout << Sin(Real("0.5")).toString(20,10) << "\n";
>>>
>>> gives:
>>>
>>> 4.79425538604203005377e-01
>>> 4.79425538604203000282e-01
>>> 4.79425538604203000273e-01
>>>
>>> The last one is from MPFR.
>>>
>>> In most cases you'll get more accurate results from sinl().
>>
>> but if you replace 0.5 with 1.0e22 ?
>
> Then it's less accurate.  In most cases, however, the long double
> version wins.  Your statement is not true: in most reasonable cases
> sinl() is currently more accurate than sin(), and it does readers of
> this list a disservice to suggest otherwise.  In the case of absurdly
> large arguments it's less accurate, but those cases are less likely to
> be significant for real-world computation.
>

I was trying to make the point that the accuracy varies depending on
input values, and this fact should be documented.
I.e. Accurate to 1 ulp for x in the range of ...
Not just "sin(x) is accurate to 1 ulp"
You say "In most reasonable cases sinl() is currently more accurate than sin()".
I am suggesting that we specify the range of x considered to be reasonable.
The term "reasonable" seems to me to be inexact.


Re: weird optimization in sin+cos, x86 backend

2012-02-18 Thread James Courtier-Dutton
On 13 February 2012 15:24, Vincent Lefevre  wrote:
> On 2012-02-10 17:41:49 +, Andrew Haley wrote:
>> On 02/10/2012 05:31 PM, Paweł Sikora wrote:
>> > it would be also nice to see functions for reducing argument range in 
>> > public api.
>> > finally the end-user can use e.g. sin(reduce(x)) to get the best precision
>> > with some declared cpu overhead.
>>
>> Hmm.  I'm not sure this is such a terrific idea: each function has its
>> own argument reduction (e.g. to [0, pi/4], [0, pi/8] or even [0, some
>> weird constant that looks arbitrary but just happens to be exactly
>> representable in binary]).  You really don't want double rounding,
>> which is what would happen with sin(reduce(x)).
>
> I agree. Also, range reduction may also be completely different.
> The general scheme is:
>
> 1. Reduce the argument x (for periodic function, it is an additive
>   reduction, but for some other functions, it can be a multiplicative
>   reduction).
>
> 2. Compute some alternate function(s) on the reduced argument.
>   For the first range reduction of periodic functions, it is the
>   same function, but in other cases, this may be other functions.
>
> 3. Reconstruct the final value. Nothing to do for the first range
>   reduction of periodic functions, but again, this is not always
>   the case.
>

Would it be useful to have some lib functions:
remainder_2pi(x, &remainder) /* returns remainder of x / 2Pi */
remainder_pi2(x, &remainder, "ient)  /* returns remainder of x /
(Pi/2)  with a quotient returned so you can tell where in the range [0
, 2Pi] it would fall.*/
remainder_pi4(x, &remainder, "ient)  /* returns remainder of x /
(Pi/4), with a quotient returned.

The reason for these special pi remainder functions is do with PI
being need to many 100s of decimal places in order to create an
accurate result so remainder(x, y) with y being set to double float PI
would not be accurate enough.

Kind Regards

James


Re: Some confuse about the pass of the arguments by gcc

2012-02-22 Thread James Courtier-Dutton
On 22 February 2012 13:34, 嘉谟  wrote:
> 2012/2/22 James Courtier-Dutton :
>> The order that function parameters are evaluated is undefined. Therefore it
>> is wise to ensure that no matter what order they are evaluated, the result
>> should be the same. It is the ++ that breaks it in this case. Didn't you get
>> a compiler warning?
>
> Yes you are right. gcc -Wall indeed get the warning.
> operation on 'a' may be undefined [-Wsequence-point]
>
> Thanks  for you reminder.
> Let me know ,If we want the result we want ,we should do the precision
> logic design .

>>> #include 
>>> int main(int argc , char *argv[]){
>>>int a=3;
>>>int b=3;
>>>int c=3;
>>>printf("%d %d\n",++a+c,a+c);
>>>printf("%d %d\n",++b,b);
>>>return 0;
>>> }

I sure exactly what you are asking for, but a version of the above
that will be portable and defined is:
#include 
int main(int argc , char *argv[]){
   int a=3;
   int b=3;
   int c=3;

   printf("%d %d\n",++a+c,a+c);
   printf("%d %d\n",++b,b);
   return 0;
}


Re: Some confuse about the pass of the arguments by gcc

2012-02-22 Thread James Courtier-Dutton
On 22 February 2012 19:05, James Courtier-Dutton  wrote:
> On 22 February 2012 13:34, 嘉谟  wrote:
>> 2012/2/22 James Courtier-Dutton :
>>> The order that function parameters are evaluated is undefined. Therefore it
>>> is wise to ensure that no matter what order they are evaluated, the result
>>> should be the same. It is the ++ that breaks it in this case. Didn't you get
>>> a compiler warning?
>>
>> Yes you are right. gcc -Wall indeed get the warning.
>> operation on 'a' may be undefined [-Wsequence-point]
>>
>> Thanks  for you reminder.
>> Let me know ,If we want the result we want ,we should do the precision
>> logic design .
>
>>>> #include 
>>>> int main(int argc , char *argv[]){
>>>>        int a=3;
>>>>        int b=3;
>>>>        int c=3;
>>>>        printf("%d %d\n",++a+c,a+c);
>>>>        printf("%d %d\n",++b,b);
>>>>        return 0;
>>>> }
>

Send button fired accidentally before I had finished.

 I am not sure exactly what you are asking for, but a version of the above
 that will be portable and defined is:
#include 
int main(int argc , char *argv[]){
      int a=3;
      int b=3;
      int c=3;
  int tmp1, tmp2, tmp3, tmp4;
  tmp1 = ++a+c;
  tmp2 = a+c;
  printf("%d %d\n",tmp1, tmp2);
  tmp3 = ++b;
  tmp4 = b;
      printf("%d %d\n", tmp3, tmp4);
      return 0;
}


Re: [LLVMdev] updated code size comparison

2012-05-07 Thread James Courtier-Dutton
On 17 December 2009 21:53, Bill Wendling  wrote:
> On Dec 16, 2009, at 1:26 AM, Paolo Bonzini wrote:
>
>> On 12/16/2009 03:21 AM, John Regehr wrote:
>>> Hopefully the results are more fair and useful now.  Again, feedback is
>>> appreciated.
>>
>> I would also avoid testcases using volatile.  Smaller code on these
>> testcases is often a sign of miscompilation rather than optimization.
>> For example,
>> http://embed.cs.utah.edu/embarrassing/src_harvested_dec_09/076389.c is
>> miscompiled on GCC 3.4 and SunCC 5.10.
>>
> Perhaps just leaving out those volatile tescases which are miscompiled on 
> other platforms, since not every volatile testcase fails for all compilers. 
> :-)
>
> -bw
>
>

Would it be possible for the test cases to detect if they have been
compiled wrongly, for example, check that volatile is actually
working?
How about running the resulting compiled code is a small virtual
machine, that is configured to return a different value each time the
volatile variable is read. The test code could then read the volatile
variable twice and return a different result depending on whether the
two read values are different or not.
If the mis-compiled code only read the value once, having wrongly
optimized out the second read, the test would fail.


[OT] Control Flow Graph(CFG) into Abstract Syntax Tree(AST)

2012-09-14 Thread James Courtier-Dutton
Hi,

I know most compilers go from AST to CFG.
I am writing a decompiler, so I was wondering if anyone knew of any
documents describing how best to get from CFG to AST.
The decompiler project is open source.
https://github.com/jcdutton/libbeauty

The decompiler already contains a disassembler and a virtual machine
resulting in an annotated CFG. It uses information gained from using a
virtual machine to annotate the CFG. Another use of the VM will be to
help analyze self modifying code.

The decompiler can output C source code form the CFG, but it is not
easy to understand the result due to lack of structure such as for {}
loops.
I wish to create an AST from the CFG in order to be able to output for
{}, while {}  and if...then...else structure.

The CFG to AST step seems a little complicated, so I was looking for
some pointers to how best to do it to save me re-inventing the wheel.

Kind Regards

James


Processor for header files.

2008-02-01 Thread James Courtier-Dutton
Hi,

I am writing a decompiler for lib or .o files.
For the application developer, one would have the lib or .o file and a
.h file that would identify the api for the application developer to
use to make use of the lib or .o file.
For my decompiler, I therefore need to be able to process the .h
files, as they will obviously help with the decompiler task.
I know gcc processes .h header files, so I am hoping to use gcc's
already implemented header processor.
Can anyone point me to which part of the gcc source tree does the
task, and also what format the data is stored in once processed.

Kind Regards

James


Re: Security vulernarability or security feature?

2008-04-27 Thread James Courtier-Dutton
2008/4/25 Prateek Saxena <[EMAIL PROTECTED]>:
> On Thu, Apr 24, 2008 at 2:20 PM, Ralph Loader <[EMAIL PROTECTED]> wrote:
>  > > I am very interested in seeing how this optimization can remove
>  >  > arithmetic overflows.
>  >
>  >  int foo (char * buf, int n)
>  >  {
>  > // buf+n may overflow of the programmer incorrectly passes
>  > // a large value of n.  But recent versions of gcc optimise
>  > // to 'n < 100', removing the overflow.
>  > return buf + n < buf + 100;
>  >  }
>
>  This clearly is insecure coding. The optimization to replace "buf + n
>  < buf + 100" with "n < 100" assumes something about the value of buf.
>  I assume that the location of "buf", could change arbitrarily accross
>  platforms depending on the memory layout.
>  I ran foo as follows, getting different outputs :
>

>From the algebra perspective "buf + n < buf + 100" should be the same
as "n < 100". There should really be a feature in C to handle the
special overflow/carry case in order to handle overflows and wrap
arounds.

This is probably a fundamental problem with C.
If one takes the following:

int a,b,c;
a = b + c;

How does one detect if there was a signed int overflow?
Programmers are forced to jump all sorts of hoops to do this check.
Fortunately there is a assembler instruction to do just this on most CPUs.
e.g. jo, jc, js
It would be nice to be able to write this sort of C code.

int a,b,c;
a = b + c;
if (a overflowed) {
handle_overflow();
}

One cannot simply code a special function to test the carry/overflow
flags as the compiler might reorder the previous instructions, and
therefore the carry/overflow state gets messed up.

Why has the C language lacked this sort of functionality for so long?

James


Re: Security vulernarability or security feature?

2008-04-27 Thread James Courtier-Dutton
2008/4/27 Robert Dewar <[EMAIL PROTECTED]>:
>
> > Fortunately there is a assembler instruction to do just this on most CPUs.
> > e.g. jo, jc, js
> > It would be nice to be able to write this sort of C code.
> >
> > int a,b,c;
> > a = b + c;
> > if (a overflowed) {
> >handle_overflow();
> > }
> >
>
>  Yes, but there is no such feature
>
>
> >
> > One cannot simply code a special function to test the carry/overflow
> > flags as the compiler might reorder the previous instructions, and
> > therefore the carry/overflow state gets messed up.
> >
>
>  Right indeed.
>  You could code an addition function that did an overflow check and
>  call that function
>
>
> >
> > Why has the C language lacked this sort of functionality for so long?
> >
>
>  It would be a major language change, there are of course languages (e.g.
>  Ada) that handle this conveniently and properly. To me, the more
> interesting question is how on earth Java missed this fundamental
>  requirement.
>
> >
> > James
> >
>
>

I think Java handles it OK for floats. I.e. Tests for positive
infinity and negative infinity etc.
I don't think Java handles it for integer maths. I agree with you. Big
oversight for the Java spec developers.
It would have been nice to also have some good handling of reals but
that is a compete other story.


Code representations

2008-04-28 Thread James Courtier-Dutton
I am trying to look at assembler code, and representing it as C code.

For ia32, x86 platforms,
assembler like the following

ADD eax,ebx;
JO integer_overflow_detected;

How would I represent this in C?

Kind Regards

James


Re: Code representations

2008-04-28 Thread James Courtier-Dutton
2008/4/28 Kai Tietz <[EMAIL PROTECTED]>:
> [EMAIL PROTECTED] wrote on 28.04.2008 13:11:39:
>
>
>
>  > I am trying to look at assembler code, and representing it as C code.
>  >
>  > For ia32, x86 platforms,
>  > assembler like the following
>  >
>  > ADD eax,ebx;
>  > JO integer_overflow_detected;
>  >
>  > How would I represent this in C?
>  >
>  > Kind Regards
>  >
>  > James
>
>  It would be something like this:
>
>  #define MSB (type)  ((1<<((sizeof(type)*8)-1))
>  typedef unsigned int myscalar;
>  ...
>  {
>   myscalar a,b,savea;
>   ...
>   savea = a;
>   a+=b;
>   if ( ((savea & MSB(myscalar)) & ((b & MSB(myscalar)) & ~(a &
>  MSB(myscalar ||
> ( ~(savea & MSB(myscalar)) & ~(b&MSB(myscalar)) & (a&MSB(myscalar
>  /* overflow */
>   ...
>  }
>
>  For signed integers you can ease this as follow
>
>   savea = a;
>   a+=b;
>   if ( (savea<0 && b<0 && a>=0)) ||
> (savea>=0 && b>=0 && a<0))
>  /* overflow */
>

I am taking a wild guess here, but can I assume that the above will
not compile back to something like:
ADD eax,ebx;
JO integer_overflow_detected;

I think I will have to have some macro/function in C that does the following:
add(int a,int b, int (&integer_overflow_detected));
This will add a and b, and jump to the overflow handler if there is an overflow.
I can then implement CPU specific implementations for each target
platform, and that would at least return to the same ASM code
generated at compile.

James