Bug 80331 - unused const std::string not optimized away
Summary: unused const std::string not optimized away
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on: 23383
Blocks:
  Show dependency treegraph
 
Reported: 2017-04-05 16:50 UTC by AK
Modified: 2023-12-30 20:42 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-01-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description AK 2017-04-05 16:50:56 UTC
$ cat t.cpp
#include<string>
int sain() {
  const std::string s("a");
  return 0;
}

# gcc version 7.0.0 20170118 (experimental) (GCC)
$ g++ -S -o t.s t.cpp -O2 -fno-exceptions -std=c++11

$ cat t.s
	.type	_Z4sainv, @function
_Z4sainv:
.LFB940:
	.cfi_startproc
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	movl	$.LC0+1, %esi
	subq	$32, %rsp
	.cfi_def_cfa_offset 48
	leaq	16(%rsp), %rbx
	movq	%rsp, %rdi
	movq	%rbx, (%rsp)
	call	_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag.isra.16.constprop.20
	movq	(%rsp), %rdi
	cmpq	%rbx, %rdi
	je	.L13
	call	_ZdlPv
.L13:
	addq	$32, %rsp
	.cfi_def_cfa_offset 16
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE940:
	.size	_Z4sainv, .-_Z4sainv


clang++, on the other hand, completely optimizes the const string.

	.type	_Z4sainv,@function
_Z4sainv:                               # @_Z4sainv
	.cfi_startproc
# BB#0:
	xorl	%eax, %eax
	retq
.Lfunc_end0:
	.size	_Z4sainv, .Lfunc_end0-_Z4sainv
Comment 1 Markus Trippelsdorf 2017-04-05 16:56:00 UTC
Cannot reproduce. Try a more recent snapshot?
Comment 2 Marc Glisse 2017-04-05 17:03:27 UTC
If you replace "a" with something longer (size>16 when counting the last '\0'), it does reproduce. I'd say this is a dup of 2 known issues:
- the compiled part of libstdc++ prevents optimization (maybe eventually with LTO?),
- gcc knows about malloc and free but not about new and delete.

I didn't check if those are the only blockers in this case...
Comment 3 Marc Glisse 2017-04-05 17:13:50 UTC
(In reply to Marc Glisse from comment #2)
> I didn't check if those are the only blockers in this case...

Looks like they are indeed the only blockers, since we optimize the below just fine. So, known issue (which doesn't mean we shouldn't do something about it).
(with 2 dead strings instead of 1, we need -O3, -O2 is not sufficient)

#include <bits/c++config.h>
#undef _GLIBCXX_EXTERN_TEMPLATE
#define _GLIBCXX_EXTERN_TEMPLATE 0
#include <string>
#include <memory>
inline void operator delete(void*p){__builtin_free(p);}
inline void* operator new(size_t n){return __builtin_malloc(n);}
int main() {
  const std::string s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
Comment 4 Andrew Pinski 2017-04-05 17:31:17 UTC
23383
Comment 5 Markus Trippelsdorf 2017-04-05 18:01:57 UTC
Lets close as dup.

*** This bug has been marked as a duplicate of bug 78104 ***
Comment 6 Andrew Pinski 2022-01-07 02:03:35 UTC
Reopening as it is not a dup of that one (though I think there is another bug about this one).
Comment 7 Andrew Pinski 2022-01-07 02:21:40 UTC
With -std=c++20 -O2 I get better code than just -std=c++17 -O2:
  _34 = operator new (24);
  __builtin_memcpy (_34, "a                      ", 23);
  MEM[(char_type &)_34 + 23] = 0;
  operator delete (_34, 24);

That is all I think due to what is referenced in PR 86590.
Comment 8 Jonathan Wakely 2022-01-07 10:54:05 UTC
(In reply to Andrew Pinski from comment #7)
> With -std=c++20 -O2 I get better code than just -std=c++17 -O2:
>   _34 = operator new (24);
>   __builtin_memcpy (_34, "a                      ", 23);
>   MEM[(char_type &)_34 + 23] = 0;
>   operator delete (_34, 24);
> 
> That is all I think due to what is referenced in PR 86590.

Yes, it's because the explicit instantiations are disabled for C++20:

# if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
  extern template class basic_string<char>;
Comment 9 AK 2022-06-04 22:55:53 UTC
can't repro this with gcc 12.1 Seems like this is fixed?

https://godbolt.org/z/e6n94zK4E
Comment 10 Marc Glisse 2022-06-05 07:54:47 UTC
(In reply to AK from comment #9)
> can't repro this with gcc 12.1 Seems like this is fixed?

No. As stated in other comments, it still reproduces with a longer string (or with -D_GLIBCXX_USE_CXX11_ABI=0).