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)