linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Sanders <Daniel.Sanders@imgtec.com>
To: "Maciej W. Rozycki" <macro@linux-mips.org>
Cc: Toma Tabacu <Toma.Tabacu@imgtec.com>,
	Ralf Baechle <ralf@linux-mips.org>,
	Markos Chandras <Markos.Chandras@imgtec.com>,
	Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>,
	"linux-mips@linux-mips.org" <linux-mips@linux-mips.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH 3/5] MIPS: LLVMLinux: Fix an 'inline asm input/output type mismatch' error.
Date: Thu, 5 Feb 2015 15:43:38 +0000	[thread overview]
Message-ID: <E484D272A3A61B4880CDF2E712E9279F4591CDE8@hhmail02.hh.imgtec.org> (raw)
In-Reply-To: <alpine.LFD.2.11.1502041151300.22715@eddie.linux-mips.org>

Apologies for the slow response. I've had an excessive amount of meetings in the last couple days.

> -----Original Message-----
> From: Maciej W. Rozycki [mailto:macro@linux-mips.org]
> Sent: 04 February 2015 12:58
> To: Daniel Sanders
> Cc: Toma Tabacu; Ralf Baechle; Markos Chandras; Leonid Yegoshin; linux-
> mips@linux-mips.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 3/5] MIPS: LLVMLinux: Fix an 'inline asm input/output
> type mismatch' error.
> 
> On Tue, 3 Feb 2015, Daniel Sanders wrote:
> 
> > From: Toma Tabacu <toma.tabacu@imgtec.com>
> >
> > Change the type of csum_ipv6_magic's 'proto' argument from unsigned
> > short to __u32.
> >
> > This fixes a type mismatch between the 'htonl(proto)' inline asm
> > input, which is __u32, and the 'proto' output, which is unsigned
> > short.
> >
> > This is the error message reported by clang:
> > arch/mips/include/asm/checksum.h:285:27: error: unsupported inline asm:
> input with type '__be32' (aka 'unsigned int') matching output with type
> 'unsigned short'
> >           "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
> >                                  ^~~~~~~~~~~~
> >
> > The changed code can be compiled successfully by both gcc and clang.
> 
>  This definitely looks like a bug in clang to me.  What this construct
> means is both input #5 and output #1 live in the same register, and that
> an `__u32' value is taken on input (from the result of the `htonl(proto)'
> calculation) and an `unsigned short' value produced in the same register
> on output, that'll be the value of the `proto' variable from there on.  A
> perfectly valid arrangement.  This would be the right arrangement to use
> with the MIPS16 SEH instruction for example.  Has this bug been reported
> to clang maintainers?

I'm not convinced it's a bug, but I do at least agree that the use case sounds
sensible. It makes sense to me that the focus should be on register allocations
rather than on types. However, the relevant clang source is being very specific
about the cases it is/isn't allowing which suggests it's deliberate. I've started a
thread on the clang mailing list to try to find out more about why we currently
reject it.

>  And I'd prefer to leave the declaration of `proto' alone as IPv6 network
> protocol numbers are 16-bit quantities.
>
>  That said this code is indeed weird if not wrong, which is probably why
> this arrangement resulted, in an attempt to prevent GCC from messing up
> the registers used.
> 
>  First and foremost both outputs, and especially #1, lack an earlyclobber.
> This I imagine may have prompted GCC to overwrite one of the inputs, which
> in turn is why whoever poked at this code decided to alias input #5 to
> output #1.  But as you can see in the asm there's no real aliasing between
> input #5 and output #1.  Input #5 is consumed early on (and even referred
> to with `%5' rather than `%1', which would be the norm in the case of
> actual aliasing), and the containing register reused for something else.
> So the two operands can be separated.  This is unlike input #4 vs output
> #0, that is both read and written right away (and just as one'd expect
> there's no reference to `%4' anywhere).
> 
>  Output #0 can do without an earlyclobber as it is aliased to input #4 and
> therefore cannot be assigned by GCC to another input.  But it won't hurt
> to have one too and it will set a good practice and serve a documentation
> purpose.
> 
>  I suggest a fix like this then:
> 
> static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
> 					  const struct in6_addr *daddr,
> 					  __u32 len, unsigned short proto,
> 					  __wsum sum)
> {
> 	__wsum tmp;
> 
> 	__asm__(
> [...]
> 	: "=&r" (sum), "=&r" (tmp)
> 	: "r" (saddr), "r" (daddr),
> 	  "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
> 
>         return csum_fold(sum);
> }
> 
> Try and see if it works for you.
> 
>  I wonder why this is an asm in the first place though.  There's no rocket
> science here that GCC couldn't handle.  I guess it must have been very bad
> at optimising a C equivalent then.
> 
>   Maciej

Yes, that works for me on both GCC and Clang. I'll change the patch to this.
Would you like a 'Suggested-By' in the patch description?

  reply	other threads:[~2015-02-05 15:43 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-03 13:37 [PATCH 0/5] MIPS: LLVMLinux: Patches to enable compilation of a working kernel for MIPS using Clang/LLVM Daniel Sanders
2015-02-03 13:37 ` [PATCH 1/5] LLVMLinux: Correct size_index table before replacing the bootstrap kmem_cache_node Daniel Sanders
2015-02-03 15:14   ` Christoph Lameter
2015-02-03 16:00     ` Daniel Sanders
2015-02-04 20:52       ` [PATCH v2 " Daniel Sanders
2015-02-04 21:06       ` [PATCH v3 1/5] slab: " Daniel Sanders
2015-02-05  8:37         ` Pekka Enberg
2015-02-04 19:33   ` [PATCH 1/5] LLVMLinux: " Pekka Enberg
2015-02-04 20:38     ` Daniel Sanders
2015-02-04 20:42       ` Pekka Enberg
2015-02-04 21:08         ` Daniel Sanders
2015-02-03 13:37 ` [PATCH 2/5] MIPS: LLVMLinux: Fix a 'cast to type not present in union' error Daniel Sanders
2015-02-03 13:37 ` [PATCH 3/5] MIPS: LLVMLinux: Fix an 'inline asm input/output type mismatch' error Daniel Sanders
2015-02-04 12:57   ` Maciej W. Rozycki
2015-02-05 15:43     ` Daniel Sanders [this message]
2015-02-06 10:09       ` Maciej W. Rozycki
2015-02-09 11:33   ` [PATCH v2 " Daniel Sanders
2015-02-09 14:12     ` Maciej W. Rozycki
2015-02-09 16:44     ` [PATCH v3 " Daniel Sanders
2015-02-03 13:37 ` [PATCH 4/5] MIPS: LLVMLinux: Silence variable self-assignment warnings Daniel Sanders
2015-02-03 13:37 ` [PATCH 5/5] MIPS: LLVMLinux: Silence unicode warnings when preprocessing assembly Daniel Sanders
2015-02-04 10:36   ` Maciej W. Rozycki
2015-02-05 10:25     ` Toma Tabacu
2015-02-05 12:35       ` Maciej W. Rozycki
2015-02-05 12:56         ` Måns Rullgård
2015-02-11 17:37           ` Daniel Sanders

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E484D272A3A61B4880CDF2E712E9279F4591CDE8@hhmail02.hh.imgtec.org \
    --to=daniel.sanders@imgtec.com \
    --cc=Leonid.Yegoshin@imgtec.com \
    --cc=Markos.Chandras@imgtec.com \
    --cc=Toma.Tabacu@imgtec.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=macro@linux-mips.org \
    --cc=ralf@linux-mips.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).