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)

Reply via email to