From owner-freebsd-hackers@FreeBSD.ORG Tue Oct 21 15:12:05 2014 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id EB221BAA for ; Tue, 21 Oct 2014 15:12:04 +0000 (UTC) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 72BA0B17 for ; Tue, 21 Oct 2014 15:12:04 +0000 (UTC) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.14.9/8.14.9) with ESMTP id s9LFBwnx056171 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 21 Oct 2014 18:11:58 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.9.2 kib.kiev.ua s9LFBwnx056171 Received: (from kostik@localhost) by tom.home (8.14.9/8.14.9/Submit) id s9LFBviN056170; Tue, 21 Oct 2014 18:11:57 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Tue, 21 Oct 2014 18:11:57 +0300 From: Konstantin Belousov To: Adam Nowacki Subject: Re: panic in ivy_rng_store() when compiled with -O0 Message-ID: <20141021151157.GC1877@kib.kiev.ua> References: <54384ABD.5080806@FreeBSD.org> <2533199.DHZybpy49d@ralph.baldwin.cx> <54415E13.4000203@delphij.net> <7A5C3D84-1B1F-4BA3-818D-37231BF424FE@FreeBSD.org> <5443B2D4.3020407@platinum.linux.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5443B2D4.3020407@platinum.linux.pl> User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on tom.home Cc: freebsd-hackers@freebsd.org X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Oct 2014 15:12:05 -0000 On Sun, Oct 19, 2014 at 02:47:16PM +0200, Adam Nowacki wrote: > On 2014-10-17 20:33, Dimitry Andric wrote: > > On 17 Oct 2014, at 20:21, Xin Li wrote: > >> On 10/17/14 08:53, John Baldwin wrote: > >>> On Friday, October 10, 2014 02:08:13 PM Navdeep Parhar wrote: > > ... > >> movq %rdi,(%rdi) is obviously wrong (%rdi holds the result from > >> rdrand), which I believed to be a compiler bug in register allocation. > >> > >> Navdeep have committed a change to mark 'tmp' input+output, which does > >> fix the output but I'm not 100% sure if that's right, as 'tmp' is not > >> considered an input of the inline assembler block, and this may break > >> compile on other compilers, but for now it's better than previous > >> situation. > >> > >> Speaking for the compiler issue, Dimitry have reported this upstream at: > >> > >> http://llvm.org/bugs/show_bug.cgi?id=21273 > >> > >> There is a suggestion in the reply, that change 'tmp' to early clobber > >> would workaround the issue, like: > >> > >> Index: ivy.c > >> =================================================================== > >> - --- ivy.c (revision 273195) > >> +++ ivy.c (working copy) > >> @@ -79,7 +79,7 @@ > >> "2:\n\t" > >> "mov %2,%1\n\t" /* *buf = tmp */ > >> "3:" > >> - - : "+q" (retry), "=m" (*buf), "+q" (tmp) : : "cc"); > >> + : "+q" (retry), "=m" (*buf), "=&q" (tmp) : : "cc"); > > > > Yes, this generates the correct code for all cases I tried, e.g. with > > gcc 4.2 from base, gcc 4.7 through 5.0 from ports, clang 3.4, clang 3.5 > > and clang trunk, all at -O0 through -O3, and -Os. > > > > So at the moment this fix is the best option, I think. > > GCC documentation explains what happens: > "The same problem can occur if one output parameter (a) allows a > register constraint and another output parameter (b) allows a memory > constraint. The code generated by GCC to access the memory address in b > can contain registers which might be shared by a, and GCC considers > those registers to be inputs to the asm. As above, GCC assumes that such > input registers are consumed before any outputs are written. This > assumption may result in incorrect behavior if the asm writes to a > before using b. Combining the `&' constraint with the register > constraint ensures that modifying a will not affect what address is > referenced by b. Omitting the `&' constraint means that the location of > b will be undefined if a is modified before using b. " > > Both tmp and retry need the '&' constraint. > > : "+&q" (retry), "=m" (*buf), "=&q" (tmp) : : "cc"); The inline asm documentation was extensively rewritten for gcc 5.0, it seems. Thank you for the pointer, indeed, the situation in ivy_rng_store() exactly matches the paragraph you cite. Should the '&' modifier be applied for register output operands only ? In particular, I wonder if *buf operand should be fixed the same way. The gcc doc does not say explicitely which operand, (a) or (b), should be marked as earlyclobber at all. diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c index 23fd542..9fbfbf0 100644 --- a/sys/dev/random/ivy.c +++ b/sys/dev/random/ivy.c @@ -79,7 +80,7 @@ ivy_rng_store(long *buf) "2:\n\t" "mov %2,%1\n\t" /* *buf = tmp */ "3:" - : "+q" (retry), "=m" (*buf), "+q" (tmp) : : "cc"); + : "+&q" (retry), "=&m" (*buf), "=&q" (tmp) : : "cc"); return (retry); #else /* __GNUCLIKE_ASM */ return (0);