forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			101 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 | |
| ; RUN: opt -S -simplifycfg < %s | FileCheck %s
 | |
| 
 | |
| declare void @llvm.experimental.guard(i1, ...)
 | |
| 
 | |
| define i32 @f_0(i1 %c) {
 | |
| ; CHECK-LABEL: @f_0(
 | |
| ; CHECK-NEXT:  entry:
 | |
| ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
 | |
| ; CHECK-NEXT:    unreachable
 | |
| ;
 | |
| entry:
 | |
|   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
 | |
|   ret i32 10
 | |
| }
 | |
| 
 | |
| define i32 @f_1(i1 %c) {
 | |
| ; Demonstrate that we (intentionally) do not simplify a guard on undef
 | |
| ; CHECK-LABEL: @f_1(
 | |
| ; CHECK-NEXT:  entry:
 | |
| ; CHECK-NEXT:    br i1 [[C:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]]
 | |
| ; CHECK:       true:
 | |
| ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ]
 | |
| ; CHECK-NEXT:    ret i32 10
 | |
| ; CHECK:       false:
 | |
| ; CHECK-NEXT:    ret i32 20
 | |
| ;
 | |
| 
 | |
| entry:
 | |
|   br i1 %c, label %true, label %false
 | |
| 
 | |
| true:
 | |
|   call void(i1, ...) @llvm.experimental.guard(i1 undef) [ "deopt"() ]
 | |
|   ret i32 10
 | |
| 
 | |
| false:
 | |
|   ret i32 20
 | |
| }
 | |
| 
 | |
| define i32 @f_2(i1 %c, i32* %buf) {
 | |
| ; CHECK-LABEL: @f_2(
 | |
| ; CHECK-NEXT:  entry:
 | |
| ; CHECK-NEXT:    br i1 [[C:%.*]], label [[GUARD_BLOCK:%.*]], label [[MERGE_BLOCK:%.*]]
 | |
| ; CHECK:       guard_block:
 | |
| ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
 | |
| ; CHECK-NEXT:    unreachable
 | |
| ; CHECK:       merge_block:
 | |
| ; CHECK-NEXT:    ret i32 50
 | |
| ;
 | |
| entry:
 | |
|   br i1 %c, label %guard_block, label %merge_block
 | |
| 
 | |
| guard_block:
 | |
|   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
 | |
|   %val = load i32, i32* %buf
 | |
|   br label %merge_block
 | |
| 
 | |
| merge_block:
 | |
|   %to.return = phi i32 [ %val, %guard_block ], [ 50, %entry ]
 | |
|   ret i32 %to.return
 | |
| 
 | |
| }
 | |
| 
 | |
| define i32 @f_3(i1* %c, i32* %buf) {
 | |
| ; CHECK-LABEL: @f_3(
 | |
| ; CHECK-NEXT:  entry:
 | |
| ; CHECK-NEXT:    [[C0:%.*]] = load volatile i1, i1* [[C:%.*]]
 | |
| ; CHECK-NEXT:    br i1 [[C0]], label [[GUARD_BLOCK:%.*]], label [[MERGE_BLOCK:%.*]]
 | |
| ; CHECK:       guard_block:
 | |
| ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
 | |
| ; CHECK-NEXT:    unreachable
 | |
| ; CHECK:       merge_block:
 | |
| ; CHECK-NEXT:    [[C1:%.*]] = load volatile i1, i1* [[C]]
 | |
| ; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[C1]], i32 50, i32 100
 | |
| ; CHECK-NEXT:    ret i32 [[DOT]]
 | |
| ;
 | |
| entry:
 | |
|   %c0 = load volatile i1, i1* %c
 | |
|   br i1 %c0, label %guard_block, label %merge_block
 | |
| 
 | |
| guard_block:
 | |
|   call void(i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ]
 | |
|   %val = load i32, i32* %buf
 | |
|   %c2 = load volatile i1, i1* %c
 | |
|   br i1 %c2, label %left, label %right
 | |
| 
 | |
| merge_block:
 | |
|   %c1 = load volatile i1, i1* %c
 | |
|   br i1 %c1, label %left, label %right
 | |
| 
 | |
| left:
 | |
|   %val.left = phi i32 [ %val, %guard_block ], [ 50, %merge_block ]
 | |
|   ret i32 %val.left
 | |
| 
 | |
| right:
 | |
|   %val.right = phi i32 [ %val, %guard_block ], [ 100, %merge_block ]
 | |
|   ret i32 %val.right
 | |
| 
 | |
| 
 | |
| }
 |