You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			97 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
| ; RUN: opt -S -early-cse < %s | FileCheck %s
 | |
| ; RUN: opt -S -basicaa -early-cse-memssa < %s | FileCheck %s
 | |
| 
 | |
| declare void @clobber_and_use(i32)
 | |
| 
 | |
| define void @f_0(i32* %ptr) {
 | |
| ; CHECK-LABEL: @f_0(
 | |
| ; CHECK:   %val0 = load i32, i32* %ptr, !invariant.load !0
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| ; CHECK:   ret void
 | |
| 
 | |
|   %val0 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val0)
 | |
|   %val1 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val1)
 | |
|   %val2 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val2)
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @f_1(i32* %ptr) {
 | |
| ; We can forward invariant loads to non-invariant loads.
 | |
| 
 | |
| ; CHECK-LABEL: @f_1(
 | |
| ; CHECK:   %val0 = load i32, i32* %ptr, !invariant.load !0
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| 
 | |
|   %val0 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val0)
 | |
|   %val1 = load i32, i32* %ptr
 | |
|   call void @clobber_and_use(i32 %val1)
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @f_2(i32* %ptr) {
 | |
| ; We can forward a non-invariant load into an invariant load.
 | |
| 
 | |
| ; CHECK-LABEL: @f_2(
 | |
| ; CHECK:   %val0 = load i32, i32* %ptr
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| ; CHECK:   call void @clobber_and_use(i32 %val0)
 | |
| 
 | |
|   %val0 = load i32, i32* %ptr
 | |
|   call void @clobber_and_use(i32 %val0)
 | |
|   %val1 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val1)
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @f_3(i1 %cond, i32* %ptr) {
 | |
| ; CHECK-LABEL: @f_3(
 | |
|   %val0 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val0)
 | |
|   br i1 %cond, label %left, label %right
 | |
| 
 | |
| ; CHECK:  %val0 = load i32, i32* %ptr, !invariant.load !0
 | |
| ; CHECK: left:
 | |
| ; CHECK-NEXT:  call void @clobber_and_use(i32 %val0)
 | |
| 
 | |
| left:
 | |
|   %val1 = load i32, i32* %ptr
 | |
|   call void @clobber_and_use(i32 %val1)
 | |
|   ret void
 | |
| 
 | |
| right:
 | |
|   ret void
 | |
| }
 | |
| 
 | |
| define void @f_4(i1 %cond, i32* %ptr) {
 | |
| ; Negative test -- can't forward %val0 to %va1 because that'll break
 | |
| ; def-dominates-use.
 | |
| 
 | |
| ; CHECK-LABEL: @f_4(
 | |
|   br i1 %cond, label %left, label %merge
 | |
| 
 | |
| left:
 | |
| ; CHECK: left:
 | |
| ; CHECK-NEXT:  %val0 = load i32, i32* %ptr, !invariant.load !
 | |
| ; CHECK-NEXT:  call void @clobber_and_use(i32 %val0)
 | |
| 
 | |
|   %val0 = load i32, i32* %ptr, !invariant.load !{}
 | |
|   call void @clobber_and_use(i32 %val0)
 | |
|   br label %merge
 | |
| 
 | |
| merge:
 | |
| ; CHECK: merge:
 | |
| ; CHECK-NEXT:   %val1 = load i32, i32* %ptr
 | |
| ; CHECK-NEXT:   call void @clobber_and_use(i32 %val1)
 | |
| 
 | |
|   %val1 = load i32, i32* %ptr
 | |
|   call void @clobber_and_use(i32 %val1)
 | |
|   ret void
 | |
| }
 |