From owner-freebsd-hackers@FreeBSD.ORG Sun Oct 19 13:00:18 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 B0FAD39C for ; Sun, 19 Oct 2014 13:00:18 +0000 (UTC) Received: from platinum.linux.pl (platinum.edu.pl [81.161.192.4]) by mx1.freebsd.org (Postfix) with ESMTP id 711BA35E for ; Sun, 19 Oct 2014 13:00:17 +0000 (UTC) Received: by platinum.linux.pl (Postfix, from userid 87) id 1C48D45218C; Sun, 19 Oct 2014 14:50:13 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on platinum.linux.pl X-Spam-Level: X-Spam-Status: No, score=-1.0 required=3.0 tests=ALL_TRUSTED,AWL, TO_NO_BRKTS_PCNT autolearn=disabled version=3.4.0 Received: from [10.255.0.2] (unknown [83.151.38.73]) by platinum.linux.pl (Postfix) with ESMTPA id 916BA4520C0 for ; Sun, 19 Oct 2014 14:50:12 +0200 (CEST) Message-ID: <5443B2D4.3020407@platinum.linux.pl> Date: Sun, 19 Oct 2014 14:47:16 +0200 From: Adam Nowacki User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: freebsd-hackers@freebsd.org Subject: Re: panic in ivy_rng_store() when compiled with -O0 References: <54384ABD.5080806@FreeBSD.org> <2533199.DHZybpy49d@ralph.baldwin.cx> <54415E13.4000203@delphij.net> <7A5C3D84-1B1F-4BA3-818D-37231BF424FE@FreeBSD.org> In-Reply-To: <7A5C3D84-1B1F-4BA3-818D-37231BF424FE@FreeBSD.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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: Sun, 19 Oct 2014 13:00:18 -0000 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");