
After 9645267, TypeByteSize is 0 if both access do not have the same size (i.e. HasSameSize will be false). This can cause an infinite loop in couldPreventStoreLoadForward, if HasSameSize is not checked first. So check HasSameSize first instead of after couldPreventStoreLoadForward. Checking HasSameSize first is also cheaper.
102 lines
3.6 KiB
LLVM
102 lines
3.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: opt -passes='print<access-info>' -disable-output < %s 2>&1 | FileCheck %s
|
|
|
|
; for (unsigned i = 0; i < 100; i++) {
|
|
; A[i+8] = B[i] + 2;
|
|
; C[i] = A[i] * 2;
|
|
; }
|
|
|
|
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
define void @forward_loop_carried(ptr noalias %A, ptr noalias %B, ptr noalias %C, i64 %N) {
|
|
; CHECK-LABEL: 'forward_loop_carried'
|
|
; CHECK-NEXT: for.body:
|
|
; CHECK-NEXT: Memory dependences are safe
|
|
; CHECK-NEXT: Dependences:
|
|
; CHECK-NEXT: Forward:
|
|
; CHECK-NEXT: store i32 %a_p1, ptr %Aidx_ahead, align 4 ->
|
|
; CHECK-NEXT: %a = load i32, ptr %Aidx, align 4
|
|
; 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 label %for.body
|
|
|
|
for.body: ; preds = %for.body, %entry
|
|
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
|
|
%idx = add nuw nsw i64 %indvars.iv, 8
|
|
|
|
%Aidx_ahead = getelementptr inbounds i32, ptr %A, i64 %idx
|
|
%Bidx = getelementptr inbounds i32, ptr %B, i64 %indvars.iv
|
|
%Cidx = getelementptr inbounds i32, ptr %C, i64 %indvars.iv
|
|
%Aidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
|
|
|
|
%b = load i32, ptr %Bidx, align 4
|
|
%a_p1 = add i32 %b, 2
|
|
store i32 %a_p1, ptr %Aidx_ahead, align 4
|
|
|
|
%a = load i32, ptr %Aidx, align 4
|
|
%c = mul i32 %a, 2
|
|
store i32 %c, ptr %Cidx, align 4
|
|
|
|
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
|
br i1 %exitcond, label %for.end, label %for.body
|
|
|
|
for.end: ; preds = %for.body
|
|
ret void
|
|
}
|
|
|
|
%struct = type { i8, [3 x i8], i32 }
|
|
|
|
define void @forward_different_access_sizes(ptr readnone %end, ptr %start) {
|
|
; CHECK-LABEL: 'forward_different_access_sizes'
|
|
; CHECK-NEXT: loop:
|
|
; 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: Forward loop carried data dependence that prevents store-to-load forwarding.
|
|
; CHECK-NEXT: Dependences:
|
|
; CHECK-NEXT: Forward:
|
|
; CHECK-NEXT: %l = load i24, ptr %gep.1, align 1 ->
|
|
; CHECK-NEXT: store i24 %l, ptr %ptr.iv, align 1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: ForwardButPreventsForwarding:
|
|
; CHECK-NEXT: store i32 0, ptr %gep.2, align 4 ->
|
|
; CHECK-NEXT: %l = load i24, ptr %gep.1, align 1
|
|
; CHECK-EMPTY:
|
|
; CHECK-NEXT: Forward:
|
|
; CHECK-NEXT: store i32 0, ptr %gep.2, align 4 ->
|
|
; CHECK-NEXT: store i24 %l, ptr %ptr.iv, align 1
|
|
; 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 label %loop
|
|
|
|
loop:
|
|
%ptr.iv = phi ptr [ %start, %entry ], [ %next, %loop ]
|
|
%gep.2 = getelementptr %struct, ptr %ptr.iv, i64 0, i32 2
|
|
store i32 0, ptr %gep.2, align 4
|
|
%gep.1 = getelementptr %struct, ptr %ptr.iv, i64 0, i32 1
|
|
%l = load i24, ptr %gep.1, align 1
|
|
store i24 %l, ptr %ptr.iv, align 1
|
|
%next = getelementptr inbounds %struct, ptr %ptr.iv, i64 1
|
|
%ec = icmp eq ptr %ptr.iv, %end
|
|
br i1 %ec, label %exit, label %loop
|
|
|
|
exit:
|
|
ret void
|
|
}
|