396 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			396 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; RUN: opt -S -instcombine < %s | FileCheck %s
 | 
						|
 | 
						|
declare void @use(i32)
 | 
						|
 | 
						|
; These 18 exercise all combinations of signed comparison
 | 
						|
; for each of the three values produced by your typical 
 | 
						|
; 3way compare function (-1, 0, 1)
 | 
						|
 | 
						|
define void @test_low_sgt(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_low_sgt
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sgt i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_low_slt(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_low_slt
 | 
						|
; CHECK: br i1 false, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp slt i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_low_sge(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_low_sge
 | 
						|
; CHECK: br i1 true, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sge i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_low_sle(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_low_sle
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sle i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_low_ne(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_low_ne
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp ne i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_low_eq(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_low_eq
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_mid_sgt(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_mid_sgt
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sgt i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_mid_slt(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_mid_slt
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp slt i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_mid_sge(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_mid_sge
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sge i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_mid_sle(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_mid_sle
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sle i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_mid_ne(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_mid_ne
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp eq i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp ne i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_mid_eq(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_mid_eq
 | 
						|
; CHECK: icmp eq i64 %a, %b
 | 
						|
; CHECK: br i1 %eq, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_high_sgt(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_high_sgt
 | 
						|
; CHECK: br i1 false, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sgt i32 %result, 1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_high_slt(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_high_slt
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp slt i32 %result, 1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_high_sge(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_high_sge
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sge i32 %result, 1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_high_sle(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_high_sle
 | 
						|
; CHECK: br i1 true, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp sle i32 %result, 1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_high_ne(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_high_ne
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %normal, label %unreached
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp ne i32 %result, 1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_high_eq(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @test_high_eq
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -1, i32 1
 | 
						|
  %result = select i1 %eq, i32 0, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, 1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; These five make sure we didn't accidentally hard code one of the
 | 
						|
; produced values
 | 
						|
 | 
						|
define void @non_standard_low(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @non_standard_low
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -3, i32 -1
 | 
						|
  %result = select i1 %eq, i32 -2, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, -3
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @non_standard_mid(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @non_standard_mid
 | 
						|
; CHECK: icmp eq i64 %a, %b
 | 
						|
; CHECK: br i1 %eq, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -3, i32 -1
 | 
						|
  %result = select i1 %eq, i32 -2, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, -2
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @non_standard_high(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @non_standard_high
 | 
						|
; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
 | 
						|
; CHECK: br i1 [[TMP1]], label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -3, i32 -1
 | 
						|
  %result = select i1 %eq, i32 -2, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, -1
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @non_standard_bound1(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @non_standard_bound1
 | 
						|
; CHECK: br i1 false, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -3, i32 -1
 | 
						|
  %result = select i1 %eq, i32 -2, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, -20
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @non_standard_bound2(i64 %a, i64 %b) {
 | 
						|
; CHECK-LABEL: @non_standard_bound2
 | 
						|
; CHECK: br i1 false, label %unreached, label %normal
 | 
						|
  %eq = icmp eq i64 %a, %b
 | 
						|
  %slt = icmp slt i64 %a, %b
 | 
						|
  %. = select i1 %slt, i32 -3, i32 -1
 | 
						|
  %result = select i1 %eq, i32 -2, i32 %.
 | 
						|
  %cmp = icmp eq i32 %result, 0
 | 
						|
  br i1 %cmp, label %unreached, label %normal
 | 
						|
normal:
 | 
						|
  ret void
 | 
						|
unreached:
 | 
						|
  call void @use(i32 %result)
 | 
						|
  ret void
 | 
						|
}
 |