forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			676 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			676 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 | 
						|
; RUN: opt -indvars -S -indvars-predicate-loops=0 < %s | FileCheck %s
 | 
						|
 | 
						|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 | 
						|
target triple = "x86_64-unknown-linux-gnu"
 | 
						|
 | 
						|
; General case: without extra knowledge, trunc cannot be eliminated.
 | 
						|
define void @test_00(i64 %start, i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_00(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
 | 
						|
; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
 | 
						|
; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
define void @test_01(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_01(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
 | 
						|
; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Max value at which we can eliminate trunc: SINT_MAX - 1.
 | 
						|
define void @test_02(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_02(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 2147483646)
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
 | 
						|
; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 2147483646, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 2147483646, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; If we start from SINT_MAX then the predicate is always false.
 | 
						|
define void @test_03(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_03(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [2147483647, %entry], [%iv.next, %loop]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Minimum value at which we can apply the transform: SINT_MIN + 1.
 | 
						|
define void @test_04(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_04(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 -2147483647)
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[SMAX]], 1
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ -2147483647, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ -2147483647, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; FIXME: Harmful LFTR should be thrown away.
 | 
						|
define void @test_05(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_05(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ -2147483648, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Trunc changes the actual value of the IV, so it is invalid to remove it: SINT_MIN - 1.
 | 
						|
define void @test_06(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_06(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ -2147483649, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; General case: without extra knowledge, trunc cannot be eliminated.
 | 
						|
define void @test_00_unsigned(i64 %start, i32 %n) {
 | 
						|
; CHECK-LABEL: @test_00_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
 | 
						|
; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
 | 
						|
; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; FIXME: Harmful LFTR should be thrown away.
 | 
						|
define void @test_01_unsigned(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_01_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Max value at which we can eliminate trunc: UINT_MAX - 1.
 | 
						|
define void @test_02_unsigned(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_02_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 -2)
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[UMAX]], 1
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 4294967294, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 4294967294, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; If we start from UINT_MAX then the predicate is always false.
 | 
						|
define void @test_03_unsigned(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_03_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 4294967295, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Minimum value at which we can apply the transform: UINT_MIN.
 | 
						|
define void @test_04_unsigned(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_04_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Start from 1.
 | 
						|
define void @test_05_unsigned(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_05_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], 1
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Trunc changes the actual value of the IV, so it is invalid to remove it: UINT_MIN - 1.
 | 
						|
define void @test_06_unsigned(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_06_unsigned(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ -1, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ult i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Do not eliminate trunc if it is used by something different from icmp.
 | 
						|
define void @test_07(i32* %p, i32 %n) {
 | 
						|
; CHECK-LABEL: @test_07(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N:%.*]], i32 0)
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
 | 
						|
; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[TMP0]] to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
 | 
						|
; CHECK-NEXT:    store i32 [[NARROW_IV]], i32* [[P:%.*]], align 4
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  store i32 %narrow.iv, i32* %p
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Check that we can eliminate both signed and unsigned compare.
 | 
						|
define void @test_08(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_08(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
 | 
						|
; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 [[N]] to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
 | 
						|
; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
 | 
						|
; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[TMP0]], [[TMP1]]
 | 
						|
; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp1 = icmp slt i32 %narrow.iv, %n
 | 
						|
  %cmp2 = icmp ult i32 %narrow.iv, %n
 | 
						|
  %cmp = and i1 %cmp1, %cmp2
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Widen NE as unsigned.
 | 
						|
define void @test_09(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_09(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[N:%.*]] to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
 | 
						|
; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ne i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Widen NE as signed.
 | 
						|
define void @test_10(i32 %n) {
 | 
						|
; CHECK-LABEL: @test_10(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 100
 | 
						|
; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
 | 
						|
; CHECK-NEXT:    [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP1]], i64 90)
 | 
						|
; CHECK-NEXT:    [[TMP2:%.*]] = add nuw nsw i64 [[UMIN]], -99
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ -100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[TMP2]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ -100, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %trunccmp = icmp ne i32 %narrow.iv, %n
 | 
						|
  %negcmp = icmp slt i64 %iv, -10
 | 
						|
  %cmp = and i1 %trunccmp, %negcmp
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_11() {
 | 
						|
; CHECK-LABEL: @test_11(
 | 
						|
; CHECK-NEXT:    br label [[BB1:%.*]]
 | 
						|
; CHECK:       bb1:
 | 
						|
; CHECK-NEXT:    br i1 undef, label [[BB2:%.*]], label [[BB6:%.*]]
 | 
						|
; CHECK:       bb2:
 | 
						|
; CHECK-NEXT:    br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
 | 
						|
; CHECK:       bb3:
 | 
						|
; CHECK-NEXT:    br label [[BB4]]
 | 
						|
; CHECK:       bb4:
 | 
						|
; CHECK-NEXT:    br label [[BB6]]
 | 
						|
; CHECK:       bb5:
 | 
						|
; CHECK-NEXT:    [[_TMP24:%.*]] = icmp slt i16 undef, 0
 | 
						|
; CHECK-NEXT:    br i1 [[_TMP24]], label [[BB5:%.*]], label [[BB5]]
 | 
						|
; CHECK:       bb6:
 | 
						|
; CHECK-NEXT:    br i1 false, label [[BB1]], label [[BB7:%.*]]
 | 
						|
; CHECK:       bb7:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
  br label %bb1
 | 
						|
 | 
						|
bb1:                                              ; preds = %bb6, %0
 | 
						|
  %e.5.0 = phi i32 [ 0, %0 ], [ %_tmp32, %bb6 ]
 | 
						|
  br i1 undef, label %bb2, label %bb6
 | 
						|
 | 
						|
bb2:                                              ; preds = %bb1
 | 
						|
  %_tmp15 = trunc i32 %e.5.0 to i16
 | 
						|
  br i1 undef, label %bb3, label %bb4
 | 
						|
 | 
						|
bb3:                                              ; preds = %bb2
 | 
						|
  br label %bb4
 | 
						|
 | 
						|
bb4:                                              ; preds = %bb3, %bb2
 | 
						|
  br label %bb6
 | 
						|
 | 
						|
bb5:                                              ; preds = %bb5, %bb5
 | 
						|
  %_tmp24 = icmp slt i16 %_tmp15, 0
 | 
						|
  br i1 %_tmp24, label %bb5, label %bb5
 | 
						|
 | 
						|
bb6:                                              ; preds = %bb4, %bb1
 | 
						|
  %_tmp32 = add nuw nsw i32 %e.5.0, 1
 | 
						|
  br i1 false, label %bb1, label %bb7
 | 
						|
 | 
						|
bb7:                                             ; preds = %bb6
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Show that we can turn signed comparison to unsigned and use zext while
 | 
						|
; comparing non-negative values.
 | 
						|
define void @test_12(i32* %p) {
 | 
						|
; CHECK-LABEL: @test_12(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[N:%.*]] = load i32, i32* [[P:%.*]], align 4, [[RNG0:!range !.*]]
 | 
						|
; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[N]], i32 1)
 | 
						|
; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 | 
						|
; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
 | 
						|
; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  %n = load i32, i32* %p, !range !0
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add i64 %iv, 1
 | 
						|
  %narrow.iv = trunc i64 %iv.next to i32
 | 
						|
  %cmp = icmp slt i32 %narrow.iv, %n
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_13a(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_13a(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 1024 to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
 | 
						|
; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add nsw nuw i64 %iv, 2
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ne i32 1024, %narrow.iv
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_13b(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_13b(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 1024 to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
 | 
						|
; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add nsw nuw i64 %iv, 2
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp ugt i32 1024, %narrow.iv
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_13c(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_13c(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 1024 to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
 | 
						|
; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add nsw nuw i64 %iv, 2
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp sgt i32 1024, %narrow.iv
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_13d(i32 %n) {
 | 
						|
;
 | 
						|
; CHECK-LABEL: @test_13d(
 | 
						|
; CHECK-NEXT:  entry:
 | 
						|
; CHECK-NEXT:    [[SEXT:%.*]] = sext i32 1024 to i64
 | 
						|
; CHECK-NEXT:    br label [[LOOP:%.*]]
 | 
						|
; CHECK:       loop:
 | 
						|
; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ -20, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
 | 
						|
; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
 | 
						|
; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
 | 
						|
; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
 | 
						|
; CHECK:       exit:
 | 
						|
; CHECK-NEXT:    ret void
 | 
						|
;
 | 
						|
entry:
 | 
						|
  br label %loop
 | 
						|
loop:
 | 
						|
  %iv = phi i64 [ -20, %entry ], [ %iv.next, %loop ]
 | 
						|
  %iv.next = add nsw i64 %iv, 2
 | 
						|
  %narrow.iv = trunc i64 %iv to i32
 | 
						|
  %cmp = icmp sgt i32 1024, %narrow.iv
 | 
						|
  br i1 %cmp, label %loop, label %exit
 | 
						|
exit:
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
!0 = !{i32 0, i32 1000}
 |