forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			116 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; RUN: opt < %s -simplifycfg -S | FileCheck %s
 | |
| 
 | |
| declare void @f()
 | |
| declare void @llvm.foo(i32) nounwind
 | |
| declare void @ProcessCLRException()
 | |
| 
 | |
| define void @test1() personality void ()* @ProcessCLRException {
 | |
| entry:
 | |
|   invoke void @f()
 | |
|     to label %exit unwind label %exn.dispatch
 | |
| exn.dispatch:
 | |
|   %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
 | |
| pad1:
 | |
|   %cp1 = catchpad within %cs [i32 1]
 | |
|   call void @llvm.foo(i32 1)
 | |
|   catchret from %cp1 to label %exit
 | |
| pad2:
 | |
|   %cp2 = catchpad within %cs [i32 2]
 | |
|   unreachable
 | |
| exit:
 | |
|   ret void
 | |
| }
 | |
| ; Remove unreachble catch2, leave catch1 as-is
 | |
| ; CHECK-LABEL: define void @test1()
 | |
| ; CHECK: %cs = catchswitch within none [label %pad1] unwind to caller
 | |
| ; CHECK-NOT: catchpad
 | |
| ; CHECK: %cp1 = catchpad within %cs [i32 1]
 | |
| ; CHECK-NOT: catchpad
 | |
| 
 | |
| ; Remove both catchpads and the catchswitch from exn.dispatch
 | |
| ; CHECK-LABEL: define void @test2()
 | |
| define void @test2() personality void ()* @ProcessCLRException {
 | |
| entry:
 | |
|   invoke void @f()
 | |
|     to label %via.cleanup unwind label %exn.dispatch
 | |
|   ; CHECK-NOT: invoke
 | |
|   ; CHECK: call void @f()
 | |
| via.cleanup:
 | |
|   invoke void @f()
 | |
|     to label %via.catchswitch unwind label %cleanup.inner
 | |
| cleanup.inner:
 | |
|   %cp.inner = cleanuppad within none []
 | |
|   call void @llvm.foo(i32 0)
 | |
|   cleanupret from %cp.inner unwind label %exn.dispatch
 | |
|   ; CHECK: cleanupret from %cp.inner unwind to caller
 | |
| via.catchswitch:
 | |
|   invoke void @f()
 | |
|     to label %exit unwind label %dispatch.inner
 | |
| dispatch.inner:
 | |
|   %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
 | |
|   ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind to caller
 | |
| pad.inner:
 | |
|   %catch.inner = catchpad within %cs.inner [i32 0]
 | |
|   ; CHECK: %catch.inner = catchpad within %cs.inner
 | |
|   call void @llvm.foo(i32 1)
 | |
|   catchret from %catch.inner to label %exit
 | |
| exn.dispatch:
 | |
|   %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller
 | |
|   ; CHECK-NOT: catchswitch within
 | |
|   ; CHECK-NOT: catchpad
 | |
| pad1:
 | |
|   catchpad within %cs [i32 1]
 | |
|   unreachable
 | |
| pad2:
 | |
|   catchpad within %cs [i32 2]
 | |
|   unreachable
 | |
| exit:
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| ; Same as @test2, but exn.dispatch catchswitch has an unwind dest that
 | |
| ; preds need to be reidrected to
 | |
| ; CHECK-LABEL: define void @test3()
 | |
| define void @test3() personality void ()* @ProcessCLRException {
 | |
| entry:
 | |
|   invoke void @f()
 | |
|     to label %via.cleanup unwind label %exn.dispatch
 | |
|   ; CHECK: invoke void @f()
 | |
|   ; CHECK-NEXT: to label %via.cleanup unwind label %cleanup
 | |
| via.cleanup:
 | |
|   invoke void @f()
 | |
|     to label %via.catchswitch unwind label %cleanup.inner
 | |
| cleanup.inner:
 | |
|   %cp.inner = cleanuppad within none []
 | |
|   call void @llvm.foo(i32 0)
 | |
|   cleanupret from %cp.inner unwind label %exn.dispatch
 | |
|   ; CHECK: cleanupret from %cp.inner unwind label %cleanup
 | |
| via.catchswitch:
 | |
|   invoke void @f()
 | |
|     to label %exit unwind label %dispatch.inner
 | |
| dispatch.inner:
 | |
|   %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
 | |
|   ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind label %cleanup
 | |
| pad.inner:
 | |
|   %catch.inner = catchpad within %cs.inner [i32 0]
 | |
|   ; CHECK: %catch.inner = catchpad within %cs.inner
 | |
|   call void @llvm.foo(i32 1)
 | |
|   catchret from %catch.inner to label %exit
 | |
| exn.dispatch:
 | |
|   %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup
 | |
|   ; CHECK-NOT: catchswitch within
 | |
|   ; CHECK-NOT: catchpad
 | |
| pad1:
 | |
|   catchpad within %cs [i32 1]
 | |
|   unreachable
 | |
| pad2:
 | |
|   catchpad within %cs [i32 2]
 | |
|   unreachable
 | |
| cleanup:
 | |
|   %cp = cleanuppad within none []
 | |
|   call void @llvm.foo(i32 0)
 | |
|   cleanupret from %cp unwind to caller
 | |
| exit:
 | |
|   ret void
 | |
| }
 |