forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			190 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; RUN: opt < %s -jump-threading -print-lvi-after-jump-threading -disable-output 2>&1 | FileCheck %s
 | 
						|
 | 
						|
; Testing LVI cache after jump-threading
 | 
						|
 | 
						|
; Jump-threading transforms the IR below to one where
 | 
						|
; loop and backedge basic blocks are merged into one.
 | 
						|
; basic block (named backedge) with the branch being:
 | 
						|
; %cont = icmp slt i32 %iv.next, 400
 | 
						|
; br i1 %cont, label %backedge, label %exit
 | 
						|
define i8 @test1(i32 %a, i32 %length) {
 | 
						|
; CHECK-LABEL: LVI for function 'test1':
 | 
						|
entry:
 | 
						|
; CHECK-LABEL: entry:
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: 'i32 %a' is: overdefined
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: 'i32 %length' is: overdefined
 | 
						|
  br label %loop
 | 
						|
 | 
						|
; CHECK-LABEL: backedge:
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: 'i32 %a' is: overdefined
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: 'i32 %length' is: overdefined
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400>
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<399, 400>
 | 
						|
; CHECK-NEXT:  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: '  %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, 401>
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: '  %iv.next = add nsw i32 %iv, 1' in BB: '%exit' is: constantrange<400, 401>
 | 
						|
; CHECK-NEXT:  %iv.next = add nsw i32 %iv, 1
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: '  %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined
 | 
						|
; CHECK-NEXT:     ; LatticeVal for: '  %cont = icmp slt i32 %iv.next, 400' in BB: '%exit' is: constantrange<0, -1>
 | 
						|
; CHECK-NEXT:  %cont = icmp slt i32 %iv.next, 400
 | 
						|
; CHECK-NOT: loop
 | 
						|
loop:
 | 
						|
  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
 | 
						|
  %cnd = icmp sge i32 %iv, 0
 | 
						|
  br i1 %cnd, label %backedge, label %exit
 | 
						|
 | 
						|
backedge:
 | 
						|
  %iv.next = add nsw i32 %iv, 1
 | 
						|
  %cont = icmp slt i32 %iv.next, 400
 | 
						|
  br i1 %cont, label %loop, label %exit
 | 
						|
 | 
						|
exit:
 | 
						|
  ret i8 0
 | 
						|
}
 | 
						|
 | 
						|
; Here JT does not transform the code, but LVICache is populated during the processing of blocks.
 | 
						|
define i8 @test2(i32 %n) {
 | 
						|
; CHECK-LABEL: LVI for function 'test2':
 | 
						|
; CHECK-LABEL: entry:
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: 'i32 %n' is: overdefined
 | 
						|
; CHECK-NEXT: br label %loop
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
 | 
						|
; CHECK-LABEL: loop:
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: 'i32 %n' is: overdefined
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange<0, 400>
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, -2147483648>
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<0, -2147483648>
 | 
						|
; CHECK-NEXT:  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
 | 
						|
loop:
 | 
						|
  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: '  %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%loop' is: overdefined
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%backedge' is: constantrange<1, -2147483648>
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%exit' is: overdefined
 | 
						|
; CHECK-NEXT:  %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]
 | 
						|
  %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge]
 | 
						|
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: '  %cnd1 = icmp sge i32 %iv, 0' in BB: '%loop' is: overdefined
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %cnd1 = icmp sge i32 %iv, 0' in BB: '%backedge' is: overdefined
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %cnd1 = icmp sge i32 %iv, 0' in BB: '%exit' is: overdefined
 | 
						|
; CHECK-NEXT:  %cnd1 = icmp sge i32 %iv, 0
 | 
						|
  %cnd1 = icmp sge i32 %iv, 0
 | 
						|
  %cnd2 = icmp sgt i32 %iv2, 0
 | 
						|
; CHECK:       %cnd2 = icmp sgt i32 %iv2, 0
 | 
						|
; CHECK:         ; LatticeVal for: '  %cnd = and i1 %cnd1, %cnd2' in BB: '%loop' is: constantrange<-1, -1>
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %cnd = and i1 %cnd1, %cnd2' in BB: '%backedge' is: constantrange<-1, 0>
 | 
						|
; CHECK-DAG:     ; LatticeVal for: '  %cnd = and i1 %cnd1, %cnd2' in BB: '%exit' is: overdefined
 | 
						|
; CHECK-NEXT:  %cnd = and i1 %cnd1, %cnd2
 | 
						|
  %cnd = and i1 %cnd1, %cnd2
 | 
						|
  br i1 %cnd, label %backedge, label %exit
 | 
						|
 | 
						|
; CHECK-LABEL: backedge:
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: 'i32 %n' is: overdefined
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: '  %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, -2147483648>
 | 
						|
; CHECK-NEXT:  %iv.next = add nsw i32 %iv, 1
 | 
						|
backedge:
 | 
						|
  %iv.next = add nsw i32 %iv, 1
 | 
						|
  %iv2.next = sub nsw i32 %iv2, 1
 | 
						|
; CHECK:         ; LatticeVal for: '  %cont1 = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined
 | 
						|
; CHECK-NEXT:  %cont1 = icmp slt i32 %iv.next, 400
 | 
						|
  %cont1 = icmp slt i32 %iv.next, 400
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: '  %cont2 = icmp sgt i32 %iv2.next, 0' in BB: '%backedge' is: overdefined
 | 
						|
; CHECK-NEXT:  %cont2 = icmp sgt i32 %iv2.next, 0
 | 
						|
  %cont2 = icmp sgt i32 %iv2.next, 0
 | 
						|
; CHECK-NEXT:    ; LatticeVal for: '  %cont = and i1 %cont1, %cont2' in BB: '%backedge' is: constantrange<-1, -1>
 | 
						|
; CHECK-NEXT:  %cont = and i1 %cont1, %cont2
 | 
						|
  %cont = and i1 %cont1, %cont2
 | 
						|
  br i1 %cont, label %loop, label %exit
 | 
						|
 | 
						|
exit:
 | 
						|
  ret i8 0
 | 
						|
}
 | 
						|
 | 
						|
; Merging cont block into do block. Make sure that we do not incorrectly have the cont
 | 
						|
; LVI info as LVI info for the beginning of do block. LVI info for %i is Range[0,1)
 | 
						|
; at beginning of cont Block, which is incorrect at the beginning of do block.
 | 
						|
define i32 @test3(i32 %i, i1 %f, i32 %n) {
 | 
						|
; CHECK-LABEL: LVI for function 'test3':
 | 
						|
; CHECK-LABEL: entry
 | 
						|
; CHECK:  ; LatticeVal for: 'i32 %i' is: overdefined
 | 
						|
; CHECK: %c = icmp ne i32 %i, -2134
 | 
						|
; CHECK: br i1 %c, label %cont, label %exit
 | 
						|
entry:
 | 
						|
  %c = icmp ne i32 %i, -2134
 | 
						|
  br i1 %c, label %do, label %exit
 | 
						|
 | 
						|
exit:
 | 
						|
  %c1 = icmp ne i32 %i, -42
 | 
						|
  br i1 %c1, label %exit2, label %exit
 | 
						|
 | 
						|
; CHECK-LABEL: cont:
 | 
						|
; Here cont is merged to do and i is any value except -2134.
 | 
						|
; i is not the single value: zero.
 | 
						|
; CHECK-NOT:  ; LatticeVal for: 'i32 %i' is: constantrange<0, 1>
 | 
						|
; CHECK:      ; LatticeVal for: 'i32 %i' is: constantrange<-2133, -2134>
 | 
						|
; CHECK:      ; LatticeVal for: '  %cond.0 = icmp sgt i32 %i, 0' in BB: '%cont' is: overdefined
 | 
						|
; CHECK:   %cond.0 = icmp sgt i32 %i, 0
 | 
						|
; CHECK:   %consume = call i32 @consume
 | 
						|
; CHECK:   %cond = icmp eq i32 %i, 0
 | 
						|
; CHECK:   call void (i1, ...) @llvm.experimental.guard(i1 %cond)
 | 
						|
; CHECK:   %cond.3 = icmp sgt i32 %i, %n
 | 
						|
; CHECK:   br i1 %cond.3, label %exit2, label %exit
 | 
						|
cont:
 | 
						|
  %cond.3 = icmp sgt i32 %i, %n
 | 
						|
  br i1 %cond.3, label %exit2, label %exit
 | 
						|
 | 
						|
do:
 | 
						|
  %cond.0 = icmp sgt i32 %i, 0
 | 
						|
  %consume = call i32 @consume(i1 %cond.0)
 | 
						|
  %cond = icmp eq i32 %i, 0
 | 
						|
  call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
 | 
						|
  %cond.2 = icmp sgt i32 %i, 0
 | 
						|
  br i1 %cond.2, label %exit, label %cont
 | 
						|
 | 
						|
exit2:
 | 
						|
; CHECK-LABEL: exit2:
 | 
						|
; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1>
 | 
						|
  ret i32 30
 | 
						|
}
 | 
						|
 | 
						|
; FIXME: We should be able to merge cont into do.
 | 
						|
; When we do so, LVI for cont cannot be the one for the merged do block.
 | 
						|
define i32 @test4(i32 %i, i1 %f, i32 %n) {
 | 
						|
; CHECK-LABEL: LVI for function 'test4':
 | 
						|
entry:
 | 
						|
  %c = icmp ne i32 %i, -2134
 | 
						|
  br i1 %c, label %do, label %exit
 | 
						|
 | 
						|
exit:                                             ; preds = %do, %cont, %exit, %entry
 | 
						|
  %c1 = icmp ne i32 %i, -42
 | 
						|
  br i1 %c1, label %exit2, label %exit
 | 
						|
 | 
						|
cont:                                             ; preds = %do
 | 
						|
; CHECK-LABEL: cont:
 | 
						|
; CHECK:  ; LatticeVal for: 'i1 %f' is: constantrange<-1, 0>
 | 
						|
; CHECK: call void @dummy(i1 %f)
 | 
						|
  call void @dummy(i1 %f)
 | 
						|
  br label %exit2
 | 
						|
 | 
						|
do:                                               ; preds = %entry
 | 
						|
; CHECK-LABEL: do:
 | 
						|
; CHECK:  ; LatticeVal for: 'i1 %f' is: overdefined
 | 
						|
; CHECK: call void @dummy(i1 %f)
 | 
						|
; CHECK: br i1 %cond, label %exit, label %cont
 | 
						|
  call void @dummy(i1 %f)
 | 
						|
  %consume = call i32 @exit()
 | 
						|
  call void @llvm.assume(i1 %f)
 | 
						|
  %cond = icmp eq i1 %f, false
 | 
						|
  br i1 %cond, label %exit, label %cont
 | 
						|
 | 
						|
exit2:                                            ; preds = %cont, %exit
 | 
						|
  ret i32 30
 | 
						|
}
 | 
						|
 | 
						|
declare i32 @exit()
 | 
						|
declare i32 @consume(i1)
 | 
						|
declare void @llvm.assume(i1) nounwind
 | 
						|
declare void @dummy(i1) nounwind
 | 
						|
declare void @llvm.experimental.guard(i1, ...)
 |