Skip to content

Instantly share code, notes, and snippets.

@arielb1
Created June 4, 2016 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arielb1/8717eeaf5ac80fc4125e118729b5cb0c to your computer and use it in GitHub Desktop.
Save arielb1/8717eeaf5ac80fc4125e118729b5cb0c to your computer and use it in GitHub Desktop.
; ModuleID = 'example.0.rs'
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
%"2.std::str::Chars" = type { %"2.std::slice::Iter<u8>" }
%"2.std::slice::Iter<u8>" = type { i8*, i8*, %"2.std::marker::PhantomData<&'static u8>" }
%"2.std::marker::PhantomData<&'static u8>" = type {}
%"2.std::option::Option<char>" = type { i32, [0 x i32], [1 x i32] }
%"2.std::option::Option<u32>" = type { i32, [0 x i32], [1 x i32] }
; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
declare i32 @__CxxFrameHandler3(...) unnamed_addr
; Function Attrs: inlinehint uwtable
define internal i64 @something() unnamed_addr #2 personality i32 (...)* @__CxxFrameHandler3 {
entry-block:
ret i64 0
}
; Function Attrs: inlinehint uwtable
define i64 @_ZN4core4iter8iterator8Iterator4fold17h0471ccca27326883E(%"2.std::str::Chars"* noalias nocapture dereferenceable(16), i64) unnamed_addr #2 personality i32 (...)* @__CxxFrameHandler3 {
entry-block:
%arg1 = alloca i64
%self = alloca %"2.std::str::Chars"
%init = alloca i64
%accum = alloca i64
%_result = alloca {}
%iter = alloca %"2.std::str::Chars"
%x = alloca i32
%temp1 = alloca {}
%temp3 = alloca %"2.std::str::Chars"
%temp4 = alloca %"2.std::str::Chars"
%temp5 = alloca %"2.std::option::Option<char>"
%temp7 = alloca %"2.std::str::Chars"*
%temp10 = alloca { i64, i32 }
%temp15 = alloca i8
%temp16 = alloca i8
store i64 %1, i64* %arg1
br label %start
start: ; preds = %entry-block
store i8 0, i8* %temp16
store i8 0, i8* %temp15
store i8 1, i8* %temp15
%2 = bitcast %"2.std::str::Chars"* %0 to i8*
%3 = bitcast %"2.std::str::Chars"* %self to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
%4 = load i64, i64* %arg1
store i64 %4, i64* %init
%5 = load i64, i64* %init
store i8 1, i8* %temp16
store i64 %5, i64* %accum
store i8 0, i8* %temp15
%6 = bitcast %"2.std::str::Chars"* %self to i8*
%7 = bitcast %"2.std::str::Chars"* %temp4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %7, i8* %6, i64 16, i32 8, i1 false)
br label %bb3
bb1: ; preds = %bb15, %bb16
cleanupret from %cleanuppad9 unwind to caller
bb2: ; preds = %bb17, %bb18
cleanupret from %cleanuppad7 unwind label %bb16
bb3: ; preds = %start
%8 = bitcast %"2.std::str::Chars"* %temp3 to i8*
%9 = bitcast %"2.std::str::Chars"* %iter to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %9, i8* %8, i64 16, i32 8, i1 false)
br label %bb4
bb4: ; preds = %bb28, %bb22, %bb3
store %"2.std::str::Chars"* %iter, %"2.std::str::Chars"** %temp7
%10 = load %"2.std::str::Chars"*, %"2.std::str::Chars"** %temp7, !nonnull !0
%11 = invoke i64 @something()
to label %bb7 unwind label %bb24
bb5: ; preds = %bb8
br label %bb12
bb6: ; preds = %bb26, %bb29, %bb19, %bb20_cleanup_trampoline_bb6, %bb24
%cleanuppad5 = cleanuppad within none []
cleanupret from %cleanuppad5 unwind label %bb18
bb7: ; preds = %bb4
%12 = bitcast %"2.std::option::Option<char>"* %temp5 to i64*
store i64 %11, i64* %12, align 4
%13 = getelementptr inbounds %"2.std::option::Option<char>", %"2.std::option::Option<char>"* %temp5, i32 0, i32 0
%14 = load i32, i32* %13, !range !1
switch i32 %14, label %unreachable [
i32 0, label %bb8
i32 1, label %bb9
]
bb8: ; preds = %bb7
br label %bb5
bb9: ; preds = %bb7
%15 = bitcast %"2.std::option::Option<char>"* %temp5 to { i32, i32 }*
%16 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %15, i32 0, i32 1
%17 = load i32, i32* %16, !range !2
store i32 %17, i32* %x
store i8 0, i8* %temp16
%18 = load i64, i64* %accum
%19 = load i32, i32* %x, !range !2
%20 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 0
store i64 %18, i64* %20
%21 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 1
store i32 %19, i32* %21
%22 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 0
%23 = load i64, i64* %22
%24 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 1
%25 = load i32, i32* %24
%26 = invoke i64 @something()
to label %bb10 unwind label %bb20
bb10: ; preds = %bb9
store i8 1, i8* %temp16
store i64 %26, i64* %accum
br label %bb11
bb11: ; preds = %bb10
br label %bb22
bb12: ; preds = %bb5
store i8 0, i8* %temp16
%27 = load i64, i64* %accum
br label %bb13
bb13: ; preds = %bb12
br label %bb14
bb14: ; preds = %bb13
ret i64 %27
bb15: ; preds = %bb16
store i8 0, i8* %temp15
br label %bb1
bb16: ; preds = %bb27, %bb2
%cleanuppad9 = cleanuppad within none []
%28 = load i8, i8* %temp15, !range !3
%29 = trunc i8 %28 to i1
br i1 %29, label %bb15, label %bb1
bb17: ; preds = %bb18
store i8 0, i8* %temp16
br label %bb2
bb18: ; preds = %bb25, %bb6, %bb23
%cleanuppad7 = cleanuppad within none []
%30 = load i8, i8* %temp16, !range !3
%31 = trunc i8 %30 to i1
br i1 %31, label %bb17, label %bb2
bb19: ; preds = %bb20
cleanupret from %cleanuppad2 unwind label %bb6
bb20: ; preds = %bb9
%cleanuppad2 = cleanuppad within none []
%32 = getelementptr inbounds %"2.std::option::Option<char>", %"2.std::option::Option<char>"* %temp5, i32 0, i32 0
%33 = load i32, i32* %32, !range !1
switch i32 %33, label %unreachable [
i32 0, label %bb19
i32 1, label %bb20_cleanup_trampoline_bb6
]
bb21: ; preds = %bb22
br label %bb28
bb22: ; preds = %bb11
%34 = getelementptr inbounds %"2.std::option::Option<char>", %"2.std::option::Option<char>"* %temp5, i32 0, i32 0
%35 = load i32, i32* %34, !range !1
switch i32 %35, label %unreachable [
i32 0, label %bb21
i32 1, label %bb4
]
bb23: ; preds = %start
%cleanuppad = cleanuppad within none []
cleanupret from %cleanuppad unwind label %bb18
bb24: ; preds = %bb4
%cleanuppad1 = cleanuppad within none []
cleanupret from %cleanuppad1 unwind label %bb6
bb28: ; preds = %bb21
br label %bb4
unreachable: ; preds = %bb22, %bb20, %bb7
unreachable
bb20_cleanup_trampoline_bb6: ; preds = %bb20
cleanupret from %cleanuppad2 unwind label %bb6
}
; Function Attrs: nounwind
declare void @llvm.assume(i1) #3
attributes #0 = { uwtable }
attributes #1 = { argmemonly nounwind }
attributes #2 = { inlinehint uwtable }
attributes #3 = { nounwind }
!0 = !{}
!1 = !{i32 0, i32 2}
!2 = !{i32 0, i32 1114112}
!3 = !{i8 0, i8 2}
While deleting: token %cleanuppad2
Use still stuck around after Def is destroyed: cleanupret from %cleanuppad2 unwind label %bb18
Use still stuck around after Def is destroyed: cleanupret from %cleanuppad2 unwind label %bb18
opt: /home/ariel/Rust/rust/src/llvm/lib/IR/Value.cpp:82: virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.
0 opt 0x0000000001826fe5 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1 opt 0x0000000001824956 llvm::sys::RunSignalHandlers() + 54
2 opt 0x0000000001824b6a
3 libpthread.so.0 0x00007fb6b5eddd30
4 libc.so.6 0x00007fb6b50c4478 gsignal + 56
5 libc.so.6 0x00007fb6b50c58fa abort + 362
6 libc.so.6 0x00007fb6b50bd3a7
7 libc.so.6 0x00007fb6b50bd452
8 opt 0x00000000017c33fb
9 opt 0x00000000015caaa7
10 opt 0x0000000001659b2c llvm::BasicBlock::~BasicBlock() + 140
11 opt 0x0000000001659dbb llvm::BasicBlock::eraseFromParent() + 139
12 opt 0x00000000005c1594
13 opt 0x00000000013c1d76
14 opt 0x00000000013c2d31 llvm::SimplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, unsigned int, llvm::AssumptionCache*) + 65
15 opt 0x00000000013c0f02
16 opt 0x00000000013c2d31 llvm::SimplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, unsigned int, llvm::AssumptionCache*) + 65
17 opt 0x00000000005c4e2c
18 opt 0x00000000013c1dcd
19 opt 0x00000000013c2d31 llvm::SimplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, unsigned int, llvm::AssumptionCache*) + 65
20 opt 0x00000000011d6ff9
21 opt 0x0000000001796ca3 llvm::FPPassManager::runOnFunction(llvm::Function&) + 643
22 opt 0x0000000001796db9 llvm::legacy::FunctionPassManagerImpl::run(llvm::Function&) + 137
23 opt 0x0000000001796f04 llvm::legacy::FunctionPassManager::run(llvm::Function&) + 36
24 opt 0x00000000005d5d09 main + 7321
25 libc.so.6 0x00007fb6b50b1610 __libc_start_main + 240
26 opt 0x0000000000615129 _start + 41
Stack dump:
0. Program arguments: opt example.ll -S -O3
1. Running pass 'Simplify the CFG' on function '@_ZN4core4iter8iterator8Iterator4fold17h0471ccca27326883E'
Aborted
@nagisa
Copy link

nagisa commented Jun 4, 2016

I’m having a hard time reproducing the issue.

Both opt -O3 and opt -simplifycfg work fine here and produce

; ModuleID = '<stdin>'
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"

%"2.std::str::Chars" = type { %"2.std::slice::Iter<u8>" }
%"2.std::slice::Iter<u8>" = type { i8*, i8*, %"2.std::marker::PhantomData<&'static u8>" }
%"2.std::marker::PhantomData<&'static u8>" = type {}

declare i32 @__CxxFrameHandler3(...) unnamed_addr

; Function Attrs: inlinehint norecurse nounwind readnone uwtable
define i64 @_ZN4core4iter8iterator8Iterator4fold17h0471ccca27326883E(%"2.std::str::Chars"* noalias nocapture readnone dereferenceable(16), i64) unnamed_addr #0 personality i32 (...)* @__CxxFrameHandler3 {
entry-block:
  ret i64 %1
}

attributes #0 = { inlinehint norecurse nounwind readnone uwtable }

and

target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"

%"2.std::str::Chars" = type { %"2.std::slice::Iter<u8>" }
%"2.std::slice::Iter<u8>" = type { i8*, i8*, %"2.std::marker::PhantomData<&'static u8>" }
%"2.std::marker::PhantomData<&'static u8>" = type {}
%"2.std::option::Option<char>" = type { i32, [0 x i32], [1 x i32] }

; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0

declare i32 @__CxxFrameHandler3(...) unnamed_addr

; Function Attrs: inlinehint uwtable
define internal i64 @something() unnamed_addr #1 personality i32 (...)* @__CxxFrameHandler3 {
entry-block:
  ret i64 0
}

; Function Attrs: inlinehint uwtable
define i64 @_ZN4core4iter8iterator8Iterator4fold17h0471ccca27326883E(%"2.std::str::Chars"* noalias nocapture dereferenceable(16), i64) unnamed_addr #1 personality i32 (...)* @__CxxFrameHandler3 {
entry-block:
  %arg1 = alloca i64
  %self = alloca %"2.std::str::Chars"
  %init = alloca i64
  %accum = alloca i64
  %_result = alloca {}
  %iter = alloca %"2.std::str::Chars"
  %x = alloca i32
  %temp1 = alloca {}
  %temp3 = alloca %"2.std::str::Chars"
  %temp4 = alloca %"2.std::str::Chars"
  %temp5 = alloca %"2.std::option::Option<char>"
  %temp7 = alloca %"2.std::str::Chars"*
  %temp10 = alloca { i64, i32 }
  %temp15 = alloca i8
  %temp16 = alloca i8
  store i64 %1, i64* %arg1
  store i8 0, i8* %temp16
  store i8 0, i8* %temp15
  store i8 1, i8* %temp15
  %2 = bitcast %"2.std::str::Chars"* %0 to i8*
  %3 = bitcast %"2.std::str::Chars"* %self to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  %4 = load i64, i64* %arg1
  store i64 %4, i64* %init
  %5 = load i64, i64* %init
  store i8 1, i8* %temp16
  store i64 %5, i64* %accum
  store i8 0, i8* %temp15
  %6 = bitcast %"2.std::str::Chars"* %self to i8*
  %7 = bitcast %"2.std::str::Chars"* %temp4 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %7, i8* %6, i64 16, i32 8, i1 false)
  %8 = bitcast %"2.std::str::Chars"* %temp3 to i8*
  %9 = bitcast %"2.std::str::Chars"* %iter to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %9, i8* %8, i64 16, i32 8, i1 false)
  br label %bb4

bb1:                                              ; preds = %bb16, %bb15
  cleanupret from %cleanuppad9 unwind to caller

bb2:                                              ; preds = %bb18, %bb17
  cleanupret from %cleanuppad7 unwind label %bb16

bb4:                                              ; preds = %bb10, %entry-block
  store %"2.std::str::Chars"* %iter, %"2.std::str::Chars"** %temp7
  %10 = load %"2.std::str::Chars"*, %"2.std::str::Chars"** %temp7, !nonnull !0
  %11 = invoke i64 @something()
          to label %bb7 unwind label %bb18

bb7:                                              ; preds = %bb4
  %12 = bitcast %"2.std::option::Option<char>"* %temp5 to i64*
  store i64 %11, i64* %12, align 4
  %13 = getelementptr inbounds %"2.std::option::Option<char>", %"2.std::option::Option<char>"* %temp5, i32 0, i32 0
  %14 = load i32, i32* %13, !range !1
  %switch = icmp ult i32 %14, 1
  br i1 %switch, label %bb12, label %bb9

bb9:                                              ; preds = %bb7
  %15 = bitcast %"2.std::option::Option<char>"* %temp5 to { i32, i32 }*
  %16 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %15, i32 0, i32 1
  %17 = load i32, i32* %16, !range !2
  store i32 %17, i32* %x
  store i8 0, i8* %temp16
  %18 = load i64, i64* %accum
  %19 = load i32, i32* %x, !range !2
  %20 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 0
  store i64 %18, i64* %20
  %21 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 1
  store i32 %19, i32* %21
  %22 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 0
  %23 = load i64, i64* %22
  %24 = getelementptr inbounds { i64, i32 }, { i64, i32 }* %temp10, i32 0, i32 1
  %25 = load i32, i32* %24
  %26 = invoke i64 @something()
          to label %bb10 unwind label %bb18

bb10:                                             ; preds = %bb9
  store i8 1, i8* %temp16
  store i64 %26, i64* %accum
  br label %bb4

bb12:                                             ; preds = %bb7
  store i8 0, i8* %temp16
  %27 = load i64, i64* %accum
  ret i64 %27

bb15:                                             ; preds = %bb16
  store i8 0, i8* %temp15
  br label %bb1

bb16:                                             ; preds = %bb2
  %cleanuppad9 = cleanuppad within none []
  %28 = load i8, i8* %temp15, !range !3
  %29 = trunc i8 %28 to i1
  br i1 %29, label %bb15, label %bb1

bb17:                                             ; preds = %bb18
  store i8 0, i8* %temp16
  br label %bb2

bb18:                                             ; preds = %bb4, %bb9
  %cleanuppad7 = cleanuppad within none []
  %30 = load i8, i8* %temp16, !range !3
  %31 = trunc i8 %30 to i1
  br i1 %31, label %bb17, label %bb2
}

; Function Attrs: nounwind
declare void @llvm.assume(i1) #2

attributes #0 = { argmemonly nounwind }
attributes #1 = { inlinehint uwtable }
attributes #2 = { nounwind }

!0 = !{}
!1 = !{i32 0, i32 2}
!2 = !{i32 0, i32 1114112}
!3 = !{i8 0, i8 2}

respectively, where

LLVM (http://llvm.org/):
  LLVM version 3.8.0
  Optimized build.
  Built May  7 2016 (15:37:50).
  Default target: x86_64-unknown-linux-gnu
  Host CPU: haswell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment