https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94566
Bug ID: 94566 Summary: conversion between std::strong_ordering and int Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org Target Milestone: --- #include <compare> int conv1(std::strong_ordering s){ if(s==std::strong_ordering::less) return -1; if(s==std::strong_ordering::equal) return 0; if(s==std::strong_ordering::greater) return 1; __builtin_unreachable(); } std::strong_ordering conv2(int i){ switch(i){ case -1: return std::strong_ordering::less; case 0: return std::strong_ordering::equal; case 1: return std::strong_ordering::greater; default: __builtin_unreachable(); } } Compiling with -std=gnu++2a -O3. I would like the compiler to notice that those are just NOP (at most a sign-extension). Clang manages it for conv2. Gcc generates: movl $-1, %eax cmpb $-1, %dil je .L1 xorl %eax, %eax testb %dil, %dil setne %al .L1: ret and xorl %eax, %eax testl %edi, %edi je .L10 cmpl $1, %edi sete %al leal -1(%rax,%rax), %eax .L10: ret (apparently the C++ committee thinks it is a good idea to provide a type that is essentially an int that can only be -1, 0 or 1, but not provide any direct way to convert to/from int)