Florian Hahn 17139f38e5
[LAA] Check HasSameSize before couldPreventStoreLoadForward.
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.
2023-11-27 10:10:41 +00:00

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
}