llvm/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll

; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
; RUN: opt -passes='print<access-info>' -disable-output  < %s 2>&1 | FileCheck %s

%s1 = type { [32000 x double], [32000 x double], [32000 x double] }

define i32 @load_with_pointer_phi_no_runtime_checks(ptr %data) {
; CHECK-LABEL: 'load_with_pointer_phi_no_runtime_checks'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Memory dependences are safe
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %iv.next = add nuw nsw i64 %iv, 1
  %cmp5 = icmp ult i64 %iv, 15999
  %arrayidx = getelementptr inbounds %s1, ptr %data, i64 0, i32 0, i64 %iv
  br i1 %cmp5, label %if.then, label %if.else

if.then:                                          ; preds = %loop.header
  %gep.1 = getelementptr inbounds %s1, ptr %data, i64 0, i32 1, i64 %iv
  br label %loop.latch

if.else:                                          ; preds = %loop.header
  %gep.2 = getelementptr inbounds %s1, ptr %data, i64 0, i32 2, i64 %iv
  br label %loop.latch

loop.latch:                                          ; preds = %if.else, %if.then
  %gep.2.sink = phi ptr [ %gep.2, %if.else ], [ %gep.1, %if.then ]
  %v8 = load double, ptr %gep.2.sink, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %arrayidx, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @store_with_pointer_phi_no_runtime_checks(ptr %data) {
; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Memory dependences are safe
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %iv.next = add nuw nsw i64 %iv, 1
  %cmp5 = icmp ult i64 %iv, 15999
  %arrayidx = getelementptr inbounds %s1, ptr %data, i64 0, i32 0, i64 %iv
  br i1 %cmp5, label %if.then, label %if.else

if.then:                                          ; preds = %loop.header
  %gep.1 = getelementptr inbounds %s1, ptr %data, i64 0, i32 1, i64 %iv
  br label %loop.latch

if.else:                                          ; preds = %loop.header
  %gep.2 = getelementptr inbounds %s1, ptr %data, i64 0, i32 2, i64 %iv
  br label %loop.latch

loop.latch:                                          ; preds = %if.else, %if.then
  %gep.2.sink = phi ptr [ %gep.2, %if.else ], [ %gep.1, %if.then ]
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %gep.2.sink, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @store_with_pointer_phi_runtime_checks(ptr %A, ptr %B, ptr %C) {
; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Memory dependences are safe with run-time checks
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Check 0:
; CHECK-NEXT:        Comparing group ([[GRP1:0x[0-9a-f]+]]):
; CHECK-NEXT:          %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
; CHECK-NEXT:        Against group ([[GRP2:0x[0-9a-f]+]]):
; CHECK-NEXT:          %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
; CHECK-NEXT:      Check 1:
; CHECK-NEXT:        Comparing group ([[GRP1]]):
; CHECK-NEXT:          %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
; CHECK-NEXT:        Against group ([[GRP3:0x[0-9a-f]+]]):
; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
; CHECK-NEXT:      Check 2:
; CHECK-NEXT:        Comparing group ([[GRP2]]):
; CHECK-NEXT:          %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
; CHECK-NEXT:        Against group ([[GRP3]]):
; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
; CHECK-NEXT:      Grouped accesses:
; CHECK-NEXT:        Group [[GRP1]]:
; CHECK-NEXT:          (Low: %B High: (256000 + %B))
; CHECK-NEXT:            Member: {%B,+,8}<nw><%loop.header>
; CHECK-NEXT:        Group [[GRP2]]:
; CHECK-NEXT:          (Low: %C High: (256000 + %C))
; CHECK-NEXT:            Member: {%C,+,8}<nw><%loop.header>
; CHECK-NEXT:        Group [[GRP3]]:
; CHECK-NEXT:          (Low: %A High: (256000 + %A))
; CHECK-NEXT:            Member: {%A,+,8}<nw><%loop.header>
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %iv.next = add nuw nsw i64 %iv, 1
  %cmp5 = icmp ult i64 %iv, 15999
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  br i1 %cmp5, label %if.then, label %if.else

if.then:                                          ; preds = %loop.header
  %gep.1 = getelementptr inbounds double, ptr %B, i64 %iv
  br label %loop.latch

if.else:                                          ; preds = %loop.header
  %gep.2 = getelementptr inbounds double, ptr %C, i64 %iv
  br label %loop.latch

loop.latch:                                          ; preds = %if.else, %if.then
  %gep.2.sink = phi ptr [ %gep.2, %if.else ], [ %gep.1, %if.then ]
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %gep.2.sink, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @load_with_pointer_phi_outside_loop(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
; CHECK-LABEL: 'load_with_pointer_phi_outside_loop'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT:  Unknown data dependence.
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %v8 = load double, ptr %ptr, align 8 ->
; CHECK-NEXT:            store double %mul16, ptr %arrayidx, align 8
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br i1 %c.0, label %if.then, label %if.else

if.then:
  br label %loop.ph

if.else:
  %ptr.select = select i1 %c.1, ptr %C, ptr %B
  br label %loop.ph

loop.ph:
  %ptr = phi ptr [ %A, %if.then ], [ %ptr.select, %if.else ]
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
  %iv.next = add nuw nsw i64 %iv, 1
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  %v8 = load double, ptr %ptr, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %arrayidx, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @store_with_pointer_phi_outside_loop(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
; CHECK-LABEL: 'store_with_pointer_phi_outside_loop'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT:  Unknown data dependence.
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
; CHECK-NEXT:            store double %mul16, ptr %ptr, align 8
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br i1 %c.0, label %if.then, label %if.else

if.then:
  br label %loop.ph

if.else:
  %ptr.select = select i1 %c.1, ptr %C, ptr %B
  br label %loop.ph

loop.ph:
  %ptr = phi ptr [ %A, %if.then ], [ %ptr.select, %if.else ]
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
  %iv.next = add nuw nsw i64 %iv, 1
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %ptr, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @store_with_pointer_phi_incoming_phi(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT:  Unknown data dependence.
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
; CHECK-NEXT:            store double %mul16, ptr %ptr.2, align 8
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Check 0:
; CHECK-NEXT:        Comparing group ([[GRP4:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        Against group ([[GRP5:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:      Check 1:
; CHECK-NEXT:        Comparing group ([[GRP4]]):
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        Against group ([[GRP6:0x[0-9a-f]+]]):
; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:      Check 2:
; CHECK-NEXT:        Comparing group ([[GRP5]]):
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:        Against group ([[GRP6]]):
; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:      Grouped accesses:
; CHECK-NEXT:        Group [[GRP4]]:
; CHECK-NEXT:          (Low: %C High: (8 + %C))
; CHECK-NEXT:            Member: %C
; CHECK-NEXT:        Group [[GRP5]]:
; CHECK-NEXT:          (Low: %B High: (8 + %B))
; CHECK-NEXT:            Member: %B
; CHECK-NEXT:        Group [[GRP6]]:
; CHECK-NEXT:          (Low: %A High: (256000 + %A))
; CHECK-NEXT:            Member: {%A,+,8}<nuw><%loop.header>
; CHECK-NEXT:            Member: %A
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
; CHECK-EMPTY
entry:
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %iv.next = add nuw nsw i64 %iv, 1
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  br i1 %c.0, label %loop.then, label %loop.latch

loop.then:
  br i1 %c.0, label %loop.then.2, label %loop.else.2

loop.then.2:
  br label %merge.2

loop.else.2:
  br label %merge.2


merge.2:
  %ptr = phi ptr [ %A, %loop.then.2 ], [ %B, %loop.else.2 ]
  br label %loop.latch


loop.latch:
  %ptr.2 = phi ptr [ %ptr, %merge.2], [ %C, %loop.header ]
  store double %mul16, ptr %ptr.2, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

; Test cases with pointer phis forming a cycle.
define i32 @store_with_pointer_phi_incoming_phi_irreducible_cycle(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
; CHECK-LABEL: 'store_with_pointer_phi_incoming_phi_irreducible_cycle'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT:  Unknown data dependence.
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
; CHECK-NEXT:            store double %mul16, ptr %ptr.3, align 8
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Check 0:
; CHECK-NEXT:        Comparing group ([[GRP7:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        Against group ([[GRP8:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:      Check 1:
; CHECK-NEXT:        Comparing group ([[GRP7]]):
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        Against group ([[GRP9:0x[0-9a-f]+]]):
; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:      Check 2:
; CHECK-NEXT:        Comparing group ([[GRP8]]):
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:        Against group ([[GRP9]]):
; CHECK-NEXT:          %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:      Grouped accesses:
; CHECK-NEXT:        Group [[GRP7]]:
; CHECK-NEXT:          (Low: %C High: (8 + %C))
; CHECK-NEXT:            Member: %C
; CHECK-NEXT:        Group [[GRP8]]:
; CHECK-NEXT:          (Low: %B High: (8 + %B))
; CHECK-NEXT:            Member: %B
; CHECK-NEXT:        Group [[GRP9]]:
; CHECK-NEXT:          (Low: %A High: (256000 + %A))
; CHECK-NEXT:            Member: {%A,+,8}<nuw><%loop.header>
; CHECK-NEXT:            Member: %A
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
; CHECK-EMPTY
entry:
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %iv.next = add nuw nsw i64 %iv, 1
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  br i1 %c.0, label %loop.then, label %loop.latch

loop.then:
  br i1 %c.0, label %BB.A, label %BB.B

BB.A:
  %ptr = phi ptr [ %A, %loop.then ], [ %ptr.2, %BB.B ]
  br label %BB.B

BB.B:
  %ptr.2 = phi ptr [ %ptr, %BB.A ], [ %B, %loop.then ]
  br i1 %c.1, label %loop.latch, label %BB.A

loop.latch:
  %ptr.3 = phi ptr [ %ptr.2, %BB.B ], [ %C, %loop.header ]
  store double %mul16, ptr %ptr.3, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @store_with_pointer_phi_outside_loop_select(ptr %A, ptr %B, ptr %C, i1 %c.0, i1 %c.1) {
; CHECK-LABEL: 'store_with_pointer_phi_outside_loop_select'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT:  Unknown data dependence.
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %v8 = load double, ptr %arrayidx, align 8 ->
; CHECK-NEXT:            store double %mul16, ptr %ptr, align 8
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br i1 %c.0, label %if.then, label %if.else

if.then:
  br label %loop.ph

if.else:
  %ptr.select = select i1 %c.1, ptr %C, ptr %B
  br label %loop.ph

loop.ph:
  %ptr = phi ptr [ %A, %if.then ], [ %ptr.select, %if.else ]
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ]
  %iv.next = add nuw nsw i64 %iv, 1
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %ptr, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define i32 @store_with_pointer_phi_in_same_bb_use_other_phi(ptr %A, ptr %B, ptr %C, ptr %D, i1 %c.0, i1 %c.1) {
; CHECK-LABEL: 'store_with_pointer_phi_in_same_bb_use_other_phi'
; CHECK-NEXT:    loop.header:
; CHECK-NEXT:      Report: cannot identify array bounds
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Grouped accesses:
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %loop.header

loop.header:                                        ; preds = %loop.latch, %entry
  %ptr.0 = phi ptr [ %C, %entry ], [ %D, %loop.header ]
  %ptr.1 = phi ptr [ %B, %entry ], [ %ptr.0, %loop.header ]
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.header ]
  %iv.next = add nuw nsw i64 %iv, 1
  %arrayidx = getelementptr inbounds double, ptr %A, i64 %iv
  %v8 = load double, ptr %arrayidx, align 8
  %mul16 = fmul double 3.0, %v8
  store double %mul16, ptr %ptr.1, align 8
  %exitcond.not = icmp eq i64 %iv.next, 32000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 10
}

define void @phi_load_store_memdep_check(i1 %c, ptr %A, ptr %B, ptr %C) {
; CHECK-LABEL: 'phi_load_store_memdep_check'
; CHECK-NEXT:    for.body:
; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
; CHECK-NEXT:  Unknown data dependence.
; CHECK-NEXT:      Dependences:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %lv3 = load i16, ptr %c.sink, align 2 ->
; CHECK-NEXT:            store i16 %add, ptr %c.sink, align 1
; CHECK-EMPTY:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %lv3 = load i16, ptr %c.sink, align 2 ->
; CHECK-NEXT:            store i16 %add, ptr %c.sink, align 1
; CHECK-EMPTY:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            %lv = load i16, ptr %A, align 1 ->
; CHECK-NEXT:            store i16 %lv, ptr %A, align 1
; CHECK-EMPTY:
; CHECK-NEXT:        Unknown:
; CHECK-NEXT:            store i16 %lv, ptr %A, align 1 ->
; CHECK-NEXT:            %lv2 = load i16, ptr %A, align 1
; CHECK-EMPTY:
; CHECK-NEXT:      Run-time memory checks:
; CHECK-NEXT:      Check 0:
; CHECK-NEXT:        Comparing group ([[GRP10:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:        Against group ([[GRP11:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:      Check 1:
; CHECK-NEXT:        Comparing group ([[GRP10]]):
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:        ptr %A
; CHECK-NEXT:        Against group ([[GRP12:0x[0-9a-f]+]]):
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:      Check 2:
; CHECK-NEXT:        Comparing group ([[GRP11]]):
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        ptr %C
; CHECK-NEXT:        Against group ([[GRP12]]):
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:        ptr %B
; CHECK-NEXT:      Grouped accesses:
; CHECK-NEXT:        Group [[GRP10]]:
; CHECK-NEXT:          (Low: %A High: (2 + %A))
; CHECK-NEXT:            Member: %A
; CHECK-NEXT:            Member: %A
; CHECK-NEXT:        Group [[GRP11]]:
; CHECK-NEXT:          (Low: %C High: (2 + %C))
; CHECK-NEXT:            Member: %C
; CHECK-NEXT:            Member: %C
; CHECK-NEXT:        Group [[GRP12]]:
; CHECK-NEXT:          (Low: %B High: (2 + %B))
; CHECK-NEXT:            Member: %B
; CHECK-NEXT:            Member: %B
; CHECK-EMPTY:
; CHECK-NEXT:      Non vectorizable stores to invariant address were found in loop.
; CHECK-NEXT:      SCEV assumptions:
; CHECK-EMPTY:
; CHECK-NEXT:      Expressions re-written:
;
entry:
  br label %for.body

for.body:                                         ; preds = %if.end, %entry
  %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
  %lv = load i16, ptr %A, align 1
  store i16 %lv, ptr %A, align 1
  br i1 %c, label %if.then, label %if.end

if.then:                                          ; preds = %for.body
  %lv2 = load i16, ptr %A, align 1
  br label %if.end

if.end:                                           ; preds = %if.then, %for.body
  %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
  %lv3 = load i16, ptr %c.sink
  %add = add i16 %lv3, 10
  store i16 %add, ptr %c.sink, align 1
  %iv.next = add nuw nsw i16 %iv, 1
  %tobool.not = icmp eq i16 %iv.next, 1000
  br i1 %tobool.not, label %for.end.loopexit, label %for.body

for.end.loopexit:                                 ; preds = %if.end
  ret void
}