bug#13342: [PARTIALLY SOLVED] bug#13342: Errors trying to build Guile 2.0.7

2013-01-27 Thread Ludovic Courtès
Hi Peter,

Sorry for the late reply, and thanks for investigating.

I reproduced the bug on GNU/Linux with Clang 3.1.

Peter Teeson  skribis:

> I think the reason that we get this error is that the "a" argument is 
> declared to be only 8 bits wide
> but is passed in as -1 which is correctly represented as 0x
>
> However an 8-bit representation is 0xFF which is only 255.

This is part of the issue.

Consider this example:

--8<---cut here---start->8---
#include 

int64_t
test_sum (int8_t a, int64_t b)
{
  return a + b;
}
--8<---cut here---end--->8---

When compiled with GCC 4.6, the assembly is:

--8<---cut here---start->8---
test_sum:
.LFB0:
.cfi_startproc
movsbq  %dil, %rdi
leaq(%rdi,%rsi), %rax
ret
.cfi_endproc
--8<---cut here---end--->8---

With Clang 3.1, it is:

--8<---cut here---start->8---
test_sum:   # @test_sum
.cfi_startproc
# BB#0:
movslq  %edi, %rax
addq%rsi, %rax
ret
--8<---cut here---end--->8---

The ‘movsbq’ emitted by GCC arranges to keep only the 8 LSBs.  Clang
does no such thing, thus keeping all the bits of the first operand in
the addition.

I looked at Section 3.2.3 (“Parameter Passing”) of the SysV ABI x86_64
PS but couldn’t find any evidence as to what the correct behavior is.

However, on the caller side, both compilers emit the same code.  This
program:

--8<---cut here---start->8---
#include 

extern int64_t test_sum (int8_t a, int64_t b);

int64_t
foo (void)
{
  return test_sum (-1, 123132);
}
--8<---cut here---end--->8---

leads to the following assembly with both compilers:

--8<---cut here---start->8---
foo:# @foo
.cfi_startproc
movl$-1, %edi
movl$123132, %esi   # imm = 0x1E0FC
jmp test_sum# TAILCALL
--8<---cut here---end--->8---

(And as we’ve seen, libffi does the same.)

So that seems to indicate that the callee code generated by Clang is
incorrect as it fails to discard the 24 MSBs of its first argument.

Could you report it as a Clang/LLVM bug (keeping 13...@debbugs.gnu.org
Cc’d)?

Thanks!

Ludo’.





bug#13491:

2013-01-27 Thread Ludovic Courtès
retitle 13491 Dangling link in ideas.html
thanks

David Serafini  skribis:

> Minor bug: in http://www.gnu.org/software/guile/ideas.html, the link
>  "Paul Wilson's survey papers on garbage collection"
> 
> is dead, and the UT's CS dept. search doesn't have anything for Paul Wilson
> although google does find a paper at
> http://www.cse.nd.edu/~dthain/courses/cse40243/spring2006/gc-survey.pdf

Indeed, fixed.  Thanks!

Ludo’.





bug#13342: [PARTIALLY SOLVED] bug#13342: Errors trying to build Guile 2.0.7

2013-01-27 Thread Peter Teeson
Hi Ludo:
MacOS 10.7.5 Intel Dual CPU quad cores 

Many thanks for your reply. A nice demo but, no disrespect, maybe not really 
the issue.
Looking at the generated code from each compiler was going to be my next step 
after
taking a look at the stack and regs to see what got passed/pushed/popped in the 
call to test_sum.
Which is why I posted about how can I debug/step through the interpreter. 
I still don't understand how to do that even though I read through the manual.

My experiment in building guile with both compilers indicate they both produce 
the same error.
bad return from expression `(f-sum -1 2000 -3 400)': expected 
3971999; got 3972255
I am still of the opinion that it's an interpreter issue and not a compiler 
one. 

I ask for help in confirming my understanding of this scheme code from the file 
/test-suite/standalone/test-ffi
;;
;; Multiple int args of differing types
;;
(define f-sum
  (pointer->procedure int64 (dynamic-func "test_ffi_sum" lib)
  (list int8 int16 int32 int64)))
(test (f-sum -1 2000 -3 400)  ;; This calls the c function f-sum
  (+ -1 2000 -3 400));;  This executes the scheme 
interpreter to do the sum

Is my understanding correct??

If so please explain to me how the interpreter knows that the -1 in this 
expression is an int8?
My suspicion is that it thinks it's an int16 and that's why we see the 
difference!!

I don't know how to pass an int8 of -1 to the interpreter in REPL mode.
Otherwise I'd try that.

= from Terminal REPL session =
Gandalf:guile-2.0.7 pteeson$ guile
GNU Guile 2.0.7


scheme@(guile-user)> (+ -1 2000 -3 400)
$1 = 3971999
scheme@(guile-user)> ,q

which matches the fail message value.
bad return from expression `(f-sum -1 2000 -3 400)': expected 
3971999; got 3972255

= from 
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html 
=== 
Limits of exact-width integer types
Minimum values of exact-width signed integer types:
{INTN_MIN}
Exactly -(2 N-1)
Maximum values of exact-width signed integer types:
{INTN_MAX}
Exactly 2N-1 -1
==




bug#13342: [PARTIALLY SOLVED] bug#13342: Errors trying to build Guile 2.0.7

2013-01-27 Thread Mark H Weaver
Hi Ludovic,

Thanks for looking into this!  I think I understand the problem now.

l...@gnu.org (Ludovic Courtès) writes:
> Consider this example:
>
> #include 
>
> int64_t
> test_sum (int8_t a, int64_t b)
> {
>   return a + b;
> }
>
> When compiled with GCC 4.6, the assembly is:
>
> test_sum:
> .LFB0:
>   .cfi_startproc
>   movsbq  %dil, %rdi
>   leaq(%rdi,%rsi), %rax
>   ret
>   .cfi_endproc
>
> With Clang 3.1, it is:
>
> test_sum:   # @test_sum
>   .cfi_startproc
> # BB#0:
>   movslq  %edi, %rax
>   addq%rsi, %rax
>   ret
>
> The ‘movsbq’ emitted by GCC arranges to keep only the 8 LSBs.  Clang
> does no such thing, thus keeping all the bits of the first operand in
> the addition.

This is the key revelation, although I've reached a different conclusion
about where the bug is.

> I looked at Section 3.2.3 (“Parameter Passing”) of the SysV ABI x86_64
> PS but couldn’t find any evidence as to what the correct behavior is.

I read the same section, and although it is not as clear as I'd prefer,
my interpretation is that the caller is responsible for sign-extending
signed chars to ints.  This is also consistent with something I vaguely
remember reading in K&R long ago, namely that 'char' and 'short'
arguments are coerced to 'int' before making a function call.

Clang strictly requires callers to sign-extend, whereas GCC is tolerant
of callers who fail to do so.  IMO, both behaviors are permitted by the
ABI.

The problem is that libffi does *not* sign-extend arguments passed in
registers when making calls, which is IMO a bug that has gone (mostly)
unnoticed because of the tolerance and ubiquity of GCC.

> However, on the caller side, both compilers emit the same code.  This
> program:
>
> #include 
>
> extern int64_t test_sum (int8_t a, int64_t b);
>
> int64_t
> foo (void)
> {
>   return test_sum (-1, 123132);
> }
>
> leads to the following assembly with both compilers:
>
> foo:# @foo
>   .cfi_startproc
>   movl$-1, %edi
>   movl$123132, %esi   # imm = 0x1E0FC
>   jmp test_sum# TAILCALL
>
> (And as we’ve seen, libffi does the same.)

No, libffi does *not* do the same.  Take a look at the relevant code:

  https://github.com/atgreen/libffi/blob/master/src/x86/ffi64.c#L488

As you can see in lines 487 and 488, arguments passed in registers are
never sign-extended, but rather zero-extended.  The register values are
then copied whole in the darwin-specific assembly stub:

  https://github.com/atgreen/libffi/blob/master/src/x86/darwin64.S#L61

Interestingly, arguments passed on the stack *are* sign-extended:

  https://github.com/atgreen/libffi/blob/master/src/x86/darwin64.S#L120

* * * * *

In summary, I think this is a bug in libffi.

Note that it has already been reported that the libffi testsuite shows
many failures on OS X Lion, and the failures appear to be related to
this precise issue:

  http://sourceware.org/ml/libffi-discuss/2012/msg00162.html

The libffi maintainer wrote "I'm going to chalk this up to compiler
bugs", based on his observation that the tests worked properly when
compiled with -O0.  I think it's time to raise this issue again on the
libffi-discuss mailing list.

In any case, it's certainly not a bug in Guile.  The bug is either in
LLVM/Clang or libffi, depending on how one chooses to interpret the
x86-64 API.

Regards,
  Mark





bug#13342: [PARTIALLY SOLVED] bug#13342: Errors trying to build Guile 2.0.7

2013-01-27 Thread Peter Teeson
Hi Mark:
Thanks for your comments and I agree I was wrong.
Ludovic pointed out GCC dropping off the MSB 24-bits whereas Clang does not.
You pointed out the lack of sign extension in the libffi implementation.

I would think it would be easier to make the change to libffi 
rather than expect changes to be made to the compilers.
But that's just my opinion.

Anyway glad that you wizards have nailed it.

OK if I bow out now and let others fix it?

respect….

Peter