Compiler projects using llvm
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -debugify-and-strip-all-safe < %s -mtriple=aarch64-linux-gnu | FileCheck %s

; marked as external to prevent possible optimizations
@a = external global i32
@b = external global i32
@c = external global i32
@d = external global i32

; (a > 10 && b == c) || (a >= 10 && b == d)
define i32 @combine_gt_ge_10() #0 {
; CHECK-LABEL: combine_gt_ge_10:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w9, [x8]
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    cmp w9, #10
; CHECK-NEXT:    b.le .LBB0_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w10, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w10, w9
; CHECK-NEXT:    b.ne .LBB0_4
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB0_3: // %lor.lhs.false
; CHECK-NEXT:    b.lt .LBB0_6
; CHECK-NEXT:  .LBB0_4: // %land.lhs.true3
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB0_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB0_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp sgt i32 %0, 10
  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %land.lhs.true3

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp sgt i32 %0, 9
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false, %land.lhs.true
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

; (a > 5 && b == c) || (a < 5 && b == d)
define i32 @combine_gt_lt_5() #0 {
; CHECK-LABEL: combine_gt_lt_5:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmp w8, #5
; CHECK-NEXT:    b.le .LBB1_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB1_6
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB1_3: // %lor.lhs.false
; CHECK-NEXT:    b.ge .LBB1_6
; CHECK-NEXT:  // %bb.4: // %land.lhs.true3
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB1_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB1_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp sgt i32 %0, 5
  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %if.end

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp slt i32 %0, 5
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

; (a < 5 && b == c) || (a <= 5 && b == d)
define i32 @combine_lt_ge_5() #0 {
; CHECK-LABEL: combine_lt_ge_5:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w9, [x8]
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    cmp w9, #5
; CHECK-NEXT:    b.ge .LBB2_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w10, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w10, w9
; CHECK-NEXT:    b.ne .LBB2_4
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB2_3: // %lor.lhs.false
; CHECK-NEXT:    b.gt .LBB2_6
; CHECK-NEXT:  .LBB2_4: // %land.lhs.true3
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB2_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB2_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp slt i32 %0, 5
  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %land.lhs.true3

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp slt i32 %0, 6
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false, %land.lhs.true
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

; (a < 5 && b == c) || (a > 5 && b == d)
define i32 @combine_lt_gt_5() #0 {
; CHECK-LABEL: combine_lt_gt_5:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmp w8, #5
; CHECK-NEXT:    b.ge .LBB3_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB3_6
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB3_3: // %lor.lhs.false
; CHECK-NEXT:    b.le .LBB3_6
; CHECK-NEXT:  // %bb.4: // %land.lhs.true3
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB3_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB3_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp slt i32 %0, 5
  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %if.end

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp sgt i32 %0, 5
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

; (a > -5 && b == c) || (a < -5 && b == d)
define i32 @combine_gt_lt_n5() #0 {
; CHECK-LABEL: combine_gt_lt_n5:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmn w8, #5
; CHECK-NEXT:    b.le .LBB4_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB4_6
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB4_3: // %lor.lhs.false
; CHECK-NEXT:    b.ge .LBB4_6
; CHECK-NEXT:  // %bb.4: // %land.lhs.true3
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB4_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB4_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp sgt i32 %0, -5
  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %if.end

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp slt i32 %0, -5
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

; (a < -5 && b == c) || (a > -5 && b == d)
define i32 @combine_lt_gt_n5() #0 {
; CHECK-LABEL: combine_lt_gt_n5:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmn w8, #5
; CHECK-NEXT:    b.ge .LBB5_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB5_6
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB5_3: // %lor.lhs.false
; CHECK-NEXT:    b.le .LBB5_6
; CHECK-NEXT:  // %bb.4: // %land.lhs.true3
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB5_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB5_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp slt i32 %0, -5
  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %if.end

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp sgt i32 %0, -5
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

%struct.Struct = type { i64, i64 }

@glob = internal unnamed_addr global %struct.Struct* null, align 8

declare %struct.Struct* @Update(%struct.Struct*) #1

; no checks for this case, it just should be processed without errors
define void @combine_non_adjacent_cmp_br(%struct.Struct* nocapture readonly %hdCall) #0 {
; CHECK-LABEL: combine_non_adjacent_cmp_br:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    str x30, [sp, #-48]! // 8-byte Folded Spill
; CHECK-NEXT:    .cfi_def_cfa_offset 48
; CHECK-NEXT:    stp x22, x21, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
; CHECK-NEXT:    .cfi_offset w19, -8
; CHECK-NEXT:    .cfi_offset w20, -16
; CHECK-NEXT:    .cfi_offset w21, -24
; CHECK-NEXT:    .cfi_offset w22, -32
; CHECK-NEXT:    .cfi_offset w30, -48
; CHECK-NEXT:    ldr x20, [x0]
; CHECK-NEXT:    mov w19, #24
; CHECK-NEXT:    adrp x22, glob
; CHECK-NEXT:    add x21, x20, #2
; CHECK-NEXT:  .LBB6_1: // %land.rhs
; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    ldr x8, [x19]
; CHECK-NEXT:    cmp x8, #1
; CHECK-NEXT:    b.lt .LBB6_3
; CHECK-NEXT:  // %bb.2: // %while.body
; CHECK-NEXT:    // in Loop: Header=BB6_1 Depth=1
; CHECK-NEXT:    ldr x0, [x22, :lo12:glob]
; CHECK-NEXT:    bl Update
; CHECK-NEXT:    sub x21, x21, #2
; CHECK-NEXT:    cmp x20, x21
; CHECK-NEXT:    b.lt .LBB6_1
; CHECK-NEXT:  .LBB6_3: // %while.end
; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-NEXT:    ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT:    ldr x30, [sp], #48 // 8-byte Folded Reload
; CHECK-NEXT:    .cfi_def_cfa_offset 0
; CHECK-NEXT:    .cfi_restore w19
; CHECK-NEXT:    .cfi_restore w20
; CHECK-NEXT:    .cfi_restore w21
; CHECK-NEXT:    .cfi_restore w22
; CHECK-NEXT:    .cfi_restore w30
; CHECK-NEXT:    ret
entry:
  %size = getelementptr inbounds %struct.Struct, %struct.Struct* %hdCall, i64 0, i32 0
  %0 = load i64, i64* %size, align 8
  br label %land.rhs

land.rhs:
  %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ]
  %1 = load i64, i64* inttoptr (i64 24 to i64*), align 8
  %cmp2 = icmp sgt i64 %1, 0
  br i1 %cmp2, label %while.body, label %while.end

while.body:
  %2 = load %struct.Struct*, %struct.Struct** @glob, align 8
  %call = tail call %struct.Struct* @Update(%struct.Struct* %2) #2
  %sub = add nsw i64 %rp.06, -2
  %cmp = icmp slt i64 %0, %rp.06
  br i1 %cmp, label %land.rhs, label %while.end

while.end:
  ret void
}

; undefined external to prevent possible optimizations
declare void @do_something() #1

define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT:    .cfi_def_cfa_offset 32
; CHECK-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT:    .cfi_offset w19, -8
; CHECK-NEXT:    .cfi_offset w20, -16
; CHECK-NEXT:    .cfi_offset w30, -32
; CHECK-NEXT:    adrp x19, :got:a
; CHECK-NEXT:    ldr x19, [x19, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x19]
; CHECK-NEXT:    cmn w8, #2
; CHECK-NEXT:    b.gt .LBB7_4
; CHECK-NEXT:  // %bb.1: // %while.body.preheader
; CHECK-NEXT:    sub w20, w8, #1
; CHECK-NEXT:  .LBB7_2: // %while.body
; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    bl do_something
; CHECK-NEXT:    adds w20, w20, #1
; CHECK-NEXT:    b.mi .LBB7_2
; CHECK-NEXT:  // %bb.3: // %while.cond.while.end_crit_edge
; CHECK-NEXT:    ldr w8, [x19]
; CHECK-NEXT:  .LBB7_4: // %while.end
; CHECK-NEXT:    cmp w8, #1
; CHECK-NEXT:    b.gt .LBB7_7
; CHECK-NEXT:  // %bb.5: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB7_7
; CHECK-NEXT:  // %bb.6:
; CHECK-NEXT:    mov w0, #123
; CHECK-NEXT:    b .LBB7_8
; CHECK-NEXT:  .LBB7_7: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:  .LBB7_8: // %return
; CHECK-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT:    ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT:    .cfi_def_cfa_offset 0
; CHECK-NEXT:    .cfi_restore w19
; CHECK-NEXT:    .cfi_restore w20
; CHECK-NEXT:    .cfi_restore w30
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp4 = icmp slt i32 %0, -1
  br i1 %cmp4, label %while.body.preheader, label %while.end

while.body.preheader:                             ; preds = %entry
  br label %while.body

while.body:                                       ; preds = %while.body, %while.body.preheader
  %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
  tail call void @do_something() #2
  %inc = add nsw i32 %i.05, 1
  %cmp = icmp slt i32 %i.05, 0
  br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge

while.cond.while.end_crit_edge:                   ; preds = %while.body
  %.pre = load i32, i32* @a, align 4
  br label %while.end

while.end:                                        ; preds = %while.cond.while.end_crit_edge, %entry
  %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ]
  %cmp1 = icmp slt i32 %1, 2
  br i1 %cmp1, label %land.lhs.true, label %if.end

land.lhs.true:                                    ; preds = %while.end
  %2 = load i32, i32* @b, align 4
  %3 = load i32, i32* @d, align 4
  %cmp2 = icmp eq i32 %2, %3
  br i1 %cmp2, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true, %while.end
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
  ret i32 %retval.0
}

define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset w19, -8
; CHECK-NEXT:    .cfi_offset w30, -16
; CHECK-NEXT:    .cfi_remember_state
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmp w8, #0
; CHECK-NEXT:    b.gt .LBB8_3
; CHECK-NEXT:  // %bb.1: // %while.body.preheader
; CHECK-NEXT:    sub w19, w8, #1
; CHECK-NEXT:  .LBB8_2: // %while.body
; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    bl do_something
; CHECK-NEXT:    adds w19, w19, #1
; CHECK-NEXT:    b.mi .LBB8_2
; CHECK-NEXT:  .LBB8_3: // %while.end
; CHECK-NEXT:    adrp x8, :got:c
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:c]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmn w8, #2
; CHECK-NEXT:    b.lt .LBB8_6
; CHECK-NEXT:  // %bb.4: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB8_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #123
; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT:    .cfi_def_cfa_offset 0
; CHECK-NEXT:    .cfi_restore w19
; CHECK-NEXT:    .cfi_restore w30
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB8_6: // %if.end
; CHECK-NEXT:    .cfi_restore_state
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT:    .cfi_def_cfa_offset 0
; CHECK-NEXT:    .cfi_restore w19
; CHECK-NEXT:    .cfi_restore w30
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp4 = icmp slt i32 %0, 1
  br i1 %cmp4, label %while.body.preheader, label %while.end

while.body.preheader:                             ; preds = %entry
  br label %while.body

while.body:                                       ; preds = %while.body, %while.body.preheader
  %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
  tail call void @do_something() #2
  %inc = add nsw i32 %i.05, 1
  %cmp = icmp slt i32 %i.05, 0
  br i1 %cmp, label %while.body, label %while.end.loopexit

while.end.loopexit:                               ; preds = %while.body
  br label %while.end

while.end:                                        ; preds = %while.end.loopexit, %entry
  %1 = load i32, i32* @c, align 4
  %cmp1 = icmp sgt i32 %1, -3
  br i1 %cmp1, label %land.lhs.true, label %if.end

land.lhs.true:                                    ; preds = %while.end
  %2 = load i32, i32* @b, align 4
  %3 = load i32, i32* @d, align 4
  %cmp2 = icmp eq i32 %2, %3
  br i1 %cmp2, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true, %while.end
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
  ret i32 %retval.0
}

; Test in the following case, we don't hit 'cmp' and trigger a false positive
; cmp  w19, #0
; cinc w0, w19, gt
; ...
; fcmp d8, #0.0
; b.gt .LBB0_5

define i32 @fcmpri(i32 %argc, i8** nocapture readonly %argv) #0 {
; CHECK-LABEL: fcmpri:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    str d8, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT:    .cfi_def_cfa_offset 32
; CHECK-NEXT:    stp x30, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT:    .cfi_offset w19, -8
; CHECK-NEXT:    .cfi_offset w30, -16
; CHECK-NEXT:    .cfi_offset b8, -32
; CHECK-NEXT:    cmp w0, #2
; CHECK-NEXT:    b.lt .LBB9_3
; CHECK-NEXT:  // %bb.1: // %land.lhs.true
; CHECK-NEXT:    ldr x8, [x1, #8]
; CHECK-NEXT:    cbz x8, .LBB9_3
; CHECK-NEXT:  // %bb.2:
; CHECK-NEXT:    mov w0, #3
; CHECK-NEXT:    b .LBB9_4
; CHECK-NEXT:  .LBB9_3: // %if.end
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    bl zoo
; CHECK-NEXT:    mov w19, w0
; CHECK-NEXT:    mov w0, #-1
; CHECK-NEXT:    bl yoo
; CHECK-NEXT:    cmp w19, #0
; CHECK-NEXT:    mov w1, #2
; CHECK-NEXT:    cinc w0, w19, gt
; CHECK-NEXT:    fmov d8, d0
; CHECK-NEXT:    bl xoo
; CHECK-NEXT:    fmov d0, #-1.00000000
; CHECK-NEXT:    fcmp d8, #0.0
; CHECK-NEXT:    fmov d1, #-2.00000000
; CHECK-NEXT:    fadd d0, d8, d0
; CHECK-NEXT:    fcsel d0, d8, d0, gt
; CHECK-NEXT:    bl woo
; CHECK-NEXT:    mov w0, #4
; CHECK-NEXT:  .LBB9_4: // %return
; CHECK-NEXT:    ldp x30, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT:    ldr d8, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT:    .cfi_def_cfa_offset 0
; CHECK-NEXT:    .cfi_restore w19
; CHECK-NEXT:    .cfi_restore w30
; CHECK-NEXT:    .cfi_restore b8
; CHECK-NEXT:    ret

; CHECK-LABEL-DAG: .LBB9_3

entry:
  %cmp = icmp sgt i32 %argc, 1
  br i1 %cmp, label %land.lhs.true, label %if.end

land.lhs.true:                                    ; preds = %entry
  %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1
  %0 = load i8*, i8** %arrayidx, align 8
  %cmp1 = icmp eq i8* %0, null
  br i1 %cmp1, label %if.end, label %return

if.end:                                           ; preds = %land.lhs.true, %entry
  %call = call i32 @zoo(i32 1)
  %call2 = call double @yoo(i32 -1)
  %cmp4 = icmp sgt i32 %call, 0
  %add = zext i1 %cmp4 to i32
  %cond = add nsw i32 %add, %call
  %call7 = call i32 @xoo(i32 %cond, i32 2)
  %cmp9 = fcmp ogt double %call2, 0.000000e+00
  br i1 %cmp9, label %cond.end14, label %cond.false12

cond.false12:                                     ; preds = %if.end
  %sub = fadd fast double %call2, -1.000000e+00
  br label %cond.end14

cond.end14:                                       ; preds = %if.end, %cond.false12
  %cond15 = phi double [ %sub, %cond.false12 ], [ %call2, %if.end ]
  %call16 = call i32 @woo(double %cond15, double -2.000000e+00)
  br label %return

return:                                           ; preds = %land.lhs.true, %cond.end14
  %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ]
  ret i32 %retval.0
}

define void @cmp_shifted(i32 %in, i32 %lhs, i32 %rhs) #0 {
; CHECK-LABEL: cmp_shifted:
; CHECK:       // %bb.0: // %common.ret
; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset w30, -16
; CHECK-NEXT:    mov w8, #42
; CHECK-NEXT:    cmp w0, #0
; CHECK-NEXT:    csinc w8, w8, wzr, gt
; CHECK-NEXT:    cmp w0, #2, lsl #12 // =8192
; CHECK-NEXT:    mov w9, #128
; CHECK-NEXT:    csel w0, w9, w8, ge
; CHECK-NEXT:    bl zoo
; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT:    .cfi_def_cfa_offset 0
; CHECK-NEXT:    .cfi_restore w30
; CHECK-NEXT:    ret
; [...]

  %tst_low = icmp sgt i32 %in, 8191
  br i1 %tst_low, label %true, label %false

true:
  call i32 @zoo(i32 128)
  ret void

false:
  %tst = icmp sgt i32 %in, 0
  br i1 %tst, label %truer, label %falser

truer:
  call i32 @zoo(i32 42)
  ret void

falser:
  call i32 @zoo(i32 1)
  ret void
}

define i32 @combine_gt_ge_sel(i64 %v, i64* %p) #0 {
; CHECK-LABEL: combine_gt_ge_sel:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT:    adrp x8, :got:a
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    cmp w8, #0
; CHECK-NEXT:    csel x9, x0, xzr, gt
; CHECK-NEXT:    str x9, [x1]
; CHECK-NEXT:    b.le .LBB11_2
; CHECK-NEXT:  // %bb.1: // %lor.lhs.false
; CHECK-NEXT:    cmp w8, #2
; CHECK-NEXT:    b.ge .LBB11_4
; CHECK-NEXT:    b .LBB11_6
; CHECK-NEXT:  .LBB11_2: // %land.lhs.true
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:c
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB11_4
; CHECK-NEXT:  // %bb.3:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB11_4: // %land.lhs.true3
; CHECK-NEXT:    adrp x8, :got:b
; CHECK-NEXT:    adrp x9, :got:d
; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
; CHECK-NEXT:    ldr w8, [x8]
; CHECK-NEXT:    ldr w9, [x9]
; CHECK-NEXT:    cmp w8, w9
; CHECK-NEXT:    b.ne .LBB11_6
; CHECK-NEXT:  // %bb.5:
; CHECK-NEXT:    mov w0, #1
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB11_6: // %if.end
; CHECK-NEXT:    mov w0, wzr
; CHECK-NEXT:    ret
entry:
  %0 = load i32, i32* @a, align 4
  %cmp = icmp sgt i32 %0, 0
  %m = select i1 %cmp, i64 %v, i64 0
  store i64 %m, i64* %p
  br i1 %cmp, label %lor.lhs.false, label %land.lhs.true

land.lhs.true:                                    ; preds = %entry
  %1 = load i32, i32* @b, align 4
  %2 = load i32, i32* @c, align 4
  %cmp1 = icmp eq i32 %1, %2
  br i1 %cmp1, label %return, label %land.lhs.true3

lor.lhs.false:                                    ; preds = %entry
  %cmp2 = icmp sgt i32 %0, 1
  br i1 %cmp2, label %land.lhs.true3, label %if.end

land.lhs.true3:                                   ; preds = %lor.lhs.false, %land.lhs.true
  %3 = load i32, i32* @b, align 4
  %4 = load i32, i32* @d, align 4
  %cmp4 = icmp eq i32 %3, %4
  br i1 %cmp4, label %return, label %if.end

if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false
  br label %return

return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
  %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
  ret i32 %retval.0
}

declare i32 @zoo(i32)

declare double @yoo(i32)

declare i32 @xoo(i32, i32)

declare i32 @woo(double, double)

attributes #0 = { uwtable }