<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/63415>63415</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            clang miscompilation with std::optional?
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          shkoo
      </td>
    </tr>
</table>

<pre>
    I'm encountering a case where constructing a std::optional from std::nullopt behaves differently from using the default constructor, which I don't think should ever happen.  Best I can tell, using std::nullopt results in a poison value propagating that ends up causing a register to not be cleared, resulting in miscompilation?

Here's the version of clang I'm using:
> Ubuntu clang version 15.0.7
> Target: x86_64-pc-linux-gnu
> Thread model: posix
> InstalledDir: /usr/bin
> Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
> Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
> Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
> Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
> Candidate multilib: .;@ m64
> Selected multilib: .;@ m64
> Found CUDA installation: /usr/local/cuda, version 

Though the problem also looks like it occurs on compiler explorer for "clang trunk" with the "x86-64 gcc 10.3" toolchain.

I'm using the following options to generate the miscompile: "-std=c++17 -DMISCOMPILE -O2 --target=x86_64-pc-linux-gnu". Without the -DMISCOMPILE it compiles differently (and I believe correctly).

Compiler explorer shows that the MISCOMPILE version is missing a "xor %eax, %eax":
Compiler explorer link for clang 15.0.0: https://godbolt.org/z/ded5q1f8W
Compiler explorer link for clang trunk: https://godbolt.org/z/rh87KMnje

I've used cvise to try to trim down the test case as much as I can:
```
#include <cassert>
#include <functional>
#include <memory>
#include <optional>
#include <tuple>
namespace llvm {
template <typename To, typename, typename>
struct DefaultDoCastIfPossible {
    static To doCastIfPossible(int);
};
template <typename, typename, typename = void>
struct CastInfo;
template <typename To, typename From>
auto dyn_cast(From Val) {
    return CastInfo<To, From>::doCastIfPossible(Val);
}
template <typename>
class SmallVectorImpl;
}  // namespace llvm
using llvm::dyn_cast;
using llvm::SmallVectorImpl;
namespace llvm {
template <typename T, bool = std::is_class<T>::value>
struct function_traits : function_traits<decltype(&T::operator())> {};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType (ClassType::*)(Args...) const, false> {
 template <size_t Index>
    using arg_t = std::tuple_element_t<Index, std::tuple<Args...>>;
};
}  // namespace llvm
namespace mlir {
struct LogicalResult {};
class Type {
   public:
    operator bool();
};
}  // namespace mlir
namespace llvm {
template <typename To, typename From>
struct CastInfo<
    To, From,
 std::enable_if_t<std::is_same_v<mlir::Type, std::remove_const_t<From>>>>
 : DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {};
}  // namespace llvm
namespace mlir {
class ModuleOp;
class TypeConverter {
    using ConversionCallbackFn = std::function<std::optional<LogicalResult>(
        Type, SmallVectorImpl<Type> &, Type)>;

   public:
    void registerConversion(ConversionCallbackFn);
    template <typename FnT, typename T = typename llvm::function_traits<
 std::decay_t<FnT>>::template arg_t<0>>
    void addConversion(FnT callback) {
        registerConversion(wrapCallbackX<T>(callback));
 }
    template <typename T, typename FnT>
 std::enable_if_t<std::is_invocable_v<FnT, T>, ConversionCallbackFn>
 wrapCallbackX(FnT callback) {
        return wrapCallback<T>(
 [callback](T type, SmallVectorImpl<Type> &, Type) {
                if (callback(type)) {
                }
                return std::optional<LogicalResult>();
            });
    }
    template <typename T, typename FnT>
    std::enable_if_t<std::is_invocable_v<FnT, T, SmallVectorImpl<Type> &, Type>,
 ConversionCallbackFn>
    wrapCallback(FnT callback) {
        return [callback](Type type, SmallVectorImpl<Type> &results,
 Type callStack) -> std::optional<LogicalResult> {
            T derivedType = dyn_cast<T>(type);
            if (derivedType)
#ifdef MISCOMPILE
                return std::nullopt;
#else
 return std::optional<LogicalResult>();
#endif
            return callback(derivedType, results, callStack);
        };
 }
};
class Pass {
    virtual void runOnOperation();
};
template <typename>
class OperationPass : Pass {};
class ValType : public Type {};
}  // namespace mlir
using namespace mlir;
struct SemanticLoweringTypeConverter : TypeConverter {
 SemanticLoweringTypeConverter() {
        addConversion([](ValType type) {
            __assert_fail("", "", 2, __PRETTY_FUNCTION__);
 return type;
        });
    }
};
struct SemanticLoweringPass : OperationPass<ModuleOp> {
    void runOnOperation() { SemanticLoweringTypeConverter converter; }
};
std::unique_ptr<OperationPass<ModuleOp>> createSemanticLoweringPass() {
    return std::make_unique<SemanticLoweringPass>();
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WUtz4zYS_jXwpUsqGdTz4INMWbuuzcRTGWWye1JBYEtCDAIMAMp2fv0WAFIk9fB4JjUulR4E0M-vv27SzFqxU4h3ZHRPRosbVrq9Nnd2_6z1zUZnb3ePhE5yQMV1qRwaoXbAgDOL8LJHg8C1ss6U3MUV6zKSzEky14UTWjEJW6Pz5rIqpdSFgw3u2QEtZGK7RYPKybe4s7RekNsjZLhlpXSNBm0ITeFlL_geHiHTitCJA7cX6hnsXpcyAzyggT0rClR9gHu0Dh6BMwUOpfSno_gzcwzaUjoLQgGDQgurFRyYLBEKowu2Yy5axRygyiyUBXAWZTEwuBPWoQGnQWnvG3CJzGDmNUbRfqdQkAvLdV4IyXx0SLIkgwUZzOP7v9EgoRMbvD-gsUIr0FvgkqkdxEQEnd72eC55gN83pXJltak-dTvqD_qTZtOKmR06kszhdTpej4e9gvekUOVrb6fK1ra9QZZBrjOUfnOhrXhtlh-VdUxKzBbC-GVCl6U1hC43QjW7lrpUmQ96JjLmEP6VpiDiycrrk5N02e8TupRiQ-hyxzmhy8rKxkS6vB38dBXTn65h1mj4ghK5w-xnxCc92p177PmTyRz6JLknwwHk4-EFM765M4Yk_X0xv26u1JxJQpe8zJgHf43HNsxXe13u9gHkhdEbiTkwaTVIrZ8tSPGMIBxozktjQSuIBYMG8LWQ2qCBrTZAKI2Qd6ZUz4RSeBEuSiWUvk7HvfEQdpzD7aCf-GWnteR7JlS_bUyrqsLZrZZSv_hfkcCsL-odKjQ-mn7HsYQxek57gU0WnNB7Qu9vJ9BbfHr8kj59-vz4ywP0nij0eq6qv8Wl8qO0D38It9elCxo654WrA9AlS0KnTGXwCBuUAg-eiI1B7uQbobOOi-lZ_Oxev9jIZl5fS1udL2G9nxW_-XiGiI-Qvfqs1t_okYjOdUjPyj5RMUuBkAY-YnvnCusP0qWHs842Wrq-NjtCl38TuswwG_11u53-8UHJMf8fEGz208l_Pqk_8TT_B4TSYgb8ICz6fDvzFj9EDpl-USFKzjeT0PiYhbzke_8ZmktDx-NB9Yo_aSIUl2WGQJKUM2vROJI8XFrdlorHhnllQ465Nm9XFutme2XZlYVHa7WmWI62YBxBykMOZHIfrzvMC-lR7k-8Fej3wUr7hNc_O99rebE5wyK264VOmXWP28_aWrGR2MgHALCOOcFhpSE72UfoVChH6MxTT_Rhsjh-v2TbNcOAJAs4aJGdWhgUqq1-V-qJx7A0Oj8KYqXTkL2pNWfWETr1i_DVM96s66dBVxrV0phGsbW0MHxcCEGU1QnBdf9rq7hk1sKXnEn5Ff2Y9JgXsi0DINYEdFMf1yP3hd_Rqtq9WsDphmuKvg9XPhobrWXI1nEeE3YdvPEBO8YpDGKnyawLZu0ME86CZ4CTayRJM-TS6yR0Suh4VY-mns39NDn1wfbxfgjmfgNwkHrTVkFcCyG_hVyfXu73-zA3O_sNu0mSNuc9qTc6gq2EzoONUy-r7-eAWRyIva4tkxZr4yP22nZb8TeuHTyqDF-PZnh0VoOr2a1dN_yBKNYoMUfl1o4kaTxM05M9JElrg3yWHi4W7beQ11zLpTCNE1WkftE7wZn8LczPp_mJmI9BaxVeUW6k4EdC9s7W2Q5oq1L-cWu9Zf-YNrskcsZGaWNsiyVoffkYeVRsI3EttiEz7ZqxLMf1wXcJGSZzksxrPB63Gcz1AdcBPEHAkYvqV1TnC-kKl3dpjKbv8NtZQf0oGGKiP-mslPhUXMh_qtUBjb_96jBwxHhc9CNNyqTcMP68VF3I1_XYjmjTTtMOCL1ndNroCBmr4nzGimks4gcgdOw3xI2zTrG8A1vfwI53lo0bniEu-NQGtT99EZRLteqgchUicfzZMPw5R51CMUPO3iKK1KpGUGCHWnFgF5Kkgw64asdYlnV8WqoV8Mqbs2YaG-qFSLwYVtQx-G_dMui0JagTl2M3vRqhbnwq1z5chUIdNA-LhyowPu3BpvQiEhvpXU8-FI8wYLTPNQGo_R3dH2WMFoROV-C-E63nius_sYVOqKeuwvd7hzoZaP9V7ny0Ak_Q3hZ_svSPch4G1h9N-4ejHPBRaXwfJQDdhH8cJ-dQ8J3zQ2ioHo01NoajXtoXV2nt-a0fyd1lZKwgQyMOmMV2niyaEfsI6Rpdl9IeodiS4Tceb4O2GW5bt7gfw1_1XLBhapqgn7Xi4R9Hq5ejMrE9t6KS2SqojkP1c0Sfh07wzyLSbroN_M9np8_-rZOPgzCuZLJqPaV6Uk9hdopk-123Zt1bk6OYqDOZN8rPzPrKZAWDedUWmynvO6a12P5PVpLugPkFc6ac4L_ol_Bg-2SaSOZX54t3T8ZYnUP9tOfFR-7xpq9Vjlfoc72Ozw_WWybiGEvDK4XmW3hbrz__9rBa_W-9_P3XdPX49Ot63YFJBbSg7BJ2rhFoO_pXAnhMbyfhJEmb8e2EAq5CzW_7RoL4MeDJ_TUzqwItlfirxHXhDEnSd4zz9nGDzOEl1y4l9pQKcvaM66iOJOlFKeekcLS9fn50k90l2SyZsRu8ux1PJ3Q2oLPRzf4u2Y75kA0mMxwMhnwyxWRAB8PNLWNbitkUb8QdHdBkMKaD29lwOBr1s_FksNniLBmNaYabKRkOMGdC9v2419dmdyOsLfFunAxvRzeSbVDa8N8gShW-QFj08BotbsydP9PblDtLhgMprLONFCecxLv4SK77X474YPYCWS5vSiPvTh7bCbcvN33u7y-WYSKNH73C6D-RO0KXwSRL6DKY_P8AAAD__5cWMtU">