Open shiltian opened 3 months ago
The IR is fairly simple:
; ModuleID = 'foo.ll' source_filename = "foo.cpp" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" %"class.std::__cxx11::basic_ostringstream" = type { %"class.std::basic_ostream.base", %"class.std::__cxx11::basic_stringbuf", %"class.std::basic_ios" } %"class.std::basic_ostream.base" = type { ptr } %"class.std::__cxx11::basic_stringbuf" = type { %"class.std::basic_streambuf", i32, %"class.std::__cxx11::basic_string" } %"class.std::basic_streambuf" = type { ptr, ptr, ptr, ptr, ptr, ptr, ptr, %"class.std::locale" } %"class.std::locale" = type { ptr } %"class.std::__cxx11::basic_string" = type { %"struct.std::__cxx11::basic_string<char>::_Alloc_hider", i64, %union.anon } %"struct.std::__cxx11::basic_string<char>::_Alloc_hider" = type { ptr } %union.anon = type { i64, [8 x i8] } %"class.std::basic_ios" = type { %"class.std::ios_base", ptr, i8, i8, ptr, ptr, ptr, ptr } %"class.std::ios_base" = type { ptr, i64, i64, i32, i32, i32, ptr, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, ptr, %"class.std::locale" } %"struct.std::ios_base::_Words" = type { ptr, i64 } @_ZZ3fooB5cxx11vE2osB5cxx11 = internal thread_local global %"class.std::__cxx11::basic_ostringstream" zeroinitializer, align 8 @_ZGVZ3fooB5cxx11vE2osB5cxx11 = internal thread_local global i8 0, align 1 @__dso_handle = external hidden global i8 ; Function Attrs: mustprogress noinline optnone uwtable define void @_Z3fooB5cxx11v(ptr dead_on_unwind noalias writable sret(%"class.std::__cxx11::basic_string") align 8 %agg.result) #0 { entry: %result.ptr = alloca ptr, align 8 store ptr %agg.result, ptr %result.ptr, align 8 %0 = load i8, ptr @_ZGVZ3fooB5cxx11vE2osB5cxx11, align 1 %guard.uninitialized = icmp eq i8 %0, 0 br i1 %guard.uninitialized, label %init.check, label %init.end, !prof !4 init.check: ; preds = %entry call void @_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev(ptr noundef nonnull align 8 dereferenceable(112) @_ZZ3fooB5cxx11vE2osB5cxx11) %1 = call i32 @__cxa_thread_atexit(ptr @_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev, ptr @_ZZ3fooB5cxx11vE2osB5cxx11, ptr @__dso_handle) #3 store i8 1, ptr @_ZGVZ3fooB5cxx11vE2osB5cxx11, align 1 br label %init.end init.end: ; preds = %init.check, %entry %2 = call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @_ZZ3fooB5cxx11vE2osB5cxx11) call void @_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv(ptr dead_on_unwind writable sret(%"class.std::__cxx11::basic_string") align 8 %agg.result, ptr noundef nonnull align 8 dereferenceable(112) %2) ret void } declare void @_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev(ptr noundef nonnull align 8 dereferenceable(112)) unnamed_addr #1 ; Function Attrs: nounwind declare void @_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev(ptr noundef nonnull align 8 dereferenceable(112)) unnamed_addr #2 ; Function Attrs: nounwind declare i32 @__cxa_thread_atexit(ptr, ptr, ptr) #3 ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #4 declare void @_ZNKSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv(ptr dead_on_unwind writable sret(%"class.std::__cxx11::basic_string") align 8, ptr noundef nonnull align 8 dereferenceable(112)) #1 attributes #0 = { mustprogress noinline optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #3 = { nounwind } attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } !llvm.module.flags = !{!0, !1, !2, !3} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 8, !"PIC Level", i32 2} !2 = !{i32 7, !"uwtable", i32 2} !3 = !{i32 7, !"frame-pointer", i32 2} !4 = !{!"branch_weights", i32 1, i32 1023}
If LLVM is built with expensive check on, it emits backend errors:
*** Bad machine code: FrameSetup is after another FrameSetup *** - function: _Z3fooB5cxx11v - basic block: %bb.1 init.check (0x57da4b683c38) - instruction: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp *** Bad machine code: FrameDestroy is not after a FrameSetup *** - function: _Z3fooB5cxx11v - basic block: %bb.1 init.check (0x57da4b683c38) - instruction: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
However, there is no issue if the expensive check is off.
@llvm/issue-subscribers-backend-x86
Author: Shilei Tian (shiltian)
Looks like this is the same problem as in https://github.com/llvm/llvm-project/issues/45574.
The IR is fairly simple:
If LLVM is built with expensive check on, it emits backend errors:
However, there is no issue if the expensive check is off.