From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id 9FF853858404 for ; Thu, 28 Oct 2021 07:10:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9FF853858404 Received: by mail-pl1-x636.google.com with SMTP id w16so3794751plg.3 for ; Thu, 28 Oct 2021 00:10:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=vJ+El7xEDtZGRxw6Av9fPpbQ+x7AYoynUYzpaaHYAJM=; b=CFa+YEDGWoKAjSF5qG/RLoUKI52pc29D39Ux3KCO0qmW9dsLBPk+TrFt4TNa1Y43WH S56+cvldkhAJlHthgxh3UbFOaGIGEw/PS65HmT+QTc8hCRB5bM+8y7lpLEgG5LohD/AW vC09KEC6D6gYZkAR3z6+t713lWYcg9+XbYSm7L8zhfNuGdDUrcEJvR6TH6MNQDFbCww2 +gNdrBKpPeTKukmiqblpBT5KYTmOd9mGn20Aeqyjenfayhzd/EeKupkg7bBeQkiy81bm 3Rsfq4G4cacoVZz0JlSbyz8VZZr6TFSIFzMW6oBBv9tOxAQ1ztdMtMsMsdL4iQ3iUNeE /JlQ== X-Gm-Message-State: AOAM531QgMN7BTU1NSBNqpvte9eW2ojxE2RTxJjZ2fFU7f2LRYPlQTVP dIGqYfkzuKhTDc4UOSQmbbmfiq22Ybvze9WcdAq40yjPurX/b0bD X-Google-Smtp-Source: ABdhPJzOZGhtell4hLnm8GwYVer+jYMsWrOCpGg+38qJmwCth2w+7KBUJQHFm4qwd48GUssBG8ktLb+9odtkJ0UOhek= X-Received: by 2002:a17:90a:ce13:: with SMTP id f19mr2677129pju.151.1635405052386; Thu, 28 Oct 2021 00:10:52 -0700 (PDT) MIME-Version: 1.0 From: =?UTF-8?B?4piCSm9zaCBDaGlhICjorJ3ku7vkuK0p?= Date: Thu, 28 Oct 2021 15:10:41 +0800 Message-ID: Subject: Generated assembly code for returning std::optional To: gcc-help X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Oct 2021 07:10:55 -0000 Under -O3 -std=c++17, the assembly code generated by gcc 11.2 for some std::optional C++ code seems less optimal than I expect; it is writing the content of optional return values to both the stack and to the RAX register. What am I missing? I was under the impression that return values are put in RAX if they can fit. Why does gcc have to write the return value to both the stack and RAX instead of just one of them? Can the writing to the stack be avoided? foo() & bar() return optional and demonstrate this problem. baz() returns int32_t and does not have the problem. bun(), which calls foo() and bar(), accesses the optional return value through RAX and not through the stack, so it is evident that the stack value is redundant. https://godbolt.org/z/Ef14n8EcM C++ code: #include #include using namespace std; optional foo() { return 111; } optional bar() { return nullopt; } uint32_t baz() { return 111; } bool bun(bool x) { auto f = x ? foo : bar; return f().has_value(); } Generated assembly code: foo(): mov DWORD PTR [rsp-8], 111 mov BYTE PTR [rsp-4], 1 mov rax, QWORD PTR [rsp-8] ret bar(): mov BYTE PTR [rsp-4], 0 mov rax, QWORD PTR [rsp-8] ret baz(): mov eax, 111 ret bun(bool): sub rsp, 24 mov edx, OFFSET FLAT:bar() test dil, dil mov eax, OFFSET FLAT:foo() cmove rax, rdx call rax add rsp, 24 shr rax, 32 ret