578 lines
22 KiB
LLVM
578 lines
22 KiB
LLVM
|
; 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
|
||
|
}
|