From owner-freebsd-hackers@freebsd.org Wed Jul 27 06:46:02 2016 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 473F7BA5084 for ; Wed, 27 Jul 2016 06:46:02 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from citapm.icyb.net.ua (citapm.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id 668151C0C; Wed, 27 Jul 2016 06:46:01 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from porto.starpoint.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citapm.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id JAA18030; Wed, 27 Jul 2016 09:45:53 +0300 (EEST) (envelope-from avg@FreeBSD.org) Received: from localhost ([127.0.0.1]) by porto.starpoint.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1bSIbJ-000D8N-1U; Wed, 27 Jul 2016 09:45:53 +0300 To: Dimitry Andric , "freebsd-hackers@freebsd.org" From: Andriy Gapon Subject: problem when compiling zfs.ko with clang with O1 on amd64 Message-ID: <667ac922-533f-2d37-706e-93fa9b069034@FreeBSD.org> Date: Wed, 27 Jul 2016 09:44:56 +0300 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jul 2016 06:46:02 -0000 First of all, what I describe next happens only when compiling with -O1 which is a non-standard option that I used to get better debugging. So, I compile zfs module with clang on amd64 head. Clang is: FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0) When -O1 is used I see that statements like 'T x = { 0 };' are translated to calls to external memset function with the standard arguments. On the other hand, since recently a few ZFS source files (all hash related: sha256c.c, sha512c.c, skein.c) have explicit calls to memset(x, 0, s). Those get inlined but in a particular fashion: a local memset function is generated in each file, the function is a very thin wrapper around bzero and it expects the same argument as bzero. Because of how kernel loadable modules are implemented on amd64 the external calls to memset get resolved to the first of the local functions. Because of the mismatch between the arguments provided and the arguments expected the effective calls are 'bzero(x, 0)', NOPs that is. I am not sure if I can blame clang here. It is probably correct to expect that it can generate a _local_ function named 'memset' without interfering without other compilation units. However, that can be unhelpful as we can see. Some data: $ nm -A --defined-only *.o | fgrep -w memset sha256c.o:0000000000000e60 t memset sha512c.o:00000000000010f0 t memset skein.o:0000000000000120 t memset $ nm /boot/kernel.z/zfs.ko | fgrep -w memset 0000000000019030 t memset 0000000000017e60 t memset 0000000000019500 t memset U memset Assembly of one of the local memset functions: .align 16, 0x90 .type memset, @function memset: # @memset .Lfunc_begin6: .file 5 "/usr/src/sys/sys" "libkern.h" .loc 5 187 0 # /usr/src/sys/sys/libkern.h:187:0 .cfi_startproc # BB#0: # %entry pushq %rbp .Ltmp105: .cfi_def_cfa_offset 16 .Ltmp106: .cfi_offset %rbp, -16 movq %rsp, %rbp .Ltmp107: .cfi_def_cfa_register %rbp #DEBUG_VALUE: memset:c <- 0 .loc 5 191 3 prologue_end # /usr/src/sys/sys/libkern.h:191:3 .Ltmp108: popq %rbp jmp bzero # TAILCALL .Ltmp109: .Lfunc_end6: .size memset, .Lfunc_end6-memset .cfi_endproc -- Andriy Gapon