; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=correlated-propagation %s | FileCheck %s

declare void @use(i1)

define void @ctpop1(i8 %v) {
; CHECK-LABEL: define void @ctpop1(
; CHECK-SAME: i8 [[V:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[RES:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[V]])
; CHECK-NEXT:    [[C0_0:%.*]] = icmp samesign uge i8 [[RES]], 3
; CHECK-NEXT:    [[C0_1:%.*]] = icmp samesign ule i8 [[RES]], 7
; CHECK-NEXT:    [[C0:%.*]] = and i1 [[C0_0]], [[C0_1]]
; CHECK-NEXT:    br i1 [[C0]], label %[[RANGE_3_8:.*]], label %[[ED:.*]]
; CHECK:       [[RANGE_3_8]]:
; CHECK-NEXT:    call void @use(i1 true)
; CHECK-NEXT:    [[CMP1:%.*]] = icmp uge i8 [[V]], 8
; CHECK-NEXT:    call void @use(i1 [[CMP1]])
; CHECK-NEXT:    call void @use(i1 true)
; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i8 [[V]], -3
; CHECK-NEXT:    call void @use(i1 [[CMP3]])
; CHECK-NEXT:    ret void
; CHECK:       [[ED]]:
; CHECK-NEXT:    ret void
;
entry:
  %res = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 %v)
  %c0.0 = icmp uge i8 %res, 3
  %c0.1 = icmp ule i8 %res, 7
  %c0 = and i1 %c0.0, %c0.1
  br i1 %c0, label %range.3.8, label %ed

range.3.8:
  %cmp0 = icmp uge i8 %v, 7
  call void @use(i1 %cmp0) ; true
  %cmp1 = icmp uge i8 %v, 8
  call void @use(i1 %cmp1) ; unknown
  %cmp2 = icmp ule i8 %v, 254
  call void @use(i1 %cmp2) ; true
  %cmp3 = icmp ule i8 %v, 253
  call void @use(i1 %cmp3) ; unknown
  ret void

ed:
  ret void
}

define void @ctpop2(i8 %v) {
; CHECK-LABEL: define void @ctpop2(
; CHECK-SAME: i8 [[V:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[RES:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[V]])
; CHECK-NEXT:    [[C2_0:%.*]] = icmp samesign uge i8 [[RES]], 1
; CHECK-NEXT:    [[C2_1:%.*]] = icmp samesign ule i8 [[RES]], 4
; CHECK-NEXT:    [[C2:%.*]] = and i1 [[C2_0]], [[C2_1]]
; CHECK-NEXT:    br i1 [[C2]], label %[[RANGE_1_5:.*]], label %[[ED:.*]]
; CHECK:       [[RANGE_1_5]]:
; CHECK-NEXT:    call void @use(i1 true)
; CHECK-NEXT:    [[CMP9:%.*]] = icmp uge i8 [[V]], 2
; CHECK-NEXT:    call void @use(i1 [[CMP9]])
; CHECK-NEXT:    call void @use(i1 true)
; CHECK-NEXT:    [[CMP11:%.*]] = icmp ule i8 [[V]], -17
; CHECK-NEXT:    call void @use(i1 [[CMP11]])
; CHECK-NEXT:    ret void
; CHECK:       [[ED]]:
; CHECK-NEXT:    ret void
;
entry:
  %res = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 %v)
  %c2.0 = icmp uge i8 %res, 1
  %c2.1 = icmp ule i8 %res, 4
  %c2 = and i1 %c2.0, %c2.1
  br i1 %c2, label %range.1.5, label %ed

range.1.5:
  %cmp8 = icmp uge i8 %v, 1
  call void @use(i1 %cmp8) ; true
  %cmp9 = icmp uge i8 %v, 2
  call void @use(i1 %cmp9) ; unknown
  %cmp10 = icmp ule i8 %v, 240
  call void @use(i1 %cmp10) ; true
  %cmp11 = icmp ule i8 %v, 239
  call void @use(i1 %cmp11) ; unknown
  ret void

ed:
  ret void
}

define void @ctpop3(i8 %v) {
; CHECK-LABEL: define void @ctpop3(
; CHECK-SAME: i8 [[V:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ctpop.i8(i8 [[V]])
; CHECK-NEXT:    [[C3:%.*]] = icmp samesign uge i8 [[RES]], 8
; CHECK-NEXT:    br i1 [[C3]], label %[[RANGE_8_9:.*]], label %[[ED:.*]]
; CHECK:       [[RANGE_8_9]]:
; CHECK-NEXT:    call void @use(i1 true)
; CHECK-NEXT:    ret void
; CHECK:       [[ED]]:
; CHECK-NEXT:    ret void
;
entry:
  %res = call i8 @llvm.ctpop.i8(i8 %v)
  %c3 = icmp uge i8 %res, 8
  br i1 %c3, label %range.8.9, label %ed

range.8.9:
  %cmp4 = icmp eq i8 %v, -1
  call void @use(i1 %cmp4) ; true
  ret void

ed:
  ret void
}

define void @ctpop4(i8 %v) {
; CHECK-LABEL: define void @ctpop4(
; CHECK-SAME: i8 [[V:%.*]]) {
; CHECK-NEXT:  [[TEST4:.*:]]
; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ctpop.i8(i8 [[V]])
; CHECK-NEXT:    [[C4:%.*]] = icmp eq i8 [[RES]], 0
; CHECK-NEXT:    br i1 [[C4]], label %[[RANGE_0_1:.*]], label %[[ED:.*]]
; CHECK:       [[RANGE_0_1]]:
; CHECK-NEXT:    call void @use(i1 true)
; CHECK-NEXT:    ret void
; CHECK:       [[ED]]:
; CHECK-NEXT:    ret void
;
test4:
  %res = call i8 @llvm.ctpop.i8(i8 %v)
  %c4 = icmp eq i8 %res, 0
  br i1 %c4, label %range.0.1, label %ed

range.0.1:
  %cmp5 = icmp eq i8 %v, 0
  call void @use(i1 %cmp5) ; true
  ret void

ed:
  ret void
}
