419 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			419 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 | |
| ; RUN: opt < %s -instsimplify -S | FileCheck %s
 | |
| 
 | |
| ; Fold icmp with a constant operand.
 | |
| 
 | |
| define i1 @tautological_ule(i8 %x) {
 | |
| ; CHECK-LABEL: @tautological_ule(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %cmp = icmp ule i8 %x, 255
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @tautological_ule_vec(<2 x i8> %x) {
 | |
| ; CHECK-LABEL: @tautological_ule_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %cmp = icmp ule <2 x i8> %x, <i8 255, i8 255>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| define i1 @tautological_ugt(i8 %x) {
 | |
| ; CHECK-LABEL: @tautological_ugt(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %cmp = icmp ugt i8 %x, 255
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) {
 | |
| ; CHECK-LABEL: @tautological_ugt_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'urem x, C2' produces [0, C2)
 | |
| define i1 @urem3(i32 %X) {
 | |
| ; CHECK-LABEL: @urem3(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %A = urem i32 %X, 10
 | |
|   %B = icmp ult i32 %A, 15
 | |
|   ret i1 %B
 | |
| }
 | |
| 
 | |
| define <2 x i1> @urem3_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @urem3_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %A = urem <2 x i32> %X, <i32 10, i32 10>
 | |
|   %B = icmp ult <2 x i32> %A, <i32 15, i32 15>
 | |
|   ret <2 x i1> %B
 | |
| }
 | |
| 
 | |
| ;'srem x, C2' produces (-|C2|, |C2|)
 | |
| define i1 @srem1(i32 %X) {
 | |
| ; CHECK-LABEL: @srem1(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %A = srem i32 %X, -5
 | |
|   %B = icmp sgt i32 %A, 5
 | |
|   ret i1 %B
 | |
| }
 | |
| 
 | |
| define <2 x i1> @srem1_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @srem1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %A = srem <2 x i32> %X, <i32 -5, i32 -5>
 | |
|   %B = icmp sgt <2 x i32> %A, <i32 5, i32 5>
 | |
|   ret <2 x i1> %B
 | |
| }
 | |
| 
 | |
| ;'udiv C2, x' produces [0, C2]
 | |
| define i1 @udiv5(i32 %X) {
 | |
| ; CHECK-LABEL: @udiv5(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %A = udiv i32 123, %X
 | |
|   %C = icmp ugt i32 %A, 124
 | |
|   ret i1 %C
 | |
| }
 | |
| 
 | |
| define <2 x i1> @udiv5_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @udiv5_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %A = udiv <2 x i32> <i32 123, i32 123>, %X
 | |
|   %C = icmp ugt <2 x i32> %A, <i32 124, i32 124>
 | |
|   ret <2 x i1> %C
 | |
| }
 | |
| 
 | |
| ; 'udiv x, C2' produces [0, UINT_MAX / C2]
 | |
| define i1 @udiv1(i32 %X) {
 | |
| ; CHECK-LABEL: @udiv1(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %A = udiv i32 %X, 1000000
 | |
|   %B = icmp ult i32 %A, 5000
 | |
|   ret i1 %B
 | |
| }
 | |
| 
 | |
| define <2 x i1> @udiv1_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @udiv1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %A = udiv <2 x i32> %X, <i32 1000000, i32 1000000>
 | |
|   %B = icmp ult <2 x i32> %A, <i32 5000, i32 5000>
 | |
|   ret <2 x i1> %B
 | |
| }
 | |
| 
 | |
| ; 'sdiv C2, x' produces [-|C2|, |C2|]
 | |
| define i1 @compare_dividend(i32 %a) {
 | |
| ; CHECK-LABEL: @compare_dividend(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %div = sdiv i32 2, %a
 | |
|   %cmp = icmp eq i32 %div, 3
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @compare_dividend_vec(<2 x i32> %a) {
 | |
| ; CHECK-LABEL: @compare_dividend_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %div = sdiv <2 x i32> <i32 2, i32 2>, %a
 | |
|   %cmp = icmp eq <2 x i32> %div, <i32 3, i32 3>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2]
 | |
| ;    where C2 != -1 and C2 != 0 and C2 != 1
 | |
| define i1 @sdiv1(i32 %X) {
 | |
| ; CHECK-LABEL: @sdiv1(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %A = sdiv i32 %X, 1000000
 | |
|   %B = icmp slt i32 %A, 3000
 | |
|   ret i1 %B
 | |
| }
 | |
| 
 | |
| define <2 x i1> @sdiv1_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @sdiv1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %A = sdiv <2 x i32> %X, <i32 1000000, i32 1000000>
 | |
|   %B = icmp slt <2 x i32> %A, <i32 3000, i32 3000>
 | |
|   ret <2 x i1> %B
 | |
| }
 | |
| 
 | |
| ; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)]
 | |
| define i1 @shl5(i32 %X) {
 | |
| ; CHECK-LABEL: @shl5(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %sub = shl nuw i32 4, %X
 | |
|   %cmp = icmp ugt i32 %sub, 3
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @shl5_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @shl5_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
 | |
|   %cmp = icmp ugt <2 x i32> %sub, <i32 3, i32 3>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
 | |
| define i1 @shl2(i32 %X) {
 | |
| ; CHECK-LABEL: @shl2(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %sub = shl nsw i32 -1, %X
 | |
|   %cmp = icmp eq i32 %sub, 31
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @shl2_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @shl2_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
 | |
|   %cmp = icmp eq <2 x i32> %sub, <i32 31, i32 31>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
 | |
| define i1 @shl4(i32 %X) {
 | |
| ; CHECK-LABEL: @shl4(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %sub = shl nsw i32 -1, %X
 | |
|   %cmp = icmp sle i32 %sub, -1
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @shl4_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @shl4_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
 | |
|   %cmp = icmp sle <2 x i32> %sub, <i32 -1, i32 -1>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1]
 | |
| define i1 @icmp_shl_nsw_1(i64 %a) {
 | |
| ; CHECK-LABEL: @icmp_shl_nsw_1(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %shl = shl nsw i64 1, %a
 | |
|   %cmp = icmp sge i64 %shl, 0
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @icmp_shl_nsw_1_vec(<2 x i64> %a) {
 | |
| ; CHECK-LABEL: @icmp_shl_nsw_1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %shl = shl nsw <2 x i64> <i64 1, i64 1>, %a
 | |
|   %cmp = icmp sge <2 x i64> %shl, zeroinitializer
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
 | |
| define i1 @icmp_shl_nsw_neg1(i64 %a) {
 | |
| ; CHECK-LABEL: @icmp_shl_nsw_neg1(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %shl = shl nsw i64 -1, %a
 | |
|   %cmp = icmp sge i64 %shl, 3
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @icmp_shl_nsw_neg1_vec(<2 x i64> %a) {
 | |
| ; CHECK-LABEL: @icmp_shl_nsw_neg1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %shl = shl nsw <2 x i64> <i64 -1, i64 -1>, %a
 | |
|   %cmp = icmp sge <2 x i64> %shl, <i64 3, i64 3>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'lshr x, C2' produces [0, UINT_MAX >> C2]
 | |
| define i1 @lshr2(i32 %x) {
 | |
| ; CHECK-LABEL: @lshr2(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %s = lshr i32 %x, 30
 | |
|   %c = icmp ugt i32 %s, 8
 | |
|   ret i1 %c
 | |
| }
 | |
| 
 | |
| define <2 x i1> @lshr2_vec(<2 x i32> %x) {
 | |
| ; CHECK-LABEL: @lshr2_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %s = lshr <2 x i32> %x, <i32 30, i32 30>
 | |
|   %c = icmp ugt <2 x i32> %s, <i32 8, i32 8>
 | |
|   ret <2 x i1> %c
 | |
| }
 | |
| 
 | |
| ; 'lshr C2, x' produces [C2 >> (Width-1), C2]
 | |
| define i1 @exact_lshr_ugt_false(i32 %a) {
 | |
| ; CHECK-LABEL: @exact_lshr_ugt_false(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %shr = lshr exact i32 30, %a
 | |
|   %cmp = icmp ult i32 %shr, 15
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @exact_lshr_ugt_false_vec(<2 x i32> %a) {
 | |
| ; CHECK-LABEL: @exact_lshr_ugt_false_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %shr = lshr exact <2 x i32> <i32 30, i32 30>, %a
 | |
|   %cmp = icmp ult <2 x i32> %shr, <i32 15, i32 15>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'lshr C2, x' produces [C2 >> (Width-1), C2]
 | |
| define i1 @lshr_sgt_false(i32 %a) {
 | |
| ; CHECK-LABEL: @lshr_sgt_false(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %shr = lshr i32 1, %a
 | |
|   %cmp = icmp sgt i32 %shr, 1
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @lshr_sgt_false_vec(<2 x i32> %a) {
 | |
| ; CHECK-LABEL: @lshr_sgt_false_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %shr = lshr <2 x i32> <i32 1, i32 1>, %a
 | |
|   %cmp = icmp sgt <2 x i32> %shr, <i32 1, i32 1>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2]
 | |
| define i1 @ashr2(i32 %x) {
 | |
| ; CHECK-LABEL: @ashr2(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %s = ashr i32 %x, 30
 | |
|   %c = icmp slt i32 %s, -5
 | |
|   ret i1 %c
 | |
| }
 | |
| 
 | |
| define <2 x i1> @ashr2_vec(<2 x i32> %x) {
 | |
| ; CHECK-LABEL: @ashr2_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %s = ashr <2 x i32> %x, <i32 30, i32 30>
 | |
|   %c = icmp slt <2 x i32> %s, <i32 -5, i32 -5>
 | |
|   ret <2 x i1> %c
 | |
| }
 | |
| 
 | |
| ; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
 | |
| define i1 @ashr_sgt_false(i32 %a) {
 | |
| ; CHECK-LABEL: @ashr_sgt_false(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %shr = ashr i32 -30, %a
 | |
|   %cmp = icmp sgt i32 %shr, -1
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @ashr_sgt_false_vec(<2 x i32> %a) {
 | |
| ; CHECK-LABEL: @ashr_sgt_false_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %shr = ashr <2 x i32> <i32 -30, i32 -30>, %a
 | |
|   %cmp = icmp sgt <2 x i32> %shr, <i32 -1, i32 -1>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
 | |
| define i1 @exact_ashr_sgt_false(i32 %a) {
 | |
| ; CHECK-LABEL: @exact_ashr_sgt_false(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %shr = ashr exact i32 -30, %a
 | |
|   %cmp = icmp sgt i32 %shr, -15
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @exact_ashr_sgt_false_vec(<2 x i32> %a) {
 | |
| ; CHECK-LABEL: @exact_ashr_sgt_false_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %shr = ashr exact <2 x i32> <i32 -30, i32 -30>, %a
 | |
|   %cmp = icmp sgt <2 x i32> %shr, <i32 -15, i32 -15>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 | |
| ; 'or x, C2' produces [C2, UINT_MAX]
 | |
| define i1 @or1(i32 %X) {
 | |
| ; CHECK-LABEL: @or1(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %A = or i32 %X, 62
 | |
|   %B = icmp ult i32 %A, 50
 | |
|   ret i1 %B
 | |
| }
 | |
| 
 | |
| define <2 x i1> @or1_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @or1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %A = or <2 x i32> %X, <i32 62, i32 62>
 | |
|   %B = icmp ult <2 x i32> %A, <i32 50, i32 50>
 | |
|   ret <2 x i1> %B
 | |
| }
 | |
| 
 | |
| ; 'and x, C2' produces [0, C2]
 | |
| define i1 @and1(i32 %X) {
 | |
| ; CHECK-LABEL: @and1(
 | |
| ; CHECK-NEXT:    ret i1 false
 | |
| ;
 | |
|   %A = and i32 %X, 62
 | |
|   %B = icmp ugt i32 %A, 70
 | |
|   ret i1 %B
 | |
| }
 | |
| 
 | |
| define <2 x i1> @and1_vec(<2 x i32> %X) {
 | |
| ; CHECK-LABEL: @and1_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 | |
| ;
 | |
|   %A = and <2 x i32> %X, <i32 62, i32 62>
 | |
|   %B = icmp ugt <2 x i32> %A, <i32 70, i32 70>
 | |
|   ret <2 x i1> %B
 | |
| }
 | |
| 
 | |
| ; 'add nuw x, C2' produces [C2, UINT_MAX]
 | |
| define i1 @tautological9(i32 %x) {
 | |
| ; CHECK-LABEL: @tautological9(
 | |
| ; CHECK-NEXT:    ret i1 true
 | |
| ;
 | |
|   %add = add nuw i32 %x, 13
 | |
|   %cmp = icmp ne i32 %add, 12
 | |
|   ret i1 %cmp
 | |
| }
 | |
| 
 | |
| define <2 x i1> @tautological9_vec(<2 x i32> %x) {
 | |
| ; CHECK-LABEL: @tautological9_vec(
 | |
| ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 | |
| ;
 | |
|   %add = add nuw <2 x i32> %x, <i32 13, i32 13>
 | |
|   %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12>
 | |
|   ret <2 x i1> %cmp
 | |
| }
 | |
| 
 |