From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp2-g21.free.fr (smtp2-g21.free.fr [IPv6:2a01:e0c:1:1599::11]) by sourceware.org (Postfix) with ESMTPS id 4F5E43858D32 for ; Sun, 17 Sep 2023 19:33:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4F5E43858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=free.fr Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=free.fr Received: from [192.168.1.28] (unknown [90.112.30.115]) (Authenticated sender: paulf@free.fr) by smtp2-g21.free.fr (Postfix) with ESMTPSA id C93C12003C8 for ; Sun, 17 Sep 2023 21:33:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=free.fr; s=smtp-20201208; t=1694979201; bh=DVrnrfiFFLsm6cmD7bEiEuLUSf6/9T0B4msXu5C9CuM=; h=Date:To:From:Subject:From; b=Xkt+/HoYbpxMm1ps3YwiHHkolN/Qpab6Fq4milmCHTIbqMwpArOEgVgyT/4rZfLue s6nLhsyy7cEek50YIqOXPDtXo6juMRM+TAL27LxB3P+avP2Ej1pRYJBnR0+kZc9Fqk zdtb8btVcToFrzStSw+rjWE10VXjAD0OurVZAESq86/+EyraA6aR8d+PZ0izHUSq45 5pxqj9l30YQbk/tCXhcsw0wqfdhF6Lh9zqcvyLF95juiQ4Z6q+bSiShvPLDsYllElz iV3hEgOTWMDKKDWX/7ov+Flw+CGMcAivvBbE50DWEzRBZuRW/7br/88vqXtejQh11K SVqXBQC1ZCpRg== Message-ID: <12c6db0e-10cf-eef6-6209-77da64738897@free.fr> Date: Sun, 17 Sep 2023 21:33:21 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:102.0) Gecko/20100101 Thunderbird/102.15.1 To: gcc@gcc.gnu.org Content-Language: en-US From: Paul Floyd Subject: Safe transposition of logical and operands Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,JMQ_SPF_NEUTRAL,KAM_SHORT,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi I'm looking at a Valgrind issue. Full details here https://bugs.kde.org/show_bug.cgi?id=472329 This code void foo(std::optional f) { std::cout << (f ? *f : 0) << std::endl; std::set test; test.emplace(0); auto it{test.begin()}; while (it != test.end()) { int64_t b{*it}; // Valgrind error on next line if (f && *f != b) { [snip] int main() { foo(std::nullopt); } generates (using g++ 12.2 on FreeBSD 13.2 amd64) movq 40(%rbx), %rax Error on next line: cmpq %r14, %rax # f, SR.252 je .L47 cmpb $0, -97(%rbp) #, %sfp jne .L69 Unless I'm completely mistaken cmpq %r14, %rax is the quadword comparison of *f != b and cmpb $0, -97(%rbp) is the std::optional::operator bool() comparison with 0. That means that g++ has transposed the order of evaluation. The first cmpq/je generates a ==49599== Conditional jump or move depends on uninitialised value(s) Valgrind has machinery to detect transformations like this and to convert them back into bit accurate bitwise ands. However, Valgrind thinks that these transpositions can't be done when there are potentially trapping memory loads like *f. So who is right? Is this a safe transformation? Regards Paul